我最近将 Proxmox 设置为虚拟化主机。它只是一个不错的 Linux 发行版中的 KVM + Debian。我的家庭网络是 192.168.12.0/24。我想使用 192.168.14.0/24 作为 proxmox 机器上所有虚拟机的子网。我使用 DHCP 来配置几乎所有的主机。如果我想要一个“静态 IP”,我通常只需手动为设备配置一个 DHCP 保留。所以,我希望我的虚拟机在 192.168.14.0/24 子网中获取 DHCP 地址。
当我安装 Proxmox 时,它创建了一个名为 的桥接器vmbr0
,该桥接器与 桥接eth0
。该桥接器的 IP 地址是192.168.12.12
。
/etc/network/interfaces
我在 中添加了一个名为vmbr14
bridged with 的桥接器eth0.14
。我给它分配了一个 IP 地址192.168.14.12
。我还在模块中对它进行了 modprobe8021q
并将其添加到/etc/modules
。
我的 DHCP 服务器位于另一台机器上,该机器上192.168.12.95
有一个接口eth0
。我添加了另一个名为 的接口eth0.14
,并为其指定了 IP 192.168.14.95
。我/etc/dhcp/dhcpd.conf
使用另一个池更新了子网192.168.14.0
。指定的默认路由是192.168.14.12
Proxmox 机器。DHCP 立即运行,没有任何问题。
为了让192.168.12.0/24
网络上的主机知道如何路由,192.168.14.0/24
我进入了我的互联网网关(192.168.12.2
)并添加了一条路由,如下所示
192.168.14.0 192.168.12.12 255.255.255.0 UG 1 0 0 eth2
proxmox 盒已启用 IPv4 转发
ericu@basov:~$ cat /proc/sys/net/ipv4/ip_forward
1
之后,一切就都正常了。我可以从我的桌面通过 SSH 和 ping 虚拟机,没有任何问题。
但在虚拟机上,我只能访问192.168.12.95
。192.168.14.95
我对其中一台虚拟机进行了 ping 操作,192.168.12.95
并使用以下方法捕获了数据包:tcpdump
ericu@katz:~$ sudo tcpdump -n -i eth0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
18:50:16.007898 IP 192.168.14.130 > 192.168.12.95: ICMP echo request, id 11498, seq 18, length 64
18:50:17.010380 IP 192.168.14.130 > 192.168.12.95: ICMP echo request, id 11498, seq 19, length 64
18:50:18.012969 IP 192.168.14.130 > 192.168.12.95: ICMP echo request, id 11498, seq 20, length 64
18:50:19.015433 IP 192.168.14.130 > 192.168.12.95: ICMP echo request, id 11498, seq 21, length 64
18:50:20.018043 IP 192.168.14.130 > 192.168.12.95: ICMP echo request, id 11498, seq 22, length 64
数据包显然到达了机器,但我不知道之后会发生什么。机器就是不回复。TCP 也不起作用。
ericu@katz:~$ sudo tcpdump -n tcp port 3000
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
18:53:21.048128 IP 192.168.14.130.58499 > 192.168.12.95.3000: Flags [S], seq 2306774687, win 14600, options [mss 1460,sackOK,TS val 665263 ecr 0,nop,wscale 7], length 0
18:53:22.051442 IP 192.168.14.130.58499 > 192.168.12.95.3000: Flags [S], seq 2306774687, win 14600, options [mss 1460,sackOK,TS val 666264 ecr 0,nop,wscale 7], length 0
18:53:24.060540 IP 192.168.14.130.58499 > 192.168.12.95.3000: Flags [S], seq 2306774687, win 14600, options [mss 1460,sackOK,TS val 668268 ecr 0,nop,wscale 7], length 0
如果我尝试从虚拟机访问 IP,192.168.14.95
一切都正常。
如果我这样做,那么就可以从虚拟机访问ifdown eth0.14
该机器192.168.12.95
。显然,这并不实用,因为 DHCP 服务器需要可访问。
为什么子网上的机器只能访问使用该地址的192.168.14.0/24
机器,而不能访问该地址?192.168.14.95
192.168.12.95
路由表位于192.168.12.95
ericu@katz:~$ ip route show
default via 192.168.12.2 dev eth0 metric 100
192.168.12.0/24 dev eth0 proto kernel scope link src 192.168.12.95
192.168.14.0/24 dev eth0.14 proto kernel scope link src 192.168.14.95
ericu@katz:~$
这是192.168.14.130
[ericu@squid3 ~]$ ip route show
default via 192.168.14.12 dev ens18 proto static metric 1024
192.168.14.0/24 dev ens18 proto kernel scope link src 192.168.14.130
[ericu@squid3 ~]$
为了进一步解决此问题,我在桌面上创建了一个虚拟机。我进行/etc/network/interfaces
了如下编辑
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet dhcp
auto eth0.14
iface eth0.14 inet static
address 192.168.14.14
netmask 255.255.255.0
该机器在 的 eth0 上获得了 DHCP 地址192.168.12.172
。从192.168.12.130
我仍然无法使用 访问它192.168.12.172
。在测试虚拟机上,我将其更改/etc/iproute2/rt_tables
为如下所示
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
14 vlan14
然后我运行了以下命令
root@ubuntuvmdesktop:/home/ericu# ip route show
default via 192.168.12.2 dev eth0
192.168.12.0/24 dev eth0 proto kernel scope link src 192.168.12.172
192.168.14.0/24 dev eth0.14 proto kernel scope link src 192.168.14.14
root@ubuntuvmdesktop:/home/ericu# ip route del 192.168.14.0/24 dev eth0.14 src 192.168.14.14
root@ubuntuvmdesktop:/home/ericu# ip route show
default via 192.168.12.2 dev eth0
192.168.12.0/24 dev eth0 proto kernel scope link src 192.168.12.172
root@ubuntuvmdesktop:/home/ericu# ip route add 192.168.14.0/24 dev eth0.14 src 192.168.14.14 table vlan14
root@ubuntuvmdesktop:/home/ericu# ip route add default via 192.168.14.12 dev eth0.14 src 192.168.14.14 table vlan14
RTNETLINK answers: Network is unreachable
root@ubuntuvmdesktop:/home/ericu# ip rule add from 192.168.14.14 table vlan14
root@ubuntuvmdesktop:/home/ericu# ip route show table vlan14
192.168.14.0/24 dev eth0.14 scope link src 192.168.14.14
完成此操作后,具有 IP 的虚拟机可以使用192.168.14.14
和192.168.12.172
[ericu@squid3 ~]$ nc -v 192.168.12.172 22
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connected to 192.168.12.172:22.
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2
^C
[ericu@squid3 ~]$ nc -v 192.168.14.14 22
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Connected to 192.168.14.14:22.
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2
^C
[ericu@squid3 ~]$
所以这至少是解决问题的一种方法。但是,我真的不明白它的作用。我知道我为机器添加了一个名为“vlan14”的单独路由表。我猜使用以ip rule add
某种方式将发往的流量定向192.168.14.14
到它自己的路由表中。这是否会将两个子网的路由隔离到它们自己的路由表中?但是,我使用的所有路由更改ip route
在重新启动后都不会保留。似乎我需要更新/etc/network/interfaces
以某种方式指示路由应该进入这个备用路由表。
有人能解释一下独立路由表是如何工作的吗?有人能解释一下如何更改我的配置,以便使用该ip
命令所做的更改在重启后仍然有效吗?
答案1
所有 Linux 路由都是通过路由表完成的。
默认安装不做任何修改,将有一个“主”表、一个“默认”表和一个“本地”表。如果您运行时ip route show
没有使用其他选项,则会显示“主”表;“本地”表用于环回地址(127.0.0.0/8
, ff00::/8
)。“默认”表是作为最后的手段使用的,通常为空。
您可以添加适用于ip rule
命令选择的目的地的特殊路由指令。您可以添加具有优先级的规则,最低数字将首先匹配。默认情况下,这些是默认规则:
$ ip rule show
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
规则的典型用途是当您拥有多宿主系统(即具有多个互联网连接的系统)时。在此设置中,您需要确保回复数据包通过与原始数据包进入的相同接口(即互联网连接)发送出去。通常,这意味着确保具有特定源地址的数据包从相应的接口发送出去:
# ip rule add from 1.2.3.4 pref 30000 lookup first
# ip rule add from 5.6.7.8 pref 30000 lookup second
# ip route add table first default via 1.2.3.254 dev if1 src 1.2.3.4
# ip route add table second default via 5.6.7.254 dev if2 src 5.6.7.8
现在添加一条通过首选连接(例如最快或最便宜的连接)的默认路由:
# ip route add table default via 5.6.7.254 dev if2 src 5.6.7.8
当首选接口发生故障时附加第二条默认路由:
# ip route add table default via 1.2.3.254 dev if1 src 1.2.3.4
您必须确保当首选接口恢复时,其默认路由再次位于表中的第一位。我通常通过添加该路由、删除另一条路由并再次添加它来实现这一点;可能还有其他更好的方法...
您可以在 中使用不同的选择器ip rule add
,例如,使其依赖于 已在数据包上设置的防火墙标记iptables
。使用ip rule add help
您可以放在那里的内容;这通常适用于所有ip
命令(例如ip help
,ip route help
)。
这Linux 高级路由指南描述关于这个主题的一切。
为了使您的手动路由配置在重新启动等之后应用,请将它们添加到前面添加的/etc/network/interfaces
接口定义中post-up
,这些配置将在接口启动后执行。man interfaces
描述了您可以放入文件中的所有可能的内容interfaces
。