操作系统是 Linux Mint 19,我想在 iptables 中设置一条规则,以丢弃传入的 FIN 数据包作为 FIN_WAIT_2 状态的响应。这适用于给定端口。我想测试一个应用程序,需要一些连接保持在 FIN_WAIT_2 tcp 状态。防火墙是 ufw
答案1
如果您只是想在始终启动关闭连接时丢弃传入的 FIN 数据包,那么如下规则就足够了:
iptables -I INPUT --protocol tcp --destination-port 1337 --tcp-flags FIN FIN -j DROP
但是,这会导致连接另一端关闭连接时出现混乱。我认为不可能只在 ACK 之前丢弃 FIN。
答案2
不幸的是,我没有在 ufw 手册中找到有关检查 tcp 标志的任何说明。
在 iptables 中,可以使用 ipset 以某种复杂的方式实现您的方案,但存在一些限制。我猜,您的主机是 tcp 客户端,服务器端口号是 1234(可以自由更改)。
# create the ipset list for fin_wait sockets.
# every entry is tuple (local-ip,local-port,remote-ip)
ipset create fin_wait hash:ip,port,ip timeout 3000
# if local host sends the fin packet inside established connection
# add entry into fin_wait list
iptables -A OUTPUT \
-p tcp --tcp-flags FIN FIN \
--dport 1234 \
-m conntrack --ctstate ESTABLISHED \
-j SET --add-set fin_wait src,src,dst --exist
# if local host receives the fin packet for fin wait socket
# drop it before tcp stack processing
iptables -A INPUT \
-p tcp --tcp-flags FIN FIN \
--sport 1234 \
-m set --match-set fin_wait dst,dst,src \
-j DROP
对于服务器来说,存在差异。
# create list for test clients
ipset create test_clients hash:ip
# add addresses of test clients
ipset add test_clients 192.168.100.10
# create list for clients in fin wait state
# server ip,port is known, so ip,port type is enough
ipset create fin_wait_clients hash:ip,port timeout 3000
# if server receives fin from test client
# add client's ip,port into set
iptables -A INPUT -p tcp \
--dport 1234 \
--tcp-flags FIN FIN \
-m set --match-set test_clients src \
-j SET --add-set fin_wait_clients src,src --exist
# if server sends fin to test client as reply
# block this fin
iptables -A OUTPUT -p tcp \
--sport 1234 \
--tcp-flags FIN FIN \
-m set --match-set fin_wait_clients dst,dst \
-j DROP
一些说明:
使用
ipset list fin_wait
命令从 iptables 的角度列出当前被阻止的条目使用
ss -t4 state fin-wait-2
命令列出处于 fin wait 2 状态的套接字规则的顺序非常重要。
最好使用 iptables-save / iptables-restore / iptables-apply 工具来安全规则集更改。