防火墙是保护服务器和基础设施安全的重要工具。在 Linux 生态系统中,iptables 是使用很广泛的防火墙工具之一,它能够用来完成封包过滤、封包重定向和网络地址转换(NAT)等功能。 iptables 基于内核的包过滤框架 netfilter 。如果管理员或用户不了解这些系统的架构,那可能就无法创建出可靠的防火墙策略。

这里我们只简单地使用 iptables 的包过滤功能(后面讨论的命令也仅限于此) ,因为它能够很方便地模拟各种网络状况(TCP 三握四挥的异常处理、报文丢失等),非常有助于我们对网络理论知识的学习。其他功能的详细介绍可以参见iptables用法规则小结


命令格式:

ACCEPT 允许数据包通过
DROP 直接丢弃数据包,不给任何回应信息
REJECT 拒绝数据包通过,必要时会给数据发送端一个响应的信息

注意: 即使我们在输入链 INPUT 上 DROP 了指定报文,tcpdump/wireshark 仍然可以抓到该报文,因为报文的进入顺序是:Wire -> NIC -> tcpdump -> netfilter/iptables ;而出站顺序为:iptables -> tcpdump -> NIC -> Wire ,此时 tcpdump/wireshark 才无法抓到指定报文。

注意,在 INPUT 中丢弃报文后,虽然可以被 tcpdump 捕获,但指定的端口或程序仍然无法收到该报文。

示例:

1)在 lo 接口上丢弃目标 IP 为 192.168.248.128 ,目标端口为 12345 的 TCP 报文

1
iptables -i lo -I INPUT  -d 192.168.248.128 -p tcp --dport 12345 -j DROP

指定端口必须放在指定协议之后
另外,如果是做实验,那么添加之后记得删除,将 -I 改为 -D 再执行一次即可。

2)拒绝目标 IP 为 192.168.248.128 ,目标端口为 12345 的 TCP 报文

1
iptables -I INPUT  -d 192.168.248.128 -p tcp --dport 12345 -j REJECT

拒绝报文后,一般会给发送端发送 IMCP 报文以报告错误:

3)拒绝源 IP 为 192.168.248.128 ,目标端口为 12345 ,且报文含有 SYN 标志的报文:

1
iptables -I INPUT -s 192.168.248.128 -p tcp --dport 12345 --tcp-flags SYN SYN -j DROP

这样我们就屏蔽了源 IP 为 192.168.248.128 发向 12345 端口的第一次握手。

这条命令使用了 tcp 扩展模块。

1
--tcp-flags mask comp

第一个参数 mask 是我们应该检查的标志,写成由逗号分隔的列表。
第二个参数 comp 是必须匹配的标志的列表,列表以逗号分隔。
没有被匹配上的标志则要求不能被设置。比如:

1
iptables -I INPUT -s 192.168.248.128 -p tcp --dport 12345 --tcp-flags SYN,ACK ACK -j DROP

这条命令只会匹配到设置了 ACK 而没有设置 SYN 的报文。
Flags : SYN ,ACK ,FIN ,RST ,URG ,PSH ,ALL ,NONE

另外,有时会使用 -m 显式指定模块:

1
iptables -I INPUT -s 192.168.248.128 -p tcp --dport 12345 -m tcp --tcp-flags SYN,ACK ACK -j DROP
1
iptables -A FORWARD -m mac --mac-source 00:0c:29:27:55:3F -j DROP

4)列出 filter 表的所有规则:

1
2
3
4
5
# iptables -t filter -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- 192.168.248.128 anywhere tcp dpt:12345 flags:SYN,ACK/ACK
DROP tcp -- 192.168.248.128 anywhere tcp dpt:12345 flags:SYN/SYN

注意,如果不使用 -t 指定表,则默认都为 filter

5)删除指定规则:

1
iptables  -D INPUT 1  删除第一条规则

6)! 取反:

1
iptables -I INPUT ! -s 192.168.248.128 -p tcp -j DROP

丢弃除了源 IP 为 192.168.248.128 的其他所有 TCP 报文。

7)操作网段:

1
iptables -I INPUT -s 10.20.30.0/24 -j DROP

8)端口范围:

1
iptables -I INPUT -s 192.168.248.128 -p tcp --dport 1000:2000 -j DROP

9)拒绝 DDOS 攻击:

1
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT

-m limit: 启用limit扩展,限制速度。
–limit 25/minute: 允许最多每分钟25个连接
–limit-burst 100: 当达到100个连接后,才启用上述25/minute限制

这种方式似乎不能有效解决 DDOS 攻击。

10)包含指定字符串:

1
iptables -D INPUT -p tcp --dport 12345 -m string --algo bm --string 'admin' -j REJECT

拒绝目标端口为 12345 且数据中包含 “admin” 字符串的报文。