-2

我们在 Ubuntu Xenial 中的网络路由配置有问题。

我们有许多服务器同时使用 Debian 8.4 (Jessie) 和 Ubuntu 16.04.2 (xenial) 以及完全相同的网络设置(或者至少就我们所见而言)。

它们都有两个连接到两个 VLAN(比如“A”和“B”)的 NIC,尽管其他 VLAN 都可以访问,例如从 VLAN“C”。

这两个/etc/network/interfaces文件的格式为:

注意:为了更好的可读性,我伪造了名称和 IP。

# VLAN A
auto eth0
iface eth0 inet static
address 192.168.111.xxx
netmask 255.255.255.0
broadcast 192.168.111.255
network 192.168.111.0
gateway 192.168.111.254
dns-nameservers 192.168.111.25 192.168.111.26

# VLAN B
auto eth1
iface eth1 inet static
address 192.168.222.xxx
netmask 255.255.255.0
broadcast 192.168.222.255
network 192.168.222.0
gateway 192.168.222.254 # <-- (Commented out in Ubuntu machine)
dns-nameservers 192.168.111.25 192.168.111.26

...说xxxDebian 机器为 100,Ubuntu 机器为 200,我正在尝试从 VLAN“C”中的 192.168.1.10 ping 到以下地址:

  • 192.168.111.100:工作正常。
  • 192.168.222.100:工作正常。
  • 192.168.111.200:工作正常。
  • 192.168.222.200:没有答案!!

“B”vlan 主要用于备份和其他“后台”流量,以避免 vlan “A”中的饱和问题。

我知道有两个网络路径来访问同一台机器不是通常的设置,我必须说,现在只能连接来自其他网络的其中一个不是一个大问题。但困扰我的是为什么 我可以访问 Debian 机器而不是 Ubuntu 机器?

甚至,另一方面,如果它在两个平台上都运行良好,我们可以考虑从 NIC "A" 关闭一些服务(例如 ssh 和后端接口)以提高安全性(我们的防火墙只允许访问 vlan "B"来自我们的 IT 人员 vlan)。

当然,正如前面的接口片段中所注释的那样,网关 行在 Ubuntu 机器中被注释掉,但那是因为否则该机器中的网络初始化会失败。实际上,这就是我们要解决的问题。

但是两台机器的路由表几乎是一样的。我能看到的唯一区别是Ubuntu 机器中的onlink标志:

myUser@debianMachine:~$ sudo ip route
default via 192.168.111.254 dev eth0
192.168.111.0/24 dev eth0  proto kernel  scope link  src 192.168.111.100
192.168.222.0/24 dev eth1  proto kernel  scope link  src 192.168.222.100


myUser@ubuntuMachine:~$ sudo ip route
default via 192.168.111.254 dev eth0 onlink
192.168.111.0/24 dev eth0  proto kernel  scope link  src 192.168.111.200
192.168.222.0/24 dev eth1  proto kernel  scope link  src 192.168.222.200

...但我可以通过以下命令将其删除:

myUser@ubuntuMachine:~$ sudo ip route replace default via 192.168.111.254 dev eth0
myUser@ubuntuMachine:~$ sudo ip route
default via 192.168.111.254 dev eth0
192.168.111.0/24 dev eth0  proto kernel  scope link  src 192.168.111.200
192.168.222.0/24 dev eth1  proto kernel  scope link  src 192.168.222.200

它并没有解决问题。

之后,我还尝试取消注释“VLAN B”的网关行,正如我所说,它在/etc/network/interfaces文件中被注释掉并尝试重新启动网络,但这就是发生的事情:

myUser@ubuntuMachine:~$ sudo /etc/init.d/networking restart
[....] Restarting networking (via systemctl): networking.serviceJob for networking.service failed because the control process exited with error code. See "systemctl status networking.service" and "journalctl -xe" for details.
failed!

...并且onlink标志又回来了。

作为注释,再次注释掉该行并发出新 /etc/init.d/networking restart命令,输出是相同的,直到机器重新启动,(即使网络,尽管 VLAN B 默认gateyay 问题,继续照常工作)。

以下是建议命令的输出:

myUser@ubuntuMachine:~$ sudo systemctl status networking.service
● networking.service - Raise network interfaces
   Loaded: loaded (/lib/systemd/system/networking.service; enabled; vendor preset: enabled)
  Drop-In: /run/systemd/generator/networking.service.d
           └─50-insserv.conf-$network.conf
   Active: failed (Result: exit-code) since jue 2017-12-21 14:55:29 CET; 42s ago
     Docs: man:interfaces(5)
  Process: 8552 ExecStop=/sbin/ifdown -a --read-environment --exclude=lo (code=exited, status=0/SUCCESS)
  Process: 8940 ExecStart=/sbin/ifup -a --read-environment (code=exited, status=1/FAILURE)
  Process: 8934 ExecStartPre=/bin/sh -c [ "$CONFIGURE_INTERFACES" != "no" ] && [ -n "$(ifquery --read-envi
 Main PID: 8940 (code=exited, status=1/FAILURE)

dic 21 14:55:29 ubuntuMachine systemd[1]: Stopped Raise network interfaces.
dic 21 14:55:29 ubuntuMachine systemd[1]: Starting Raise network interfaces...
dic 21 14:55:29 ubuntuMachine ifup[8940]: RTNETLINK answers: File exists
dic 21 14:55:29 ubuntuMachine ifup[8940]: Failed to bring up eth1.
dic 21 14:55:29 ubuntuMachine systemd[1]: networking.service: Main process exited, code=exited, status=1/FAILUR
dic 21 14:55:29 ubuntuMachine systemd[1]: Failed to start Raise network interfaces.
dic 21 14:55:29 ubuntuMachine systemd[1]: networking.service: Unit entered failed state.
dic 21 14:55:29 ubuntuMachine systemd[1]: networking.service: Failed with result 'exit-code'.

...和有意义的部分sudo journalctl -xe

dic 21 14:55:29 ubuntuMachine sudo[8922]:   myUser : TTY=pts/0 ; PWD=/home/myUser ; USER=root ; COMMAND=/etc/init.d/networking restart
dic 21 14:55:29 ubuntuMachine sudo[8922]: pam_unix(sudo:session): session opened for user root by myUser(uid=0)
dic 21 14:55:29 ubuntuMachine systemd[1]: Stopped Raise network interfaces.
-- Subject: Unit networking.service has finished shutting down
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit networking.service has finished shutting down.
dic 21 14:55:29 ubuntuMachine systemd[1]: Starting Raise network interfaces...
-- Subject: Unit networking.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit networking.service has begun starting up.
dic 21 14:55:29 ubuntuMachine ifup[8940]: RTNETLINK answers: File exists
dic 21 14:55:29 ubuntuMachine ifup[8940]: Failed to bring up eth1.
dic 21 14:55:29 ubuntuMachine systemd[1]: networking.service: Main process exited, code=exited, status=1/FAILURE
dic 21 14:55:29 ubuntuMachine systemd[1]: Failed to start Raise network interfaces.
-- Subject: Unit networking.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit networking.service has failed.
--
-- The result is failed.
dic 21 14:55:29 ubuntuMachine systemd[1]: networking.service: Unit entered failed state.
dic 21 14:55:29 ubuntuMachine systemd[1]: networking.service: Failed with result 'exit-code'.
dic 21 14:55:29 ubuntuMachine sudo[8922]: pam_unix(sudo:session): session closed for user root

我搜索了很多关于能够找到一些相关信息但没有完全回答我的问题:

  • 在我看来,对“onlink”标志的解释指出了“onlink”标志可能导致“错误的反向路由”,意思是«告诉内核它不必检查是否当前机器可以直接访问网关»所以(我想通了)内核可能认为它可以(或应该)将来自 VLAN C 的传入连接的答案路由到默认网关,而不是认为从连接开始的同一个 NIC .

    • 但是,正如我所说,删除“onlink”标志似乎并没有改变任何东西。
  • 这个unix StackExchange 答案似乎通过使用多个路由表和规则(告诉内核使用哪个表)来解决问题(我还没有测试过)。但这并不能解释为什么 Debian 机器运行良好(我检查了两台机器的/etc/iproute2/rt_tables文件,它们也相同

myUser@bothMachines:~$ sudo cat /etc/iproute2/rt_tables
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep

所以我的最后一个假设是,它可能只是内核版本之间的实现差异,并且拥有那个 ubuntu 版本更新得多,这可能是正确的行为,所以在现代内核中,我需要使用两个不同的路由表(但我'不确定也不知道为什么......)。

myUser@debianMachine:~$ sudo uname -a
Linux debianMachine 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64 GNU/Linux

myUser@ubuntuMachine:~$ sudo uname -a
Linux ubuntuMachine 4.4.0-87-generic #110-Ubuntu SMP Tue Jul 18 12:55:35 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

因此,问题是:

我们在 Ubuntu 机器上做错了什么(或者其中有一些错误)吗?或者,相反,这是正确的行为,我们被迫设置更复杂的路由模式(通过每个 vlan 路由或通过使用两个路由表使两个默认网关再次工作)?

编辑:

现在我尝试添加静态路由来解决问题:

myUser@ubuntuMachine:~$ sudo ip route add 192.168.1.0/24 via 192.168.222.254 dev eth1

...但这冻结了我的 ssh 连接(认为 NIC A),即使我可以连接认为 NIC B(在 192.168.111.200)

两条规则同时似乎是不可能的:

myUser@ubuntuMachine:~$ sudo ip route add 192.168.1/24 via 102.168.111.254 dev eth0
myUser@ubuntuMachine:~$ sudo ip route add 192.168.1/24 via 192.168.222.254 dev eth1
RTNETLINK answers: File exists

编辑2:

我终于找到了Linux Advanced Routing & Traffic Control HOWTO,它似乎比我找到的所有其他文档更准确,特别是在它的第 4 章。规则 - 路由策略数据库我看到以下文本:

如果您想使用此功能,请确保您的内核编译时带有“IP:高级路由器”和“IP:策略路由”功能

...所以我的一切都表明,我之前关于内核实现差异的假设是正确的,具体而言,差异在于编译了这两个特性。

4

1 回答 1

1

不是权威答案,而是我的第一次工作尝试(应用我设法理解的内容):

sudo ip route add 192.168.1.0/24 via 192.168.222.254 from 192.168.222.200 dev eth1 table 253 
sudo ip rule add from 192.168.222.200 table 253

更新: from命令中的dev参数ip route不是必需的(没有它们它可以很好地工作)。

...发出第一个命令后我还无法连接,但在发出第二个命令后是的。

其背后的逻辑来自我在本文档中找到的文本:

Linux-2.x 可以将路由打包到多个路由表中,这些路由表由 1 到 255 范围内的数字或文件 /etc/iproute2/rt_tables 中的名称标识 默认情况下,所有正常路由都插入主表(ID 254)并且内核在计算路由时只使用这个表。

实际上,始终存在另一张表,它是看不见的,但更重要的是。它是本地表 (ID 255)。此表由本地和广播地址的路由组成。内核自动维护这个表,管理员通常不需要修改它,甚至不需要查看它。

事实上,我最终使用了另一个路由表,由它的 id (253) 标识,而不是我现在理解的它只是一个别名(在/etc/iproute2/rt_tables文件中定义)。

...并再次检查该文件,我现在看到已经为该路由表定义了一个别名(“默认”)(在“主”旁边,正如我之前粘贴的文本片段所说的那样,它确实是 254。

我还不知道这是这个命名背后的逻辑(我的意思是 253 路由表的“默认”),如果出于任何原因,最好使用较低的路由表(1、2、3... )就像这个解决方案(问题中已经提到)一样。

但是,为了简单起见,如果我们不打算构建复杂的路由策略并且只想解决这个连接问题,我想使用类似(尚未测试)的东西可能是一个很好的解决方案:

gateway 192.168.222.254 table 253
post-up ip rule add from 192.168.222.200 table 253

我仍然需要测试并检查是否需要via 192.168.222.254网关行中添加额外的内容,或者它是否根本不起作用并且需要使用另一个post-up命令来添加它。

我会用结果更新这个答案。

编辑 1:默认路由相同:

sudo ip route add default from 192.168.222.200 via 192.168.222.254 table 253
sudo ip rule add from 192.168.222.200 table 253

编辑 2:第一个(现在完全¹)工作方法

用测试机玩了一段时间后,我认为最好的解决方案是在/etc/network/interfaces文件的第二个网卡配置中添加以下行:

gateway 192.168.222.254 table 1
post-up ip rule add from 192.169.222.200 table 1
pre-down ip rule del from 192.168.222.200 table 1
post-up ip route add 192.188.222.0/24 dev eth1 src 192.168.222.200 table 1

注释:

  • 添加table 1gateway关键字效果很好,因此不需要额外的(不太可读的)后期命令来添加默认路由。

    • ...事实上,对第一个 NIC 使用特定表(除了main)以及与我们用于第二个 NIC 的规则类似的规则将是一个坏主意,因为该规则仅适用于 192.168.111.200将用作源地址,因此不会有任何“默认默认网关”。将第一个 NIC 配置保留在路由表中,将使所有(“本地生成”)到远程 LAN 的传出连接默认通过我们的第一个默认网关
  • 第一个post-up命令添加了一条规则,即具有该 NIC 源地址的数据包应使用表 1 进行路由(否则将不会使用我们的新默认网关)。

  • pre-down命令删除该规则。这不是强制性的,但如果没有它,多次网络服务重新启动将每次都重复此规则。

  • 我也尝试使用dev eth1代替from 192.169.222.200(以避免重复网络地址),但它没有用。我猜想哪个 NIC 用于“响应”数据包“尚未决定”。

  • 我用于table 1eth1 我们的第二个 NIC),我可以table 2用于最终的第三个,依此类推。不需要为第一个 NIC 指定任何表/规则,因为它涉及到表(不是“默认”:见下文注释)。

  • 最后(¹)第二个post-up命令使一切正常,因为(正如我现在意识到的那样)仅(第一次匹配)一个路由表被使用,因此默认网络路由(在接口启动时自动创建)不适用,因为它是在表main中创建。

    • 我仍然不知道是否有办法强制将其直接放入表 1中。

注意:通过命令sudo ip rule list我们可以看到当前的路由规则如下:

0:      from all lookup local 
32765:  from 192.168.222.200 lookup 1 
32766:  from all lookup main 
32767:  from all lookup default

据我所知,它们从 32767 逐渐减少到 0,并不断尝试直到匹配。默认情况下已经定义了最后两个和“0”。前者是因为我之前从本文档中引用的逻辑,但该文档说规则从“1”开始,所以我猜“0”也应该是一些预定义的“默认起点”。

编辑3:

正如我在Edit 2 (of the question) 中所说的,我发现这个Linux Advanced Routing & Traffic Control HOWTO对我澄清事情有很大帮助。

具体来说,多上行链路/提供商的路由章节对我理解具有“网络环路”的设置非常有用(即使在我们的例子中,我们也不是充当 Internet 的路由器)。

于 2017-12-22T13:17:27.857 回答