在至少两个版本的 Linux(Ubuntu 9 和 Debian 7)上,我注意到,即使我在 lo 上只配置了一个环回地址(标准 127.0.0.1),它也会愉快地接受发往任何 127.xxx 地址的数据包。我发现这非常令人惊讶,因为其他 Unix 变体会丢弃未配置地址的数据包。
- 为什么/如何做到这一点?其他地址范围都不会发生这种情况,对吗?
- 我如何让它做更明智(和安全!)的事情并真正关注配置的地址?
编辑:我读过 RFC 5735,这是对它的一个相当草率的解释,“整个 127.0.0.0/8 块内的地址并未合法地出现在网络上的任何地方”到“这台机器必须接受所有这些 IP 的数据包”毕竟,您不会看到主机接受所有 172.16.0.0/12 的数据包,只是因为它们配置了其中一个地址。
我的目的不是询问地址的规范,而是询问 Linux 接收数据包逻辑的实现。这里的“为什么”和“如何”是指实际的 Linux 内核中什么导致正常的“这个数据包是给我的吗”逻辑被绕过?
答案1
环回是特殊的。它是整个 127.0.0.0/8 空间,并且它永远不会离开机器。这是仅监听已配置地址的唯一例外,如果它在环回上,它就是特殊的。
我认为这不会带来任何安全隐患,因为这些地址永远不可能出现在物理网络上。
答案2
正常路线逻辑不是被绕过,并且此配置更安全而不是你提议的那个。
首先让我们看一下路由表,看看发生了什么。
# ip address show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
# ip route show table 0
...
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
我们可以看到接口配置了前缀/8
,这导致Linux自动地生成一条127.0.0.0/8
通往lo
接口的路由。这将强制执行以下要求:此块的所有数据包都不会出现在网络上的任何地方,也不会在主机内部循环。
如果没有这条路由,127.0.0.0/8
网络数据包将不是被回环到主机内部,并有可能被路由出网络接口。这会带来不安全性和 RFC 不合规性。
请记住,“环回”就是这个意思。在常规接口上,发送给它的数据包会出去,而在环回接口上,发送给它的数据包会出去并立即返回。这就是环回的意思,也是您看到这种流量的原因。
答案3
它不是 Linux 独有的(Win 的工作原理完全相同),而是遵循规范(正如 Eric 指出的那样):来自RFC 5735 - 特殊用途 IPv4 地址
127.0.0.0/8 - This block is assigned for use as the Internet host
loopback address. A datagram sent by a higher-level protocol to an
address anywhere within this block loops back inside the host. This
is ordinarily implemented using only 127.0.0.1/32 for loopback. As
described in [RFC1122], Section 3.2.1.3, addresses within the entire
127.0.0.0/8 block do not legitimately appear on any network anywhere.