FreeBSD 12でNATを使わずに別ネットワークセグメントでbhyveを使う
FreeBSDの仮想化基盤bhyveでネットワークを使う場合、以下の構成を取る事が多いようだ。
- ブリッジ接続(VMとホストが同一ネットワークとなるL2接続)
- NAT接続(VMとホストが別ネットワークとなり、その間をNATで接続するL3接続)
- NICのPCIパススルー接続(VMに物理NICを割り当て物理ネットワークに直接参加させる。言ってみればL1接続?)
この記事では、NATを使わずにVMネットワークとホストネットワークを分けるL3接続、つまりルータやL3スイッチで行う普通のIPルーティング(IPフォワーディング)で接続する方法を説明する。
試した環境
- FreeBSD 12.0-RELEASE
- FreeBSD 12.1-RELEASE
- vm-bhyve 1.3.0
IPフォワーディングは、それこそ大昔からFreeBSDが持っている機能なので、bhyveが搭載された10-RELEASEでも使えると思う。
手順
手順は極めてシンプル。ホストとなるFreeBSDのパケットフォワードを有効にし、ご家庭のルータ/L3スイッチに経路情報を追加するだけ。目指すネットワーク構成は下図のとおり。NATは使わないので、VMと宅内機器が互いのIPアドレスで直接通信可能な極めてシンプルな構成だ。
ネットワーク要件はこんな感じ。
- 宅内ネットワーク
- ネットワークセグメント:172.16.32.0/24
- デフォルトゲートウェイ:172.26.32.254
- VMネットワーク
- ネットワークセグメント:172.16.33.0/24
- デフォルトゲートウェイ:172.16.33.254
仮想スイッチの作成
vm-bhyveの仮想スイッチを作る。このスイッチに割り当てたIPアドレスがVMのデフォルトゲートウェイ、およびVM用ネットワークへのネクストホップとなる。
# vm switch create -a 172.16.33.254/24 public # sudo vm switch list NAME TYPE IFACE ADDRESS PRIVATE MTU VLAN PORTS public standard vm-public 172.16.33.254/24 no - - -
FreeBSDのパケットフォワーディングを有効にする
仮想スイッチと物理NIC間でIPパケットがやり取りできるよう、FreeBSDのパケットフォワーディングを有効にする。
# sysrc gateway_enable="YES"
再起動またはsysctl -w net.inet.ip.forwarding=1
を実行すると、パケットフォワーディングが動き出す。
この段階でVM→宅内ネットワーク/インターネットへの通信が通るようになる。
ルータに経路情報を追加
宅内ネットワーク側からVMへの通信をさばくため、宅内ルータに経路情報を追加する。
一般のご家庭にはおなじみRTX1200あたりなら↓こんな感じで。ネクストホップには、仮想スイッチのIPアドレスを指定する。
# ip route 172.16.33.0/24 gateway 172.16.33.254
VMの設定
VMをぶら下げる仮想スイッチを、初めに作った“public”に設定する。vm-bhyveのVM設定ファイルを編集する。
network0_switch="public"
VM起動後、VMのOSのネットワーク設定を編集する。今回、bhyveのホストマシンではDNSリゾルバを動かしていないので、DNSサーバは宅内ルータを指定した。
IPアドレス | 172.16.33.1 | |
---|---|---|
サブネットマスク | 255.255.255.0 | |
デフォルトゲートウェイ | 172.16.33.254 | 仮想スイッチのIPアドレス |
DNSサーバ | 172.16.32.254 | 宅内LANのルータ |
これでめでたく、VMと宅内機器の間で互いに通信が通るようになる。
あとがき
ネット上の設定例を見ると、bhyveのネットワーク設定はブリッジかNATを用いていることが多く、またNATの場合はpfを使っている例が多い。pfのことは分からんので、NATといいつつ実はこの記事のように単なるIPルーティングしてるだけなのかもしれないが、それこそsysctlのフラグを1つONにすれば済む話。
凝った設定をしないなら、本記事の方法が一番楽で簡単だと思うんだけど、何でみんなこの方法でやらないんだろう?(2023-05-31 追記:ルータに経路情報追加しなきゃいけないってのが一番のネックなのかも?bhyveホスト側でNAPTすれば経路情報は気にする必要なくなるしなー。逆にホスト外からゲストVMへのアクセスがちょっと面倒になるけれども。)