web-dev-qa-db-ja.com

Wireguard as VM VPN上にハイパーバイザーが表示されていないブリッジ

インターネットを介して2つのハイパーバイザーを接続しようとしています。両方のハイパーバイザーが仮想化のためにKVMを実行しており、現在機能しているVMネットワーキング用のブリッジを手動で作成しました。

Wireguardを使用してこれら両方のハイパーバイザーのVMブリッジを接続し、VM自体。

それを始める前に、私は、両方のハイパーバイザーのブリッジが他のハイパーバイザーに見えるようにワイヤーガードを設定する方法がわからないことに気づきましたareハイパーバイザー自体は--not VPNに表示されるため、VMはハイパーバイザーに直接接続/攻撃できません。

Wireguardはこれを行うことができますか?それとも、WireguardがイーサネットフレームレベルではなくOSIスタックで上位に機能する方法が原因で不可能になるのでしょうか。

Wireguardを使用して2つのネットワークを「ブラインド」でブリッジできるかどうか、だれでも言えるでしょうか。それとも、ホストは常にネットワークにも表示されますか?他のVPNソリューションでこれが可能になるでしょうか?または、ファイアウォールを使用して、アクセスしたくないホストをロックダウンするのが最善でしょうか?

前もって感謝します!

1
Alex

Wireguardはレイヤー3(ルーティングされたIPパケット)で機能し、ブリッジはレイヤー2(スイッチドイーサネットフレーム)で機能します。したがって、wireguardはこれを行うことができません。この質問はすでに行われており、wireguardの作成者がwireguardのメーリングリストで回答しました: wgと通常のインターフェイスのブリッジ?

したがって、ワイヤーガードを通過する前に、追加のカプセル化レイヤーが必要です。私はいくつかの選択肢があると確信しています(これらの中から [〜#〜] vxlan [〜#〜]Linux でも利用可能)。

代わりに [〜#〜] gretap [〜#〜] と名前空間(実際のハイパーバイザーとVMではなく)を使用して例を作成しました。ローカルVMトラフィックのパケットサイズを可能な限り制限する必要がないようにするには、フラグメンテーション処理が必要ですが、GRETAPにはいくつかの制限があることがわかりました。ここで説明します: GREブリッジング、IPsec、およびNFQUEUE 。NFQUEUEとユーザースペースではなく、 nftablesのパケットマングリング を使用して回避することを選択しました。

また、 RFC 6864 は、IP IDフィールドの制限により、フラグメント化されたパケットはほとんどの場合6.4Mbp/sに制限される必要があることを説明しています。これは、最近は低速ですが、 強力な整合性チェックを備えたトンネル 、それを緩和します。

ここで(偽の)VMはブリッジにリンクされており、他の接続はありません。彼らは自分以外のものを見ることができません。gretap+ wireguardを使用して2つのブリッジをリンクしている(偽の)ハイパーバイザーを見ることができません。いくつかの名前空間を作成および構成するこのbashスクリプトを実行するだけです。 nftables0.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
2
A.B