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 インストール
- Raspberry Pi Imager をPCにインストール
- Raspberry Pi Imager を起動し、以下を選択:
- Device: Raspberry Pi 3
- OS: Raspberry Pi OS (64-bit) または Raspberry Pi OS Lite (64-bit)
- Storage: 対象のmicroSDカード
- ⚙️ 設定アイコンから以下を事前設定(推奨):
- ホスト名
- ユーザー名とパスワード
- SSHを有効化
- 書き込み完了後、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
5 Localisation OptionsL4 WLAN Country-
JP Japanを選択 - 終了して再起動
再起動後に確認:
rfkill list all
Wi-FiがすべてSoft blocked: no になっていればOKです。
Step 5: NetworkManager の確認
systemctl status NetworkManager
nmcli device status
wlan0、wlan1、eth0 がすべて 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.addresses が 192.168.4.1/24 になっていない場合は設定ファイルを修正して再読み込み:
sudo nmcli connection reload
sudo nmcli connection down "RPi-AP" && sudo nmcli connection up "RPi-AP"
まとめ
ハマりポイントをまとめると以下の3点でした。
-
ドライバー:
morrownr/8821au-20210708はカーネル6.12非対応。lwfinger/rtw88を使う -
国コード設定:
raspi-configで必ず設定しないとWi-Fi自体が使えない -
NM managed設定:
/etc/NetworkManager/NetworkManager.confのmanaged=falseがある場合はtrueに変更が必要
NATやDHCPをNetworkManagerのsharedモードに任せることで、iptablesやdnsmasq、hostapdの個別設定が不要になり構成がシンプルになりました。
Discussion