6月 282023
 

自分でも、強引な手法だなぁ。と、思ってしまいます。

まず、 Windows11 Pro 上で動作している Hyper-V サーバがあります。その下で FreeBSD/amd64 13.2-RELEASE が動作しております。

Hyper-V の母艦である Windows11 Pro は NotePC なので WiFi 使ったり RJ45 使ったり VPN 使ったりするので Hyper-V のサーバとクライアントの間の「仮想スイッチ」はブリッジ、それはつまりは仮想スイッチマネージャの「接続の種類」で[外部ネットワーク]を選択することはほぼ不可能(利用する物理ネットワークによって毎回変更する必要がある)なのであります。

母艦側で複数のネットワークアダプタを利用する場合は、どうしても NAT、それはつまりは[内部ネットワーク]をチョイスするしかないのであります。

Hyper-V の仮想スイッチが NAT になると、色々と制約を受けます。まず、 DHCP を克服する必要があります。これについてはウェブ上に、設定方法について、色々書かれたドキュメントがあるのでそちらを参考にしてください。

いろいろ設定すると Hyper-V のクライアント (俗に『仮想マシン』と、言いますな) は NAT 配下で、固定 IPv4 アドレスで動作させることが可能になりました。

Hyper-V の母艦からは仮想マシンに対して ssh などのアクセスができるようになります。が、当然リモートのマシンからは Hyper-V 管理下の仮想マシンへはアクセスできません。

あと、仮想マシンのネットワークは NAT が入るのでこれまた色々と制約受けます。上に書いた、外部からのアクセスができません。他に NFS マウントできません。 gif トンネル張れません。とか・・。

 
そもそも、 Hyper-V の母艦の外部のネットワークに IPv6 がない場合、仮想マシンは IPv6 を利用することができません。あれ? Hyper-V の NAT 仮想スイッチで IPv6 喋れるのか?

どうして仮想マシン側に IPv6 が欲しいのだ? -> だって、IPv4 は NAT なので上記の制約受けるじゃん。それなら、トンネルでも良いから IPv6 でどっかーんっ!! と抜けていきたいじゃん。

と、いうのが発想の原点にあります。

と、いうことで図を書いてみました。

簡単に説明します。

  • 真ん中に Windows11 Pro の Hyper-V サーバがいます
  • Windows11 Pro の Hyper-V サーバは上位のネットワークとは IPv4 アドレスのみが降ってくるネットワークに接続しています
  • Hyper-V 配下の仮想マシンは FreeBSD/amd64 13.2-RELEASE です
  • Hyper-V サーバと仮想マシンの間には NAT の仮想スイッチが入っています
  • NAT の仮想スイッチは仮想マシンが固定 IPv4 アドレスを利用できるようにしています

 
これが現状、フツーにできる Hyper-V 環境です。この状態で、仮想マシン側に IPv6 グローバルアドレスを付加して、IPv4 の NAT 超えをあきらめ、IPv6 で外部との通信をできるようにして色々楽しめる状態にします。

  • 仮想マシンの FreeBSD は wireguard で外部に接続します
  • wireguard で作成した VPN トンネルの中に gif トンネルを通します
  • 仮想マシンに IPv6 が通ったので様々通信ができるようになります

 
トンネルの多段ですね。
図の左側は VyOS と wireguard のサーバは別々に描かれていますが、最近の VyOS を使うと一個にまとめられると思います。僕の環境では未だに VyOS-1.1.8 を利用していますので wireguard は別サーバに構築しました。

 
wireguard と VyOS の置き場所によって仮想マシンの IPv6 の通信速度は圧倒的に変わります。色々考えてみてください;-)。

と、いうことで、次に設定を見ていきましょうか。

 
1. 仮想マシン側の wireguard の設定
今回、仮想マシンは FreeBSD/amd64 13.2-RELEASE なので wireguard は ports から簡単に入ります。 net/wireguard をインストールしましょう。もしかしたら wireguard-kmod-0.0.20220615_1 がインストールされるかもしれませんが、実際には利用しません。

wireguard-kmod-0.0.20220615_1 をインストールした場合には /boot/modules/if_wg.ko がインストールされますが 13.2-RELEASE からは OS 標準で /boot/kernel/if_wg.ko が用意されています。フツーに wireguard_enable=”YES” すると /boot/kernel/if_wg.ko が利用されます。

僕の環境では wireguard-2,1 、wireguard-kmod-0.0.20220615_1 、 wireguard-tools-1.0.20210914_1 がインストールされました。

次に設定です。

が、その前に、まず最初に wireguard では鍵のペアを作成する必要があります。

# cd /usr/local/etc/wireguard/
# wg genkey > server.key
# wg pubkey < server.key > server.pub
#
# wg genkey > client.key
# wg pubkey < client.key > client.pub
# 
# chmod 600 *.key 
#

 
サーバ側とクライアント側のキーの両方を作成しましたが、これを利用します。

続いて設定を見ていきます。今回は wireguard のトンネルを一個作成するだけですので wg0.conf のみです。複数に接続する場合は wg1.conf wg2.conf などと設定フアイルを複数書きます。

・/usr/local/etc/wireguard/wg0.conf

[Interface]
PrivateKey = 8LJDuAU9Ste2ySHRmgHnOAyk+E4ZMbw+vCBbMHXMbZU=
Address = 192.168.254.11/32

[Peer]
PublicKey = 17CucZLVbS1Jt/8LXREvrDGEnYunIA2RYYjlJhxftlk=
AllowedIPs = 192.168.254.1/32, 10.20.65.201/32
Endpoint = 10.20.65.15:51820

 
[Interface] の 設定は自分側の設定を記載します。

  • PrivateKey は作成した鍵ファイルの client.key の内容を記載します。
  • Address は wg0 インターフェイスに付加する IPv4 アドレスです。 wireguard で接続するためだけに利用するので /32 で指定します。ただ、サーバ側と同じレンジが良いでしょう。

続いて [Peer] の設定で、これは wireguard のサーバ側に関する設定になります。

  • PublicKey は server.pub の内容を記載します。
  • AllowedIPs は wireguard サーバの wg0 インターフェイスの IPv4 アドレスを記載します。
  • AllowedIPs にはもう一個 IPv4 アドレスを記載します。 gif トンネルの接続先 IPv4 アドレスを “,” で区切って記載します。詳細についてはあとで書きます。
  • Endpoint は wireguard が動作しているサーバの IPv4 アドレスと Port 番号を記載します。

 
だいたいこんな感じで良いと思います。非常に簡単な設定ですね。ただ、一点。 [Peer] 側の設定の AllowedIPs の設定がクセモノです。
AllowedIPs に wireguard サーバ側の wg0 インターフェースの IP アドレスを書いただけでは wireguard サーバとしか通信ができません。

『wireguard サーバ側で NAT の設定を入れてないから他のネットワークと通信できんのか?』と思い、wireguard サーバ側の設定を色々いじってしまうのですが、そうではなく、クライアント側がどこと通信したいのか、AllowedIPs に記載することにより通信が可能となります。

今回は wireguard トンネルを抜けいてったあと gif トンネルを張りたいので VyOS の IPv4 アドレスを AllowedIPs に追加しました。 10.20.65.0/24 と通信したい場合は AllowedIPs には wireguard サーバの wg0 インターフェースの IPv4 アドレスと 10.20.65.0/24 を追加で書けば良いです。

で、自動起動するように設定を書きます。 /boot/loader.conf に明示的に if_wg_load=”YES” と書かずともカーネルモジュールがロードされます。

・/etc/rc.conf

wireguard_enable="YES"
wireguard_interfaces="wg0"

 
これでクライアント側の設定は完了です。

次にサーバ側の設定を見ていきましょう。

 
2. wireguard のサーバ側の設定
上のほうでも書きましたが、 wireguard のサーバは自前で用意せずとも VyOS で利用可能です。 VyOS-1.3 以降から wireguard に対応したんだったかな? 詳細なバージョンは覚えていませんが・・。

今回、僕は wireguard サーバも FreeBSD 側で作成しました。インストールは ports からですが、クライアント側のと同様のモノをインストールしました。

鍵は既に作成したので、それを使いまわしましょう。すると、サーバ側で用意するのは設定フアイル一個のみです。

・/usr/local/etc/wireguard/wg0.conf

[Interface]
PrivateKey = aJbypbTUy5LB+EIPd6FHf25D2rbTw9l+x5o7fBLL+Ec=
Address = 192.168.254.1/24
ListenPort = 51820

[Peer]
PublicKey = F8kvub6jdPnl99rISnffYtilNVEswDUo+sqGWzc7FRY=
AllowedIPs = 192.168.254.11/32

 
[Interface] の 設定は自分側の設定を記載します。

  • PrivateKey は server.key の内容を記載します。
  • Address は wg0 インターフェイスに付加する IPv4 アドレスです。

続いて [Peer] の設定で、これは wireguard のサーバ側に関する設定になります。

  • PublicKey は client.pub の内容を記載します。
  • AllowedIPs は wireguard クライアントの wg0 インターフェイスの IPv4 アドレスを記載します。

 
以上で設定は完了です。 /etc/rc.conf にクライアントのと同じ設定を追加して wireguard を起動します。サーバ側とクライアント側の両方で service wireguard start を実行すると wg0 インターフェースが生えてきます。

双方の wg0 の IPv4 アドレスに ping を打ち、到達性を確認します。この時点で ping が当たらない場合は設定情報が間違っています。なおしてください。そもそも wireguard のサーバとクライアントの物理インターフェース間で通信できることを確認します。

 
双方の wg0 に付加された IPv4 アドレスに ping が当たるようになったら OK。クライアント側の [Peer] 設定の AllowedIPs に記載した VyOS の IPv4 アドレスに ping が当たることを確認します。
上にも書いた通り 10.2.65.201 だけでなく、もっと他のマシンにも接続したい場合はクライアント側で設定してみてください。

 
最後に wireguard の wg0 トンネルをぬけて gif トンネルを掘ります。 gif トンネルが掘れると Hyper-V の仮想マシンにはグローバルな IPv6 アドレスが付加されます。 IPv6 を利用することにより IPv4 で受けていた NAT の制約から開放されることになります。パチパチパチっ!!

と、いうことで IPv6 gif トンネルの設定については以前書いているのでそつらを参考にしてください。

IPv6 Over IPv4 トンネルを dtcp から VyOSへ。

 
移動する PC 上で Hyper-V を動かしたとき、その下で動作する仮想マシンはネットワーク的に色々な制約を受けるモノです。今回は多段トンネルでその問題を解決してみました。

  • 仮想マシンは NAT ネットワークで gif トンネルが利用できないので wireguard なトンネルを掘る
  • wg0 を抜けて gif トンネルを掘る
  • IPv4 は NAT ネットワークなので IPv6 の直アクセスで NAT 問題を回避
  • 仮想マシンに IPv6 アドレスが付加されたので仮想マシンのネットワークはもーサイコーっ!!

 
こんな感じの手順で今回の構成を構築しましたが、フツーここまでやる?

ってか、まあ、Hyper-V が動作するのは WindowsOS なので、ネットワーク的に色々な制約が多すぎてやりたいことができない。
ネットワークはトンネルで抜けて色々やりましょう。と、いう雰囲気ですが・・。

一点だけ。まだ検証してないし、計算が必要だと思うのですが・・。 MTU って、一体いくつになるの? f(^^;;。