需要删除与iptables建立的连接

时间:2013-12-02 11:45:53

标签: linux networking tcp firewall iptables

对于应用程序测试目的,当有状态防火墙通过超时将已建立的TCP连接从客户端丢弃到服务器时,我需要模拟一种情况。我在Virtualbox中安装了3个客户虚拟机:

  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
  4. 客户端和服务器是禁用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建立了连接。

    如何在30秒无活动后让iptables真正关闭已建立的连接?

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

尝试插入FORWARD -m状态INVALID -j DROP 这将丢弃没有建立连接的数据包。