投稿日

ラズパイで作るWi-Fiアクセスポイントとトラフィック計測の実践 ― systemd-networkd 利用

こんにちは、ソラコムのテクノロジー・エバンジェリスト松下(ニックネーム: Max)です。

Raspberry Pi(以下、ラズパイ)を Wi-Fi アクセスポイント化することは、IoT のエッジコンピューティングの開発や通信計測の現場でよくあるケースです。

過去にもラズパイの Wi-Fi アクセスポイント化(ブリッジパターンNAPT パターン)を紹介しましたが、Raspberry Pi OS の 12(bookworm 以降)ではネットワーク管理が systemd ベースになっており、より簡素にできるようになりました。

本記事では、ラズパイの Wi-Fi アクセスポイント化を「ブリッジ(L2)」と「NAPT(L3)」の2パターンを解説します。

全体構成:パターンの選択

2つのパターンにおいて共通の構成としては、ラズパイの Wi-Fi をアクセスポイントとし、インターネットへの出口(バックホール)は有線 LAN とします。また、ネットワーク管理は NetworkManager ではなく systemd-networkd を利用します。その上で、用途に合わせて以下のいずれかの構成を選択します。

1. ブリッジパターン(L2ブリッジ)

有線LAN(eth0)とWi-Fi(wlan0)を仮想ブリッジ(br0)で結合します。

  • メリット: Wi-Fi 端末が上位ルーターから直接 IP アドレス を取得するため、既存ネットワークと同じセグメントで通信可能。
  • デメリット: 接続端末毎に IP アドレスが必要。

2. NAPTパターン(L3ルーター)

ラズパイをルーターとして動作させ、eth0wlan0 を別セグメントにします。

  • メリット: Wi-Fi 側のネットワークを独立させることができ、上位ネットワーク側の IP アドレス消費が1つで済む。
  • デメリット: 二重ルーター構成になる。

構築手順

Raspberry Pi 自体のインストールやセットアップは割愛します。

構築時の注意事項

設定作業はラズパイ本体自体で行うのがよいでしょう。作業中の設定変更やミスでネットワークが切断される可能性があるからです。リモートから行う場合は有線 LAN 経由を強くおすすめします(Raspberry Pi Imager での書き込み時に Wi-Fi 設定を入れなければ Wi-Fi は使われません)。

共通手順:不要サービスの停止とインターフェース確認

NetworkManager の干渉を防ぎ、不要なサービスを停止します。

cat << _EOT_ | sudo tee /etc/NetworkManager/conf.d/99-unmanaged-devices.conf
[keyfile]
unmanaged-devices=interface-name:eth0;interface-name:wlan0;interface-name:br0
_EOT_

sudo systemctl restart NetworkManager
sudo systemctl mask wpa_supplicant
sudo systemctl disable --now dhcpcd

NetworkManager に、管理対象外のネットワークインターフェースを指定して、再読み込みします。さらに、wpa_supplicant と dhcpcd を停止しておきます(dhcpcd はインストールされていない場合もあるため失敗する可能性もありますが無視してかまいません)。

ネットワークインターフェースの確認コマンドは networkctl(8)status サブコマンドです。都度使っていきましょう。

$ networkctl status eth0
...(略)...
                    Address: 192.168.4.118 (DHCPv4 via 192.168.4.254)
                              fd24:9eed:b2cd:4a67:ba27:ebff:fee6:bf8c
                              fe80::ba27:ebff:fee6:bf8c
...(略)...
Jan 11 13:58:37 hostapd systemd-networkd[1883]: eth0: Found matching .network file, based on potentially unpredictable interface nam>
Jan 11 13:58:37 hostapd systemd-networkd[1883]: eth0: Configuring with /etc/systemd/network/10-eth0.network.
Jan 11 13:58:37 hostapd systemd-networkd[1883]: eth0: DHCPv4 address 192.168.4.118/24, gateway 192.168.4.254 acquired from 192.168.4>
Jan 11 14:00:36 hostapd systemd-networkd[1922]: eth0: Link UP

ここからは採用パターンによって分岐します。

ブリッジパターン(L2ブリッジ)

eth0wlan0 を接続する br0 を作成と、eth0br0 に参加させます。なお、この時点では wlan0br0 に参加させる設定はしません。wlan0br0 に参加させるのは、後述の hostapd です。

cat << _EOT_ | sudo tee /etc/systemd/network/10-br0.netdev
[NetDev]
Name=br0
Kind=bridge
_EOT_

cat << _EOT_ | sudo tee /etc/systemd/network/10-br0.network
[Match]
Name=br0
[Network]
DHCP=yes
ConfigureWithoutCarrier=yes
_EOT_

cat << _EOT_ | sudo tee /etc/systemd/network/10-eth0.network
[Match]
Name=eth0
[Network]
Bridge=br0
_EOT_

sudo systemctl enable systemd-networkd
sudo systemctl restart systemd-networkd

sudo systemctl restart systemd-networkd の直後、 eth0 への割り当て IP アドレスが解放されて br0 に IP アドレスが割り当てとなります。DHCP 環境の場合はアドレス変更となる可能性があるため、その場合は SSH 接続が切れます。リモートからのセットアップ時には特に気を付けてください。

ブリッジの確認は bridge(8)link サブコマンドでできます。

$ bridge link show master br0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 19

手順のポイント

10-br0.networkConfigureWithoutCarrier=yes は必須です。これを忘れると再起動時に br0 が作られず、ネットワーク接続ができなくなる可能性があるからです。ブリッジのデフォルト挙動eth0 の準備完了(例えば IP アドレス取得)後に br0 が立ち上がるのですが、eth0br0 内なので DHCP=yes にしてたりすると eth0 の準備が完了せず、 br0 が立ち上がらないためです。

br0 を固定 IP アドレスにしたければ 10-br0.network[Network] を以下のようにします。その際も ConfigureWithoutCarrier=yes にすることをおすすめします。

[Network]
DHCP=no
Address=192.168.1.100/24
Gateway=192.168.1.1
DNS=192.168.1.1
DNS=8.8.8.8
ConfigureWithoutCarrier=yes

ブリッジパターンの設定は以上です。引き続き hostapd の設定をします。

NAPTパターン(L3ルーター)

eth0wlan0 の設定を行います。

cat << _EOT_ | sudo tee /etc/systemd/network/10-wlan0.network
[Match]
Name=wlan0
[Network]
Address=192.168.200.1/24
DHCPServer=yes
IPMasquerade=ipv4
[DHCPServer]
DNS=8.8.8.8
DNS=1.1.1.1
_EOT_

cat << _EOT_ | sudo tee /etc/systemd/network/10-eth0.network
[Match]
Name=eth0
[Network]
DHCP=yes
IPForward=yes
_EOT_

sudo systemctl enable systemd-networkd
sudo systemctl restart systemd-networkd

確認は networkctl(8) で行えます。

手順のポイント

DHCP サーバーは systemd-networkd 内蔵のサーバーを利用します。配布 DNS サーバーアドレスは手書きしています。例のように DNS=複数指定可能です。eth0 が持ってる DNS サーバーアドレスを使いたいなら systemd-resolved を使うようにしてください(ここでは割愛します)。

10-eth0.networkIPForward=yes は必須です。これを設定するとカーネルパラメーターの net.ipv4.ip_forward1(= 転送可)にしてくれます。sysctl(8) の手動実行は不要です。

eth0 の IP アドレスを固定化したいときは、ブリッジパターンで紹介している 10-br0.network を参考に 10-eth0.network[Network] を記載してください。その際 IPForward=yes を必ず入れるようにしましょう。

共通手順:hostapd

Wi-Fi アクセスポイントとなる hostapd のインストールから設定手順です。この設定で

  • SSID= traffic_monitoring0
  • WPA2-PSK/パスフレーズ= TrafficMonitor0

というアクセスポイントが立ち上がります。

なお、これはブリッジパターンの時の設定です。NAPT パターンの場合は後述の「NAPT パターン時の hostapd.conf 設定ポイント」をご覧ください。

sudo apt install -y hostapd

cat << _EOT_ | sudo tee /etc/hostapd/hostapd.conf
ssid=traffic_monitoring0
wpa_passphrase=TrafficMonitor0
channel=3

interface=wlan0
bridge=br0
driver=nl80211
hw_mode=g
ieee80211n=1
country_code=JP
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
_EOT_

sudo chmod 600 /etc/hostapd/hostapd.conf
sudo systemctl unmask hostapd

cat << _EOT_ | sudo SYSTEMD_EDITOR=tee systemctl edit hostapd.service
[Unit]
BindsTo=sys-subsystem-net-devices-wlan0.device
[Service]
ExecStartPre=/usr/sbin/rfkill unblock wlan
_EOT_

sudo systemctl enable hostapd.service
sudo systemctl start hostapd.service

ブリッジパターンであれば bridge(8)br0eth0wlan0 が参加しているのがわかります。

$ bridge link show master br0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 19
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 100

NAPT パターン時の hostapd.conf 設定ポイント

NAPT パターンでは hostapd.conf の中の bridge=br0 という行を削除してください。それ以外はブリッジパターンと共通です。書いてある場合、hostapd の起動に失敗します。hostapd.conf の当該行を削除してから sudo systemctl restart hostapd として hostapd を再起動してください。

手順のポイント

hostapd.conf の設定項目はこちらを見るのがよいでしょう。

wpa_passphrase は平文です。 wpa_passphrase(8) コマンドで難読化(暗号化ではない)できますが、あくまで難読化です。まずは sudo chmod 600 /etc/hostapd/hostapd.conf といった基礎をやっておきましょう。

hostapd.service で hostapd 起動前に rfkill(8)rfkill unblock wlan と実行するようにしています。これを忘れると Wi-Fi インターフェースが使えない場合があります。必ず実行するようにしましょう。また、wlan0 の存在に紐づいて hostapd が起動するようにしています(linkのup/downではないので注意)。

トラフィック計測

ブリッジパターン、もしくは NAPT パターンによるアクセスポイント化ができれば eth0wlan0 を対象にトラフィック計測ができるようになります。

pmacct による流量計測

pmacct はトラフィック計測ソフトウェアです。例えば以下のようにすると、Wi-Fiアクセスポイントとして構成されている wlan0 インターフェースを通過したトラフィック(通信量)を計測できます。

sudo apt install -y pmacct
sudo pmacctd -P print -r 10 -i wlan0 -c src_host,dst_host,dst_port

10秒毎に、以下のように画面へ出力されます。

SRC_IP                                         DST_IP                                         DST_PORT  PACKETS               BYTES
192.168.4.107                                  255.255.255.255                                9478      1                     68
192.168.4.200                                  224.0.0.251                                    5353      2                     178
192.168.4.107                                  224.0.0.251                                    5353      7                     3803
fe80::ea2e:8f0:f386:7b10                       ff02::fb                                       5353      7                     3943
192.168.4.117                                  224.0.0.22                                     0         3                     120
fe80::4ee:fcff:fe38:f427                       ff02::16                                       0         3                     228
192.168.4.117                                  224.0.0.251                                    5353      4                     536
fe80::4ee:fcff:fe38:f427                       ff02::fb                                       5353      4                     616

ここでは単純に画面に表示するようにしましたが、pmacct は SQLite といった DB 保存もサポートしています。詳細はトラフィック計測ツール “pmacct” の結果をSQLiteに保存するをご覧ください。

tcpdump/Wireshark でトラフィックを確認する

トラフィックの確認なら tcpdump(8) でパケットを取得し、Wireshark といったツールで見るというのが良いでしょう。ラズパイ上で以下のように tcpdump を実行して pcap ファイルを作成します。

sudo tcpdump -i wlan0 -s 0 -n -w packet.pcap
# 終了は CTRL+C

得られた pcap ファイルを Wireshark で開くと、以下のように確認できます。

セルラー通信側のトラフィック確認なら「SORACOM Peek」

ここではWi-Fiデバイスのトラフィックをラズパイ上で計測する方法を紹介しました。
IoTにおいては、Wi-Fi以外にもLTEや5Gといったセルラー通信も利用されます。その場合は、SORACOMプラットフォーム上でIPパケットをキャプチャできる「SORACOM Peek(ピーク)」をご利用ください。

SORACOM PeekはSIM(=通信回線)単位、もしくはVPG(=ネットワーク)単位でキャプチャができ、そのフォーマットは pcap 形式であるため、先ほど紹介したWiresharkで解析できます。

詳細はオンデマンドパケットキャプチャ「SORACOM Peek」をご覧ください。

まとめ

Raspberry Pi OS(12 / bookworm 以降)における、Wi-Fi アクセスポイント構築手順と、トラフィック計測について紹介しました。systemd を使うことでより簡潔になります。しかし、再起動時にも安全に起動するテクニックは試してみないとわからない部分が多いため、 Tips として共有しました。

トラフィックが見えることで開発が進みやすかったり、またトラブル解消につながります。このような環境を持っておくことで安定的なIoTシステム構築ができるのではないでしょうか。

― ソラコム松下 (Max)