Wireguard 作为虚拟机桥,无需在 VPN 上显示虚拟机管理程序

Wireguard 作为虚拟机桥,无需在 VPN 上显示虚拟机管理程序

我正在尝试通过互联网将两个虚拟机管理程序连接在一起。两个虚拟机管理程序都运行 KVM 进行虚拟化,我手动创建了虚拟机网络桥接,目前可以正常工作。

我想使用 Wireguard 连接这两个虚拟机管理程序上的 VM 桥,以便 VM 可以从一个虚拟机管理程序迁移到另一个虚拟机管理程序,而无需对 VM 本身进行任何路由/网络更改。

不过,在开始之前,我意识到我不知道如何设置 Wireguard,以便两个虚拟机管理程序上的桥接器对其他虚拟机管理程序可见,但虚拟机管理程序本身却不是出现在 VPN 上,以便虚拟机无法直接连接/攻击虚拟机管理程序。

Wireguard 能做到这一点吗?还是说由于 Wireguard 在 OSI 堆栈上而不是以太网帧级别上工作的方式,这是不可能的?

有人能说说 Wireguard 是否可以用来“盲目”地桥接两个网络吗?或者主机也会始终出现在网络上吗?其他 VPN 解决方案是否允许这样做?或者我最好使用防火墙来锁定我不想访问的主机?

提前致谢!

答案1

Wireguard 在第 3 层(路由 IP 数据包)工作,而网桥在第 2 层(交换以太网帧)工作。因此 wireguard 无法做到这一点。这个问题已经在 wireguard 的邮件列表中被提出,并且 wireguard 的作者也给出了答案:桥接 wg 和正常接口?

因此,在经过 wireguard 之前,需要额外的封装层。我相信有几种选择(其中包括VXLAN也可Linux)。

我做了一个例子格瑞塔普和命名空间(而不是实际的虚拟机管理程序和虚拟机)。我发现,为了避免强制本地虚拟机流量具有比可能更有限的数据包大小,需要进行碎片处理,但GRETAP它有一些限制,如下所述:GRE 桥接、IPsec 和 NFQUEUE。我选择使用nftables 的有效载荷处理而不是 NFQUEUE 和用户空间。

另请注意RFC 6864解释说,由于 IP ID 字段的限制,碎片数据包在大多数情况下应限制在 6.4Mbp/s,这在当今很慢,但经过具有强完整性检查的隧道,放松它。

在这里,(假)虚拟机通过网桥连接,没有其他连接。它们看不到自己以外的任何东西:它们看不到使用 gretap+wireguard 连接两个网桥的(假)虚拟机管理程序。只需运行此 bash 脚本即可创建和配置多个命名空间。使用 nftables 0.9.2 和内核 5.2.x 进行测试。

#!/bin/bash

if ip netns id | grep -qv '^ *$' ; then
    printf 'ERROR: leave netns "%s" first\n' $(ip netns id) >&2
    exit 1
fi

hosts='vm11 vm12 hyp1 router hyp2 vm21 vm22'

for ns in $hosts; do
    ip netns del $ns 2>/dev/null || :
    ip netns add $ns
    ip netns exec $ns sysctl -q -w net.ipv6.conf.default.disable_ipv6=1
    ip netns exec $ns sysctl -q -w net.ipv4.icmp_echo_ignore_broadcasts=0
done

for ns in $hosts; do
    ip -n $ns link set lo up
done

link_ns () {
    ip -n $1 link add name "$3" type veth peer netns $2 name "$4"
    ip -n $1 link set dev "$3" up
    ip -n $2 link set dev "$4" up
}

for h in 1 2; do
    ip -n hyp$h link add bridge0 address 02:00:00:00:00:0$h type bridge
    ip -n hyp$h link set bridge0 up
    for n in 1 2; do
        link_ns vm$h$n hyp$h eth0 port$n
        ip -n hyp$h link set dev port$n master bridge0
        ip -n vm$h$n address add 10.0.$h.$n/16 dev eth0
    done
    link_ns hyp$h router eth0 site$h
done

ip -n router address add 192.0.2.1/24 dev site1
ip -n router address add 198.51.100.1/24 dev site2

ip -n hyp1 address add 192.0.2.100/24 dev eth0
ip -n hyp1 route add default via 192.0.2.1

ip -n hyp2 address add 198.51.100.200/24 dev eth0
ip -n hyp2 route add default via 198.51.100.1

privkey1=$(wg genkey)
privkey2=$(wg genkey)

pubkey1=$(printf '%s' "$privkey1" | wg pubkey)
pubkey2=$(printf '%s' "$privkey2" | wg pubkey)

for h in 1 2; do
    ip -n hyp$h link add name wg0 type wireguard
    ip -n hyp$h address add 10.100.0.$h/24 dev wg0
    ip -n hyp$h link set dev wg0 up
done

ip netns exec hyp1 wg set wg0 private-key <(printf '%s' "$privkey1") listen-port 11111 peer "$pubkey2" endpoint 198.51.100.200:22222 allowed-ips 10.100.0.2
ip netns exec hyp2 wg set wg0 private-key <(printf '%s' "$privkey2") listen-port 22222 peer "$pubkey1" endpoint 192.0.2.100:11111 allowed-ips 10.100.0.1

for h in 1 2; do
    ip -n hyp$h link add name gt0 mtu 1500 type gretap remote 10.100.0.$((3-$h)) local 10.100.0.$h nopmtud
    ip -n hyp$h link set gt0 master bridge0
    ip -n hyp$h link set gt0 up
    ip netns exec hyp$h nft -f /dev/stdin << EOF
table ip filter {
    chain output {
        type filter hook output priority 0; policy accept;
        ip protocol gre ip saddr 10.100.0.$h ip daddr 10.100.0.$((3-$h)) ip frag-off set ip frag-off & 0xbfff counter
    }
}
EOF
done

示例(远程端的延迟更大):

# ip netns exec vm11 ping -b 10.0.255.255
WARNING: pinging broadcast address
PING 10.0.255.255 (10.0.255.255) 56(84) bytes of data.
64 bytes from 10.0.1.1: icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=0.194 ms (DUP!)
64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.646 ms (DUP!)
64 bytes from 10.0.2.1: icmp_seq=1 ttl=64 time=0.685 ms (DUP!)
64 bytes from 10.0.1.1: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.154 ms (DUP!)
64 bytes from 10.0.2.2: icmp_seq=2 ttl=64 time=0.476 ms (DUP!)
64 bytes from 10.0.2.1: icmp_seq=2 ttl=64 time=0.490 ms (DUP!)
^C
--- 10.0.255.255 ping statistics ---
2 packets transmitted, 2 received, +6 duplicates, 0% packet loss, time 1050ms
rtt min/avg/max/mdev = 0.048/0.344/0.685/0.243 ms

相关内容