iptables 不是防火墙,而是一个客户端,通过执行命令将防火墙的配置放置在真正的防火墙框架中,位于用户空间,netfilter 才是真正的防火墙安全框架,位于内核空间。我们可以通过 iptables 对进入主机和从主机的 ip 以及端口进行限制,还可以进行网络转发。下面图片来源于博客 iptables详解:iptables 概念
如上图所示,”链“ 表示的是数据流经过的一个一个的关卡,一共有五个链:PREROUTING, INPUT, FORWORD, OUTPUT, POSTROUTING
“表” 表示的是每个关卡上设置的规则的分类,一共有四类
并不是所有的链上都同时存在上面四个表,同时每个表也不会存在所有的链上:
同一个链中,表的优先级 raw -> mangle -> nat -> filter
- -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 参数指定,分为基本动作和扩展动作,扩展动作通过自定义链实现的
基本动作主要分为以下几种:
- icmp-net-unreachable
- icmp-host-unreachable
- icmp-port-unreachable
- icmp-proto-unreachable
- icmp-net-prohibited
- icmp-host-prohibited
- icmp-admin-prohibited
// 所有从内部机器 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
// 所有从外部访问主机 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
iptables -t nat -I POSTROUTING -s 10.1.0.0 -j -o eth0 MASQUEREAD
--log-level 可以给指定的日志加级别:emerg,alert,crit,error,warn,notice,debug,info
--log-prefix 可以给指定的日志加标签,便于查看
//将本机的 80 端口转发到 8080 端口
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
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 指定扩展模块,常用的扩展模块有如下:
--sport:指定源端口
--dport:指定目标端口
--tcp-flags: 可以根据 tcp 标志头进行匹配
--syn: 用于匹配 tcp 新建连接的请求报文
--sport:指定源端口
--dport:指定目标端口
--icmp-type: 用于指定 icmp 报文的具体类型
//通过 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
默认规则表示如果没有匹配到某个链上任何一个规则时,使用该默认规则进行匹配,通过默认规则我们实现白名单和黑名单访问限制:
//-P: 指定一个链,给某个链设置默认规则
iptables -t filter -P INPUT -j REJECT
$ 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
iptables -t filter -I INPUT -s 某个IP -j REJECT