Example #1
0
 private void CreateChains(IpTablesDetails config, RuleBuilder rb)
 {
     foreach (var c in config.Chains)
     {
         if (c.IsDynamic)
         {
             rb.DefineDynamicChain(c.Dynamic);
         }
         foreach (var v in c.Versions)
         {
             var rules = _ruleSets[v];
             var chains = rules.Chains;
             foreach (var t in c.Tables)
             {
                 if (c.IsDynamic)
                 {
                     rb.Dcr.RegisterDynamicChain(c.Dynamic, t, c.Name, v);
                 }
                 else if (!chains.HasChain(c.Name, t))
                 {
                     chains.AddChain(c.Name, t, _iptables);
                 }
             }
         }
     }
 }
Example #2
0
        private RuleBuilder InitEnvironment(Dictionary<String, EnvironmentDetails> environment)
        {
            RuleBuilder rb = new RuleBuilder(_iptables, "/var/x4b/bin/bpf/nfbpf_compile", _ruleSets);
            var mappings = environment.AsParallel().Select((e) =>
            {
                if (e.Value.Language == "bash")
                {
                    e.Value.Command = rb.ExecuteBash(e.Value.Command);
                }
                else if (e.Value.Language == "bpf")
                {
                    e.Value.Command = rb.CompileBpf("RAW", e.Value.Command);
                }
                else if (e.Value.Language == "bpfl4")
                {
                    e.Value.Command = rb.CompileBpf("RAW_TRANSPORT", e.Value.Command);
                }
                else if (e.Value.Language != "text")
                {
                    throw new Exception("Invalid language: " + e.Value.Language);
                }
                return e;
            });

            foreach (var e in mappings)
            {
                rb.DefineMapping(e.Key, e.Value.Command, e.Value.Default);
            }
            return rb;
        }
Example #3
0
        private void CreateSets(IpTablesDetails config, RuleBuilder rb)
        {
            foreach (var set in config.Sets)
            {
                var      ipset    = new IpSetSet(IpSetTypeHelper.StringToType(set.Type), set.Name, 0, set.Family, _iptables, IpSetSyncMode.SetAndEntries);
                String[] resolved = set.Entries.ToArray();

                if (ipset.Type == IpSetType.HashIp)
                {
                    IPAddress ip;
                    int       retries = 0;
                    do
                    {
                        List <Task> tasks = new List <Task>();
                        for (int index = 0; index < resolved.Length; index++)
                        {
                            var entry = resolved[index];

                            String entryIp = rb.Format(entry);
                            if (!IPAddress.TryParse(entryIp, out ip))
                            {
                                DomainName domain;
                                if (!DomainName.TryParse(entryIp, out domain))
                                {
                                    throw new Exception("Unable to parse domain " + entryIp);
                                }
                                var asyncResult = _dns.ResolveAsync(domain).ContinueWith(CompleteLambda(index, resolved));
                                tasks.Add(asyncResult);
                            }
                        }

                        if (tasks.Any())
                        {
                            Task.WaitAll(tasks.ToArray());
                        }
                    } while (++retries <= 3 && resolved.Any((entry) => !IPAddress.TryParse(rb.Format(entry), out ip)));
                    for (int index = 0; index < resolved.Length; index++)
                    {
                        var entry = resolved[index];

                        String entryIp = rb.Format(entry);
                        if (!IPAddress.TryParse(entryIp, out ip))
                        {
                            throw new Exception("Unable to resolve " + entryIp);
                        }
                    }
                }

                //Check Uniqueness
                HashSet <IpSetEntry> ipsetEntries = new HashSet <IpSetEntry>();

                for (int index = 0; index < resolved.Length; index++)
                {
                    var    entry    = resolved[index];
                    String entryIp  = rb.Format(entry);
                    var    setEntry = IpSetEntry.ParseFromParts(ipset, entryIp);
                    if (ipsetEntries.Add(setEntry))
                    {
                        ipset.Entries.Add(setEntry);
                    }
                }
                _sets.AddSet(ipset);
            }

            //Add new sets (dont delete!)
            _sets.Sync((a) => false);
        }
Example #4
0
        private IEnumerable<IpTablesRule> ParseAll(RuleBuilder rb, RuleDetails c)
        {
            var rule = c.Rule;
            if (rule.Contains("{"))
            {
                foreach (var v in c.Versions)
                {
                    var rules = _ruleSets[v];

                    foreach (var t in c.Tables)
                    {
                        IpTablesRule.ChainCreateMode chainMode = IpTablesRule.ChainCreateMode.DontCreateErrorInstead;
                        rule = c.Rule;
                        string formattedRule;
                        lock (_dynamicLock)
                        {
                            formattedRule = rb.Format(rule, t, v);
                        }
                        if (formattedRule != rule)
                        {
                            rule = formattedRule;
                            chainMode = IpTablesRule.ChainCreateMode.ReturnNewChain;
                        }

                        yield return IpTablesRule.Parse(rule, _iptables, rules.Chains, v, t, chainMode);
                    }
                }
            }
            else
            {
                IpTablesRule ruleTemplate = null;

                foreach (var v in c.Versions)
                {
                    var chains = _ruleSets[v].Chains;
                    foreach (var t in c.Tables)
                    {
                        if (ruleTemplate == null)
                        {
                            ruleTemplate = IpTablesRule.Parse(rule, _iptables, chains, v, t,
                                IpTablesRule.ChainCreateMode.DontCreateErrorInstead);
                            yield return ruleTemplate;
                        }
                        else
                        {
                            //TODO: IPTables Rule clone
                            var theRule = new IpTablesRule(ruleTemplate);
                            theRule.Chain = chains.GetChainOrDefault(ruleTemplate.Chain.Name, t);
                            yield return theRule;
                        }
                    }
                }
            }
        } 
Example #5
0
        private void CreateSets(IpTablesDetails config, RuleBuilder rb)
        {
            foreach (var set in config.Sets)
            {
                var ipset = new IpSetSet(IpSetTypeHelper.StringToType(set.Type), set.Name, 0, set.Family, _iptables, IpSetSyncMode.SetAndEntries);
                String[] resolved = set.Entries.ToArray();

                if (ipset.Type == IpSetType.HashIp)
                {
                    List<IAsyncResult> tasks = new List<IAsyncResult>();
                    for (int index = 0; index < resolved.Length; index++)
                    {
                        var entry = resolved[index];

                        String entryIp = rb.Format(entry);
                        IPAddress ip;
                        if (!IPAddress.TryParse(entryIp, out ip))
                        {
                            var asyncResult = Dns.BeginGetHostAddresses(entryIp, (a) =>
                            {
                                var ips = Dns.EndGetHostAddresses(a);
                                if (ips.Length == 0)
                                {
                                    throw new Exception("Unable to resolve: " + entryIp);
                                }
                                String entryIp2 = ips.First().ToString();
                                resolved[(int) a.AsyncState] = entryIp2;
                            }, index);
                            tasks.Add(asyncResult);
                        }
                    }

                    if (tasks.Any()) { 
                        WaitHandle.WaitAll(tasks.Select((a) => a.AsyncWaitHandle).ToArray());
                    }
                }

                //Check Uniqueness
                HashSet<IpSetEntry> ipsetEntries = new HashSet<IpSetEntry>();

                for (int index = 0; index < resolved.Length; index++)
                {
                    var entry = resolved[index];
                    String entryIp = rb.Format(entry);
                    var setEntry = IpSetEntry.ParseFromParts(ipset, entryIp);
                    if (ipsetEntries.Add(setEntry))
                    {
                        ipset.Entries.Add(setEntry);
                    }
                }
                _sets.AddSet(ipset);
            }

            //Add new sets (dont delete!)
            _sets.Sync((a) => false);
        }
Example #6
0
        private void CreateRules(IpTablesDetails config, RuleBuilder rb)
        {
            var rules = config.Rules.AsParallel().AsOrdered()
                .Where((c) => rb.IsConditionTrue(c.Condition))
                .SelectMany((c) => ParseAll(rb, c)).AsSequential();

            foreach(var rule in rules){
                lock (_dynamicLock)
                {
                    if (rb.Dcr.IsDynamic(rule.Chain))
                    {
                        rb.Dcr.AddRule(rule);
                        continue;
                    }
                }

                var chains = _ruleSets[rule.IpVersion].Chains;
                IpTablesChain chain;
                lock (chains)
                {
                    chain = chains.GetChainOrDefault(rule.Chain.Name, rule.Chain.Table);
                }
                if (chain == null)
                {
                    throw new Exception(String.Format("Chain was not created ipv{0},{1}:{2}",
                        rule.Chain.IpVersion, rule.Chain.Table, rule.Chain.Name));
                }
                lock (chain)
                {
                    chain.AddRule(rule);
                }
            }
        }