構成
自宅NWの冗長化目的で Raspberry Pi を2台使い、WiFiアクセスポイントを組んでいる。
| ホスト名 | チャンネル | SSID |
|---|---|---|
| pi-1 | 1 | your-ssid |
| pi-2 | 11 | your-ssid |
同一SSIDで別チャンネルにする構成は ESS(Extended Service Set) と呼ばれ、クライアントが自動的に電波の強い方に接続する。WPA2-PSKで普通に成立する冗長化構成。
ブリッジ構成で bridge interface(br0)にWiFiインタフェース(wlan0)を参加させ、hostapdで電波を飛ばしている。
問題
OS再起動後、SSIDが片方または両方スキャンに出ない。
systemctl status hostapdはactive (running)- エラーログも一見出ていない
- hostapdを手動で再起動すると出る
調査
チャンネルの干渉を疑う
最初にhostapd.confのチャンネル設定を確認した。
2.4GHz帯で実際に干渉しないチャンネルは 1、6、11 の3つだけ。元の設定は6と7だったため、ほぼ完全に干渉していた。
ch6 --|--
ch7 --|-- ← 隣接していてほぼ被る
チャンネルを1と11に変更した。
# pi-1
channel=1
# pi-2
channel=11
BSSIDレベルで電波を確認
sudo iw dev wlan0 scan | grep -E "BSS |SSID|freq|signal"
BSS xx:xx:xx:xx:xx:xx(on wlan0)
freq: 2462
signal: -15.00 dBm
SSID: your-ssid
BSS xx:xx:xx:xx:xx:xx(on wlan0)
freq: 2412
signal: -68.00 dBm
SSID: your-ssid
両台ともビーコンは出ていた。ESSとして動作は成立している。
power_saveを疑う
APなのにpower_saveが有効になっている可能性を確認した。
sudo iw dev wlan0 get power_save
hostapdが wlan0 を掴んでいるため、設定変更にはhostapd停止が必要:
sudo systemctl stop hostapd
sudo iw dev wlan0 set power_save off
sudo systemctl start hostapd
ただし再起動で戻るため、永続化はsystemdのoverride.confで対応:
# /etc/systemd/system/hostapd.service.d/override.conf
[Service]
ExecStartPost=/sbin/iw dev wlan0 set power_save off
これだけでは問題は解決しなかった。
beacon_intを疑う
元の設定は beacon_int=200(デフォルトは100ms)。ビーコン間隔が長いと、起動直後のスキャンでSSIDを見逃す可能性がある。
beacon_int=100
に戻したが、問題は解決しなかった。
journalctlで起動ログを確認
sudo journalctl -u hostapd -b 0
pi-2のログに以下が出ていた:
hostapd: nl80211: Failed to add the bridge interface br0: File exists
hostapd: nl80211 driver initialization failed.
hostapd: wlan0: interface state UNINITIALIZED->DISABLED
hostapd: wlan0: AP-DISABLED
hostapd: wlan0: CTRL-EVENT-TERMINATING
hostapd.service: Failed with result 'exit-code'.
その後:
hostapd.service: Scheduled restart job, restart counter is at 1.
hostapd: wlan0: AP-ENABLED
原因はここにあった。 Restart=on-failure がセーフティネットになっていただけで、初回起動は失敗していた。
起動順序を確認
sudo systemctl show hostapd | grep -E "After|Wants|Requires"
pi-1とpi-2で差異があった:
# pi-1
After=sys-subsystem-net-devices-wlan0.device network.target networking.service ...
# pi-2
After=network.target ← wlan0.deviceもnetworking.serviceも待っていない
pi-2は network.target しか待っていなかった。
ブリッジの管理主体を確認
ls /etc/NetworkManager/system-connections/
# br0.nmconnection bridge-slave-eth0.nmconnection
br0は NetworkManager が管理していた。
原因
起動フローが以下の順序になっていた:
1. OS起動
2. NetworkManager が br0 を作成(非同期)
3. hostapd が起動 → br0 がまだ中途半端な状態
4. "Failed to add the bridge interface br0: File exists" で失敗
5. Restart=on-failure で2秒後に再起動
6. 今度はbr0が正常になっているので成功
File exists エラーは「br0が存在しない」ではなく「br0が中途半端な状態で既に存在している」ことを示している。hostapdが wlan0 をbr0に追加しようとした時に競合が発生していた。
systemctl status が active に見えるのは Restart=on-failure が自動回復しているためで、SSIDが出るのが遅延していた。
解決策
両台に systemd の override.conf を作成し、network-online.target を待つようにする。
sudo mkdir -p /etc/systemd/system/hostapd.service.d/
sudo nano /etc/systemd/system/hostapd.service.d/override.conf
[Unit]
Wants=sys-subsystem-net-devices-wlan0.device network-online.target
After=sys-subsystem-net-devices-wlan0.device network-online.target
sudo systemctl daemon-reload
sudo reboot
network-online.targetが有効か確認
sudo systemctl is-enabled NetworkManager-wait-online.service
enabled になっていること。disabled の場合は network-online.target が機能しないので有効化する:
sudo systemctl enable NetworkManager-wait-online.service
network-online.target と network.target の違い
| target | 意味 |
|---|---|
network.target |
ネットワークスタックの起動完了。インターフェースがオンラインかは問わない |
network-online.target |
少なくとも1つのインターフェースがオンラインになった状態 |
NetworkManagerが管理するbr0のような仮想インターフェースを依存先にする場合は network-online.target が適切。
補足:hostapd.confの注意点
TKIPはCCMPに統一する
# 非推奨
wpa_pairwise=TKIP
# 推奨
wpa_pairwise=CCMP
rsn_pairwise=CCMP
TKIPはWPA2と組み合わせた場合に一部クライアントから拒否されることがある。
チャンネルは1・6・11を使う
2.4GHz帯で干渉しないチャンネルの組み合わせは 1と6、1と11、6と11 のみ。隣接チャンネルは必ず干渉する。
まとめ
| 項目 | 内容 |
|---|---|
| 原因 | NetworkManagerによるbr0初期化完了前にhostapdが起動 |
| 症状 | Restart=on-failure で自動回復するため active に見えるが遅延あり |
| 対処 | network-online.target をAfter/Wantsに追加 |
| 対象 | NetworkManagerがブリッジを管理している環境全般 |
systemctl status が active でも、journalctl -u hostapd -b 0 で起動ログを必ず確認すること。