How can I programmatically manage iptables rules on the fly?

后端 未结 9 1236
盖世英雄少女心
盖世英雄少女心 2020-11-29 00:20

I need to query existing rules, as well as being able to easily add and delete rules. I haven\'t found any API\'s for doing this. Is there something that I\'m missing?

相关标签:
9条回答
  • 2020-11-29 00:45

    From the netfilter FAQ:

    The answer unfortunately is: No.

    Now you might think 'but what about libiptc?'. As has been pointed out numerous times on the mailinglist(s), libiptc was NEVER meant to be used as a public interface. We don't guarantee a stable interface, and it is planned to remove it in the next incarnation of linux packet filtering. libiptc is way too low-layer to be used reasonably anyway.

    We are well aware that there is a fundamental lack for such an API, and we are working on improving that situation. Until then, it is recommended to either use system() or open a pipe into stdin of iptables-restore. The latter will give you a way better performance.

    0 讨论(0)
  • 2020-11-29 00:46

    You may consider using rfw which is the REST API for iptables. It is serializing iptables commands from various potentially concurrent sources and remotely executes iptables on the fly.

    rfw is designed for distributed systems that try to update firewall rules on multiple boxes but it can be run also on a single machine on localhost interface. Then it allows avoiding the SSL and authentication overhead as it can be run on plain HTTP in this case.

    Sample command:

    PUT /drop/input/eth0/11.22.33.44
    

    which corresponds to:

    iptables -I INPUT -i eth0 -s 11.22.33.44 -j DROP
    

    You can insert and delete rules as well as query for current status to get the existing rules in JSON format:

    GET /list/input
    

    Disclaimer: I started that project. It's open source under the MIT license.

    0 讨论(0)
  • 2020-11-29 00:49

    Using iptables-save and iptables-restore to query and regenerate rules is easily the most efficient way of doing it. These used to, once, be shell scripts, but now they are C programs that work very efficiently.

    However, I should point out that there is a tool that you can use which will make maintaining iptables much easier. Most dynamic rulesets are really the same rule repeated many times, such as:

    iptables -A INPUT -s 1.1.1.1 -p tcp -m --dport 22 -j ACCEPT
    iptables -A INPUT -s 2.2.2.0/24 -p tcp -m --dport 22 -j ACCEPT
    iptables -A INPUT -p tcp -m tcp --dport 22 -j REJECT
    

    Instead of replacing those rules every time you want to change what ports can access port 22 (useful for say, port knocking), you can use ipsets. Viz:

    ipset -N ssh_allowed nethash
    iptables -A ssh_allowed -m set --set ssh_allowed src -p tcp -m --dport 22 -j ACCEPT
    ipset -A ssh_allowed 1.1.1.1
    ipset -A ssh_allowed 2.2.2.0/24
    

    Sets can hold ip addresses, networks, ports, mac addresses, and have timeouts on their records. (Ever wanted to add something for just an hour?).

    There is even an atomic way of swapping one set with another, so a refresh means creating a new temporary set, then swapping it in as the name of the existing set.

    0 讨论(0)
  • 2020-11-29 00:54

    As far as I understand (although no reference seems to mention it), iptables-restore is atomic. At the end, when the COMMIT line is read, iptables calls iptc_commit in libiptc (which in an internal interface you aren't supposed to use), which then calls setsockopt(SO_SET_REPLACE) with your new rulesets.

    That sounds about as atomic as you can get: with one kernel call. However, more knowledgeable parties are invited to dispute this. :-)

    Edit: I can confirm that your description is correct. iptables-restore is done as an atomic operation in the kernel.

    To be even more specific the operation "only" is atomic on a per CPU basis. As we store the entire ruleset blob per CPU (due to cache optimizations).

    0 讨论(0)
  • 2020-11-29 00:56

    This morning I woke up to find that was getting a Denial Of Service (DOS) attack from Russia. They were hitting me from dozens of IP blocks. They must have either had a large pool of IPs or some sort of proxy list/service. Every time I blocked an IP, another one popped up. Finally, I looked for a script, and found I needed to write my own solution. The following is a bit agressive, but they were running my TOP LOAD LEVEL to over 200.

    Here is a quick script I wrote to block the DOS in realtime.

    cat  **"output of the logs"** | php ipchains.php **"something unique in the logs"**
    

    ==> PHP Script:

    <?php
    
    $ip_arr = array();
    
    while(1)
    {
       $line = trim(fgets(STDIN)); // reads one line from STDIN
       $ip = trim( strtok( $line, " ") );
    
       if( !array_key_exists( $ip, $ip_arr ) )
          $ip_arr[$ip] = 0;
    
       $regex = sprintf( "/%s/", $argv[1] );
    
       $cnt = preg_match_all( $regex, $line );
    
       if( $cnt < 1 ) continue;
    
       $ip_arr[$ip] += 1;
    
       if( $ip_arr[$ip] == 1  )
         {
    //     printf( "%s\n", $argv[1] );
    //     printf( "%d\n", $cnt );
    //     printf( "%s\n", $line );
    
           printf( "-A BLOCK1 -s %s/24 -j DROP\n", $ip );
    
           $cmd = sprintf( "/sbin/iptables  -I BLOCK1  -d %s/24 -j DROP", $ip );
           system( $cmd );
         }
    }
    
    ?>
    

    Assumptions:

    1) BLOCK1 is a Chain already created. 
    2) BLOCK1 is a Chain that is run/called from the INPUT CHAIN 
    3) Periodically you will need to run "ipchains -S BLOCK1" and put output in /etc/sysconfig file. 
    4) You are familiar with PHP 
    5) You understand web log line items/fields and output.
    
    0 讨论(0)
  • 2020-11-29 00:56

    I know its a short term solution, per the netfilter discussion, but in the short term you can use iptc wrapped in python with this:

    https://github.com/ldx/python-iptables

    I played with it some in a recent project of mine and found it quite effective.

    0 讨论(0)
提交回复
热议问题