Raspberry Pi OS Lite on Raspberry Pi Zero 2 WをLTE接続してWi-Fiルータにする

# 作った物
LTEでインターネット接続するWiFiルータ。
モバイルルータとは違いバッテリーが接続されて「いない」ので、主電源が通電中のみ動作する。
車載してシガーソケット等からUSB給電し、IG-ON時のみインターネットに繋がるインフラを提供したいときに使う(例えば、GPSでの測位位置をクラウドサービスに打ち上げる等)。
![001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/ebc2502e-f11e-15c3-0092-9c720cc43223.png)
![002.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/ebe04752-bc54-2454-7f37-8fa8d992c23c.png)

# 用意した物

1. Raspberry Pi OS Lite (32-bit) が書き込まれたmicroSDカード(SDXC) 64GB
    * 執筆時点のリリース日時：2022-09-22
1. Raspberry Pi Zero 2 W (RPiZero2w)
1. Docomo L-02C
    * IIJ Mioで契約したSIMカードを挿入
1. RPiZero2wとL-02Cを接続する手段
    * mincro USB Type B-USB Type Aケーブル
1. セットアップ時に必要な機器
    * USBハブ
    * USB接続可能なキーボード
    * HDMIディスプレイ
    * RPiZero2wとHDMIディスプレイを接続する手段
        * MiniHDMI-HDMIケーブル
    * 動作確認用のスマートフォン
    * [オプション] USB接続のLANアダプター
        * SSH接続で他のPCからログインして作業する場合に接続する(ターミナル越しにコピー＆ペーストができると作業性が上がる)
        * 最終段階では外しておかないと、パケット転送できなくてWiFiクライアントからインターネット接続できなくなるので注意が必要

# 実行したこと

## 機器を接続する
![003.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/c855232e-644c-b565-534e-c7d21973d98f.png)

## システムを最新状態にする
```
sudo apt update
sudo apt dist-upgrade -y
```

## L-02Cを固定デバイスとして認識させるようにする
L-02Cに対して/dev/usbmodemからシンボリックリンクを張るように設定する。
```
sudo tee /etc/udev/rules.d/95-l-02c.rules << EOF
KERNEL=="ttyUSB[0-9]*", SUBSYSTEM=="tty", ATTRS{bInterfaceNumber}=="02", ATTRS{../idVendor}=="1004", ATTRS{../idProduct}=="618f", SYMLINK+="usbmodem"
```
Ctrl+Dで抜ける。
念のため再起動しておく。
```
reboot
```

## LTE接続を設定する(wvdialのセットアップ)
wvdialをインストールする。
```
sudo apt install -y wvdial
```
wvdialの設定ファイルをバックアップする。
```
sudo cp /etc/wvdial.conf /etc/wvdial.conf.default
```
wvdialの設定ファイルを、IIJmioを使えるように生成する。
```
sudo tee /etc/wvdial.conf << EOF
[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0 
Init3 = AT+CGDCONT=1,"IP","iijmio.jp"
Dial Attempts = 3
Stupid Mode = 1
Modem Type = Analog Modem
Dial Command = ATD
Stupid Mode = yes
Baud = 460800
New PPPD = yes
APN = iijmio.jp
Modem = /dev/ttyUSB2
ISDN = 0
Phone = *99#
Password = iij
Username = mio@iij
Carrier Check = no
```
Ctrl+Dで抜ける。
wvdialを遅延起動するスクリプトを/usr/local/bin/wvdialとして作成する。
```
sudo tee /usr/local/bin/wvdial << EOF
#!/bin/sh

sleep 30
/usr/bin/wvdial 
```
Ctrl+Dで抜ける。
/usr/local/bin/wvdialに実行権を付与する。
```
sudo chomod +x /usr/bin/wvdial 
```
wvdialをsystemdでサービスとして起動する設定ファイルを生成する。
```
sudo tee /etc/systemd/system/wvdial.service << EOF
[Unit]
Description=wvdial service
Wants=network.target
 
[Service]
ExecStart=/usr/local/bin/wvdial
ExecStop=/bin/kill -HUP $MAINPID
Type=simple
Restart = always
StartLimitBurst=0
 
[Install]
WantedBy=multi-user.target
```
Ctrl+Dで抜ける。
wvdialをサービスとして起動する。
```
sudo systemctl daemon-reload
sudo systemctl start wvdial.service
```
60秒後にサービスのステータスを表示させて、動作確認する。
```
sleep 60; sudo systemctl status wvdial.service
```
以下のような表示になれば、接続はできている(xxx.xxx.xxx.xxxには適切なIPアドレスが入る)。表示後は"q"キーで抜ける。
```
● wvdial.service - wvdial service
     Loaded: loaded (/etc/systemd/system/wvdial.service; disabled; vendor preset: enabled)
     Active: active (running) since Mon 2023-01-02 07:09:22 GMT; 40s ago
   Main PID: 785 (wvdial)
      Tasks: 3 (limit: 407)
        CPU: 380ms
     CGroup: /system.slice/wvdial.service
             ├─785 /bin/sh /usr/local/bin/wvdial
             ├─795 /usr/bin/wvdial
             └─796 /usr/sbin/pppd 460800 modem crtscts defaultroute usehostname -detach user mio@iij >

Jan 02 07:09:54 vehicle-gw pppd[796]: Could not determine remote IP address: defaulting to 10.64.64.64
Jan 02 07:09:54 vehicle-gw pppd[796]: not replacing default route to eth0 [192.168.0.1]
Jan 02 07:09:54 vehicle-gw pppd[796]: local  IP address xxx.xxx.xxx.xxx
Jan 02 07:09:54 vehicle-gw pppd[796]: remote IP address xxx.xxx.xxx.xxx
Jan 02 07:09:54 vehicle-gw pppd[796]: primary   DNS address xxx.xxx.xxx.xxx
Jan 02 07:09:54 vehicle-gw pppd[796]: secondary DNS address xxx.xxx.xxx.xxx
Jan 02 07:09:54 vehicle-gw wvdial[795]: --> local  IP address xxx.xxx.xxx.xxx
Jan 02 07:09:54 vehicle-gw wvdial[795]: --> remote IP address xxx.xxx.xxx.xxx
Jan 02 07:09:54 vehicle-gw wvdial[795]: --> primary   DNS address xxx.xxx.xxx.xxx
```
wvdialが自動起動するように設定する。
```
sudo systemctl enable wvdial.service
```
## ルータとして機能するように設定する
### 必要なパッケージのインストール
```
sudo DEBIAN_FRONTEND=noninteractive apt install -y hostapd dnsmasq netfilter-persistent iptables-persistent
```
### dhcpcdの設定
RPiZero2wのWiFi(wlan0)の親機としてのIPアドレスを、固定アドレスに設定する。ここでは、192.168.111.1とする。
```
sudo tee --append /etc/dhcpcd.conf << EOF
interface wlan0
   static ip_address=192.168.111.1/24
   nohook wpa_supplicant
```
Ctrl+Dで抜ける。
### dnsmasqの設定
WiFi(wlan0)に接続してきたクライアントにDHCPで割り当てるIPアドレスの範囲を指定する。ここでは、192.168.111.2から192.168.111.127とする。
```
sudo tee --append /etc/dnsmasq.d/dnsmasq.conf << EOF
dhcp-range=tag:wlan0,192.168.111.2,192.168.111.127,24h
dhcp-option=tag:wlan0,option:router,192.168.111.1
```
Ctrl+Dで抜ける。
### hostapdの設定
アクセスポイントとしての設定をする。[SSID]にはアクセスポイント名、[PASSPHRASE]にはパスフレーズを、あらかじめ決めて記載する。
```
sudo tee /etc/hostapd/hostapd.conf << EOF
interface=wlan0
country_code=JP
driver=nl80211
ssid=[SSID]
hw_mode=g
channel=6
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=[PASSPHRASE]
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
```
Ctrl+Dで抜ける。
上記のアクセスポイントとしての設定ファイルを、hostapdが読み込むように設定する。
```
sudo tee --append /etc/default/hostapd << EOF
DAEMON_CONF="/etc/hostapd/hostapd.conf"
```
Ctrl+Dで抜ける。
### パケット転送の設定
WiFi(wlan0)で受けたパケットをLTE側に転送するように設定する。
```
sudo sed -i s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/ /etc/sysctl.conf
sudo iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
sudo netfilter-persistent save
```
### サービス周りの設定
dhcpcd、hostaptを再起動する。dnsmasqを自動起動するように設定する。
```
rfkill unblock wifi
sudo systemctl restart dhcpcd
sudo systemctl start dnsmasq
sudo systemctl enable dnsmasq
sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl start hostapd
```
## 動作確認する
L-02CがLTE接続中にwvdialを起動すると失敗することがあるので、一旦、シャットダウンする。
```
sudo shutdown -h now
```
RasPiZero2wの電源を抜いて、もう一度電源を投入する。
ログインして、1分弱待った後に、ネットワークインターフェスとしてppp0が存在し、IPアドレスが取得できていることを確認する。
```
ifconfig
...
ppp0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet xxx.xxx.xxx.xxx  netmask 255.255.255.255  destination 10.64.64.64
...
```
動作確認用のスマートフォンで、設定したSSIDのアクセスポイントが存在することを確認し、設定したパスフレーズで接続できることを確認する。
また、インターネット接続ができることを確認する。
このとき、USBハブにUSB接続のLANアダプターが接続されていると、パケット転送がうまくいかずに、インターネット接続できないため、外しておくようにする。
## 電源を抜いてもシステムが壊れないようにする(システムのReadOnly化)
raspi-configを起動する。
```
sudo raspi-config
```
"Performance Options"を選択する。
![001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/fa315cfc-74ea-86cf-9a91-b9dec8715d83.png)
"P3 Overlay File System"を選択する。
![002.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/99284a01-09ae-f04b-c988-0675703e323f.png)
"\<Yes\>"を選択する。
![003.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/70baefd6-8fe6-6e69-78a5-2eeba7a4b614.png)
"\<Ok\>"を選択する。
![004.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/2ec5c3f9-5a5e-6f7c-a607-a0e371d614f8.png)
"\<Yes\>"を選択する。
![005.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/a7a139b7-862f-18da-9466-339524a380a2.png)
"\<Ok\>"を選択する。
![006.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/6f54ab00-a7b4-d381-248f-5f74e5476f85.png)
"\<Finish\>"を選択する。
![007.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/8b1c499f-6800-c012-b549-60519475d9af.png)
"\<Yes\>"を選択する。
![008.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169654/cd7aec38-0cc9-efc4-3a94-de048acfe767.png)
再起動後、改めて動作確認を行う。

# 参考サイト

https://www.ingenious.jp/articles/howto/raspberry-pi-howto/l-02c/

https://bitware-blog.com/2020/05/25/raspberry-pi%E3%81%A7%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B-wvialhostpad-dnsmasq/

https://www.hiroom2.com/2017/02/18/linux-systemd%E3%81%AEstart-request-repeated-too-quickly-for-xxx-service/

https://letraspberry.hatenablog.com/entry/2021/09/07/232620