tl;dr:访问(例如)被重定向(内部)到(任何端口号在哪里)(例如,上一个命令与 相同);为什么会发生这种情况以及如何阻止发往 的连接?0.0.0.0
:port
curl http://0.0.0.0:443
127.0.0.1:port
port
curl
curl http://127.0.0.1:443
0.0.0.0
UPDATE2:我找到了一种通过修补 Linux 内核(版本 6.0.9)来阻止它的方法:
--- .orig/usr/src/linux/net/ipv4/route.c
+++ /usr/src/linux/net/ipv4/route.c
@@ -2740,14 +2740,17 @@ struct rtable *ip_route_output_key_hash_
}
if (!fl4->daddr) {
- fl4->daddr = fl4->saddr;
+ rth = ERR_PTR(-ENETUNREACH);
+ goto out;
+ /* commenting out the rest:
+ fl4->daddr = fl4->saddr; // if you did specify src address and dest is 0.0.0.0 then set dest=src addr
if (!fl4->daddr)
- fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK);
+ fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK); // if you didn't specify source address and dest address is 0.0.0.0 then make them both 127.0.0.1
dev_out = net->loopback_dev;
fl4->flowi4_oif = LOOPBACK_IFINDEX;
res->type = RTN_LOCAL;
flags |= RTCF_LOCAL;
- goto make_route;
+ goto make_route; END of COMMENTed out block */
}
err = fib_lookup(net, fl4, res, 0);
结果:发送到 IP 0.0.0.0 的数据包到哪里去了?:
$ ip route get 0.0.0.0
RTNETLINK answers: Network is unreachable
...他们没有!
客户端尝试从 127.1.2.18:5000 连接到 0.0.0.0:80
$ nc -n -s 127.1.2.18 -p 5000 -vvvvvvvv -- 0.0.0.0 80
(UNKNOWN) [0.0.0.0] 80 (http) : Network is unreachable
sent 0, rcvd 0
(如果你没有应用内核补丁,你将需要一个像下面这样的服务器来使上面的客户端能够成功连接:(作为 root,在 bash 中)while true; do nc -n -l -p 80 -s 127.1.2.18 -vvvvvvvv -- 127.1.2.18 5000; echo "------------------$(date)";sleep 1; done
)
已修补ping
(即ping
当目标地址为 0.0.0.0 时未将目标地址设置为与源地址相同的 a,即注释掉您在此处// special case for 0 dst address
看到的下面的 2 行):
$ ping -c1 0.0.0.0
ping: connect: Network is unreachable
立即的。但是,如果指定源地址,则需要超时(10 秒)才能完成:
$ ping -I 127.1.2.3 -c1 -- 0.0.0.0
PING 0.0.0.0 (0.0.0.0) from 127.1.2.3 : 56(84) bytes of data.
--- 0.0.0.0 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
更新1:
此处解释了为什么部分,但我期待更多关于为什么会发生这种情况的详细信息,例如(感谢在 liberachat #kernel 频道上有昵称的用户):anyone
$ ip route get 0.0.0.0
local 0.0.0.0 dev lo src 127.0.0.1 uid 1000
cache <local>
这表明以某种方式发往的数据包0.0.0.0
被路由到本地主机接口lo
并且它们获得了源 ip 127.0.0.1
(如果我解释正确的话)并且因为该路由未出现在此列表中:
$ ip route list table local
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 169.254.6.5 dev em1 proto kernel scope host src 169.254.6.5
broadcast 169.254.6.255 dev em1 proto kernel scope link src 169.254.6.5
local 192.168.0.17 dev em1 proto kernel scope host src 192.168.0.17
broadcast 192.168.255.255 dev em1 proto kernel scope link src 192.168.0.17
这意味着它必须以某种方式存在于 Linux 内核内部。IE。硬编码
为了给你一个想法,下面是它如何查找互联网上的 IP(我使用 quad1 作为示例 IP):
$ ip route get 1.1.1.1
1.1.1.1 via 192.168.1.1 dev em1 src 192.168.0.17 uid 1000
cache
我的网关在哪里192.168.1.1
,即:
$ ip route
default via 192.168.1.1 dev em1 metric 2
169.254.6.0/24 dev em1 proto kernel scope link src 169.254.6.5
192.168.0.0/16 dev em1 proto kernel scope link src 192.168.0.17
因为iptables
不能用于感知(并因此阻止/丢弃)此类以某种方式路由到 127.0.0.1 的连接,目的地为 0.0.0.0,所以可能很难找到阻止它们的方法......但我一定会尝试找到一种方法,除非有人已经知道了。
@Stephen Kitt(在评论中)提出了一种方法来阻止驻留在 /etc/hosts 中的主机名,因此:
0.0.0.0 someblockedhostname
您可以拥有
127.1.2.3 someblockedhostname
127.1.2.3 someOTHERblockedhostname
(127.0.0.1 以外的任何内容,但您可以对每个被阻止的主机名使用相同的 IP,除非你想区分)
然后你可以阻止使用哪个IP iptables
。
但是,如果您的 DNS 解析器(即NextDNS或1.1.1.3)返回0.0.0.0
被阻止的主机名(而不是NXDOMAIN
),那么您不能这样做(当然,除非您想手动添加每个主机/etc/hosts
,因为 /etc/hosts 优先- 假设你没有hosts: files dns
从/etc/nsswitch.conf
)更改行
旧:(尽管已编辑)
在 Linux 上(我试过 Gentoo 和 Pop OS!,最新的)如果你有这行/etc/hosts
:
0.0.0.0 somehosthere
然后你以 root 身份运行它(模拟本地主机服务器监听端口 443)
# nc -l -p 443 -s 127.0.0.1
然后你进入你的浏览器(Firefox 和 Chrome/Chromium 测试)并将它放在地址栏中:
https://somehosthere
或
0.0.0.0:443
或
https://0.0.0.0
然后你开始的终端nc
(又名netcat)显示连接尝试(somehosthere
如果你在url中使用它,一些垃圾文本包括明文)
或者代替浏览器,您可以尝试:
curl https://somehosthere
或者如果您想查看明文请求:
curl http://somehosthere:443
dnsmasq
即使在使用时,这似乎也无法0.0.0.0 somehosthere
缓解/etc/hosts
,但在使用时dnsmasq
,您的 DNS 解析器(即 NextDNS 或Cloudflare 的 1.1.1.3)返回0.0.0.0
而不是NXDOMAIN
(在撰写本文时为true )和主机名不在你的/etc/hosts
(并且在你告诉dnsmasq
的是/etc/hosts
使用)中,那么有两种方法可以减轻它(一种或两种都有效):
- 使用
dnsmasq
参数--stop-dns-rebind
--stop-dns-rebind
Reject (and log) addresses from upstream nameservers which are in
the private ranges. This blocks an attack where a browser behind
a firewall is used to probe machines on the local network. For
IPv6, the private range covers the IPv4-mapped addresses in pri‐
vate space plus all link-local (LL) and site-local (ULA) ad‐
dresses.
- 使用使自己返回解析为的任何主机名的行
bogus-nxdomain=0.0.0.0
(再次除外,如果该主机名在 /etc/hosts 中(绕过 dnsmasq)以及您告诉 dnsmasq 使用的内容(如果您这样做了))/etc/dnsmasq.conf
dnsmasq
NXDOMAIN
0.0.0.0
/etc/hosts
那么,这个问题的第二部分是如何禁止对 0.0.0.0 的访问被重定向到 127.0.0.1 ?我想要这个是因为当使用 NextDNS(或cloudflare 的 1.1.1.3)作为 DNS 解析器时,它会返回0.0.0.0
被阻止的主机名,而不是 NXDOMAIN,因此在加载网页时,其中的一部分(位于被阻止的主机名上)将尝试访问我的本地主机服务器在端口 443(如果有)上运行并从中加载页面,而不是仅仅被阻止。
意识到这一点的相关特定于浏览器的公共问题(0.0.0.0 映射到 127.0.0.1):
Chrome/Chromium:https ://bugs.chromium.org/p/chromium/issues/detail?id=
1300021 Firefox:https ://bugzilla.mozilla.org/show_bug.cgi?id=1672528#c17