ラズパイ+4GPiでLTEルータを作る（Wi-Fi・有線LAN 両対応）

今回はラズパイ+4GPiを使用して、Wi-Fi端末・有線LAN端末の両方で使えるLTEルータを作ってみます。

概要図
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1283849/e35360e6-185e-f239-9349-1deef7b3c4f7.png" width=70%>

# 用意するもの
* Raspberry Pi
* [4GPi（ラズパイ用4G LTE通信モジュール）](https://mechatrax.com/products/4gpi/)
* SIMカード（今回はSORACOMのSIMを使用）
* [ACアダプタ(ラズパイ+4GPiの電力供給用 12V2A)](https://store.mechatrax.com/product.php?id=12)
* Micro SDカード
* PC（Windows10）

# 準備

## OSイメージ書き込み
今回は最新の4GPiのOSイメージ([4gpi-bookworm-lite-arm64-20240319.img.xz](https://mechatrax.com/data/4gpi/))を使用しました。
4GPiのOSイメージは公式のRaspberry Pi OSを元に作られたOSイメージで、必要なパッケージが含まれています。
OSイメージの書き込み方法については下の記事で紹介しています。

https://qiita.com/kiyonaga/items/73fa842ddcde0e028294

## ラズパイに4GPi（+SIMカード）を接続

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1283849/fe14127f-c0e3-67ba-f646-f0d24d605717.jpeg" width=50%>

上の写真のような感じでラズパイの上に4GPiを接続します※。
4GPiからGPIO経由でラズパイに電力供給されます。
ラズパイが起動したらログインします。

※上の写真ではログインするために UART接続をしています。

https://qiita.com/hayat00/items/0d586f5500e998ab4d2e


# LTEルータ作成手順

## ラズパイを4G(LTE)回線でインターネットに接続
コマンド一つで4G(LTE)通信ができるようになります（詳細は[こちら](https://github.com/mechatrax/4gpi/wiki/%E3%81%9D%E3%81%AE%E4%BB%96#%E6%8E%A5%E7%B6%9A%E8%A8%AD%E5%AE%9A)）。

```console
pi@4gpiRT:~$ sudo nmcli con add type gsm ifname "*" con-name soracom apn soracom.io user sora password sora
```
接続に成功するとwwan0インターフェースにIPアドレスが自動で振られます。
```console
pi@4gpiRT:~$ ip a show dev wwan0
4: wwan0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/none
    inet 10.237.221.207/27 brd 10.237.221.223 scope global noprefixroute wwan0
       valid_lft forever preferred_lft forever
```

## ラズパイをAP（アクセスポイント）化
NetworkManager[^1]を使ってラズパイのwlan0インターフェースをWi-Fi APにします。

4GPi OSイメージ（bookworm版）では デフォルトで Wi-Fi を無効化しているため[^2]、
以下のコマンドで Wi-Fi を有効化します。
```console
pi@4gpiRT:~$ sudo raspi-config nonint do_wifi_country JP
```

SSID/パスワードが "RPiAP" / "password" のAPを作成します。
```console
pi@4gpiRT:~$ sudo nmcli c add type wifi ifname wlan0 autoconnect yes ssid RPiAP
```
（con-nameを指定しない場合は）wifi-wlan0という名前のコネクションが作成されます。
```console
pi@4gpiRT:~$ nmcli c
NAME                UUID                                  TYPE      DEVICE
soracom             ad08caef-ca78-42ab-a9a4-a2ad74d38dd8  gsm       cdc-wdm0
wifi-wlan0          4d8418a7-43b1-4073-a70e-f3b07f16cb51  wifi      --
Wired connection 1  afb41213-5fc8-34d3-8790-70d3c1521ec9  ethernet  --
```
使用する帯域やパスワードを設定します。
```console
pi@4gpiRT:~$ sudo nmcli c mod wifi-wlan0 802-11-wireless.mode ap 802-11-wireless.band bg
pi@4gpiRT:~$ sudo nmcli c mod wifi-wlan0 wifi-sec.key-mgmt wpa-psk wifi-sec.psk "password"
```
wlan0インターフェースのIPアドレスを固定にします。
```console
pi@4gpiRT:~$ sudo nmcli c mod wifi-wlan0 ipv4.addresses 10.10.0.1/24 ipv4.method manual
```

```console
pi@4gpiRT:~$ sudo nmcli c up wifi-wlan0
pi@4gpiRT:~$ ip a show dev wlan0
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:ae:d9:35 brd ff:ff:ff:ff:ff:ff
    inet 10.10.0.1/24 brd 10.10.0.255 scope global noprefixroute wlan0
       valid_lft forever preferred_lft forever
    inet6 fe80::d85a:ebe3:ff19:bc48/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
```

## ラズパイをDHCPサーバ化

dnsmasqをインストールします。
```console
pi@4gpiRT:~$ sudo apt install dnsmasq
```

dnsmasqの設定ファイルに設定を追記します。
今回はIPアドレスの割り当て範囲を10.10.0.2 ～ 10.10.0.20、リース時間を24時間としました。

```/etc/dnsmasq.conf
#ファイル末尾に追記

interface=wlan0
dhcp-range=10.10.0.2,10.10.0.20,255.255.255.0,24h
```

dnsmasqを再起動して設定変更を反映します。
```console
pi@4gpiRT:~$ sudo systemctl restart dnsmasq
```

## ラズパイをルータ化

ufw[^3]を使って設定します。

### IPパケット転送設定
`/etc/ufw/sysctl.conf`の`net/ipv4/ip_forward=1`のコメントを外し、パケット転送設定を有効にします。

```/etc/ufw/sysctl.conf
# ..略

net/ipv4/ip_forward=1

# ..略
```

ufw（ファイアウォール）で パケットの着信と転送を許可します。

```console
pi@4gpiRT:~$ sudo ufw default allow incoming
pi@4gpiRT:~$ sudo ufw default allow routed
```

ufw（ファイアウォール）の状態を確認して以下のように許可されていることを確認します。

```console
pi@4gpiRT:~$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: allow (incoming), allow (outgoing), allow (routed)
```

注意点として、パケット着信をデフォルトで許可した場合、例えばwwan0にグローバルIPが付いている場合は外部（インターネット）からラズパイ（wwan0）へのアクセスが可能になり、セキュリティリスクになります。これを考慮して、ここでは wwan0 のパケット着信は拒否するようにしておきます[^4]。

```console
pi@4gpiRT:~$ sudo ufw deny in on wwan0
```


### IPマスカレード(NAPT)設定

`before.rules`にルールを追記します。

```/etc/ufw/before.rules
# ファイル末尾に追記
# NAT Table rules
*nat
:POSTROUTING ACCEPT [0:0]
-F
-A POSTROUTING -s 10.10.0.0/24 -o wwan0 -j MASQUERADE
COMMIT
```

ufwの設定変更を反映します。

```console
pi@4gpiRT:~$ sudo ufw reload
```

## スマホでWi-Fi接続確認

Wi-Fi端末からLTE回線経由でインターネットに接続できるようになりました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1283849/3101d781-2914-bedd-deac-4f0c64374350.png" width=30%>

# 有線LAN端末もLTE回線経由でインターネット接続できるようにする

## 仮想ブリッジ作成

Linux bridge（br0）を作成します。
Linux bridgeはL2スイッチのように動作します。
```console
pi@4gpiRT:~$ sudo nmcli c add ifname br0 type bridge
```

同時にbridge-br0という名前のコネクションが生成されます。
```console
pi@4gpiRT:~$ nmcli c
NAME                UUID                                  TYPE      DEVICE
bridge-br0          ece60180-ea1f-46a3-978d-87b4886b4d4e  bridge    br0
soracom             ad08caef-ca78-42ab-a9a4-a2ad74d38dd8  gsm       cdc-wdm0
wifi-wlan0          e7a96011-2bd7-4570-9712-8dbb25b17324  wifi      wlan0
Wired connection 1  afb41213-5fc8-34d3-8790-70d3c1521ec9  ethernet  --
```

eth0を仮想ブリッジに接続します。
```console
pi@4gpiRT:~$ sudo nmcli c add ifname eth0 type bridge-slave master bridge-br0
```

仮想ブリッジのIPアドレス固定します。
```console
pi@4gpiRT:~$ sudo nmcli c mod bridge-br0 ipv4.addresses 10.20.0.1/24 ipv4.method manual
```

## 仮想ブリッジにDHCPサーバを設定

Wi-Fiの時と同様にDHCPサーバを設定します。
```/etc/dnsmasq.conf
#ファイル末尾に追記

interface=br0
dhcp-range=10.20.0.2,10.20.0.20,255.255.255.0,24h
```

## IPマスカレード設定
IPマスカレードの設定を追記します。

```/etc/ufw/before.rules
# ファイル末尾に追記
# NAT Table rules
*nat
:POSTROUTING ACCEPT [0:0]
-F
-A POSTROUTING -s 10.10.0.0/24 -o wwan0 -j MASQUERADE
-A POSTROUTING -s 10.20.0.0/24 -o wwan0 -j MASQUERADE  # 追記部分
COMMIT
```

ufwの設定変更を反映します。

```console
pi@4gpiRT:~$ sudo ufw reload
```

以上の設定により、ラズパイに接続した有線LAN端末がLTE回線経由でインターネット接続できるようになります。

# （補足）上の方法で接続がうまくいかないとき
MSSクランプの設定を行うことで解消する場合があります。

・/etc/ufw/before.rules の末尾に以下を追記する。
```/etc/ufw/before.rules
# MANGLE Table rules
*mangle
-F
-A FORWARD -o wwan0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
COMMIT
```

[^1]: 4GPiのOSイメージはNetworkManagerがインストール済です。
[^2]: Bookworm の OS イメージではデフォルトで 5GHz帯が有効になり、屋外利用で問題になるためです。
[^3]: 4GPiのOSイメージはufwがインストール済です。
[^4]: 4GPiのOSイメージではあらかじめwwan0へのパケット着信を拒否する設定が入っています。