iptables 详解

4,100 阅读11分钟

iptables 不是防火墙,而是一个客户端,通过执行命令将防火墙的配置放置在真正的防火墙框架中,位于用户空间,netfilter 才是真正的防火墙安全框架,位于内核空间。我们可以通过 iptables 对进入主机和从主机的 ip 以及端口进行限制,还可以进行网络转发。下面图片来源于博客 iptables详解:iptables 概念

image

如上图所示,”链“ 表示的是数据流经过的一个一个的关卡,一共有五个链:PREROUTING, INPUT, FORWORD, OUTPUT, POSTROUTING

  • 到本机某进程的报文:PREROUTING -> INPUT
  • 从本机某进程出去的报文:OUTPUT -> POSTROUTING
  • 由本机转发的报文:PREROUTING -> FORWARD -> POSTROUTING

"表" 表示的是每个关卡上设置的规则的分类,一共有四类

  • filter 表:负责过滤功能,防火墙;内核模块:iptable_filter
  • nat 表:网络地址转换功能;内核模块:iptable_nat
  • mangle 表:对报文进行拆分和修改;内核模块:iptable_mangle
  • raw 表:关闭 nat 表上启用的连接追踪机制:iptable_raw

表和链的关系

并不是所有的链上都同时存在上面四个表,同时每个表也不会存在所有的链上:

  • PREROUTING:raw,mangle,nat
  • INPUT: mangle, filter
  • FORWARD: mangle, filter
  • OUTPUT: filter, nat, mangle, raw
  • POSTROUTING: mangle, nat

同一个链中,表的优先级 raw -> mangle -> nat -> filter

规则

  • 规则表示一条链上某个表的一些匹配条件,比如拒绝某个 IP 访问
  • 一个链上某个表可以设置多条规则
  • 规则的顺序很重要,一旦有一个规则匹配成功了,后面的规则将会被忽略
  • 如果所有规则没有匹配,那么会有一个默认规则
  • 修改规则的逻辑最好是先删除某条规则,再加入新的规则
  • iptables 所有的规则都保存在 /etc/sysconfig/iptables
  • 设置了新的规则后,必须使用 service iptables save 进行保存或者使用iptable-save > /etc/sysconfig/iptables,否则重启后,新设置的规则将失效
  • 一个规则中存在多个匹配条件时,这些条件默认规则是与的关系,比如端口,IP必须满足才算匹配
  • 默认的匹配规则有:
- -s: 指定源地址,可以匹配多个 ip 地址,用逗号隔开,也可以指定一个 ip 段
- -d: 指定目标地址
- -p: 指定协议类型,可以是 tcp/udp/icmp/sctp/esp 等
- -i: 表示指定从哪个网卡流入的,只能用于 INPUT,PREROUTING,FORWARD 链
- -o: 表示指定从哪个网卡留出的,只能用于 OUTPUT,POSTROUTING,FORWORD 链
- -m: 指定扩展模块,可以指定扩展模块,扩展模块中可以定义一系列的匹配规则
- --dport/--sport: 表示源端口和目标端口,依赖于 tcp 扩展模块(-m tcp),而且必须指定协议 -p tcp,--dport/--sport 是 tcp 扩展模块中的一个扩展匹配条件
- -m multiport --dports 334,80:通过扩展模块 multiport 使一条规则中同时指定多个端口 
  • 规则的增删改
- -F:指定一个链,清空对应链中的所有规则
- -I: 指定一个链,表示要加入一条规则在链中,放在所有规则的首部
- -A:指定一个链,追加一条规则,放在所有规则尾部
- -D: 删除一条规则,删除规则时必须指定表和链,可以根据 --line-number 返回的行号删除,也可以根据规则具体信息(匹配规则和动作)删除
- -S:指定链,查看规则定义,有时候我们想直接使用已有规则进行复制产生新的规则,可以使用 -S
- -P: 指定一个链,给某个链设置默认规则

处理动作

对上文中提到的规则定义的处理动作,通过 -j 参数指定,分为基本动作和扩展动作,扩展动作通过自定义链实现的

基本动作主要分为以下几种:

  • ACCEPT:允许数据包通过
  • DROP: 直接丢弃数据包,不作处理
  • REJECT:拒绝数据包,会给一个拒绝的响应 --reject-with 'message' 可以指定如果被拒绝的情况下的回应消息,message 默认是 icmp-port-unreachable,还可以有如下选择
- icmp-net-unreachable
- icmp-host-unreachable
- icmp-port-unreachable
- icmp-proto-unreachable
- icmp-net-prohibited
- icmp-host-prohibited
- icmp-admin-prohibited
  • SNAT:源地址转换(Source Network Address, Translation):内部报文发送出去时,报文的源 IP 被修改,SNAT 报文必须存在 POSTROUTING 链中,也就是从内部发出去的报文经过的最后一道关卡,对应的 --to-source 选项
// 所有从内部机器 IP=10.1.0.0 发过来的报文都会被隐藏源 IP,并转发到 192.168.1.163 机器上
iptables -t nat -I POSTROUTING -s 10.1.0.0 -j SNAT --to-source 192.168.1.163 
  • DNAT:目标地址转换(Destination Network Address, Translation): 外部报文响应时,目标 IP 再次被修改,从外部网络发送到内部网络的报文,目的 IP 被修改,一般配置在 PREROUTING 链中
// 所有从外部访问主机 192.168.1.164 对应的端口为 3306 的服务,都会被转发到 10.1.0.6:3306 上,目标 IP 被修改
iptables -t nat -I POSTROUTING -d 192.168.1.164 --dport 3306 -j DNAT --to-destination 10.1.0.6:3306 
  • MASQUEREAD:MASQUEREAD 与 SNAT 类似,也是将内部发出去的报文映射成公网 IP,不同是 MASQUEREAD 可以指定网卡,而不需要关心 IP 是什么,即使 IP 发生变化也可以正常映射
iptables -t nat -I POSTROUTING -s 10.1.0.0 -j  -o eth0 MASQUEREAD 
  • LOG:打印日志,对匹配到规则的请求打印日志,然后将数据包传给下一个规则,不做任何处理,日志会被记录到 /var/log/messages 里
--log-level 可以给指定的日志加级别:emerg,alert,crit,error,warn,notice,debug,info
--log-prefix 可以给指定的日志加标签,便于查看
  • REDIRECT:在本机做端口映射
//将本机的 80 端口转发到 8080 端口
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080

自定义链

  • 默认链中,如果规则太多时不方便管理,所以引入了自定义链
  • 自定义链不能直接使用,需要默认链引用才能使用,通过 -j 引用自定义链
  • 只有自定义链没有被任何默认链的规则引用且没有任何规则时才可以删除
iptables -t filter -N IN_WEB //新建一个自定义链
iptables -t filter -nvL IN_WEB //查看自定义链中的规则
iptables -t filter -I IN_WEB -s 10.164.12.138 -j REJECT //给自定义链加入一条规则
iptables -t filter -I INPUT -p tcp --dport 80  -j IN_WEB //在默认链中引用自定义链,必须在默认链中引用,自定义链中的规则才能生效
iptables -E IN_WEB WEB //将自定义链 IN_WEB 改名为 WEB

常用扩展模块

上面列出了常用的匹配规则,如果常用的匹配规则不够,我们可以使用扩展模块的匹配规则,通过 -m 指定扩展模块,常用的扩展模块有如下:

  • tcp
--sport:指定源端口
--dport:指定目标端口
--tcp-flags: 可以根据 tcp 标志头进行匹配
--syn: 用于匹配 tcp 新建连接的请求报文
  • udp
--sport:指定源端口
--dport:指定目标端口
  • icmp
--icmp-type: 用于指定 icmp 报文的具体类型
  • multiport:同时指定多个端口
  • iprange: 指定一个 ip 范围
  • string:可以针对报错字符串进行匹配
  • time:针对报文达到的时间进行匹配
  • connlimit: 可以限制每个 ip 连接同时连接到 server 段的数量
  • limit:对报文达到的到达率进行限制,单位时间内流入的数据量
  • state:让 iptables 实现了连接追踪,可以对建立连接的状态进行追踪屏蔽,比如只能是我主动和你进行建立连接,而你不能和我主动建立连接
  • set:可以匹配通过 ipset 定义一堆 ip 的集合
//通过 ipset 定义一个 ip 集合,把 59.111.198.55,59.111.198.56 加入 office 中
#!/bin/sh
sudo ipset -! create office hash:net
sudo ipset add office 59.111.198.55
sudo ipset add office 59.111.198.56

//对 INPUT 链上所在 office 集合中 IP 列表进行拒绝访问 src 表示来源 IP 
iptables -t table -I INPUT -m set --match-set office src -j DROP

iptables 黑白名单机制

默认规则表示如果没有匹配到某个链上任何一个规则时,使用该默认规则进行匹配,通过默认规则我们实现白名单和黑名单访问限制:

  • 黑名单:如果默认规则是 ACCEPT,那么没有匹配到的都会通过
  • 白名单:如果默认规则是 REJECT,那么没有匹配到的都会被拒绝
  • 在使用白名单时建议不要将默认规则设置成 REJECT,万一机器重启以后,管理员自己可能都被拒之门外,可以将默认规则设置 ACCEPT,然后在默认加一条规则 REJECT,这样也可以实现白名单机制
  • 默认规则设置:
//-P: 指定一个链,给某个链设置默认规则
iptables -t filter -P INPUT -j REJECT

常用参数详解

  • -t :指定 table,默认是 filter
  • -v : 会显示更多的列的详细信息
  • -n : 表示不对 ip 进行 dns 反解析
  • -L : 后面不加参数是列出所有规则,可以加对应的链,列出对应链的规则
  • --line-number:显示每条规则的序号,可以使用该序号直接删除该规则
  • -F:指定一个链,清空对应链中的所有规则
  • -I: 指定一个链,表示要加入一条规则在链中,放在所有规则的首部
  • -A:指定一个链,追加一条规则,放在所有规则尾部
  • -D: 删除一条规则,删除规则时必须指定表和链,可以根据 --line-number 返回的行号删除,也可以根据规则具体信息(匹配规则和动作)删除
  • -S:指定链,查看规则定义,有时候我们想直接使用已有规则进行复制产生新的规则,可以使用 -S
  • -P: 指定一个链,给某个链设置默认规则
  • -N:新建一个自定义链
  • -E: 修改自定义链的名字
  • -X:删除自定义链,只有自定义链没有被任何默认链的规则引用时才可以删除
  • -s: 指定源地址,可以匹配多个 ip 地址,用逗号隔开,也可以指定一个 ip 段
  • -d: 指定目标地址
  • -j: 指定处理动作,比如 ACCEPT,DRO,或者是一个自定义链
  • -p: 指定协议类型,可以是 tcp/udp/icmp/sctp/esp 等
  • -i: 表示指定从哪个网卡流入的,只能用于 INPUT,PREROUTING,FORWARD 链
  • -o: 表示指定从哪个网卡留出的,只能用于 OUTPUT,POSTROUTING,FORWORD 链
  • -m: 指定扩展模块
  • --dport/--sport: 表示源端口和目标端口,依赖于 tcp 扩展模块(-m tcp),而且必须指定协议 -p tcp,--dport/--sport 是 tcp 扩展模块中的一个扩展匹配条件
  • -m multiport --dports 334,80: 来在一条规则中同时指定多个端口

使用案例

  • 获取某个链下对应表的所有规则
$ iptables -t nat -nvL

=> 返回结果: 每个链下面对应的规则

1. pkts: 对应规则匹配到的报文个数
2. bytes: 对应规则匹配到的报文大小
3. target: 匹配到规则后,对应采取的动作
4. prot:表示规则对应的协议
5. opt: 表示规则对应的选项
6. in:表示由哪个网卡流入的报文需要匹配当前规则
7. out:表示由那个网卡流出的报文需要匹配当前规则
8. source:表示规则对应的来源地址,可以ip也可以ip段,才会匹配到这个规则
9. destination:表示规则对应的目的地址,可以ip也可以ip段,才会匹配到这个规则

Chain PREROUTING (policy ACCEPT 22134 packets, 1517K bytes)
 pkts bytes target     prot opt in     out     source               destination
 431K   26M DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set office src tcp dpt:6390 to:10.200.129.51:6379
39935 2462K DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set office src tcp dpt:3360 to:10.122.139.122:3306
  245 15560 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:6391 to:10.200.129.51:6379
    2   128 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:6392 to:10.200.129.51:6379
    1    64 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:3361 to:10.164.100.129:3306
  120  7680 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:3362 to:10.122.139.122:3306

Chain INPUT (policy ACCEPT 705 packets, 57624 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 10110 packets, 630K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 2173 packets, 129K bytes)
 pkts bytes target     prot opt in     out     source               destination
9573K  592M SNAT       all  --  *      eth1    0.0.0.0/0            0.0.0.0/0            to:10.122.139.165
  • 端口转发
//外面访问公网IP的3306端口转发到私有IP对应的3306端口上
iptables -t nat -I PREROUTING -d 公网IP -p tcp --dport 3306 -j DNAT --to-destination 私网IP:3306
  • 禁止某个 IP 访问服务

iptables -t filter -I INPUT -s 某个IP -j REJECT

参考文献