Summary
- Proxmox上のFreeBSD VMにUSB無線LANドングルを接続し、IoT機器専用Wi-Fi APを構築した
- VLANを作成し、IoT機器を宅内の他ネットワークから分離することで侵害時の被害を局所化した
- ESP32等のIoT機器に接続させるにはhostapd.confのパラメータチューニングが必要だった
やらないこと
- ProxmoxホストやVLAN間ルーティング・ファイアウォールの詳細設定
- DHCP/DNSサーバの構築手順
- IoT機器側の設定
本記事における課題
宅内にIoT機器(Amazon Alexa、Google Home、ESP32等)が増加するにつれ、これらが侵害された際のリスクが高まる。IoT機器は普段から最新のファームウェアを適用することは難しく、脆弱性を突かれ乗っ取りに発展するリスクを考慮し、他のネットワークセグメントから分離することが望ましい。侵害された機器を踏み台にして同一ネットワーク上のPCやNASへ攻撃が波及する事態を防ぐことが目的である。
FreeBSD(今回はProxmoxでVMを作成)と押し入れに眠っていたUSB無線LANドングルを活用し、低コストでIoT機器用APを構築する。
やったこと
VMのOSにFreeBSDを選定したのは、「ネットワーク処理が高速」という評判をなんとなく聞いていたためである。深い根拠や検証があるわけではなく、Linuxでも同様の構成は実現できると思われる。
こちらによると、NetflixやSonyが採用しているそうで。私は最近はすっかりKubernetesやパブリッククラウドのPaaSで慣れきってしまったので利点はちゃんと知りたい。
その昔本番環境でメンテナンスしていた経験が有って久々に思い出したという理由もあります。
Proxmox側:VLANの作成とVMへの接続
VMにネットワークインターフェースを追加
Proxmox管理画面から対象VM(FreeBSD)の設定を開き、Hardware → Add → Network Device にてVLAN用ブリッジ(vmbr3)を割り当てる。FreeBSD上では em0 として認識される。
USBドングルをVMにパススルー
Hardware → Add → USB Device にてUSBドングルを選択しVMへパススルーする。FreeBSD上での認識確認のため、 usbconfig コマンドをVM内で実行する。
root@freebsd-ap:~ # usbconfig list
ugen4.2: <WLI-UC-GNM Wireless LAN Adapter [Ralink RT8070] BUFFALO INC. (formerly MelCo., Inc.)> at usbus4, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (450mA)
FreeBSD側の設定
hostapd.confの作成
/etc/hostapd.conf を以下の通り作成する。通信が安定しなければ channel は変えてみると良い。
interface=wlan0
driver=bsd
ssid=MySSID
hw_mode=g
channel=6
ieee80211n=0
ieee80211w=0
wpa=2
wpa_passphrase=MyPassword
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
wpa_pairwise=CCMP
country_code=JP
wmm_enabled=1
ap_isolate=1
⚠️ ESP32接続のためのチューニングポイント
以下のパラメータを明示的に指定しないとESP32から接続できない。デフォルト値に任せず必ず記載すること。根拠は不明だが、Won't Connect to hostapd / Linux-Generated Hotspots の記事を参考にパラメータを絞り込んだ。
| パラメータ | 値 | 理由 |
|---|---|---|
ieee80211n |
0 |
ESP32のn接続が不安定なためg固定 |
ieee80211w |
0 |
PMF(Protected Management Frames)無効化 |
country_code |
JP |
地域コード未設定だと不安定 |
wpa_pairwise |
CCMP |
TKIPを排除しCCMPに統一 |
wmm_enabled |
1 |
WMM有効化(WPA2必須要件) |
ap_isolate=1 について
AP配下の端末同士の直接通信を遮断する。ALEXA・Google Home等はインターネットへの出口さえあれば機能するため、万一いずれかの機器が侵害されても、同じAPに接続している他のIoT機器への直接攻撃を防ぐことができる。
rc.confへの追記
/etc/rc.conf に以下を追記する。channel は hostapd.conf に合わせる。
# Wi-Fi AP
if_run_load="YES"
if_bridge_load="YES"
wlans_run0="wlan0"
create_args_wlan0="wlanmode hostap channel 6"
ifconfig_wlan0="up"
ifconfig_em0="up"
cloned_interfaces="bridge0"
ifconfig_bridge0="addm em0 addm wlan0 SYNCDHCP"
hostapd_enable="YES"
em0(ProxmoxからのVLANインターフェース)と wlan0 をブリッジすることで、新たなサブネットを切ることなくIoT機器をVLAN(192.168.xx.0/24)に参加させる。DHCPは上位ルータのものをそのままパススルーする。
再起動して確認
reboot
⚠️ hostapdの再起動では設定が反映されない
service hostapd restart では正常に動作しないケースがある。設定変更後は必ずOS再起動すること。
起動後、ifconfig にてbridge0・wlan0の状態を確認する。
root@freebsd-ap:~ # ifconfig
(抜粋)
bridge0: ...
inet 192.168.xx.xxx netmask 0xffffff00 broadcast 192.168.xx.255
member: wlan0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
member: em0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
wlan0: ...
ssid MySSID channel 6 (2437 MHz 11g ht/20)
authmode WPA2/802.11i privacy MIXED
status: running
bridge0 がIPアドレスを取得し、wlan0 が running 状態になっていれば正常である。
まとめ・所感
- 敢えてFreeBSDで構築してみたが、非常にシンプルにAPを構築することができた
- ESP32の接続確立には
ieee80211n=0やieee80211w=0等の明示的な設定が必要と思われる。なぜこれらの設定が必要なのかは完全には把握できていないが、同様の事象で詰まっている事例は散見される -
ap_isolate=1はIoT機器間の直接通信遮断に有効