为什么必须使用 iptables 授权环回流量才能访问网络?

dgo*_*o.a 7 iptables

我认为以下是桌面(非服务器)上传出 HTTP 所必需的:

iptables -A INPUT  -p tcp -m multiport --sports 80,443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

但是,事实证明我需要这两个才能使它工作。我不知道为什么:

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

我知道最后一条规则允许 UDP 到lo接口。

但是,我认为我需要的只是outgoing TCP for NEW/ESTABLISHED connections+ incoming TCP for ESTABLISHED connections。这对我来说似乎违反直觉(因为我仍在学习)。

Hau*_*ing 7

您显然不需要loInternet 访问。但也许您有一个本地 DNS 服务器(转发器)正在运行。DNS 使用 UDP,Web 访问除了 HTTP 之外还需要 DNS。

顺便说一句,您的规则不允许(相关)ICMP 响应。这可能会导致问题(除非您使用较低的 MSS/MTU 值)。但是您甚至不允许传出 ICMP,因此路径 MTU 发现甚至不起作用。


Dri*_*ist 6

我只能做出假设,因为你没有列出你的默认策略。在输出的顶部找到iptables -S。我会假设您受到限制并且您有这样的事情。

-P INPUT DROP
-P FORWARD DROP
-P OUTPUT DROP
Run Code Online (Sandbox Code Playgroud)

伟大的!对于 IP 数据包,您的机器现在完全不可见、被蒙上眼睛、被束缚和堵塞。这几乎与将其从以太网网络中拔出一样好。

所以,如果你想在这个残酷、黑暗的世界里有希望,你就必须制定一些规则来接受一些包裹,也许会遇到一个拿着刀割断你的绳索的人,但哪些包裹是正确的?

需要一个输出规则来允许数据包到达服务器用于 http/https 流量的端口

-A OUTPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

需要一个 INPUT 规则来允许数据包从用于 http/https 流量的端口进入您的浏览器。

-A INPUT -p tcp -m multiport --sports 80,443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

因此,现在您可以从您的 Web 浏览器建立新的 http/https 连接,并通过这些已建立的连接接收返回的信息。

那有什么问题呢?没有办法获取 DNS 信息,您应该可以在您的网络浏览器中输入您要访问的网站的 IP 地址,但这并不是我们想要的。DNS 流量使用 UDP 协议通过端口 53 进行处理。

-A OUTPUT -p udp --dport 53 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

为了收到这些方便的回复,我们需要在眼罩上再挖一些洞。

-A INPUT -p udp --sport 53 -m conntrack --ctstate ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

现在有一些亮光,你可以听到它,比如说,如果你对谷歌的其中一台服务器进行 dns 查询

dig @8.8.8.8 slashdot.org
Run Code Online (Sandbox Code Playgroud)

这样的回应!但是也许您的浏览器仍然无法弄清楚 slashdot 在世界上的真正位置。至少有一个发行版 (Ubuntu) 设置为使用内部 DNS 代理,因此您需要通过设置规则来允许您作为服务器进行通信,从而与自己对话(无论如何世界其他地方都很无聊)端口 53

-A OUTPUT -o lo -p udp --sport 53 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A INPUT -i lo -p udp --dport 53 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

请注意这些“我是我自己的服务器”规则与之前的“我只想看看世界规则”之间的细微差别。还-o lo-i lo表示该服务器只会这台机器,一个很好的措施,以避免被吸进一些复杂的DNS反弹类型的攻击。

您现在应该看到您的浏览器再次正常工作。


Dav*_*man 1

INPUT这将取决于和/或链是否OUTPUT设置为ACCEPT不匹配的数据包。如果是的话,您根本不需要任何规则。如果您没有更改它,这可能是默认值。

最后 2 条规则允许来自或流向lo接口(即 127.0.0.1 / ::1)的任何流量,而不仅仅是 UDP。除非您连接到本地桌面上的 Web 服务器,否则它们与 HTTP 无关。