如何将端口 80 重定向到 8080,同时保持 8080 对 Internet 关闭?

如何将端口 80 重定向到 8080,同时保持 8080 对 Internet 关闭?

我有一台运行 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

示意图应该可以帮助您了解数据包处理是如何完成的:

Netfilter 和常规网络中的数据包流

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 的conntrackmatch 查询 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比赛和conntrackmatch 看起来类似,已state被 取代conntrack。实际上,内核模块在内部除了 match 之外还xt_conntrack.ko处理match ,以实现向后兼容。stateconntrack

  • 传输此信息的另一种方法是使用数据包标记,这是一种更通用的方法,可以应用于许多其他情况。它是一个任意数字,用于标记数据包(仅在内核中,而不是在网络上),可以在几个地方使用,包括 iptablesmark比赛来改变决定。作为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 专家,所以我不会尝试解决方案来解决上述问题。

相关内容