アプローチ比較:仮想ルーターのアーキテクチャ
火曜日の深夜2時15分、自宅のサーバーラック全体が突如沈黙しました。15台のセルフホストノードから監視アラートがスマートフォンへ一斉に届き、DNSクエリはタイムアウトし、Cephストレージのレプリケーションも停止しました。
さらに悪いことに、メインのファイアウォールVMがオフサイトバックアップのバースト処理中に6GBものRAMを消費し尽くし、カーネルパニックを引き起こしていました。暗闇の中で応答しないコンソールを見つめながら、私はルーティングトポロジ全体を根本から見直すことにしました。ホームラボのエッジで肥大化した仮想アプライアンスを動かすことは、障害発生時に初めて露呈する単一障害点(SPOF)を作り出すだけだったのです。
Proxmox VE内でネットワークルーティングを仮想化する場合、一般的に次の3つのアプローチから選択することになります:
- 重量級FreeBSDファイアウォール(pfSense / OPNsense):ディープパケットインスペクションや大規模なステートテーブルを備えた高機能セキュリティスイートです。しかし、通常は少なくとも2基の専用vCPUと4GBのRAMを必要とします。高速なVLAN間ルーティング、DHCP、NATのみが必要な場合、これは不要なオーバーヘッドとなります。
- 物理ハードウェアルーター(MikroTik / Ubiquiti EdgeRouter):ハイパーバイザーとエッジゲートウェイを明確に分離できます。サーバーの再起動時にも停止することはありません。その代償として、ポート構成が固定され、低価格モデルではCPUスループットが低く、実験的な設定でネットワークが壊れた際にスナップショットによる即座のロールバックができないという難点があります。
- 軽量Linux仮想ルーター(KVM上のOpenWrt):不要なものを削ぎ落とし、最新のLinuxカーネル上で動作します。OpenWrtは約3秒で起動し、アイドル時のRAM消費量は70MB未満で、ProxmoxのLinuxブリッジと直接連携します。BSD特有のドライバの癖に悩まされることなく、標準的なLinux 802.1Q VLANフィルタリングを処理できます。
Proxmox上でOpenWrtを仮想化するメリットとデメリット
テストコンテナやストレージプールをホストする同一ハードウェア上にゲートウェイを配置することは、運用上のトレードオフを伴います。
メリット
- 極めて小さなフットプリント:OpenWrtは1 vCPUと512MBのRAMで軽快に動作します。私のIntel N100ノードでは、ギガビットトラフィックのルーティング中でもアイドル時のCPU使用率はわずか0.3%にとどまります。
- ネイティブLinuxブリッジVLAN:OpenWrtは標準でdot1qタギングに対応しています。Proxmoxの
vlan-awareブリッジと組み合わせることで、上位スイッチのポートプロファイルを変更することなく、設定ファイルに数行記述するだけでIoT、ゲスト、信頼済みサブネットのトランキングが完了します。 - 高速なスナップショットロールバック:ファイアウォールポリシーの誤設定でSSHアクセスを遮断されてしまった場合でも、ホストのCLIから直接10秒でProxmoxスナップショットを復元できます。
- ワイヤースピードのVirtIOスループット:準仮想化VirtIOドライバにより、専用のPCIeパススルーを必要とせず、CPUオーバーヘッドを無視できるレベルに抑えながら、標準の1 Gbpsアップリンクで940 Mbps以上、10 Gbps仮想ブリッジで9.2 Gbps以上のスループットを安定して発揮します。
デメリット
- ホスト再起動時のダウンタイム:Proxmoxホストに新しいPVEカーネルをインストールして再起動する際、マシンがPOSTを実行してVMが起動するまでの45〜90秒間、家庭内のインターネット接続が切断されます。
- 管理アクセスのロックアウトトラップ:仮想OpenWrtインスタンス経由でのみルーティングされるサブネットにProxmox管理用IPを割り当てている場合、ファイアウォールルールのミスやブリッジの破損によってホスト自体のWeb GUIにアクセスできなくなるリスクがあります。
耐障害性に優れたホームラボ向け推奨構成
Proxmoxの管理IPへのアクセスを仮想ルーターインターフェースに依存させてはなりません。代わりに、基盤となるブリッジ上に独立した管理用アドレスを設定します。
以下は、マルチポートミニPCや1Uサーバーで使用しているアーキテクチャの基準構成です:
- WANブリッジ(vmbr1):モデムまたはONTに接続された物理WAN NIC(例:
enp2s0)に接続します。Proxmox側ではこのブリッジにIPアドレスやゲートウェイを設定せず、完全にアンナンバード(unnumbered)の状態にしておきます。 - LAN・トランクブリッジ(vmbr0):物理LAN NIC(例:
enp1s0)にbridge-vlan-aware yesを指定して接続します。このブリッジ上にProxmoxの静的ホストIP(192.168.1.2/24など)を直接割り当てることで、OpenWrtがシャットダウンしていてもホストへのアクセスを維持できます。 - OpenWrt VMスペック:1 vCPU(AES-NI暗号化アクセラレーションのためタイプは
host)、512MB RAM、シリアルコンソール、VirtIO NIC、1GB仮想ディスク。
実装ガイド
ステップ1:Proxmox上でVLAN対応ブリッジを設定する
ProxmoxホストにSSH接続し、ネットワークインターフェース設定ファイルを編集します:
nano /etc/network/interfaces
WANインターフェース用と内部トランク用にそれぞれ専用ブリッジを設定します:
# 物理WANインターフェース(ホストIPなし)
auto enp2s0
iface enp2s0 inet manual
# OpenWrtにパススルーするWANブリッジ
auto vmbr1
iface vmbr1 inet manual
bridge-ports enp2s0
bridge-stp off
bridge-fd 0
# 物理LANインターフェース
auto enp1s0
iface enp1s0 inet manual
# VLAN対応LANブリッジ(Proxmox管理用IPをここに配置)
auto vmbr0
iface vmbr0 inet static
address 192.168.1.2/24
gateway 192.168.1.1
bridge-ports enp1s0
bridge-stp off
bridge-fd 0
bridge-vlan-aware yes
bridge-vids 2-4094
サーバーを再起動することなく設定を安全に反映します:
ifreload -a
ステップ2:OpenWrtイメージのダウンロードと展開
OpenWrtには標準的なISOインストーラーウィザードがありません。代わりに、公式のx86/64 ext4 UEFIイメージをProxmoxホスト上に直接取得します:
mkdir -p /root/openwrt-install && cd /root/openwrt-install
# 23.05.4 汎用x86/64 combined EFIイメージのダウンロード
wget https://downloads.openwrt.org/releases/23.05.4/targets/x86/64/openwrt-23.05.4-x86-64-generic-ext4-combined-efi.img.gz
# 生ディスクイメージの展開
gunzip openwrt-23.05.4-x86-64-generic-ext4-combined-efi.img.gz
ステップ3:仮想マシンの作成とディスク設定
Proxmoxのqm CLIツールを使用してVMを作成します。ここではVMID 100を割り当て、軽量なコンソールアクセスのために仮想シリアルポートを設定します:
qm create 100 --name OpenWrt-Router \
--bios ovmf \
--machine q35 \
--cpu host \
--cores 1 \
--memory 512 \
--serial0 socket \
--net0 virtio,bridge=vmbr0,firewall=0 \
--net1 virtio,bridge=vmbr1,firewall=0 \
--ostype l26
ダウンロードしたイメージをストレージプール(例: local-lvm)にインポートし、デフォルトの120MBからディスクサイズを拡張します:
# ストレージプールにイメージをインポート
qm importdisk 100 openwrt-23.05.4-x86-64-generic-ext4-combined-efi.img local-lvm
# VirtIO SCSIコントローラーにディスクを接続
qm set 100 --scsihw virtio-scsi-single --scsi0 local-lvm:vm-100-disk-0
# UEFIブート変数用のEFIディスクを追加
qm set 100 --efidisk0 local-lvm:0,format=raw,efitype=4m,pre-enrolled-keys=0
# ブート順序を設定し、仮想ディスクを1GBに拡張
qm set 100 --boot order=scsi0
qm resize 100 scsi0 +880M
ステップ4:初期ネットワーク設定とLuCI Web管理画面の導入
VMを起動し、シリアルコンソールに直接接続します:
qm start 100
qm terminal 100
Enterキーを押してOpenWrtのrootプロンプトを開きます。この構成では、eth0がvmbr0(LAN)に、eth1がvmbr1(WAN)に接続されています。静的LANゲートウェイアドレスを設定します:
uci set network.lan.ipaddr='192.168.1.1'
uci set network.lan.netmask='255.255.255.0'
uci commit network
/etc/init.d/network restart
WANインターフェースがDHCP経由でIPアドレスを取得したら、SQMパッケージとCAKEキュースケジューラモジュールをインストールします:
opkg update
opkg install luci-app-sqm kmod-sched-cake
ステップ5:VLANセグメントとファイアウォールゾーンの設定
次に、信頼できないスマートデバイスをVLAN ID 20に分離します。Proxmoxで仮想ネットワークカードを追加するのではなく、OpenWrt内にタグ付きサブインターフェース(eth0.20)を直接アタッチします。
/etc/config/networkおよび/etc/config/dhcpで新しいインターフェースとDHCPスコープを定義します:
# VLAN 20上にIoTネットワークを設定
uci set network.iot=interface
uci set network.iot.proto='static'
uci set network.iot.device='eth0.20'
uci set network.iot.ipaddr='192.168.20.1'
uci set network.iot.netmask='255.255.255.0'
# DHCPプールを設定 (192.168.20.100 - 192.168.20.250)
uci set dhcp.iot=dhcp
uci set dhcp.iot.interface='iot'
uci set dhcp.iot.start='100'
uci set dhcp.iot.limit='150'
uci set dhcp.iot.leasetime='12h'
uci commit network
uci commit dhcp
/etc/config/firewallでIoTゾーンを厳格に制限します。以下のポリシーは、プライベートLANやハイパーバイザーサブネットへの接続を遮断しつつ、インターネットへのアウトバウンドアクセスのみを許可します:
# 制限付きIoTファイアウォールゾーンを作成
uci add firewall zone
uci set firewall.@zone[-1].name='iot'
uci set firewall.@zone[-1].network='iot'
uci set firewall.@zone[-1].input='REJECT'
uci set firewall.@zone[-1].output='ACCEPT'
uci set firewall.@zone[-1].forward='REJECT'
# IoTデバイスからWANへのアウトバウンドルーティングを許可
uci add firewall forwarding
uci set firewall.@forwarding[-1].src='iot'
uci set firewall.@forwarding[-1].dest='wan'
# ローカルDNSクエリを許可(ポート53)
uci add firewall rule
uci set firewall.@rule[-1].name='Allow-IoT-DNS'
uci set firewall.@rule[-1].src='iot'
uci set firewall.@rule[-1].proto='tcpudp'
uci set firewall.@rule[-1].dest_port='53'
uci set firewall.@rule[-1].target='ACCEPT'
# ローカルDHCPリクエストを許可(ポート67-68)
uci add firewall rule
uci set firewall.@rule[-1].name='Allow-IoT-DHCP'
uci set firewall.@rule[-1].src='iot'
uci set firewall.@rule[-1].proto='udp'
uci set firewall.@rule[-1].dest_port='67-68'
uci set firewall.@rule[-1].target='ACCEPT'
uci commit firewall
/etc/init.d/firewall restart
ステップ6:CAKE SQMによるバッファブロートの解消
アップリンク帯域を使い果たすと、大容量転送時に深刻なレイテンシのスパイクが発生します。典型的な1 Gbps / 50 Mbpsの回線環境では、キュー管理を行わない場合、高負荷時のping応答が15msから350ms以上にまで跳ね上がることがあります。
このバッファブロート(Bufferbloat)を解消するため、WANインターフェース(eth1)にCAKEシェーピングを適用します。帯域制限には、測定した実効速度の約90〜95%の値を指定します:
uci set sqm.eth1=queue
uci set sqm.eth1.interface='eth1'
uci set sqm.eth1.qdisc='cake'
uci set sqm.eth1.script='layer_cake.qos'
uci set sqm.eth1.enabled='1'
# 帯域幅をkbit/s単位で設定(例: 下り940 Mbps、上り48 Mbps)
uci set sqm.eth1.download='940000'
uci set sqm.eth1.upload='48000'
uci commit sqm
/etc/init.d/sqm restart
設定を適用したら、Waveform Bufferbloat Testなどのツールでテストを実施してください。アップロードが100%飽和している状態でも、pingジッターは通常200ms以上から3ms未満にまで激減します。これで、ホスト側のCPU消費電力換算で2W未満という極めて省リソースでありながら、スナップショット対応で強固に分離されたルーター環境が完成しました。

