我如何以编程方式pipe理iptables规则?

我需要查询现有的规则,以及能够轻松添加和删除规则。 我还没有find任何API来做到这一点。 有什么我失踪?

最接近我的解决scheme是使用iptables-save | iptables-xml iptables-save | iptables-xml用于查询和手动调用iptables命令本身来添加/删除规则。 我考虑过的另一个解决scheme是简单地将整个规则集从我的应用程序的数据库中重新生成,并刷新整个链,然后再次应用它。 但我想避免这种情况,因为我不想丢弃任何数据包 – 除非有办法自动执行此操作。 我想知道是否有更好的方法。

C中的API将会很棒; 不过,因为我打算把它build成一个独立的suid程序,所以用这种语言来做这件事情的图书馆也不错。

从netfilter FAQ :

答案不幸的是:没有。

现在你可能会想'但是libiptc呢?' 正如在邮件列表中多次指出的那样,libiptc 从来不会被用作公共接口。 我们不保证一个稳定的接口,并且计划在接下来的linux包过滤中将其删除。 无论如何,libiptc的方式太低层,无法合理使用。

我们清楚地意识到,这样的API基本缺乏,我们正在努力改善这种情况。 在此之前,build议使用system()或打开一个pipe道到iptables-restore的stdin。 后者会给你更好的performance。

使用iptables-save和iptables-restore来查询和重新生成规则是最简单的方法。 这些曾经是shell脚本,但现在它们是C程序,非常有效地工作。

但是,我应该指出,有一个工具可以使用,这将使维护iptables变得更容易。 大多数dynamic规则集都是重复多次的相同规则,例如:

 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 

而不是每次你想改变什么端口可以访问端口22(有用的说,端口敲)取代这些规则,你可以使用ipsets。 即:

 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 

集可以保存IP地址,networking,端口,MAC地址,并在其logging上有超时。 (曾经想添加一个小时?)。

甚至有一种交换一个集合的primefaces方式,所以刷新意味着创build一个新的临时集合,然后将其作为现有集合的名称进行交换。

您可以考虑使用rfw ,这是iptables的REST API。 它是从各种可能的并发源序列化iptables命令,并远程执行iptables。

rfw是为分布式系统而devise的,它尝试在多个盒子上更新防火墙规则,但也可以在localhost接口上的一台机器上运行。 然后它可以避免SSL和validation开销,因为在这种情况下,它可以在纯HTTP上运行。

示例命令:

 PUT /drop/input/eth0/11.22.33.44 

对应于:

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

您可以插入和删除规则以及查询当前状态以获取JSON格式的现有规则:

 GET /list/input 

免责声明:我开始了这个项目。 它是MIT许可下的开源软件。

故意没有API来pipe理这些规则。 你不应该这样做。 或者其他的东西。

如果您需要足够dynamic的规则来关心执行/ sbin / iptables的性能,还有其他方法可以实现:

  • 使用类似“最近”的匹配或IP设置匹配,你可以添加/删除黑/白名单的IP地址,而无需更改规则集。
  • 您可以将数据包传递到用户空间以使用NFQUEUE进行过滤

据我所知(虽然没有参考似乎提到它), iptables-restore是primefaces。 最后,在读取COMMIT行时, iptables调用libiptc iptc_commit (在一个内部接口中,您不应该使用它),然后使用新的规则集调用setsockopt(SO_SET_REPLACE)

这听起来像你可以得到的primefaces:一个内核调用。 然而,更多有知识的人士被邀请对此提出质疑。 🙂

编辑:我可以确认你的描述是正确的。 内核中的iptables-restore是作为一个primefaces操作完成的。

具体地说 ,“仅”操作在每个CPU的基础上是primefaces的。 由于我们存储整个规则集blob每CPU(由于caching优化)。

今天早上,我醒来发现这是从俄罗斯获得拒绝服务(DOS)攻击。 他们从几十个IP块打我。 他们必须拥有大量的IP或者某种代理列表/服务。 每当我阻止一个IP,另一个popup。 最后,我找了一个脚本,发现我需要写自己的解决scheme。 以下是有点激进,但他们正在运行我的最高负载水平超过200。

这里是我写的一个快速的脚本来实时阻止DOS。

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

==> PHP脚本:

 <?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 ); } } ?> 

假设:

 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. 

MarkR的权利,你不应该这样做。 最简单的方法是从脚本调用iptables或者写iptablesconfiguration并“还原”它。

不过,如果你想读,请阅读iptables的来源。 iptables使用匹配和表作为共享对象。 您可以使用源代码或他们。

Linux netfilter在/ usr / include / netfilter *下也有一些包含文件。 这些是一些低级function。 这是iptables使用的。 这就像API可以在没有iptables的情况下一样。

但是这个API是'混乱'的。 请记住,它只能被iptables使用。 它没有很好的logging,你可以遇到非常具体的问题,API可以改变相当快没有任何警告,所以升级propably会打破你的代码等。

这是一个使用bash和iptablesdynamic阻止黑客在CentOS上滥用sshd的例子。 在这种情况下,我configuration了sshd来禁止密码login(允许键)。 我在/ var / log / secure中查看“Bye Bye”的条目,这是sshd礼貌的说f-off的方式。

 IP=$(awk '/Bye Bye/{print $9}' /var/log/secure | sed 's/://g' |sort -u | head -n 1) [[ "$IP" < "123" ]] || { echo "Found $IP - blocking it..." >> /var/log/hacker.log /sbin/iptables -A INPUT -s $IP -j DROP service iptables save sed -i "/$IP/d" /var/log/secure } 

我每秒钟,每分钟,或者任何让我快乐的事情都会循环运行。 我testing$ IP的值来validation它find一个有用的值,如果是的话,我调用iptables来删除它,我使用sed来清除$ IP的日志文件,所以不会再次添加条目。

我做了一些预处理(未显示)白名单一些重要的IP,总是有效的,可能有连接问题(由于用户错误)。

我不时地对iptablesfilter列表进行sorting,并从中创buildIP范围(使用不同的脚本 – 选中时,通常是来自印度,中国和俄罗斯的IP范围)。 因此,我的总体iptablesfilter规则集保持在50和500个条目之间; ipset在短小的列表上并没有真正提高。