iptables基本原理和常见用法

iptables的底层是现实netfilter,netfilter作为一个通用的、抽象的框架提供一整套hook函数的管理机制,使得数据包过滤、包处理、等成为可能。netfilter的架构就是在整个网络流程的若干位置放置一些钩子,并在每个钩子上挂载一些处理函数进行处理。

IP层的5个钩子点的位置,对应iptables就是5条内置链。


图1 netfilter在Linux网络中的地位

iptables -> Tables -> Chains -> Rules, Tables有Filter, NAT, Mangle, Raw四种常用内置表,另外加入了一张新表security,用于在数据包上应用SELinux. Chains有INPUT、FORWARD、OUTPUT、PREROUTING、POSTROUTING五种内置链。
数据匹配后,常见的处理动作:

  • ACCEPT: 同意数据包通过,并继续执行后续的规则
  • DROP: 防火墙丢弃包,不再进行后续处理。应用场景是不让数据源意识到你的系统的存在,可以用来模拟宕机。
  • REJECT: 给客户端返回一个connection refused或destination unreachable报文。应用场景是不让数据源访问你的系统,这里没有你要的服务内容。
  • QUEUE: 将数据包移交到用户空间,供用户空间的程序处理
  • RETURN: 跳出当前链,停止执行当前链中的后续Rules,并返回到调用链(the calling chain)中。
  • JUMP:跳转到其他用户自定义的链继续执行。JUMP存在的意义在于:用户自定义链中的规则和系统预定义的5条链中的规则没有区别。由于自定义的链没有与netfilter里的钩子进行绑定,所以它不会自动触发,只能从其他链的规则中跳转过来.

如下图2所示是iptables的工作原理,内核就如同紫禁城,不是随随便便就能进去玩耍的,有什么事必须走相关流程,iptables就相当一个御林军接待可以把一些规则保安请求上报皇上(内核),然后皇上在把这个规则纷发到各个安保点,由各个安保点执行相关规定。

图2 iptables的工作原理

紫禁城有五个安保大门分别是PREROUTING、INPUT、FORWORD、OUTPUT和POSTROUTING,每个门岗都一个checklist,需要验明正身。如下图所示蓝色的是各个节点需要检查的表项。

图3 一个网络包经过iptables的处理路径

这些检查表项是哪些内容呢?

  • filter表:用于控制到达某条链上的数据包是继续放行、直接丢弃或拒绝,除了PREROUTING和POSTROUTIN其他节点都有检查;
  • nat表:用于修改数据包的源和目的地址,分为DNAT和SNAT。对于协议栈来说,刚进来的需要检查DNAT,马上要出去的要检查SNAT;
  • mangle表:用于修改数据包的IP头信息,这是唯一一个在各个节点都需要检查的表;
  • raw表:iptables是有状态的,即iptables对数据包有连接追踪(connection tracking)机制,而raw是用来去除这种追踪机制的。刚从协议栈外进到协议栈内的都要检查,相当于不能带追踪器进到紫禁城;
  • security表:最不常用的表(通常说iptables有4张表,Security表是新加入的特性),用于在数据包上应用SELinux.
    OUTPUT节点是唯一一个5张表都要查的。

查看表

  • iptables -nvL (默认是filter表)
  • iptables -t mangle -L (查看mangle表,同样可用于nat, raw表)

添加规则策略示例

  • 配置允许ssh连接
iptables -A INPUT -s 10.2.3.4/24 -p tcp --dport 22 -j ACCEPT
  • 阻止来自某个IP/网段的所有连接
iptables -A INPUT -s 10.1.2.3 -j DROP
  • 封锁端口,要阻止从本地1234端口建立对外连接
iptables -A OUTPUT -p tcp --dport 1234 -j DROP
  • 端口转发,web服务监听在8080端口但希望用户能通过80端口访问到服务
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
  • 禁用PING
iptables -A  INPUT -p icmp -j DROP
  • 删除规则
iptables -F
iptables -t nat -F
  • 保存于恢复
    以上方法对iptables规则做出的改变是临时的,机器重启后会丢失。如果想永久保存这些更改,则需要使用如下命令:
iptables-save //永久保存规则
iptables-save > iptables.bak //重定向到一个文件
iptables-restore < iptables.bak //恢复备份文件中的规则

下图是使用Cilium使用eBPF和iptables的容器路由对比


这里有两个问题:

  1. 容器namespace是可以隔离iptables的,即每个namespace是可以独立配置iptables规则的。那这里的容器iptables只有INPUT链(未写明表)和PRERouting mangle表是为啥?
  2. 其实iptables只是用户空间工具,实际发生作用的是内核空间的netfilter.那么容器怎么就能隔离iptables的呢?

参考文档

  • 杜军《Kubernetes网络权威指南》电子工业出版社
posted @ 2021-02-24 17:02  JaneySJ  阅读(890)  评论(0编辑  收藏  举报