koktoh の雑記帳

気ままに書いていきます

NetworkManager で Wi-Fi クライアントを維持しつつアクセスポイントにする(RPi OS (bookworm))

はじめに

Raspberry Pi OS (bookworm) から、ネットワーク周りが NetworkManager で管理されるようになったみたいです

Raspberry Pi 4 とか、有線と無線両方載ってるボードなら、有線で宅内ネットワークからのアクセス(ssh とか)を確保できるので、無線をアクセスポイント利用で潰してもそんなに不便はないです

しかし、 Raspberry Pi Zero W/2 W は有線の口がないので、そうしてしまうと不便です(USB On-The-Go とか使えばいいけど)

ここでは、 Raspberry Pi Zero には電源供給の USB しか繋がない縛りプレイでいきます

なお、 Raspberry Pi の IP 固定とか ssh 接続の設定とかは終わっている前提でいきます
そこらへんが終わってない人は、ググったりして終わらせておいてください

Wi-Fi クライアントを維持してアクセスポイント化するには

方針としてはこうです

  • アクセスポイント用の仮想ネットワークインターフェースを作る(ap0
  • NetworkManager で ap0 を利用したアクセスポイント用の設定を作る

なんでそんなことするの?

Raspberry Pi Zero にはデフォルトで wlan0 というネットワークインターフェースがあります

これをそのままアクセスポイントに流用すると、 Wi-Fi クライアント機能はなくなり、アクセスポイントとしての動きしかしなくなります
Raspberry Pi Zero が家の中に飛んでる Wi-Fi とかを掴まなくなるわけですね

これは、 Raspberry Pi Zero に繋がった機器だけの閉じたネットワークが構成され、外に出ることも、外からアクセスすることもできなくなるということです
外(宅内ネットワークとか)から Raspberry Pi Zero に ssh したり、 Raspberry Pi Zero やそこに繋がってる機器からインターネットに出ていくことができません
当然 sudo apt update とかできません(めっちゃ困る)

なので、 wlan0 にはこれまで通り、家の中を飛んでる Wi-Fi を掴んでもらえるようにしておいて、新たに ap0 を作ってアクセスポイントになってもらうわけです

アクセスポイント用のネットワークインターフェースを作る

第一段階としてネットワークインターフェースを作ります

現在のネットワークインターフェースと MAC アドレスを確認

まずは現在設定されているネットワークインターフェースを確認してみましょう

iw dev

実行結果

phy#0
        Unnamed/non-netdev interface
                wdev 0x2
                addr xx:xx:xx:xx:xx:xx
                type P2P-device
                txpower 31.00 dBm
        Interface wlan0
                ifindex 2
                wdev 0x1
                addr xx:xx:xx:xx:xx:xx
                ssid <SSID 名>
                type managed
                channel 10 (2457 MHz), width: 20 MHz, center1: 2457 MHz
                txpower 31.00 dBm

wlan0addr の値(MAC アドレス)は今後も使うので、どこかにメモしておいてください

仮想ネットワークインターフェースを作る

まずは ap0 という名前でネットワークインターフェースを作ります

sudo iw phy phy0 interface add ap0 type __ap

次に、 ap0MAC アドレスを設定します
さっき確認した addr と同じで大丈夫です

sudo ip link set ap0 address xx:xx:xx:xx:xx:xx

確認すると ap0 が新たにできています

phy#0
        Interface ap0
                ifindex 3
                wdev 0x3
                addr xx:xx:xx:xx:xx:xx
                type AP
                channel 10 (2457 MHz), width: 20 MHz, center1: 2457 MHz
                txpower 31.00 dBm
        Unnamed/non-netdev interface
                wdev 0x2
                addr xx:xx:xx:xx:xx:xx
                type P2P-device
                txpower 31.00 dBm
        Interface wlan0
                ifindex 2
                wdev 0x1
                addr xx:xx:xx:xx:xx:xx
                ssid <SSID 名>
                type managed
                channel 10 (2457 MHz), width: 20 MHz, center1: 2457 MHz
                txpower 31.00 dBm

udev でアクセスポイントの設定を永続化

Raspberry Pi を再起動すると ap0 は消えてしまうので、 udev で起動時に ap0 を作成するようにします

まずはファイルを作ります

sudo vi /etc/udev/rules.d/99-ap0.rules

以下の内容を書き込みます

SUBSYSTEM=="ieee80211", ACTION=="add|change", ATTR{macaddress}=="xx:xx:xx:xx:xx:xx", KERNEL=="phy0", \
  RUN+="/sbin/iw phy phy0 interface add ap0 type __ap", \
  RUN+="/bin/ip link set ap0 address xx:xx:xx:xx:xx:xx"

再起動して ap0 がちゃんと作られているか確認しましょう

NetworkManager でアクセスポイントの設定をする

NetworkManager には nmclinmtui という2つのユーザーインターフェースがあります

nmcliコマンドラインに直接打ち込むコマンド、 nmtuiraspi-config のようなテキストユーザーインターフェースです

どちらでも好きな方を使ってください

nmcli で設定する

この一行で終わりです(参考にしたサイトほぼそのまま)

rpi_ap という名前の connection を作成し、もろもろの設定を一気に適用します

sudo nmcli connection add type wifi ifname ap0 con-name rpi_ap autoconnect yes ssid SSID_AS_YOU_LIKE 802-11-wireless.mode ap 802-11-wireless.band bg ipv4.method shared ipv4.address 192.168.XXX.1/24 ipv4.never-default yes wifi-sec.key-mgmt wpa-psk wifi-sec.pairwise ccmp wifi-sec.proto rsn wifi-sec.psk "password_as_you_like"

SSID_AS_YOU_LIKEpassword_as_you_like は好きに決めてください
192.168.XXX.1/24XXX1 ~ 255 の間の好きな数字にしてください(すでにあるものと被らないように)

ポイントはここです

ipv4.never-default yes

これを設定しないと、今回作った rpi_ap がルートになって Raspberry PiWi-Fi を掴まなくなることがあります(この説明が正しいかは疑問だけど 、ネットワークや NetworkManager を完全に理解してないので、「たぶんそんな感じなんだろうな」くらいの感覚)
起動のたびに rpi_ap がルートになったりならなかったりするので、「再起動すると ssh できたりできなかったりする」みたいな現象が起きます

他のオプションや、 nmcli についての詳細は公式とかを見てください(「こうしとけばいいのね」くらいの理解度なので解説とかムリ)

最後に、 NetworkManager の設定を再度読み込んで、 rpi_ap を起動します(やらなくても作成時点で起動してるかも)

sudo nmcli connection reload
sudo nmcli connection up rpi_ap

nmtui で設定する

まずは nmtui を起動します

sudo nmtui

Edit a connection を選択して Enter

<Add> を選択して Enter

Wi-Fi を選択して Enter

設定は以下のようにします


IPv4 CONFIGURATION の内容は最初は隠れているので、 <Show> で表示します

赤くなっているの項目名は、正しくない(設定が必要なのに空欄、使えない文字が使われている、など)ので、適宜修正してください

SSID_AS_YOU_LIKEpassword_as_you_like は好きに決めてください
Deviceap0 を作るときに指定した MAC アドレスを大文字で入力してください(XX:XX:XX:XX:XX:XX の部分)
Addresses はアクセスポイントのアドレスです(ルーター192.168.1.1 的なやつ)
192.168.000.1/240001 ~ 255 の間の好きな数字にしてください(すでにあるものと被らないように)

nmcli の項で説明したように、 Never use this network for default route にチェックを入れることを忘れないようにしましょう

<OK> で作成を終了すると、設定した connection ができています

これで設定は終了したので、 <Back><Quit> を選択して nmtui を出ましょう

確認

nmcli でも connection を確認してみましょう

nmcli connection show

実行結果

NAME           UUID                                  TYPE      DEVICE
rpi_ap         XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX  wifi      ap0
preconfigured  XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX  wifi      wlan0
lo             XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX  loopback  lo

rpi_ap が追加されているはずです
緑色(ターミナルの設定によるかも)になっていれば起動しています

この時点で、スマホやノート PC から、設定したアクセスポイントに繋ぐことができます
しかも、このアクセスポイントを介してインターネットに出ていくこともできます

一応、再起動しても問題なく ssh やアクセスポイントへの接続ができるか確認しましょう

sudo reboot

参考

以下の記事を参考にしました

www.mikan-tech.net

raspida.com

おわりに

以上、 Raspberry Pi OS (bookworm) で(NetworkManager で) Wi-Fi クライアントを維持しつつアクセスポイント化する方法でした

Legacy (bullseye) 以前では hostapddnsmasq をインストールして色々設定する必要がありましたが、 NetworkManager を設定するだけで済むのはとても楽になった気がします

現時点では、 Raspberry Pi Imager で Paspberry Pi Zero W/2 W を選択すると Legacy (bullseye) しか選択できないようになっているので、わざわざ bookworm をインストールすることはあまりないとは思いますが、将来 bookworm が Raspberry Pi Zero W/2 W のデフォルト OS になったときには役に立つと思います

というか、そうなったときの自分のために書きました