linux - 需要删除与 iptables 建立的连接

标签 linux networking tcp firewall iptables

出于应用测试目的,我需要模拟一种情况,当状态防火墙因超时而断开从客户端到服务器的已建立 TCP 连接时。我在 Virtualbox 中安装了 3 个 guest 虚拟机:

  1. 客户端,network1 ip:10.0.2.110
  2. 防火墙,network1 ip:10.0.2.5,network2 ip:10.0.3.5
  3. 服务器,network2 ip:10.0.3.6

客户端和服务器都是禁用iptables的Fedora19 防火墙是具有以下设置的 Ubuntu 13.10:

cat/etc/iptables.conf

*filter
:INPUT ACCEPT [201:13136]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [110:14472]
-A FORWARD -j LOG --log-prefix "[netfilter] "
-A FORWARD -p icmp -j ACCEPT
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -m conntrack --ctstate INVALID -j DROP
-A FORWARD -p tcp -m tcp --dport 2000 -m state --state NEW -j ACCEPT
-A FORWARD -j DROP
COMMIT

sysctl net.netfilter

...
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 30
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 30
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 30
...

使用此设置,conntrack|iptables 应在 30 秒不活动后丢弃已建立的 TCP 连接。 为了运行测试,我在服务器上设置了“服务器”:

# ncat -l 2000 --keep-open --exec "/bin/cat"

然后在客户端用 telnet 连接:

$ telnet 10.0.3.6 2000
Trying 10.0.3.6...
Connected to 10.0.3.6.
Escape character is '^]'.

在 iptables 日志中,我得到一个正常的 TCP 握手:

Dec  2 12:24:23 ubuntu kernel: [ 5231.169804] [netfilter] IN=eth0 OUT=eth1 MAC=08:00:27:b8:68:9f:08:00:27:4f:ee:15:08:00 SRC=10.0.2.110 DST=10.0.3.6 LEN=60 TOS=0x10 PREC=0x00 TTL=63 ID=44926 DF PROTO=TCP SPT=47899 DPT=2000 WINDOW=29200 RES=0x00 SYN URGP=0
Dec  2 12:24:23 ubuntu kernel: [ 5231.170489] [netfilter] IN=eth1 OUT=eth0 MAC=08:00:27:00:72:8c:08:00:27:74:b7:df:08:00 SRC=10.0.3.6 DST=10.0.2.110 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=2000 DPT=47899 WINDOW=28960 RES=0x00 ACK SYN URGP=0
Dec  2 12:24:23 ubuntu kernel: [ 5231.171315] [netfilter] IN=eth0 OUT=eth1 MAC=08:00:27:b8:68:9f:08:00:27:4f:ee:15:08:00 SRC=10.0.2.110 DST=10.0.3.6 LEN=52 TOS=0x10 PREC=0x00 TTL=63 ID=44927 DF PROTO=TCP SPT=47899 DPT=2000 WINDOW=229 RES=0x00 ACK URGP=0

建立连接后,我使用 telnet 和 # conntrack -L 命令发送了几个数据包,我得到:

tcp      6 24 ESTABLISHED src=10.0.2.110 dst=10.0.3.6 sport=47899 dport=2000 src=10.0.3.6 dst=10.0.2.110 sport=2000 dport=47899 [ASSURED] mark=0 use=1

在 iptables 日志中我得到:

Dec  2 12:24:38 ubuntu kernel: [ 5245.917564] [netfilter] IN=eth0 OUT=eth1 MAC=08:00:27:b8:68:9f:08:00:27:4f:ee:15:08:00 SRC=10.0.2.110 DST=10.0.3.6 LEN=55 TOS=0x10 PREC=0x00 TTL=63 ID=44928 DF PROTO=TCP SPT=47899 DPT=2000 WINDOW=229 RES=0x00 ACK PSH URGP=0
Dec  2 12:24:38 ubuntu kernel: [ 5245.917961] [netfilter] IN=eth1 OUT=eth0 MAC=08:00:27:00:72:8c:08:00:27:74:b7:df:08:00 SRC=10.0.3.6 DST=10.0.2.110 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=36952 DF PROTO=TCP SPT=2000 DPT=47899 WINDOW=227 RES=0x00 ACK URGP=0
Dec  2 12:24:38 ubuntu kernel: [ 5245.918326] [netfilter] IN=eth1 OUT=eth0 MAC=08:00:27:00:72:8c:08:00:27:74:b7:df:08:00 SRC=10.0.3.6 DST=10.0.2.110 LEN=55 TOS=0x00 PREC=0x00 TTL=63 ID=36953 DF PROTO=TCP SPT=2000 DPT=47899 WINDOW=227 RES=0x00 ACK PSH URGP=0
Dec  2 12:24:38 ubuntu kernel: [ 5245.918535] [netfilter] IN=eth0 OUT=eth1 MAC=08:00:27:b8:68:9f:08:00:27:4f:ee:15:08:00 SRC=10.0.2.110 DST=10.0.3.6 LEN=52 TOS=0x10 PREC=0x00 TTL=63 ID=44929 DF PROTO=TCP SPT=47899 DPT=2000 WINDOW=229 RES=0x00 ACK URGP=0

那也行。

接下来,我等待几分钟并检查 # conntrack -L 是否返回一个空表,然后我使用 telnet 发送更多数据包并预计它会卡住或显示类似“连接已关闭”的内容, 但是,令我惊讶的是,连接实际上并没有关闭,我在 iptables 日志中收到了这样的消息:

Dec  2 12:29:51 ubuntu kernel: [ 5558.925402] [netfilter] IN=eth0 OUT=eth1 MAC=08:00:27:b8:68:9f:08:00:27:4f:ee:15:08:00 SRC=10.0.2.110 DST=10.0.3.6 LEN=55 TOS=0x10 PREC=0x00 TTL=63 ID=44930 DF PROTO=TCP SPT=47899 DPT=2000 WINDOW=229 RES=0x00 ACK PSH URGP=0
Dec  2 12:29:51 ubuntu kernel: [ 5558.925927] [netfilter] IN=eth1 OUT=eth0 MAC=08:00:27:00:72:8c:08:00:27:74:b7:df:08:00 SRC=10.0.3.6 DST=10.0.2.110 LEN=55 TOS=0x00 PREC=0x00 TTL=63 ID=36954 DF PROTO=TCP SPT=2000 DPT=47899 WINDOW=227 RES=0x00 ACK PSH URGP=0
Dec  2 12:29:51 ubuntu kernel: [ 5558.926237] [netfilter] IN=eth0 OUT=eth1 MAC=08:00:27:b8:68:9f:08:00:27:4f:ee:15:08:00 SRC=10.0.2.110 DST=10.0.3.6 LEN=52 TOS=0x10 PREC=0x00 TTL=63 ID=44931 DF PROTO=TCP SPT=47899 DPT=2000 WINDOW=229 RES=0x00 ACK URGP=0

没有 TCP 握手,这可能表明 telnet 静默地重新建立了连接,与之前的日志没有区别,其中连接是根据 conntrack 建立的。

我怎样才能真正让 iptables 在 30 秒不活动后关闭已建立的连接?

最佳答案

这可能不是答案,而是对行为的一些解释:似乎 ip_conntrack 试图分配内部客户端在外部接口(interface)上再次使用的相同源端口(如果可用)。这意味着,即使在完全删除 conntrack 表之后,它也会“透明地”在同一端口上重新建立,并且 TCP 不会看到中断。实际上,您可以将其视为一项功能。

要验证此行为,您需要 2 个具有相同源端口的客户端连接到外部世界,然后再次查看 conntrack(很难模拟,因为操作系统会自由分配源端口号)。你应该得到 2 个不同的端口号。只有在这种情况下,TCP 连接才可能认识到同时发生了某些事情(在大多数情况下将关闭连接)...

关于linux - 需要删除与 iptables 建立的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20327518/

相关文章:

linux - 使用 sed 和正则表达式替换 html 内容

linux - 为什么 wso2 服务器不能从 wso2 用户运行?

java - 如何使用Android手机唤醒远程电脑?

Java NIO 库、api ...?

c# - 用于读取和解码 SSL 消息的循环不起作用

linux - SVN - 如何上传单个文件?

linux - Linux Container 可以跑在虚拟机上吗?

python - 使用python进行socket编程连接树莓派和windows PC

c++ - token 桶的实现

uwp - UWP 中的进程间通信