Linux 中同一子网上的两个网络接口和两个 IP 地址

Sco*_*rth 22 linux routing

我最近遇到了一种情况,我需要将同一子网上的两个 IP 地址分配给一台 Linux 主机,以便我们可以运行两个 SSL/TLS 站点。我的第一种方法是使用 IP 别名,例如使用 eth0:0、eth0:1 等,但我们的网络管理员有一些相当严格的安全设置,从而粉碎了这个想法:

  1. 它们使用 DHCP 侦听,通常不允许使用静态 IP 地址。静态寻址是通过使用静态 DHCP 条目来完成的,因此相同的 MAC 地址总是获得相同的 IP 分配。如果您提出要求并且有理由禁用此功能,则可以为每个交换机端口禁用此功能(谢天谢地,我与网络人员的关系很好,这并不难)。
  2. 由于在交换机端口上禁用了 DHCP 侦听,他们必须在交换机上设置一条规则,允许 MAC 地址 X 具有 IP 地址 Y。不幸的是,这也有副作用,即 MAC 地址 X 仅允许具有IP 地址 Y。IP 别名要求为 MAC 地址 X 分配两个 IP 地址,因此这不起作用。

在交换机配置上可能有解决这些问题的方法,但为了与网络管理员保持良好的关系,我试图找到另一种方法。拥有两个网络接口似乎是下一个合乎逻辑的步骤。幸运的是,这个 Linux 系统是一个虚拟机,所以我能够轻松添加第二个网络接口(无需重新启动,我可能会添加 - 非常酷)。几次击键后,我启动并运行了两个网络接口,并且都从 DHCP 中提取了 IP 地址。

但问题来了:网络管理员可以(在交换机上)看到两个接口的 ARP 条目,但只有我提出的第一个网络接口会响应 ping 或任何类型的 TCP 或 UDP 流量。

经过大量的挖掘和戳,这就是我想出的。它似乎有效,但对于看起来应该很简单的事情来说,它似乎也需要做很多工作。有什么替代想法吗?


步骤 1:在所有接口上启用 ARP 过滤:

# sysctl -w net.ipv4.conf.all.arp_filter=1
# echo "net.ipv4.conf.all.arp_filter = 1" >> /etc/sysctl.conf
Run Code Online (Sandbox Code Playgroud)

来自 Linux 内核文档中的文件 network/ip-sysctl.txt:

arp_filter - BOOLEAN
    1 - Allows you to have multiple network interfaces on the same
    subnet, and have the ARPs for each interface be answered
    based on whether or not the kernel would route a packet from
    the ARP'd IP out that interface (therefore you must use source
    based routing for this to work). In other words it allows control
    of which cards (usually 1) will respond to an arp request.

    0 - (default) The kernel can respond to arp requests with addresses
    from other interfaces. This may seem wrong but it usually makes
    sense, because it increases the chance of successful communication.
    IP addresses are owned by the complete host on Linux, not by
    particular interfaces. Only for more complex setups like load-
    balancing, does this behaviour cause problems.

    arp_filter for the interface will be enabled if at least one of
    conf/{all,interface}/arp_filter is set to TRUE,
    it will be disabled otherwise
Run Code Online (Sandbox Code Playgroud)

第二步:实现基于源的路由

我基本上只是遵循http://lartc.org/howto/lartc.rpdb.multiple-links.html 的指示,尽管该页面的编写考虑了不同的目标(处理两个 ISP)。

假设子网为10.0.0.0/24,网关为10.0.0.1,eth0的IP地址为10.0.0.100,eth1的IP地址为10.0.0.101。

在 /etc/iproute2/rt_tables 中定义两个名为 eth0 和 eth1 的新路由表:

... top of file omitted ...
1    eth0
2    eth1
Run Code Online (Sandbox Code Playgroud)

定义这两个表的路由:

# ip route add default via 10.0.0.1 table eth0
# ip route add default via 10.0.0.1 table eth1
# ip route add 10.0.0.0/24 dev eth0 src 10.0.0.100 table eth0
# ip route add 10.0.0.0/24 dev eth1 src 10.0.0.101 table eth1
Run Code Online (Sandbox Code Playgroud)

定义何时使用新路由表的规则:

# ip rule add from 10.0.0.100 table eth0
# ip rule add from 10.0.0.101 table eth1
Run Code Online (Sandbox Code Playgroud)

主路由表已经由 DHCP 处理(在这种情况下甚至不清楚它是绝对必要的),但它基本上等同于:

# ip route add default via 10.0.0.1 dev eth0
# ip route add 130.127.48.0/23 dev eth0 src 10.0.0.100
# ip route add 130.127.48.0/23 dev eth1 src 10.0.0.101
Run Code Online (Sandbox Code Playgroud)

瞧!一切似乎都很好。向两个 IP 地址发送 ping 工作正常。从此系统向其他系统发送 ping 并强制 ping 使用特定接口工作正常 ( ping -I eth0 10.0.0.1, ping -I eth1 10.0.0.1)。最重要的是,进出任一 IP 地址的所有 TCP 和 UDP 流量都按预期工作。


所以,我的问题是:有没有更好的方法来做到这一点?对于一个看似简单的问题,这似乎是很多工作。


更新: 上述解决方案最终不完整。如果流量保持在同一子网中,则一切正常,但使用第二个接口与其他子网的通信将无法正常工作。我没有挖更大的坑,而是与网络管理员交谈,让他们允许一个接口使用多个 IP 地址并使用 IP 别名(例如 eth0 和 eth0:0)。

Zyp*_*her 8

是的,更好的方法是建立一个适当的商业案例,让他们放宽交换机上的规则,这样你就可以在一个 NIC 上拥有多个 IP。