protected bool CreateOrUpdateRule(string ruleName, string action, string hashType, int maxCount, IEnumerable <PortRange> allowedPorts, CancellationToken cancelToken) { if (cancelToken.IsCancellationRequested) { throw new OperationCanceledException(cancelToken); } PortRange[] allowedPortsArray = allowedPorts?.ToArray(); // create or update the rule in iptables RunProcess(IpTablesProcess, true, out IReadOnlyList <string> lines, "-L --line-numbers"); string portString = " "; bool replaced = false; bool block = (action == "DROP"); if (allowedPortsArray != null && allowedPortsArray.Length != 0) { string portList = (block ? IPBanFirewallUtility.GetBlockPortRangeString(allowedPorts) : IPBanFirewallUtility.GetPortRangeStringAllow(allowedPorts)); portString = " -m multiport -p tcp --dports " + portList.Replace('-', ':') + " "; // iptables uses ':' instead of '-' for range } string ruleNameWithSpaces = " " + ruleName + " "; foreach (string line in lines) { if (line.Contains(ruleNameWithSpaces, StringComparison.OrdinalIgnoreCase)) { // rule number is first piece of the line int index = line.IndexOf(' '); int ruleNum = int.Parse(line[..index]);
protected bool CreateOrUpdateRule(string ruleName, string action, string hashType, int maxCount, IEnumerable <PortRange> allowedPorts, CancellationToken cancelToken) { if (cancelToken.IsCancellationRequested) { throw new OperationCanceledException(cancelToken); } PortRange[] allowedPortsArray = allowedPorts?.ToArray(); // create or update the rule in iptables RunProcess(IpTablesProcess, true, out IReadOnlyList <string> lines, "-L --line-numbers"); string portString = " "; bool replaced = false; bool block = (action == "DROP"); if (allowedPortsArray != null && allowedPortsArray.Length != 0) { string portList = (block ? IPBanFirewallUtility.GetBlockPortRangeString(allowedPorts) : IPBanFirewallUtility.GetPortRangeStringAllow(allowedPorts)); portString = " -m multiport -p tcp --dports " + portList.Replace('-', ':') + " "; // iptables uses ':' instead of '-' for range } string ruleNameWithSpaces = " " + ruleName + " "; foreach (string line in lines) { if (line.Contains(ruleNameWithSpaces, StringComparison.OrdinalIgnoreCase)) { // rule number is first piece of the line int index = line.IndexOf(' '); int ruleNum = int.Parse(line.Substring(0, index)); // replace the rule with the new info RunProcess(IpTablesProcess, true, $"-R INPUT {ruleNum} -m state --state NEW -m set{portString}--match-set \"{ruleName}\" src -j {action}"); replaced = true; break; } } if (!replaced) { // add a new rule, for block add to end of list (lower priority) for allow add to begin of list (higher priority) string addCommand = (block ? "-A" : "-I"); RunProcess(IpTablesProcess, true, $"{addCommand} INPUT -m state --state NEW -m set{portString}--match-set \"{ruleName}\" src -j {action}"); } if (cancelToken.IsCancellationRequested) { throw new OperationCanceledException(cancelToken); } SaveTableToDisk(); return(true); }
public MemoryFirewallRuleRanges(IEnumerable <IPAddressRange> ipRanges, List <PortRange> allowedPorts, bool block, string name) { List <IPAddressRange> ipRangesSorted = new List <IPAddressRange>(ipRanges); ipRangesSorted.Sort(); allowedPorts ??= emptyPortRanges; Block = block; Name = name; foreach (IPAddressRange range in ipRangesSorted) { // optimized storage, no pointers or other overhead if (range.Begin.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { uint begin = range.Begin.ToUInt32(); uint end = range.End.ToUInt32(); Debug.Assert(end >= begin); ipv4.Add(new IPV4Range { Begin = begin, End = end }); } else { UInt128 begin = range.Begin.ToUInt128(); UInt128 end = range.End.ToUInt128(); Debug.Assert(end.CompareTo(begin) >= 0); ipv6.Add(new IPV6Range { Begin = begin, End = end }); } } ipv4.TrimExcess(); ipv6.TrimExcess(); if (block) { string portString = IPBanFirewallUtility.GetBlockPortRangeString(allowedPorts); this.portRanges = (string.IsNullOrWhiteSpace(portString) ? new List <PortRange>(0) : portString.Split(',').Select(s => PortRange.Parse(s)).ToList()); } else { this.portRanges = allowedPorts; } }
private bool GetOrCreateRule(string ruleName, string remoteIPAddresses, NetFwAction action, IEnumerable <PortRange> allowedPorts = null) { remoteIPAddresses = (remoteIPAddresses ?? string.Empty).Trim(); bool emptyIPAddressString = string.IsNullOrWhiteSpace(remoteIPAddresses) || remoteIPAddresses == "*"; bool ruleNeedsToBeAdded = false; lock (policy) { recreateRule: INetFwRule rule = null; try { rule = policy.Rules.Item(ruleName); } catch { // ignore exception, assume does not exist } if (rule is null) { rule = Activator.CreateInstance(ruleType) as INetFwRule; rule.Name = ruleName; rule.Enabled = true; rule.Action = action; rule.Description = "Automatically created by IPBan"; rule.Direction = NetFwRuleDirection.Inbound; rule.EdgeTraversal = false; rule.Grouping = "IPBan"; rule.LocalAddresses = "*"; rule.Profiles = int.MaxValue; // all ruleNeedsToBeAdded = true; } // do not ever set an empty string, Windows treats this as * which means everything if (!emptyIPAddressString) { try { PortRange[] allowedPortsArray = (allowedPorts?.ToArray()); if (allowedPortsArray != null && allowedPortsArray.Length != 0) { rule.Protocol = (int)NetFwIPProtocol.TCP; string localPorts; if (action == NetFwAction.Block) { localPorts = IPBanFirewallUtility.GetBlockPortRangeString(allowedPortsArray); } else { localPorts = IPBanFirewallUtility.GetPortRangeStringAllow(allowedPortsArray); } rule.LocalPorts = localPorts; } else { try { rule.Protocol = (int)NetFwIPProtocol.Any; } catch { // failed to set protocol to any, we are switching from tcp back to any without ports, the only option is to // recreate the rule if (!ruleNeedsToBeAdded) { policy.Rules.Remove(ruleName); goto recreateRule; } } } rule.RemoteAddresses = (remoteIPAddresses == "0.0.0.0/0,::/0" ? "*" : remoteIPAddresses); } catch (Exception ex) { // if something failed, do not create the rule emptyIPAddressString = true; Logger.Error(ex); } } if (emptyIPAddressString || string.IsNullOrWhiteSpace(rule.RemoteAddresses) || (rule.RemoteAddresses == "*" && remoteIPAddresses != "0.0.0.0/0,::/0")) { // if no ip addresses, remove the rule as it will allow or block everything with an empty RemoteAddresses string try { rule = null; policy.Rules.Remove(ruleName); } catch { } } else if (ruleNeedsToBeAdded) { policy.Rules.Add(rule); } return(rule != null); } }