《Linux系统安全:纵深防御、安全扫描与入侵检测 》 —2.2.4 禁用iptables的连接追踪
2.2.4 禁用iptables的连接追踪
1. 分析连接追踪的原理
概要来说,连接追踪系统在一个内存数据结构中记录了连接的状态,这些信息包括源IP、目的IP、双方端口号(对TCP和UDP)、协议类型、状态和超时信息等。有了这些信息,我们可以设置更灵活的过滤策略。
连接追踪系统本身不进行任何过滤动作,它为上层应用(如iptables)提供了基于状态的过滤功能。
我们看一个实际的例子(通过cat /proc/net/nf_conntrack命令可以查看当前连接追踪的表):
ipv4 2 tcp 6 62 SYN_SENT src=xxx.yyy.19.201 dst=87.240.131.117 sport=24943 dport=443 [UNREPLIED] src=87.240.131.117 dst=xxx.yyy.19.201 sport=443 dport=24943 mark=0 secmark=0 use=2 #该条目的意思是:系统收到了来自xxx.yyy.19.201:24943发送到87.240.131.117:443的第一个TCP SYN包,但此时对方还没有回复这个SYN包(UNREPLIED)
ipv4 2 tcp 6 30 SYN_RECV src=106.38.214.126 dst=xxx.yyy.19.202 sport=18102 dport=6400 src=xxx.yyy.19.202 dst=106.38.214.126 sport=6400 dport=18102 mark=0 secmark=0 use=2#该条目的意思是:系统收到了来自106.38.214.126:18102发送到xxx.yyy.19.202:6400的第一个TCP SYN包
ipv4 2 tcp 6 158007 ESTABLISHED src=xxx.yyy.19.201 dst=211.151.144.188 sport=48153 dport=80 src=211.151.144.188 dst=xxx.yyy.19.201 sport=80 dport=48153 [ASSURED] mark=0 secmark=0 use=2#该条目的意思是:xxx.yyy.19.201:48153<-->211.151.144.188:80之间的TCP连接是ESTABLISHED状态,这个连接是被保证的(ASSURED,不会因为内存耗尽而丢弃)
该表中的数据提供的状态信息可以使用iptables的state模块进行状态匹配,进而执行一定的过滤规则。目前iptables支持基于以下4种状态的过滤规则:INVALID、ESTABLISHED、NEW和RELATED。
启用连接追踪后,在某些情况下,在设置iptables时会变得比较简单。我们的服务器需要主动访问https://www.amazon.com提供的接口时,3次握手的示意图如图2-3所示。
图2-3 主动访问外网服务时3次握手示意图
在基于状态进行iptables设置时,使用如下的规则即可:
iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT # rule1
iptables -A OUTPUT -p tcp -j ACCEPT # rule2
工作流程如下:
1)第1个包①匹配到规则rule2,允许。
2)第2个包②因为在nf_conntrack表中有如下的规则匹配到rule1,允许。
ipv4 2 tcp 6 431995 ESTABLISHED src=172.30.16.1 dst=54.239.25.200 sport=50611 dport=443 src=54.239.25.200 dst=172.30.16.1 sport=443 dport=50611 [ASSURED] mark=0 secmark=0 use=2
3)第3个包③匹配到规则rule2,允许。
2. 禁用连接追踪的方法
通过2.2.4节的学习,我们知道在进行大量网络传输连接的时候,启用连接追踪可能导致网络丢包、无法新建连接、TCP重传等问题。因此,我们需要禁用连接追踪。
禁用连接追踪的方法有如下3个。
1)内核中禁用Netfilter connection tracking support。
编译内核时,依次进入Networking support→Networking options→Network packet filtering framework (Netfilter)→Core Netfilter Configuration,禁用的方法如图2-4所示(取消选中Netfilter connection tracking support)。
图2-4 编译内核时禁用连接追踪的方法
这样编译出来的内核将不支持连接追踪功能,也就是不会生成以下的ko文件。
kernel/net/netfilter/nf_conntrack.ko
kernel/net/netfilter/nf_conntrack_proto_dccp.ko
kernel/net/netfilter/nf_conntrack_proto_gre.ko
kernel/net/netfilter/nf_conntrack_proto_sctp.ko
kernel/net/netfilter/nf_conntrack_proto_udplite.ko
kernel/net/netfilter/nf_conntrack_netlink.ko
kernel/net/netfilter/nf_conntrack_amanda.ko
kernel/net/netfilter/nf_conntrack_ftp.ko
kernel/net/netfilter/nf_conntrack_h323.ko
kernel/net/netfilter/nf_conntrack_irc.ko
kernel/net/netfilter/nf_conntrack_broadcast.ko
kernel/net/netfilter/nf_conntrack_netbios_ns.ko
kernel/net/netfilter/nf_conntrack_snmp.ko
kernel/net/netfilter/nf_conntrack_pptp.ko
kernel/net/netfilter/nf_conntrack_sane.ko
kernel/net/netfilter/nf_conntrack_sip.ko
kernel/net/netfilter/nf_conntrack_tftp.ko
kernel/net/netfilter/xt_conntrack.ko
kernel/net/ipv4/netfilter/nf_conntrack_ipv4.ko
kernel/net/ipv6/netfilter/nf_conntrack_ipv6.ko
此时,在iptables中不能再使用网络地址转换功能,同时也不能再使用-m state模块。否则会产生以下的报错信息:
[root@localhost ~]# iptables -t nat -A POSTROUTING -o eth0 -s 172.30.4.0/24 -j SNAT --to 172.30.4.11
iptables v1.4.7: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
[root@localhost ~]# iptables -I INPUT -p tcp -m state --state NEW -j ACCEPT
iptables: No chain/target/match by that name.
2)在iptables中,禁用-m state模块,同时在filter表的INPUT链中显式地指定ACCEPT。
以图2-3为例,在满足这样的访问需求时,我们使用的iptables必须修改为以下内容:
iptables -A INPUT -p tcp -s 54.239.25.200 --sport 443 -j ACCEPT # rule1
iptables -A OUTPUT -p tcp -j ACCEPT # rule2
同时,在/etc/init.d/iptables中修改如下的内容:
修改前:NF_MODULES_COMMON=(x_tables nf_nat nf_conntrack) # Used by netfilter v4 and v6
修改后:NF_MODULES_COMMON=(x_tables) # Used by netfilter v4 and v6
3)在iptables中,使用raw表,指定NOTRACK。
iptables -t raw -A PREROUTING -p tcp -j NOTRACK
iptables -t raw -A OUTPUT -p tcp -j NOTRACK
iptables -A INPUT -p tcp -s 54.239.25.200 --sport 443 -j ACCEPT # rule1
iptables -A OUTPUT -p tcp -j ACCEPT # rule2
在以上的3种方法中,根据自己的业务情况,可以参考实施其中一种。
1)对于使用网络地址转换功能的服务器来说,不能禁用连接追踪。
2)对于FTP的被动模式,在FTP服务器上需要显式地打开需要进行数据传输的端口范围。关于主动FTP和被动FTP的内容,本书不再赘述。
在配置了网络地址转换的服务器上,不能禁用连接追踪,但是此时可以使用如下的方法来提高连接追踪的条目上限。
在/etc/sysctl.conf中,新增如下的内容:
net.nf_conntrack_max = 524288
net.netfilter.nf_conntrack_max = 524288
新增配置文件/etc/modprobe.d/netfilter.conf,内容如下:
options nf_conntrack hashsize=131072
执行以下的命令使其生效:
/etc/init.d/iptables restart #重新加载连接追踪模块,同时更新nf_conntrack配置hashsize
sysctl -p #使得修改的sysctl.conf中nf_conntrack上限提高
在未指定时,系统nf_conntrack_max的值根据以下公式计算得出:
nf_conntrack_max = nf_conntrack_buckets * 4
在未指定时,系统nf_conntrack_buckets的值根据以下公式计算得出:
在系统内存大于等于4GB时,nf_conntrack_buckets = 65536
在系统内存小于4GB时,nf_conntrack_buckets = 内存大小 / 16384
在本案例中,我们使用options nf_conntrack hashsize=131072自主指定了Buckets的大小。
Buckets和连接追踪表的关系如图2-5所示。
设置Buckets合理的值(一般为预计的连接追踪表上限的1/4),可以使得连接追踪表的定位效率最高。
3. 确认禁用连接追踪的效果
我们在禁用了连接追踪后,可以使用如下两个方法来验证效果:
1)检查/var/log/messages内容不再出现table full的报错信息。
2)检查lsmod |grep nf_conntrack的输出,确认没有任何输出即可。
如果是在网络地址转换服务器上,则需要执行以下的命令来检查效果:
sysctl net.netfilter.nf_conntrack_max #确认该值是我们修改后的结果
sysctl net.netfilter.nf_conntrack_count #确认该值能够突破出问题时的最大追踪数
图2-5 Buckets和连接追踪表的关系
- 点赞
- 收藏
- 关注作者
评论(0)