Raspberry Pi で無線ルータを自作する

「家に余っている Raspberry Pi で無線ルータを自作できるんじゃね」と思い立ってやってみたやつ。

ググったら同じことをやっている人は山ほどいたので特に新しい話ではない。それどころか [Raspberry Pi の公式ドキュメントにやり方が書かれており](https://www.raspberrypi.com/documentation/computers/configuration.html#setting-up-a-routed-wireless-access-point)、このエントリもこのドキュメントに従ってやってみたというだけの内容になっている。

## 作ったもの
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/35cdfaf2-2eb5-a5ad-74e6-092092784392.png)

- Raspberry Pi 内蔵の Wi-Fi を AP として使う
- DHCP サーバ (dnsmasq) を動かして IPv4 アドレスを配布する
- トラフィックを有線ポート側に流すことでインターネットに繋げる

今回は上流に DHCP で IP を配ってくれる別のルータがいて、その下で動くようなものを作った。

## 使ったもの
- Raspberry Pi 3 Model B
    - 3B 以降のモデルでは Wi-Fi を内蔵しているので、別途 USB Wi-Fi アダプタなどを用意する必要がない
    - 3B+ 以降なら 5GHz 帯が使えるが、残念ながら 3B では 2.4GHz 帯しか使えない
    - OS は Raspbian (Buster) をインストール済み

## 作っていく

### Network Interface の設定
最近の Raspbian では Network Interface の設定は `/etc/network/interfaces` を触らずに dhcpcd でやるらしい。

``` :/etc/dhcpcd.conf
interface wlan0
    static ip_address=192.168.2.1/24
    nohook wpa_supplicant
```

ここでは wlan0 側の IPv4 アドレスの固定と Wi-Fi クライアントとしての挙動の無効化をしている。

``` console
$ sudo systemctl restart dhcpcd
```

dhcpcd を再起動したところ `dhcpcd_prestartinterface: wlan0: Operation not possible due to RF-kill` というエラーが出た。

``` console
$ sudo rfkill list
0: phy0: Wireless LAN
        Soft blocked: yes
        Hard blocked: no
1: hci0: Bluetooth
        Soft blocked: no
        Hard blocked: no
```

どうやら RF-kill という機能によってワイヤレスデバイスの挙動がブロックされているらしい。

``` console
$ rfkill unblock wifi
```

これでブロック解除できた。

### DHCP の設定
ググると isc-dhcp-server を使っているケースが多いが、今回は dnsmasq を使ってやってみた。
今まで dnsmasq は簡易 DNS サーバとしか思っていなかったが、なんと DHCPd としても使えるらしい。

``` console
$ sudo apt install dnsmasq
```

``` :/etc/dnsmasq.conf
interface=wlan0
dhcp-range=192.168.2.2,192.168.2.99,255.255.255.0,24h
```

DHCP のレンジは適当に 2-99 ということにした。

``` console
$ sudo systemctl start dnsmasq
$ sudo systemctl enable dnsmasq
```

やってから思ったけど、今回は上流に DHCPd がいるので RasPi 自身に DHCPd を入れる必要はなくて、単に DHCP リレーエージェントを入れるだけでよかったかもしれない。

### Wi-Fi AP の設定
hostapd を入れて設定していく。

``` console
$ sudo apt install hostapd
```

``` /etc/hostapd/hostapd.conf
interface=wlan0
driver=nl80211
ssid=RasPi-AP
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=Fooooooo
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
```

SSID とパスワードを設定する。

Raspberry Pi 3B+ 以降の場合は `hw_mode=a` にすると 5GHz 帯が使えるのだと思う。(多分)

``` :/etc/default/hostapd
DAEMON_CONF="/etc/hostapd/hostapd.conf"
```

```
$ sudo systemctl unmask hostapd
$ sudo systemctl enable hostapd
$ sudo systemctl start hostapd
```

何故か hostapd はインストールされた時点では mask されているので unmask しないと起動できない。

### ルーティングの設定
IP フォワードの設定をする。(コメントアウトされている箇所を有効にする)

``` :/etc/sysctl.conf
net.ipv4.ip_forward=1
```

IP マスカレードの設定をする。

``` console
$ sudo iptables -t nat -A  POSTROUTING -o eth0 -j MASQUERADE
```

このままだと再起動したときに戻ってしまうので、再起動時に restore されるようにする。

```
$ sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
```

``` :/etc/rc.local
iptables-restore < /etc/iptables.ipv4.nat
```

## 接続してみる
Raspberry Pi を再起動してから、スマホから Wi-Fi 接続してみたところ、無事つながってインターネットにもアクセスできた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/1d98c6b1-30de-bbe8-7904-bc1edc6beb88.png)

## 今後
今回は上流にルータがいる構成だったが、次はファイアウォールをちゃんと設定した上で直接 PPPoE 接続できるようにしたい。

最終的には IPv6 接続できるルータを自作したいところ。