我有一台运行 CentOS 的虚拟机,上面有一台用于托管我部署的随机服务的 Web 服务器,因此为了使其可以从 Internet 访问,我使用 打开了端口 80。iptables
由于 Web 服务器本身是在专用用户下作为服务运行的,因此根,无法直接使用端口 80。因此,在阅读了文档后,我添加了从端口 80 到 8080 的重定向,以便 Web 服务器可以绑定到该端口(我确实计划稍后添加对 HTTPS 的支持,也许我会购买一个合适的域名,然后使用 Let's Encrypt 或类似的东西)。
到目前为止,它运行良好,但最近我注意到端口 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
我尝试删除打开端口 8080 的规则,但重新加载后iptables
服务器也不会响应来自端口 80 的请求。最近我一直在考虑添加另一个重定向规则,将源 IP 更改为端口 8080 中接受的特定 IP,但我不确定这是否可行。我需要指导。
笔记:我对此工具不太熟悉,这是我怀疑的主要原因。此外,也许我遗漏了一些可能有用的规则,因此,如果能在下方评论中提出任何有关新规则的建议,我将不胜感激。
答案1
这示意图应该可以帮助您了解数据包处理是如何完成的:
filter/INPUT 规则只能看到在 nat/PREROUTING 中进行 NAT 后的数据包,因此默认情况下无法区分在端口 8080 上接收数据包(因为客户端直接将数据包发送到那里)和在端口 8080 上接收数据包(因为客户端将数据包发送到端口 80,然后重定向到端口 8080)。在这两种情况下,他们都会看到数据包到达端口 8080。因此,您需要额外的信息才能区分这两种情况。
首先,这条规则应该被删除,因为它没用:
-A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
因为正如所解释的,过滤器/INPUT 不会在端口 80 上看到数据包:它现在到达端口 8080。不要tcpdump
盲目相信:如示意图所示,tcpdump
(AF_PACKET)在所有这些之前看到了数据包,因此会看到端口 80。
您可以使用 iptables 的
conntrack
match 查询 netfilter 的连接跟踪系统,从而可以访问缺失的信息:在这种情况下,使用--ctstate DNAT
(REDIRECT 是 DNAT 的一个特例,就像 MASQUERADE 是 SNAT 的一个特例一样) 来判断当前传入数据包是否属于经过 DNAT 转换的连接。此 match 还有其他选项,例如--ctorigdstport
等,可能可以实现类似的结果。我只会列出与本案例相关的重要规则(而不是全部),以说明情况。只需在需要时在正确的位置使用它们即可。
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
可能就在通用
... 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
(或者,如果稍后有一个捕获全部删除规则,则不要添加这最后的 DROP 规则)。
第一个 INPUT 规则将匹配到达端口 8080 的经过 DNAT 的流量(这里最初到达的是端口 80),而第二个规则将丢弃到达端口 8080 的剩余流量:直接连接尝试。
注意:如果你想知道为什么
state
比赛和conntrack
match 看起来类似,已state
被 取代conntrack
。实际上,内核模块在内部除了 match 之外还xt_conntrack.ko
处理match ,以实现向后兼容。state
conntrack
传输此信息的另一种方法是使用数据包标记,这是一种更通用的方法,可以应用于许多其他情况。它是一个任意数字,用于标记数据包(仅在内核中,而不是在网络上),可以在几个地方使用,包括 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
在通用
... ESTABLISHED,RELATED -j ACCEPT
行之后:iptables -A INPUT -m mark --mark 0x80 -j ACCEPT iptables -A INPUT -p tcp --dport 8080 -j DROP
我还必须警告您,在未首先丢弃(而不是拒绝)无效状态数据包的情况下使用 REJECT 规则的危险。在某些罕见的拥塞情况下,当 TCP 数据包以错误的顺序到达时,这可能会给您带来随机连接重置问题。相关此问题的文档目前正在考虑添加:
因此,不要:
-A INPUT ... -j REJECT
请考虑使用:
-A INPUT ... -m conntrack --ctstate INVALID -j DROP -A INPUT ... -j REJECT
答案2
REDIRECT 仅改变端口号,因此如果连接是:
client -> public_addres:80
它成为了
client -> public_address:8080
因此,您将无法通过执行您正在做的事情同时阻止和接受。
首先删除这条规则:
-A INPUT -p tcp -m tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
并使用 DNAT 而不是 REDIRECT,例如:
-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j DNAT --to 127.0.0.1:8080
那可能会有用。
您也可以只监听 127.0.0.1:8080(而不是 0.0.0.0:8080)。
答案3
根据我的经验,您通常会更改 8080 服务的绑定。
IE 不是将服务绑定到 0.0.0.0:8080,而是将服务绑定到 127.0.0.1:8080,这意味着应用程序不会监听您的公共接口。
在这种情况下,我将设置一个从端口 80/443 到端口 8080 的反向代理(nginx),允许您配置从 http 端口 80 到 https 端口 443 的重定向,并且应用程序能够在端口 8080 上运行而无需了解 SSL。
我不是 iptables 专家,所以我不会尝试解决方案来解决上述问题。