📡

Raspberry Pi 3B+をWi-Fiルーター兼APにする(T2U Nano + NetworkManager)

に公開

はじめに

Raspberry Piでhostapdを利用してAPを構築したり、Wi-Fiにぶら下げてルーターにするケースはありますが、
標準で搭載しているI/Fは有線/無線がそれぞれ1つずつの為、同時に構成することは出来ません。
これまで別々に構築したことはありましたが、USB Wi-Fiアダプタを追加して1台にまとめようと思い付き、手順を整理して構築してみました。
手順作成に際してはClaude (Sonnet 4.6)とチャットしながら手順書化してもらいました。
特に「ドライバーの選択」「国コードの設定」「NetworkManagerのmanaged設定」の3点は実際にハマった箇所で、試行錯誤しながら解決した部分です。

構成は以下の通り。

  • TP-Link Archer T2U Nano(USB Wi-Fiアダプタ)で上流APに接続
  • 有線LANと、オンボードWi-Fiで立てたAPにネットワークを共有
  • NATやDHCPの設定はNetworkManagerに任せてシンプルに構成

試行錯誤した部分が多かったので、ハマりポイントも含めて記録しています。

構成概要

[インターネット]
      |
[アクセスポイント] 192.168.1.0/24
      |
[T2U Nano (wlan1)] 192.168.1.x (DHCP取得)
      |
[Raspberry Pi 3B+]
      |
[有線LAN (eth0)] 10.42.0.0/24 ← NM shared(NAT+DHCP自動)
      |
[オンボードWi-Fi (wlan0)] AP モード
      SSID: RPi-AP
      192.168.4.0/24 ← NM shared(NAT+DHCP自動)
インターフェース 役割 IPアドレス
wlan1 (T2U Nano) 上流AP接続(WAN側) 192.168.1.x(DHCP)
eth0 有線LAN(NW共有先) 10.42.0.1/24
wlan0 オンボードWi-Fi AP(RPi-AP) 192.168.4.1/24

NetworkManager shared モードについて

NATやDHCPの設定にはNetworkManagerの ipv4.method shared を使います。これを設定するだけで以下が自動処理されます。

  • IPアドレスの付与
  • IPフォワーディングの有効化
  • NATルール(マスカレード)の設定(nftables経由)
  • dnsmasqによるDHCPサーバーの起動

iptablesやdnsmasqを個別にインストール・設定する必要はありません。

事前準備

必要なもの

  • Raspberry Pi 3B+
  • microSDカード(16GB以上推奨)
  • TP-Link Archer T2U Nano(USB接続)
  • インターネット接続(初期セットアップ時)

T2U Nanoについて

T2U NanoのチップはRTL8811AUです。カーネル6.12時点ではin-kernelドライバーが未対応のため、別途ドライバーのインストールが必要です(カーネル6.14以降でin-kernel対応予定)。

Step 1: Raspberry Pi OS インストール

  1. Raspberry Pi Imager をPCにインストール
  2. Raspberry Pi Imager を起動し、以下を選択:
    • Device: Raspberry Pi 3
    • OS: Raspberry Pi OS (64-bit) または Raspberry Pi OS Lite (64-bit)
    • Storage: 対象のmicroSDカード
  3. ⚙️ 設定アイコンから以下を事前設定(推奨):
    • ホスト名
    • ユーザー名とパスワード
    • SSHを有効化
  4. 書き込み完了後、Raspberry Pi にSDカードを挿入して起動

Step 2: 初期アップデート

sudo apt update && sudo apt full-upgrade -y
sudo reboot

Step 3: T2U Nano ドライバーのインストール

T2U NanoをUSBに挿した状態で以下の手順を実施します。

3-1. ビルド依存パッケージのインストール

sudo apt install -y git build-essential bc
sudo apt install -y linux-headers-$(uname -r)

3-2. ドライバーのクローンとインストール

当初 morrownr/8821au-20210708 を試みましたが、カーネル6.12との非互換(_FW_UNDER_SURVEY 未定義エラー)でビルドに失敗しました。lwfinger/rtw88 を使います。

git clone https://github.com/lwfinger/rtw88.git
cd rtw88
make
sudo make install
sudo reboot

3-3. ドライバー読み込み確認

sudo modprobe rtw_8821au
lsmod | grep rtw_8821au

rtw_8821au が表示されればOKです。

ip link show

wlan1 が追加されていれば認識成功です。

Step 4: 無線LANの国コード設定(重要)

ここを飛ばすとWi-Fiが一切使えません。

Raspberry Pi 3B+は2.4GHz/5GHz両対応モデルですが、規制上の理由から国コードが設定されるまでWi-Fiがrfkillでブロックされます。

sudo raspi-config
  1. 5 Localisation Options
  2. L4 WLAN Country
  3. JP Japan を選択
  4. 終了して再起動

再起動後に確認:

rfkill list all

Wi-FiがすべてSoft blocked: no になっていればOKです。

Step 5: NetworkManager の確認

systemctl status NetworkManager
nmcli device status

wlan0wlan1eth0 がすべて unmanaged 以外の状態(disconnected など)で表示されることを確認します。

Step 6: 周辺APの使用チャネル確認

Step 9でwlan0をAPモードで設定する際にチャネルを指定する必要があります。wlan1を上流APに接続した後はスキャンができなくなるため、接続前のこのタイミングで確認しておきます。

sudo iw dev wlan1 scan | grep -E "SSID|channel|freq"

5GHz帯のチャネル選択基準

チャネル範囲 区分 推奨度
36〜48(UNII-1) DFS不要・屋内専用 ◎ 最優先
52〜64(UNII-2A) DFS対象 △ 安定性が下がる場合あり
100〜144(UNII-2C) DFS対象 △ 安定性が下がる場合あり
149〜165(UNII-3) 日本国内使用不可 ✗ 使用禁止

まずUNII-1(36・40・44・48)の中から周辺APが使用していないチャネルを選択してください。DFS対象チャネル(52〜144)は気象レーダー等を検知すると自動的にチャネル変更または停波するため、安定運用を優先する場合は避けてください。

Step 7: T2U Nano (wlan1) をアクセスポイントに接続

nmcli コマンドでパスワードを指定するとコマンド履歴に残るため、設定ファイルを直接作成する方式を採用します。
設定ファイルにはPSKを平文で記載するため、作成後すぐに chmod 600 でアクセス権限を制限することが重要です

sudo nano /etc/NetworkManager/system-connections/upstream-ap.nmconnection
[connection]
id=upstream-ap
type=wifi
interface-name=wlan1
autoconnect=yes

[wifi]
mode=infrastructure
ssid=上流APのSSID
powersave=2

[wifi-security]
key-mgmt=wpa-psk
psk=パスワード

[ipv4]
method=auto

[ipv6]
method=disabled

powersave=2 はWi-Fiのパワーセーブ機能を無効化する設定です。アイドル時に上流APへの疎通が切れる問題の対策として設定しています。

sudo chmod 600 /etc/NetworkManager/system-connections/upstream-ap.nmconnection
sudo nmcli connection reload
sudo nmcli connection up upstream-ap

接続確認:

nmcli connection show --active
ip addr show wlan1

wlan1 に 192.168.1.x のIPが割り当てられていれば成功です。

Step 8: 有線LAN (eth0) の共有設定

sudo nmcli connection add \
  type ethernet \
  ifname eth0 \
  con-name "eth0-shared" \
  ipv4.method shared \
  connection.autoconnect yes

sudo nmcli connection up "eth0-shared"

確認:

ip addr show eth0

10.42.0.x/24 系のIPが付与されていれば成功です。

Step 9: オンボードWi-Fi (wlan0) をAPモードで設定

sudo nano /etc/NetworkManager/system-connections/RPi-AP.nmconnection
[connection]
id=RPi-AP
type=wifi
interface-name=wlan0
autoconnect=yes

[wifi]
mode=ap
ssid=RPi-AP
band=a
channel=36
powersave=2

[wifi-security]
key-mgmt=wpa-psk
psk=任意のパスワード(8文字以上)

[ipv4]
method=shared
address1=192.168.4.1/24

[ipv6]
method=disabled

band=a が5GHz指定です。Step 6で確認した空きチャネルを指定します。
2.4GHzで運用する場合は band=bg に変更し、channel は1・6・11から空きを選択してください。

sudo chmod 600 /etc/NetworkManager/system-connections/RPi-AP.nmconnection
sudo nmcli connection reload
sudo nmcli connection up RPi-AP

確認:

iw dev wlan0 info

type AP と表示されれば成功です。

Step 10: 最終確認

ip addr show
IF 期待するIP
wlan1 192.168.1.x(DHCP)
eth0 10.42.0.1/24
wlan0 192.168.4.1/24
# ルーティング確認(デフォルトGWがwlan1経由であること)
ip route show

# NATルール確認(masqueradeが表示されること)
sudo nft list ruleset

# 外部疎通確認
ping -c 3 8.8.8.8

おまけ: wlan1接続監視スクリプト

powersaveを無効化してもアイドル後に上流APへの疎通が切れることがありました。原因としては以下が考えられます。

  • 上流AP側のクライアントアイドルタイムアウト
  • ARPテーブルの期限切れ
  • out-of-kernelドライバーの長時間アイドル時のバグ

根本原因は特定できていませんが、workaroundとして1時間ごとに疎通確認してNGならdown→upする監視スクリプトをsystemdで動かしています。

スクリプト

sudo nano /usr/local/bin/wlan1-watchdog.sh
#!/bin/bash

IFACE="wlan1"
CONNECTION="upstream-ap"
GATEWAY=$(ip route show dev "$IFACE" | awk '/default/ {print $3}')
PING_TIMEOUT=5
PING_COUNT=3
LOG_TAG="wlan1-watchdog"

if [ -z "$GATEWAY" ]; then
    GATEWAY="192.168.1.1"
fi

logger -t "$LOG_TAG" "Checking connectivity to $GATEWAY via $IFACE"

if ping -c "$PING_COUNT" -W "$PING_TIMEOUT" -I "$IFACE" "$GATEWAY" > /dev/null 2>&1; then
    logger -t "$LOG_TAG" "OK: $IFACE is reachable"
else
    logger -t "$LOG_TAG" "WARN: $IFACE unreachable, attempting reconnect..."
    nmcli connection down "$CONNECTION"
    sleep 3
    nmcli connection up "$CONNECTION"

    sleep 5
    if ping -c "$PING_COUNT" -W "$PING_TIMEOUT" -I "$IFACE" "$GATEWAY" > /dev/null 2>&1; then
        logger -t "$LOG_TAG" "OK: Reconnect succeeded"
    else
        logger -t "$LOG_TAG" "ERROR: Reconnect failed"
    fi
fi
sudo chmod 755 /usr/local/bin/wlan1-watchdog.sh

systemdユニットファイル

sudo nano /etc/systemd/system/wlan1-watchdog.service
[Unit]
Description=wlan1 Connection Watchdog
After=network.target NetworkManager.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/wlan1-watchdog.sh
sudo nano /etc/systemd/system/wlan1-watchdog.timer
[Unit]
Description=wlan1 Connection Watchdog Timer

[Timer]
OnBootSec=5min
OnUnitActiveSec=1h

[Install]
WantedBy=timers.target

有効化

sudo systemctl daemon-reload
sudo systemctl enable --now wlan1-watchdog.timer

ログの確認:

journalctl -t wlan1-watchdog

トラブルシューティング

T2U Nanoが認識されない

lsusb | grep Realtek
sudo journalctl -f

journalctl -f を実行した状態でT2U NanoをUSBに挿し、認識ログを確認します。

ドライバーが読み込まれていない場合:

sudo modprobe rtw_8821au

カーネルアップデート後にT2U Nanoが動かなくなった

cd ~/rtw88
make
sudo make install
sudo reboot

Wi-FiがrfkillでブロックされてNMがunavailableになる

Step 4の手順で国コードを設定してください。設定済みでもブロックされる場合:

sudo rfkill unblock all

NetworkManagerがwlan0/wlan1をunavailableとして扱う(managed設定)

rfkillのブロックが解消されているにもかかわらずunavailableのままの場合、/etc/NetworkManager/NetworkManager.conf の設定が原因の可能性があります。

cat /etc/NetworkManager/NetworkManager.conf

[ifupdown] セクションに managed=false がある場合は true に変更します。

sudo sed -i 's/managed=false/managed=true/' /etc/NetworkManager/NetworkManager.conf
sudo systemctl restart NetworkManager

APに接続できるがインターネットに出られない

sudo nft list ruleset
cat /proc/sys/net/ipv4/ip_forward   # 1 であること

wlan0 APのクライアントに配布されるIPが 10.42.x.x になってしまう

nmcli connection show "RPi-AP" | grep ipv4

ipv4.addresses192.168.4.1/24 になっていない場合は設定ファイルを修正して再読み込み:

sudo nmcli connection reload
sudo nmcli connection down "RPi-AP" && sudo nmcli connection up "RPi-AP"

まとめ

ハマりポイントをまとめると以下の3点でした。

  1. ドライバー: morrownr/8821au-20210708 はカーネル6.12非対応。lwfinger/rtw88 を使う
  2. 国コード設定: raspi-config で必ず設定しないとWi-Fi自体が使えない
  3. NM managed設定: /etc/NetworkManager/NetworkManager.confmanaged=false がある場合は true に変更が必要

NATやDHCPをNetworkManagerのsharedモードに任せることで、iptablesやdnsmasq、hostapdの個別設定が不要になり構成がシンプルになりました。

Accenture Japan (有志)

Discussion