UTMを頑張って作る④pfSenseでVMを通して無線を使う(PCI Passthrough)

前置き 

GMKtec-G2には無線LANとしてRTL8852BEが搭載されているが、
FreeBSDでは対応ドライバが無い。(本記事執筆段階)
一方、linuxではubuntuなどのドライバが存在しているものがある。
そのため、FreeBSD上にubuntuのVMを作成し、ubuntuVMに無線の通信を行わせることにした。
FreeBSDのハイパーバイザーであるbhyveをWebUIで扱えるBVCPを使用する。

BVCPの導入

ダウンロード・展開・導入

以下URLから最新版を選んでダウンロードする。
https://github.com/DaVieS007/bhyve-webadmin/tags
pfSenseのコンソールに入ってダウンロードしてくる。
fetch https://github.com/DaVieS007/bhyve-webadmin/archive/refs/tags/v2.1.4.zip
解凍する
unzip v2.1.4.zip
解凍したディレクトリに移動し、インストール用スクリプトを起動
cd ./bhyve-webadmin-2.1.4
./install.sh
インストール完了後、認証情報が出力されるのでメモっておく
 (!) Admin Credentials recreated,
   - User: admin
   - Password: <パスワード>
ブラウザなどでアクセスし、先ほどメモった認証情報でログインする。
https://[your-ip]:8086

仮想マシンの作成

仮想マシン作成の前準備

VM用の仮想ディスクイメージの保存場所を指定する


左メニュー Storage Management > Create Storage 
任意の保存先、ストレージ識別名を入力し、enable use にチェックしSAVEする

VM用のネットワークブリッジを作成する


左メニュー Storage Management > Create Network
Network Gateway to bound では No External Network を選択する
任意の名前や説明を入力したのち、SAVEする

VMのインストール用ISOファイルを配置する

コンソールあるいはSSHにてpfSenseにログインし、OSのインストール用ISOイメージを配置する。
デフォルトだと/vms/iso_images/に配置する。
今回はubuntu22.04を導入する。
cd /vms/iso_images/
fetch https://releases.ubuntu.com/22.04.4/ubuntu-22.04.4-live-server-amd64.iso

仮想マシンの作成

仮想マシンの作成及び実行


左メニュー Virtual Machines > Create new Virtual Machine
名前などは任意に入力する。
Installed RAM Memoryはubuntu22.04だと最低1GBは確保したほうがいいみたい。
(少なすぎると起動しなかったり特定の機能で不具合を起こしたりする)
あとは Guest Operating System などは Linux にしてSAVEする

作成したら、歯車のボタンをクリックし、詳細設定に移る

まず、Virtual (ISO) CD-ROM Drive で/vms/iso_images/にダウンロードしておいたOSのイメージファイルを選択する
次に Storage Array でディスクイメージを作成する。名前とサイズに任意の値を入れてSAVEする
最後に Network Device で先ほど作成したものを指定してOK
ここまでできたらStartボタンを押下してVMを起動する
無事起動することを確認したら、インストールは開始せずに、まず事項のネットワーク設定を実施する。

ネットワーク設定

OSをインストールする際にインターネットアクセスがないとインストールが失敗する。
そのため、インストールを開始する前にpfSense側でネットワークの設定をしておく。
(VMを起動していないと bridge が作成されない仕様なので、起動させておく必要がある)
pfSenseのWebUI > Interfaces > Assingnments  で bridge300を選択してAddする。
※BVCPはVM起動時に自動的にbridge300番台でネットワークを作成する。

続いて、作成したInterfacesの設定画面に移動し設定していく。
IPなどは任意に設定してよいが、追加でMACアドレスのスプーフィングをする必要がある。
MACアドレスの値は予約アドレスでなければ何でもよい。
BVCPはOS起動毎に新しくbridgeを作成するが、その際にMACアドレスも変わる。
OS起動毎にMACアドレスが変わるとpfSense側でインターフェースを上手く認識できなくなるようなので、MACアドレスのスプーフィングによりMACアドレスを固定しておく必要がある。

必要に応じ、WebUI > Services > DHCP Server からDHCPの設定もやっておく。
本項の設定が終わり次第、VMに戻りインストール作業を行う。
インターネット接続が出来、インストールが完了すれば作業は成功している。
インストールが完了したらVMをシャットダウンしておく。

PCIパススルーの設定

VMでRLT8852BEを扱えるように設定を行っていく。
pfSenseのコンソールに入り、以下コマンドを発行する。
$ pciconf -lv
すると、何行目かにRLT8852BEっぽいのがあるので、そこの番号をメモっとく(今回の場合は0:2:0:0をメモ)
none@pci0:2:0:0:        class=0x028000 rev=0x00 hdr=0x00 vendor=0x10ec device=0x                                                       b852 subvendor=0x10ec subdevice=0xb852
    vendor     = 'Realtek Semiconductor Co., Ltd.'
    class      = network
次に、以下ファイルに先ほどメモった番号を参考に以下のような行を追記する。
 $ vi /boot/loader.conf
pptdevs="2/0/0"
上記の設定を適用するため、pfsenseを再起動する。

再度ログインして以下コマンドを発行し、ppt0となっていることを確認する。
$ pciconf -lv

ppt0@pci0:2:0:0:        class=0x028000 rev=0x00 hdr=0x00 vendor=0x10ec device=0x                           b852 subvendor=0x10ec subdevice=0xb852
    vendor     = 'Realtek Semiconductor Co., Ltd.'
    class      = network

再起動後はBVCPのサービスが立ち上がっていない可能性があるので、以下コマンドで立ち上げておく
service bvcp-backend start
service bvcp-helper start
service bvcp-frontend start
※ pfSenseは仕様上、/etc/rc.confの内容が読み込まれないらしい。そのため、bvcp_enable="YES"と記載されていても自動起動しない。
対処方法としては後述するshellcmdというものを導入すればいいみたい。

次にBVCPのWebUIにログインして、VMの以下設定をいじる。

PCI Passthrough → 2/0/0
Memory Handling → Static Allocation(PCI Passthroughを設定すると自動的に変わる)
上記の通り設定を変更したら、VMを起動する。

RTL8852BEのドライバを導入する

※ubuntu23系以降はデフォルトでドライバがあるため実施する必要なし
VMを起動し、以下を導入する。
$ apt install -y build-essential bc git
ドライバをダウンロードし、導入する。
git clone https://github.com/HRex39/rtl8852be.git
cd rtl8852be
make -j8
sudo make install
sudo modprobe 8852be
lspciコマンドを発行し、RLT8852BEが認識されているか確認する。
$ lspci
Network controller: Realtek Semiconducto Co., Ltd. Device b852
ip a でも確認する
$ ip a
※ちゃんと認識されていれば、wlp0s や wlan がリストに表示される
もし何らかの理由でデバイスが認識されなくなったら、本手順を再度行うことにより復活するかもしれない

アクセスポイントを導入する

前準備として、インターフェースの設定を行う。
以下のような感じ繋ぎたい。
pfSense-①-[BVCPのBridge(bridge300)]-②-[VMのeth(enp0s)]-③-[VMのwlan(wlp0s)]
①と②は既に繋がっているので③をbridgeで繋ぐ。

enp0sとwlp0sの設定を行う。
以下のような感じで設定する。
/etc/netplan/00-installer-config.yaml
-----------------
network:
  ethernets:
    enp0s:
      dhcp4: true
    wlp0s:
      dhcp4: true
  version:2

  bridges:
    br0:
      interfaces:
        - enp0s
      dhcp4: true
-----------------
※ bridgesの設定にwlp0sが含まれていないが、後述するhostapdで設定するため記載しない
設定を適用する。
$ sudo netplan apply

次に、アクセスポイント用にhostapdを導入する。
sudo apt install -y hostapd
sudo systemctl unmask hostapd
sudo systemctl enable hostapd

設定ファイルを書く。
/etc/hostapd/hostapd.conf
-----------------
interface=wlp0s(インターフェース名)
driver=nl80211
bridge=br0    #ここでブリッジに参加させる
channel=1
ieee80211n=1
ssid=myssid(SSID名)
wpa_passphrase=パスワード
country_code=JP
wpa=2
wpa_key_mgmt=WPA-PSK
hw_mode=g
auth_algs=1
rsn_pairwise=CCMP
#ignore_broadcast_ssid=1 #1でステルス
-----------------

記載したら以下コマンドを発行する。設定が上手くいっていれば起動する。
sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl start hostapd

pfSense起動時に自動でVMが立ち上がるようにする

今のところ、以下手順を踏むと何とか動いてくれる。(エラーが出たりはする)
BVCPの起動 → VMの起動 → pfSenseとVMを接続しているインターフェースの再起動

まずBVCPの起動をCLIから行いたいので、APIを有効化する。

pfSenseのCLIに入り、以下ファイルの api_key の値をメモる。
/var/lib/nPulse/BVCP/bvcp.conf 
メモった api_key の値を以下ファイルに張り付ける。
vi /var/lib/nPulse/BVCP/API/cli.php
pfSenseとVMを接続しているインターフェースの再起動の準備を行う。

pfSenseのCLIで以下例のようなプレイブックを作成する。
vi /etc/phpshellsessions/opt1reload
    interface_configure('opt1', true);
※ opt1 の部分は、以下画像の箇所を確認して環境に合わせて変更する。

準備ができたのでpfSense起動時のコマンドを設定していく。
pfSenseは/etc/rc.confの内容が読み込まれないから、代わりにshellcmdというものを導入する。

SystemPackage > Manager から shellcmd を探して導入する。
Services > Shellcmd から以下のように設定する。
earlyshellcmdとして以下を設定
service bvcp-backend restart && service bvcp-helper restart && service bvcp-frontend restart
※ BVCPを起動している

shellcmdとして以下を設定
/var/lib/nPulse/BVCP/API/cli.php vm start <VMのホスト名> && sleep 60 && pfSsh.php playback opt1reload && pfSsh.php playback restartdhcpd
※ VMを起動し60秒待機する。pfSenseとBVCPを繋いでいるインターフェースを再起動し、更にDHCPサービスを再起動している。

何かエラーを吐いたりするけど、現状これで動くのでヨシ!


コメント