现在有一段时间(我相信在 1.3 版中引入),iptables
' conntrack模块可以跟踪两个虚拟状态,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
或DNAT
状态的规则示例,但我还是尝试ESTABLISHED,RELATED
用SNAT
or替换DNAT
,如下所示:
# 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
它似乎有效,而且这种方法至少有一个我注意到的好处:我的防火墙曾经丢弃从我的内部主机到 Internet 的 RST 数据包(因为它们处于。INVALID
状态),但是使用这种新方法,它们被允许通过
不幸的是,虽然方便,但我不确定这种方法是否真的合适,因为我对网络的理论知识不足以理解它是否过于宽松(即允许来自我的局域网外部的一些不需要的数据包到达内部)。
我想我的问题可以这样写:一个数据包可以有SNAT
orDNAT
状态,而没有ESTABLISHED
orRELATED
状态(显然,第一个有NEW
状态的数据包除外)?
注意:我试图记录这样的数据包,但据我所知这是不可能的,因为iptables
只接受一个--ctstate
选项,并且!
不能在其中使用(换句话说,我不能说,或者至少找不到方法来比如说,“记录有SNAT
状态但没有ESTABLISHED
状态的数据包RELATED
”)。如果有另一种我没有想到的记录它们的方法,这也将非常受欢迎。
编辑 1:经过反复试验,我意识到我错了(因此是描边文本):一些数据包仍处于状态INVALID
,因此最终被丢弃。
编辑 2:如果使用SNAT
/DNAT
代替ESTABLISH,RELATED
不安全,请提供一些具体示例,说明数据包可能处于前一种状态而不处于后一种状态。
感谢@AB 关于日志记录的建议,我可以做更多测试,这里是结果,以及我自己问题的答案,希望这能帮助像我一样在网络上找不到任何东西的其他人关于状态
SNAT
和DNAT
,和/或它们替换ESTABLISHED,RELATED
匹配的能力。因此,在一个中等繁忙的家庭网络上(几台主机通过 SNAT 访问 Internet,以及一些托管服务器(HTTP/HTTPS、SMTP、IMAP 等)的虚拟机通过 DNAT 可公开访问),在五天内,我没有看到关于处于
SNAT
or状态的数据包的单行日志DNAT
,而不是ESTABLISHED
orRELATED
。SNAT
因此,“一个数据包是否可以具有orDNAT
状态而不具有ESTABLISHED
or状态”这个问题的答案RELATED
是否定的。由于我真正担心的是匹配
SNAT
或DNAT
代替ESTABLISHED,RELATED
允许数据包进入我的 LAN 可能过于宽松,起初这似乎让人放心,但我发现这不是一个好主意。事实上,相反,这似乎不太宽容:在我使用这些规则进行的测试期间,我看到一小部分但不可忽略的处于
RELATED
丢弃状态的数据包,主要是 ICMP 类型 3,代码 1 和 3(分别是destination host unreachable和destination port unreachable ),来自Internet,发往我局域网内的主机。换句话说(如果我对网络的理解正确的话),我的主机尝试与 Internet 建立一些连接,远程路由器响应无法建立连接,而我自己的防火墙/路由器主机阻止了这些响应。这可不好。因此,对于基本问题“
ESTABLISHED,RELATED
用SNAT
or替换是否是个好主意”的答案DNAT
再次是不。我不会使用您的安全方法。想象一下,您重新设计了您的网络并且不再需要使用 SNAT。会发生什么?这是显而易见的部分。可能有隐藏的问题潜伏在某个地方。
NAT 规则和过滤规则应尽可能保持独立,除非有充分的理由不这样做。我不确定你是否有充分的理由。一个很好的理由是区别对待 NATed 流量与非 NATed 流量(例如:服务器 DNAT 将服务发送到后面的其他服务器,但不允许用作路由器直接访问后面的服务器/服务)。
现在关于您的注意事项:只需将问题分为多个步骤。
这个错误的规则:
可以替换为:
或者使用 RETURN 和反转逻辑:
或者,使用标记(如果标记在其他地方使用(并且不想打扰面具))也可以实现相同的效果:
对于每种方法,可以想象轻松链接更多测试(通过增加标记方法的标记)。