我有一台运行 Ubuntu 20.04 LTS 的服务器,通过一个物理以太网接口连接到互联网。我的提供商为我分配了一个静态主 IP4(我将在此使用 AAAA 作为此 IP),因此我的 systemd-networkd 配置文件之前看起来像这样(禁用 netplan 以直接与 systemd-networkd 配合使用):
# /etc/systemd/network/20-enp7s0.network
[Match]
Name=enp7s0
[Network]
LinkLocalAddressing=ipv6
Address=A.A.A.A/32
Gateway=fe80::1
DNS=X.X.X.1
DNS=X.X.X.2
[Route]
Destination=0.0.0.0/0
Gateway=Y.Y.Y.Y
GatewayOnlink=true
我的提供商建议为我的服务器添加一个额外的 IP 地址,该地址与主 IP 路由到相同的接口。将第二个 IP 添加到我的接口时,我可以 ping 它。由于我使用的是 systemd-nspawn 容器,所以我考虑使用这个额外的 IP 为我的一个容器提供一个独占的静态 IP4(这里将使用 BBBB)。这将非常适合将 DNS 条目直接映射到我服务器上的容器,而服务器上的所有其他应用程序仍使用主 IP 地址。
因此我开始遵循 Arch wiki 上的说明systemd-nspawn和systemd-networkd。我配置了一个桥并将所有寻址从物理接口移到它:
/etc/systemd/network/br0.netdev
[NetDev]
Name=br0
Kind=bridge
MACAddress=xx:xx:xx:xx:xx:xx # same as my phys. interface
/etc/systemd/network/20-br0.network
[Match]
Name=br0
[Network]
LinkLocalAddressing=ipv6
Address=A.A.A.A/32
Gateway=fe80::1
DNS=X.X.X.1
DNS=X.X.X.2
[Route]
Destination=0.0.0.0/0
Gateway=Y.Y.Y.Y
GatewayOnlink=true
/etc/systemd/network/20-enp7s0.network
[Match]
Name=enp7s0
[Network]
Bridge=br0
IP4-Forwarding 已启用:
$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
我使用以下配置启动我的 nspawn 容器:
/etc/systemd/nspawn/mycontainer.nspawn
[Network]
VirtualEthernet=yes
Bridge=br0
在容器(Debian 11 Bullseye)内,我启用了 systemd-networkd 并使用以下配置进行网络连接:
# /etc/systemd/network/80-container-host0.network
[Match]
Name=host0
[Network]
Address=B.B.B.B/32
DNS=X.X.X.1
DNS=X.X.X.2
[Route]
Destination=0.0.0.0/0
Gateway=Y.Y.Y.Y
GatewayOnlink=true
这是此配置的结果。在主机上:
$ ip a
2: enp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet A.A.A.A/32 scope global br0
valid_lft forever preferred_lft forever
6: vb-mycontainer@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP group default qlen 1000
link/ether yy:yy:yy:yy:yy:yy brd ff:ff:ff:ff:ff:ff link-netnsid 0
$ networkctl status -a
● 1: lo [...]
● 2: enp7s0
Link File: /usr/lib/systemd/network/99-default.link
Network File: /etc/systemd/network/20-enp7s0.network
Type: ether
State: enslaved (configured)
Path: pci-0000:07:00.0
Driver: igb
Vendor: Intel Corporation
Model: I210 Gigabit Network Connection
HW Address: xx:xx:xx:xx:xx:xx
MTU: 1500 (min: 68, max: 9216)
Queue Length (Tx/Rx): 8/8
Auto negotiation: yes
Speed: 1Gbps
Duplex: full
Port: tp
Activation Policy: up
Required For Online: yes
● 3: br0
Link File: /usr/lib/systemd/network/99-default.link
Network File: /etc/systemd/network/20-br0.network
Type: bridge
State: routable (configured)
Driver: bridge
HW Address: xx:xx:xx:xx:xx:xx
MTU: 1500 (min: 68, max: 65535)
Forward Delay: 15s
Hello Time: 2s
Max Age: 20s
Ageing Time: 5min
Priority: 32768
STP: no
Multicast IGMP Version: 2
Queue Length (Tx/Rx): 1/1
Address: A.A.A.A
Gateway: Y.Y.Y.Y (Juniper Networks)
fe80::1 (Juniper Networks)
DNS: X.X.X.1
X.X.X.2
Activation Policy: up
Required For Online: yes
● 6: vb-mycontainer
Link File: /usr/lib/systemd/network/99-default.link
Network File: n/a
Type: ether
State: degraded (unmanaged)
Driver: veth
HW Address: yy:yy:yy:yy:yy:yy
MTU: 1500 (min: 68, max: 65535)
Queue Length (Tx/Rx): 1/1
Auto negotiation: no
Speed: 10Gbps
Duplex: full
Port: tp
Address: fe80::xxxx:xxxx:xxxx:xxxx
Activation Policy: up
Required For Online: yes
$ ip route
default via Y.Y.Y.Y dev br0 proto static onlink
在我的容器里:
# ip a
1: lo: [...]
2: host0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether yy:yy:yy:yy:yy:yy brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet B.B.B.B/32 scope global host0
valid_lft forever preferred_lft forever
inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link
valid_lft forever preferred_lft forever
# networkctl status -a
● 1: lo [...]
● 2: host0
Link File: n/a
Network File: /etc/systemd/network/80-container-host0.network
Type: ether
State: routable (configured)
HW Address: zz:zz:zz:zz:zz:zz
MTU: 1500 (min: 68, max: 65535)
QDisc: noqueue
IPv6 Address Generation Mode: eui64
Queue Length (Tx/Rx): 1/1
Auto negotiation: no
Speed: 10Gbps
Duplex: full
Port: tp
Address: B.B.B.B
fe80::xxxx:xxxx:xxxx:xxxx
Gateway: Y.Y.Y.Y
DNS: X.X.X.1
X.X.X.2
DHCP6 Client DUID: DUID-EN/Vendor:0000ab117511f183668420370000
Feb 17 19:45:26 mycontainer systemd-networkd[25]: host0: Link UP
Feb 17 19:45:26 mycontainer systemd-networkd[25]: host0: Gained carrier
Feb 17 19:45:27 mycontainer systemd-networkd[25]: host0: Gained IPv6LL
# ip route
default via Y.Y.Y.Y dev host0 proto static onlink
至于其他设置,我坚持使用系统默认设置。但它不起作用,我无法从主机 ping 通客户机,也无法从客户机 ping 通主机、互联网或网关,只是目标主机不可达。所以我是不是错过了什么?我对网络不是很了解,而且已经花了很多时间在这上面,但我为可能犯的一些愚蠢的错误道歉。欢迎提供任何线索。谢谢!
编辑:
我查看了邻居表:
Host:
$ ip neighbor
Y.Y.Y.Y dev br0 lladdr 84:c1:c1:76:ae:9b REACHABLE <- gateway
fe80::f80b:aff:fe80:d92 dev vb-mycontainer FAILED
fe80::6c91:a7ff:fe1f:19a2 dev br0 FAILED
fe80::1 dev br0 lladdr 84:c1:c1:76:ae:9b router STALE
fe80::f80b:aff:fe80:d92 dev br0 lladdr fa:0b:0a:80:0d:92 STALE
Guest:
$ ip neighbor
fe80::7e10:c9ff:fe21:ed87 dev host0 lladdr 7c:10:c9:21:ed:87 router STALE
fe80::6c91:a7ff:fe1f:19a2 dev host0 FAILED
fe80::1 dev host0 lladdr 84:c1:c1:76:ae:9b router STALE
fe80::6c91:a7ff:fe1f:19a2 是主机上的虚拟接口 vb-mycontainer 的链接区域设置地址。因此,我猜想客户机和主机之间似乎存在连接问题?
答案1
好的,我自己解决了这个问题。我忘记在主机的桥接配置中添加 IP 路由到我的容器:
# /etc/systemd/network/20-br0.network
[Match]
Name=br0
[Network]
LinkLocalAddressing=ipv6
Address=A.A.A.A/32
Gateway=fe80::1
DNS=X.X.X.1
DNS=X.X.X.2
[Route]
Destination=0.0.0.0/0
Gateway=Y.Y.Y.Y
GatewayOnlink=true
[Route]
Destination=B.B.B.B/32
在客户机中,网关是主机的主 IPv4 地址 (AAAA/32):
# /etc/systemd/network/80-container-host0.network
[Match]
Name=host0
[Network]
Address=B.B.B.B/32
DNS=X.X.X.1
DNS=X.X.X.2
[Route]
Destination=0.0.0.0/0
Gateway=A.A.A.A
GatewayOnlink=true
此外,还需要启用 systemd-resolved 才能获得 DNS 解析。