iptables conntrack 模块:SNAT(或 DNAT)状态代替 ESTABLISHED/RELATED?

iptables conntrack 模块:SNAT(或 DNAT)状态代替 ESTABLISHED/RELATED?

有一段时间了(我相信是在 1.3 版本中引入的),iptables'连线模块可以跟踪两个虚拟状态,SNAT 和 DNAT:

SNAT 虚拟状态,如果原始源地址与回复目的地不同则匹配。 DNAT 虚拟状态,如果原始目的地与回复源不同则匹配。

在我的路由器/防火墙主机上,我有一些 SNAT 规则,如下所示:

# SNAT
iptables -t filter -A FORWARD -i $FROM_IFACE -o $TO_IFACE -s $FROM_IP -d $TO_IP -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A FORWARD -i $TO_IFACE -o $FROM_IFACE -s $TO_IP -d $FROM_IP -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -o $TO_IFACE -s $FROM_IP -d $TO_IP -j SNAT --to-source $SNAT_IP

# DNAT
iptables -t nat -A PREROUTING -i $FROM_IFACE -d $FROM_IP -p $PROTO --dport $PORT -j DNAT --to-destination $TO_IP
iptables -t filter -A FORWARD -i $FROM_IFACE -o $TO_IFACE -d $TO_IP -p $PROTO --dport $PORT -j ACCEPT
iptables -t filter -A FORWARD -i $TO_IFACE -o $FROM_IFACE -s $TO_IP -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

经过一番谷歌搜索后,我找不到任何iptables使用这些“新”SNAT或状态的规则示例,但我还是尝试用orDNAT替换,如下所示:ESTABLISHED,RELATEDSNATDNAT

# SNAT
iptables -t filter -A FORWARD -i $FROM_IFACE -o $TO_IFACE -s $FROM_IP -d $TO_IP -m conntrack --ctstate NEW,SNAT -j ACCEPT
iptables -t filter -A FORWARD -i $TO_IFACE -o $FROM_IFACE -s $TO_IP -d $FROM_IP -m conntrack --ctstate SNAT -j ACCEPT
iptables -t nat -A POSTROUTING -o $TO_IFACE -s $FROM_IP -d $TO_IP -j SNAT --to-source $SNAT_IP

# DNAT
iptables -t nat -A PREROUTING -i $FROM_IFACE -d $FROM_IP -p $PROTO --dport $PORT -j DNAT --to-destination $TO_IP
iptables -t filter -A FORWARD -i $FROM_IFACE -o $TO_IFACE -d $TO_IP -p $PROTO --dport $PORT -j ACCEPT
iptables -t filter -A FORWARD -i $TO_IFACE -o $FROM_IFACE -s $TO_IP -m conntrack --ctstate DNAT -j ACCEPT

它似乎有效,而且这种方法至少有一个我可以注意到的好处:我的防火墙过去常常丢弃从我的内部主机到互联网的 RST 数据包(因为它们处于INVALID状态),但是使用这种新方法,它们被允许经过

不幸的是,虽然方便,但我不确定这种方法是否真的合适,因为我对网络的理论知识不足以理解它是否过于宽松(即允许来自我的 LAN 外部的一些不需要的数据包到达内部)。

我认为我的问题可以这样表述:一个数据包可以具有SNATorDNAT状态,同时不具有ESTABLISHEDorRELATED状态(显然,第一个具有该NEW状态的数据包除外)?

注意:我尝试记录此类数据包,但据我所知这是不可能的,因为iptables只接受一个--ctstate选项,并且!不能在其中使用(换句话说,我不能说,或者至少找不到一种方法例如,“记录具有SNAT状态但没有ESTABLISHED状态的数据包RELATED”)。如果有一种我没有想到的替代方法来记录它们,这也会非常受欢迎。

编辑1:经过一番尝试和错误,我意识到我错了(因此是描边文本):一些数据包仍处于状态INVALID,因此最终被丢弃。

编辑2:如果使用SNAT/DNAT代替ESTABLISH,RELATED不安全,请提供一些具体的示例,说明数据包可能处于前一种状态而不是后一种状态的情况。

答案1

感谢 @AB 关于日志记录的建议,我可以做更多测试,这里是结果,以及我自己问题的答案,希望这能帮助像我一样在网络上找不到任何内容的其他人关于状态SNATDNAT,和/或它们替换匹配的能力ESTABLISHED,RELATED

因此,在一个中等繁忙的家庭网络上(几台主机通过 SNAT 访问 Internet,以及一些托管服务器(HTTP/HTTPS、SMTP、IMAP 等)的虚拟机可通过 DNAT 公开访问),在五天内,我没有看到一行关于数据包处于SNATorDNAT状态的日志,而不是ESTABLISHEDor状态RELATED

SNAT因此,“数据包是否可以具有orDNAT状态,同时不具有ESTABLISHEDor状态”这个问题的答案RELATED

由于我真正担心的是匹配SNATDNAT代替ESTABLISHED,RELATED允许数据包进入我的 LAN 可能过于宽松,所以乍一看这似乎令人放心,但我发现这不是一个好主意。

事实上,情况恰恰相反,较少的宽容:在使用这些规则进行测试期间,我看到少量但不可忽略的处于RELATED被丢弃状态的数据包,大部分是 ICMP 类型 3、代码 1 和 3(分别为目标主机不可达目的端口不可达),来自 Internet,目的地是我的 LAN 内的主机。换句话说(如果我正确理解网络),我的主机尝试与互联网建立一些连接,远程路由器响应无法建立连接,而我自己的防火墙/路由器主机阻止了这些响应。这不可能是好事。

ESTABLISHED,RELATED因此,根本问题“用SNATor替换是个好主意吗”的答案DNAT是,

答案2

为了安全起见,我不会使用你的方法。想象一下您重新设计了您的网络并且不再需要使用 SNAT。会发生什么?这是显而易见的部分。某处可能潜伏着隐藏的问题。

NAT 规则和过滤规则应尽可能保持独立,除非有充分的理由不这样做。我不确定你有充分的理由。一个很好的理由是区别对待 NAT 流量和非 NAT 流量(例如:服务器 DNAT 向后面的其他服务器提供服务,但不允许用作直接访问后面的服务器/服务的路由器)。

现在说说你的笔记:只需将问题分成多个步骤即可。

这个不正确的规则:

iptables -A FORWARD -m conntrack --ctstate SNAT ! --ctstate ESTABLISHED,RELATED -j LOG

可以替换为:

iptables -N subtest
iptables -A FORWARD -m conntrack --ctstate SNAT -j subtest
iptables -A subtest -m conntrack ! --ctstate ESTABLISHED,RELATED -j LOG

或者用 RETURN 和相反的逻辑代替:

iptables -N speciallog
iptables -A FORWARD -j speciallog
iptables -A speciallog -m conntrack ! --ctstate SNAT -j RETURN
iptables -A speciallog -m conntrack ! --ctstate ESTABLISHED,RELATED -j LOG

或者,使用标记(如果在其他地方使用标记则不然(并且不想使用掩码))也可以实现相同的效果:

iptables -A FORWARD -m conntrack --ctstate SNAT -j MARK 1
iptables -A FORWARD -m mark --mark 1 -m conntrack ! --ctstate ESTABLISHED,RELATED -j LOG

对于每种方法,我们可以想象轻松链接更多测试(通过增加标记方法的标记)。

相关内容