Raspberry Pi 4をWi-Fiルーター化してLTE回線でインターネットに接続させてみました。
LTE回線の通信はメカトラックス社様からお借りしたラズパイ用の4G通信モジュール「4GPi」を使用しています。
##環境
・Raspberry Pi 4 Model B
※OS は Raspbian (Buster) をインストール済み
・4GPi
・SIMカード※1
・SIMカードアダプター(Nano-SIMを標準SIMに変換するアダプター)
・作業PC(Tera Termインストール済み)
・Wi-Fi環境※2
(※1)個人のスマホから抜いたNano-SIMを使用しました。
(※2)ラズパイに4GPiモジュールをインストールするまで使用します。
##構築の流れ
- 4GPiのインストール
- IPアドレスの固定化
- DHCPサービス設定
- Wi-Fi アクセスポイント設定
- IPフォワードの有効化
- iptablesによるルーティング設定
- MTU、MSS値のチューニング
##1. 4GPiのインストール
こちらの記事の#1、#4を参考に、ラズパイに4GPiをインストールします。
ラズパイからLTE通信でインターネットに接続できたら、ラズパイのWi-Fi接続を切断します。
##2. IPアドレスの固定化
ラズパイのwlan0(Wi-Fiアクセスポイント側)のIPアドレスを固定化します。
- /etc/dhcpcd.confを編集します。nohook wpa_supplicantでWi-Fiクライアントのサービスを無効化してます。
interface wlan0
static ip_address=192.168.110.7/24
nohook wpa_supplicant
static routers=
static domain_name_servers=
static domain_search=
- ワイヤレスデバイスのブロックを解除します。
Wireless LANのSoft blockedが「no」になっていればOKです。
$ rfkill unblock wifi
$
$ sudo rfkill list
0: phy0: Wireless LAN
Soft blocked: no
Hard blocked: no
1: hci0: Bluetooth
Soft blocked: no
Hard blocked: no
- dhcpcd を再起動してエラーが出力されないことを確認します。
$ sudo systemctl restart dhcpcd
$
##3. DHCPサービス設定
- Raspbianにdnsmasqをインストールします。
$ sudo apt-get install dnsmasq
- /etc/dnsmasq.confを編集してDHCPのレンジを決定します。ここでは192.168.110.10~192.168.110.20を指定しました。
interface=wlan0
dhcp-range=192.168.110.10,192.168.110.20,255.255.255.0,24h
- dnsmasqサービスを起動してエラーが出力されないことを確認します。
$ sudo systemctl start dnsmasq
$ sudo systemctl enable dnsmasq
##4. Wi-Fi アクセスポイント設定
- Raspbianにhostapd をインストールします。
$ sudo apt-get install hostapd
- /etc/hostapd/hostapd.confを編集してWi-FiのSSID(ssid)とパスワード(wpa_passphrase)を設定します。
interface=wlan0
driver=nl80211
ssid=testssid01 ← ここを編集
hw_mode=g
channel=6
wmm_enabled=0
macaddr_acl=0
auth_algs=1
wpa=2
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
wpa_passphrase=testpassword01 ← ここを編集
- /etc/default/hostapdを編集して、サービス起動時にhostapd.confを読み込ませます。
DAEMON_CONF="/etc/hostapd/hostapd.conf"
- hostapdをunmaskしてサービスを起動します。
$ sudo systemctl unmask hostapd
$ sudo systemctl enable hostapd
$ sudo systemctl start hostapd
##5. IPフォワードの有効化
- /etc/sysctl.confを編集してIPフォワードを有効化します。
net.ipv4.ip_forward=1
##6. iptablesによるルーティング設定
Rasbianのファイアウォールを設定します。
- iptablesを設定します。
・1~3行目はiptables設定のリセット
・4行目は作業端末からwlan0へのSSH接続を許可するための定義
・5行目はwlan0に入力された通信をwwan0に出力するための定義
・6行目は接続が確立(ESTABLISHED)している通信を許可するための定義
・7行目はwwan0に対するIPマスカレードの定義
$ sudo iptables -t nat -F
$ sudo iptables -t filter -F
$ sudo iptables -t mangle -F
$ sudo iptables -A INPUT -i wlan0 -p tcp -m state --state NEW,ESTABLISHED,RELATED --dport 22 -j ACCEPT
$ sudo iptables -A FORWARD -i wlan0 -o wwan0 -j ACCEPT
$ sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$ sudo iptables -t nat -A POSTROUTING -o wwan0 -j MASQUERADE
- iptablesの設定を/etc/iptables.ipv4.natに保存します。
$ sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
- /etc/rc.localに下記の行を追記して、OS再起動時にiptablesの定義ファイルが読み込まれるようにします。
iptables-restore < /etc/iptables.ipv4.nat
- Raspbianを再起動します。
$ sudo reboot
- 再起動後に作業端末から#4で作成したアクセスポイントに無事接続でき、www.yahoo.co.jpにpingで疎通できるようになりました。
- 但し、ブラウザからYahooページを表示できないため次項#7の設定を実施します。
7. MTU、MSS値のチューニング
ブラウザや特定アプリのインターネット接続に失敗する場合はWi-Fiルーターの下記の何れかを設定することで改善する可能性があります。
・RaspbianのMTU(Maximum Transmission Unit)値を変更する
・iptablesのTCP MSS(Maximum Segment Size)値を定義する
7.1 RaspbianのMTU値を変更する
MTUは隣接したネットワークに一度に送信できるパケットの最大サイズです。Wi-FiルーターのMTU値が経路上のNW機器群のMTU値より大きいとWi-Fiルーターから送信されたパケットが送信先に到達しない可能性があります。
- 作業端末のコマンドプロンプトを起動し、www.yahoo.co.jpにpingを実行します。下記の例ではpingで一度に送信できるパケットサイズの最大値が1392バイトのため、MTU値の最適値は1392バイトにヘッダの28バイトを加えた1420バイトです。この場合、1421バイト以上のパケットは通過できない可能性があります。詳細はこちらのサイトを参照してください。
- 現在のwlan0のMTU値は1500なので、1420バイト以下になるように設定します。
- 試しに、/etc/rc.localに下記の行を追記してwlan0のMTU値が1200になるように定義します。
ifconfig wlan0 mtu 1200
- Raspbianを再起動します。
$ sudo reboot
- wlan0のMTU値が1200になっています。
- Yahooのページが問題なく表示されました。
7.2 iptablesのTCP MSS値を定義する
作業PCのブラウザからYahooページへのアクセス時に、作業PCとYahooサーバー間のTCP 3ウェイハンドシェイクでMSS(Maximum Segment Size)値を調整します。MSSはTCPレイヤーで格納するデータの最大サイズです。MSS値の調整が完了すると、作業PCは調整したMSS値のサイズのパケットをYahooサーバーに送信します。このTCP 3ウェイハンドシェイクで調整されるMSS値は、中継するWi-Fiルーター側で書き換えることが可能です。
- iptablesにTCP 3ウェイハンドシェイクで使用するMSS値を定義します。
具体的な数値を定義できますが、ここではMSS値を自動調整するオプション(--clamp-mss-to-pmtu)を入れます。
$ sudo iptables -t mangle -A FORWARD -o wlan0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
$ sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
$ sudo cat /etc/iptables.ipv4.nat
- Yahooページが問題なく表示されました。
- Wiresharkのパケットの中身を確認してみます。
【自動調整オプション定義前】インターネット接続NGの時は、作業PCからYahooサーバーへの通知は「MSS=1460」、Yahooサーバーから作業PCへの通知は「MSS=1394」です。
【自動調整オプション定義後】インターネット接続OKの時は、Yahooサーバーから作業PCへの通知が「MSS=1380」となっているので、自動調整オプションによりMSS値が調整されていることが分かります。なお、Len=1380はパケットが1380バイトに分割されていることを示します。
7.3 【補足】ルーターのパケット受信時の挙動
- 「MTU値がルーターA>ルーターB」且つ「パケットのDF(Don't Fragment)ビットが1」の場合、ルーターAから送信されたパケットはルーターBを通過できない。
- ルーターは自身のMTU値より大きなパケットを分割して送信する機能を有するが、スループットが低下するので分割禁止(DF=1)にされていることが多い。
- 「DF=1」のルーターはPath MTU Discovery機能によりパケットサイズを自動調整する。Path MTU Discoveryは、ルーターが自身のMTU値より大きなサイズのパケットを受信すると、当該パケットを破棄し、送信元に対して「サイズを調整したパケットの再送要求」を送信する。
- Path MTU Discoveryの再送要求はICMP(Type 3 Code 4)を送信元ホストへ送信することで成立するが、経路上の中継ルータがICMPをブロックしているとパケットサイズが調整できない(ブラックホール問題)。
- 「DFビット=1」且つ「Path MTU Discovery機能が利用不可」の場合は、下記①②の何れか方法で問題を回避できる。
①外側のルーターほどMTU値を小さくする。例えば、データの流れが「送信元⇒A⇒B⇒C⇒D⇒E⇒送信先」の場合、MTU値は「A<B<C>D>E」とする。(#7-1参照)
②送信元と送信先のTCP 3ウェイハンドシェイクでネゴされるMSS値を中継ルーター側で調整する。(#7-2参照)
最後に
Raspberry Pi 4をWi-Fiルーター化して4GPiのLTE回線で通信させる場合は、Wi-FiルーターのNWインタフェース(wlan0)のMTU値の調整が必要となりますのでご注意ください。