Dra*_*hot 4 http iptables web port-forwarding
我有一个运行 CentOS 的虚拟机,带有一个 Web 服务器,用于托管我在那里部署的随机服务,因此为了使其可以通过 Internet 访问,我使用 .net 打开了端口 80 iptables。由于 Web 服务器本身作为服务在非root的专用用户下运行,因此无法直接使用端口 80。因此,在阅读文档后,我添加了从端口 80 到 8080 的重定向,以便 Web 服务器可以绑定到该端口(我确实计划稍后添加对 HTTPS 的支持,也许我会购买一个合适的域,然后使用让我们加密什么的)。
到目前为止,它运行良好,但最近我注意到端口 8080 也保持开放状态,因此任何针对端口 80 或 8080 的请求都会得到相同的响应。问题是,我只需要从外部访问端口 80,因为不知何故我的提供商认为让端口 8080 保持开放可能会造成某种潜在的滥用?不管怎样,我不希望定向到端口 8080 的外部请求得到响应,只有那些针对端口 80 的请求才应该得到响应。
到目前为止,我的配置文件如下所示iptables:
*nat
:PREROUTING ACCEPT [89:7936]
:INPUT ACCEPT [70:3812]
:OUTPUT ACCEPT [41:2756]
:POSTROUTING ACCEPT [41:2756]
-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
COMMIT
*filter
:INPUT ACCEPT [916:134290]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [819:117300]
:f2b-sshd - [0:0]
-A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd
-A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
Run Code Online (Sandbox Code Playgroud)
我尝试删除打开8080端口的规则,但重新加载后iptables服务器也不会响应来自80端口的请求。最近,我一直在考虑添加另一个重定向规则,将源 IP 更改为端口 8080 接受的特定内容,但我不确定这是否可行。我这里需要指导。
注意:我对这个工具不太有经验,这是我怀疑的主要原因。另外,也许我缺少一些可能有用的规则,因此下面评论中对新规则的任何建议将不胜感激。
此示意图应该可以帮助您了解数据包处理是如何完成的:
过滤器/输入规则只看到在 nat/PREROUTING 中进行 NAT 后的数据包,因此默认情况下无法区分在端口 8080 上接收数据包(因为客户端直接将其发送到那里)与在端口 8080 上接收数据包(因为客户端在端口 80 上发送它,然后重定向到端口 8080。在这两种情况下,他们都会看到数据包到达端口 8080。因此,您需要额外的信息才能区分这两种情况。
首先,这条规则应该被删除,因为它没有用:
-A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)
因为正如所解释的,过滤器/输入不会在端口 80 上看到数据包:它现在到达端口 8080。这里不要tcpdump盲目信任:如图所示,tcpdump(AF_PACKET) 在这一切之前看到数据包,因此会看到端口 80 。
您可以使用 iptables 的conntrackmatch 来查询 netfilter 的连接跟踪系统,从而访问丢失的信息:对于这种情况,当前传入数据包是否是经过 DNAT 转换的连接的一部分,使用--ctstate DNAT(REDIRECT 是 DNAT 的特殊情况) ,就像 MASQUERADE 是 SNAT 的一个特例)。这场比赛还有其他选项,比如--ctorigdstport等,可能会达到类似的结果。
我将只列出有关此案例的重要规则,而不是全部规则,以进行说明。只需在需要时在正确的位置使用它们即可。
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
Run Code Online (Sandbox Code Playgroud)
可能就在通用... ESTABLISHED,RELATED -j ACCEPT行之后:
iptables -A INPUT -p tcp --dport 8080 -m conntrack --ctstate DNAT -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j DROP
Run Code Online (Sandbox Code Playgroud)
(或者如果稍后有一个包罗万象的删除规则,则不要添加最后一个删除规则)。
第一个 INPUT 规则将匹配到达端口 8080 的已 DNAT 流量(这里是从最初到达端口 80 开始),而第二个规则将丢弃到达端口 8080 的剩余流量:直接连接尝试。
注意:如果您想知道为什么state比赛和conntrack比赛看起来很相似,那么它state已被 取代conntrack。实际上,内核模块在内部除了匹配之外还xt_conntrack.ko处理匹配,以实现向后兼容性。stateconntrack
传输此信息的另一种方法是使用数据包标记,这是一种更通用的方法,可以应用于许多其他情况。它是一个任意数字,用于标记数据包(仅在内核中,不在网络上),并且可以在几个地方使用,包括 iptables 匹配mark来改变决策。由于MARK目标不是终止规则,因此可以在实际规则之前使用REDIRECT。由于它们以十六进制显示,因此我也将它们设置为十六进制。该值由您选择其含义。这里 0x80(十进制 128)将自行传达“命中端口 80 并被重定向到端口 8080”的信息,因此无需稍后重新检查端口,检查标记即可验证所有内容。像往常一样,重要的是连接的第一个数据包:该连接的每个其他数据包均由通用 conntrack 有状态规则处理... ESTABLISHED,RELATED -j ACCEPT。
iptables -t nat -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 0x80
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
Run Code Online (Sandbox Code Playgroud)
通用行之后... ESTABLISHED,RELATED -j ACCEPT:
iptables -A INPUT -m mark --mark 0x80 -j ACCEPT
iptables -A INPUT -p tcp --dport 8080 -j DROP
Run Code Online (Sandbox Code Playgroud)我还必须警告您,如果不首先丢弃(而不是拒绝)无效状态数据包,就使用 REJECT 规则会产生危险。当 TCP 数据包以错误的顺序到达时,在某些罕见的拥塞情况下,这可能会导致随机连接重置问题。目前正在考虑补充该问题的相关文档:
所以,而不是:
Run Code Online (Sandbox Code Playgroud)-A INPUT ... -j REJECT请考虑使用:
Run Code Online (Sandbox Code Playgroud)-A INPUT ... -m conntrack --ctstate INVALID -j DROP -A INPUT ... -j REJECT