我不确定“荣誉”这个词是否合适,但这是我能想到的最好的词。我有一个场景,我在同一个网络上有两台服务器。它们有主 IP 和辅助 IP,都在同一个子网上。为了讨论方便,它们看起来像这样:
server1 eth0 172.16.45.3/24
server1-A eth0:11 172.16.45.21/27
server1-B eth0:12 172.16.45.22/27
server2 eth0 172.16.45.4/27
是的,server1 设置为 /24,是的,这是一个错误。
我注意到这个问题是因为从 server1->server2 的连接源 IP 是 172.16.45.21 而不是 172.16.45.3。由于发起连接的应用程序未指定源 IP,我很惊讶它没有使用 172.16.45.3。
就在那时,我注意到了错误的网络掩码。由于目标 IP 位于已知的较小网络中,因此它使用来自相同 /27 的 IP,而不是它认为来自 /24 的 IP。哎呀。
因此,我通过运行以下命令修复了 server1:eth0 上的网络掩码:
ifconfig eth0 netmask 255.255.255.224
ifconfig 现在看起来也很高兴:
eth0 Link encap:Ethernet HWaddr 00:22:19:54:EF:11
inet addr:172.16.45.3 Bcast:172.16.45.31 Mask:255.255.255.224
inet6 addr: fe80::222:19ff:fe54:ef11/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1085587580 errors:0 dropped:1355 overruns:0 frame:0
TX packets:1208356392 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:365708046601 (340.5 GiB) TX bytes:667099868812 (621.2 GiB)
Interrupt:169 Memory:f8000000-f8012100
此外,路由表也自行清理了。
前:
server1 0 /home/jj33 ># route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
172.16.45.0 0.0.0.0 255.255.255.224 U 0 0 0 eth0
172.16.45.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
0.0.0.0 172.16.45.1 0.0.0.0 UG 0 0 0 eth0
后:
server1 0 /home/jj33 ># route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
172.16.45.0 0.0.0.0 255.255.255.224 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
0.0.0.0 172.16.45.1 0.0.0.0 UG 0 0 0 eth0
唯一的问题是,在完成所有这些之后,操作系统似乎仍然选择 172.16.45.21 作为到同一网络的出站连接的源地址(SMTP 并不直接涉及这个问题,只是一种显示连接源 IP 的便捷方式):
server1 0 /home/jj33 ># telnet server2 25
Trying 172.16.45.4...
Connected to 172.16.45.4.
Escape character is '^]'.
220 server2.example.com ESMTP mailer ready at Wed, 23 Dec 2009 12:18:28 -0600
ehlo foo
250-server2.qcommcorp.com Hello server1-A.example.com [172.16.45.21]
250 HELP
(如果不明显的话,如果一切正常,我希望邮件程序响应我的 ehlo 说“Hello server1.example.com [172.16.45.3]”)。
那么,现在我的问题来了。我怎样才能让我的操作系统注意到 eth0 上的网络掩码已更改,以至于它是到我本地 /27 的出站连接的更好选择?我假设重新启动服务器或重新启动网络服务就可以做到这一点,但我必须等一周才能到达下一个维护窗口,这似乎是我可以在不中断服务的情况下完成的事情(这是一个生产系统,这个不正确的源 IP 是一个小的、间接的问题 - 核心应用程序运行良好)。
非常感谢您的帮助。谢谢!
更新日期:2010/1/8:
因此,这个问题比我预期的引起了更多的关注,我最终获得许可将应用程序故障转移到备用孤岛并在标准窗口之外重新启动受影响服务器上的网络服务,这意味着我无法测试以下任何理论。
但总体来说我相信朱利亚诺的回应涵盖了最详细的内容。我没有复制粘贴,但在使用 ip 时,它似乎普遍证实了他的假设。
此外,有足够多的人建议使用 ip 而不是 ifconfig,因此我花了一些时间尝试它,并向你们所有人致敬,我当然应该使用 ip。感谢你们的指点。
答案1
首先,不要使用ifconfig
和route
。这些命令如今通常被视为过时;它们是很久以前编写的,当时 Linux 的网络堆栈非常不同,并且从那时起就一直在修补。接口别名的概念(例如ethX:YY) 以便拥有多个地址如今已经过时了,它们仍然存在,主要是为了取悦 ifconfig 本身。今天,该ip
命令应该可以满足您的所有需求。
现在,了解一下您原来的情况:您的 eth0 接口最初有两个活动范围:/24 和 /27。172.16.45.3 是 /24 范围的主地址,而 172.16.45.21 是 /27 范围的主地址(因为它列在第一位)。当您发出 ifconfig 命令来更改第一个地址的前缀时,它会将其删除并将其重新插入为 /27 范围中的辅助地址。所以现在您应该有类似以下内容:
inet 172.16.45.21/27 brd 172.16.45.31 primary eth0:11
inet 172.16.45.22/27 brd 172.16.45.31 secondary eth0:12
inet 172.16.45.3/27 brd 172.16.45.31 secondary eth0
eth0 是否应该是主地址或看起来应该是主地址(另一个不使用 ifconfig 的原因)并不重要。它被插入到 /27 范围的后面,因此它是一个辅助地址。这也意味着出站数据包将被寻址到 172.16.45.21,并且如果您使用 ifconfig 关闭 eth0:11,全部你们的地址会被一起删除。这就是它的工作原理。
解决此问题的唯一方法是从接口中删除所有地址,然后按正确顺序重新插入。然后,添加的第一个地址(在 /27 范围内)将成为该范围内的主要地址,而其他地址将全部成为次要地址。
寻址从一开始就已损坏,在这种情况下您无能为力。最好的解决方案就是重新启动网络服务。
一种可能的解决方法是更改源路由地址。这将产生与更改主地址几乎相同的效果。对于您的情况:
ip route change 172.16.45.0/27 dev eth0 src 172.16.45.3
在这种情况下,发往 172.16.45.0/27 的数据包的源地址将设置为 172.16.45.3。如果您还想更改通过网关的数据包的源,则需要另一个命令。
答案2
我遇到了类似的问题(两台服务器的 eth0 和 eth1 位于同一以太网段),无法弄清楚如何在我的情况下强制使用源。但是,您可以尝试这种方法来强制使用您的情况下的源 IP:
ip route add dev eth0 src 172.16.45.3 172.16.45.4 metric 2
这又是关于度量的,但包括方程中的源。在我的家庭配置中,它允许我选择一个与内核默认选择的 IP 不同的 IP 来连接到我的服务器。
答案3
您没有说明您使用的是哪个发行版。您应该更改配置文件并使用某种 initscript 来重新加载网络设置。(如果您跳过此步骤,您的设置在重启后将丢失。)
第二件事是,如今该ip
工具比 Linux 上的 ifconfig 更受欢迎。有了ip
它,您可以随时添加和删除 IP 地址。
答案4
不确定我是否理解,但也许你可以做类似的事情
路由添加-net 172.16.45.0/27 dev eth0
这会强制所有到该子网的连接都通过具有您提到的 IP 地址的 eth0。