ラズパイを無線LANイーサネットコンバータ化する方法

#無線LANイーサネットコンバータとは
有線LAN接続しか持っていない機器をブロードバンドルータまで無線で接続できるようにする機器です。
私の家のテレビがインターネットへの接続はできるのですが、有線LANしか持っていないのでラズパイにつないでブロードバンドルータまでwifiで中継してくれています。
ラズパイにIPマスカレードの設定とDHCPサーバを構築することで実現できます。
今回、DHCPサーバは、 docker + kea-dhcp4 で構築したいと思います。

#環境
- Raspberry Pi 3 Model B
- OSバージョン

```shell-session
$ uname -a
Linux raspberrypi 4.14.79-v7  #1159 SMP Sun Nov 4 17:50:20 GMT 2018 armv7l GNU/Linux
$ grep -H "" /etc/*version ; grep -H "" /etc/*release
/etc/debian_version:9.6
/etc/os-release:PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
/etc/os-release:NAME="Raspbian GNU/Linux"
/etc/os-release:VERSION_ID="9"
/etc/os-release:VERSION="9 (stretch)"
/etc/os-release:ID=raspbian
/etc/os-release:ID_LIKE=debian
/etc/os-release:HOME_URL="http://www.raspbian.org/"
/etc/os-release:SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
/etc/os-release:BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
```

#有線LANの固定IPアドレス設定
まずは、eth0に固定IPを割り当てる必要があります。
デフォルトだと下記の状態になっています。

```shell-session
$ ip address show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   link/ether b8:27:eb:xx:xx:xx brd ff:ff:ff:ff:ff:ff
   inet 169.254.19.208/16 brd 169.254.255.255 scope global eth0
      valid_lft forever preferred_lft forever
   inet6 fe80::f14b:4ed3:336a:eae6/64 scope link
      valid_lft forever preferred_lft forever
```

eth0に固定IPを割り当てる為に /etc/dhcpcd.conf を編集します。

```shell:/etc/dhcpcd.conf
〜省略〜
# Example static IP configuration:
interface eth0 # コメントアウトされているのを外す
static ip_address=192.168.100.1/24 # コメントアウトを外して割り当てたいIPアドレスを指定する
#static ip6_address=fd51:42f8:caae:d92e::ff/64
#static routers=192.168.0.1
#static domain_name_servers=192.168.0.1 8.8.8.8 fd51:42f8:caae:d92e::1
〜省略〜
```

設定を反映させます。

```shell-session
$ sudo systemctl restart dhcpcd.service
$ ip address show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
   link/ether b8:27:eb:xx:xx:xx brd ff:ff:ff:ff:ff:ff
   inet 192.168.100.1/24 brd 192.168.100.255 scope global eth0
      valid_lft forever preferred_lft forever
   inet6 fe80::f14b:4ed3:336a:eae6/64 scope link
      valid_lft forever preferred_lft forever
```

#Dockerのインストール
続いてDockerのインストールを行います。
下記のコマンドを実行するだけでインストールできます。

```shell-session
$ curl -sSL https://get.docker.com | sh
```

ログインで使用しているユーザでもdockerが使用できるようにdockerグループに追加します。

```shell-session
$ sudo usermod -aG docker (ユーザ名)
```

dockerのバージョン確認

```shell-session
$ docker version
docker version
Client:
 Version:           18.09.0
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        4d60db4
 Built:             Wed Nov  7 00:57:21 2018
 OS/Arch:           linux/arm
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.0
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       4d60db4
  Built:            Wed Nov  7 00:17:57 2018
  OS/Arch:          linux/arm
  Experimental:     false
```

#kea-dhcp4サーバの構築
docker作業ディレクトリにDockerfileとetc/kea/kea-dhcp4.confを作成します。

```dockerfile:Dockerfile
FROM ubuntu:latest
EXPOSE 67:67/udp
ARG DEBIAN_FRONTEND=noninteractive
RUN apt update && apt install -y \
    kea-dhcp4-server \
    tzdata \
    && ln -s -f /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && echo "Asia/Tokyo" > /etc/timezone \
    && dpkg-reconfigure -f noninteractive tzdata \
    && sed -i -e "s/\/etc\/kea\-dhcp4\-server\.conf/\/etc\/kea\/kea\-dhcp4.conf/" /etc/init.d/kea-dhcp4-server \
    && rm -rf /var/lib/apt/lists/*
CMD ["kea-dhcp4", "-c", "/etc/kea/kea-dhcp4.conf"]
```

```shell:etc/kea/kea-dhcp4.conf
{

"Dhcp4":
{
  "interfaces-config": {
    "interfaces": [ "eth0" ]
  },
  "lease-database": {
    "type": "memfile"
  },
  "expired-leases-processing": {
    "reclaim-timer-wait-time": 10,
    "flush-reclaimed-timer-wait-time": 25,
    "hold-reclaimed-time": 3600,
    "max-reclaim-leases": 100,
    "max-reclaim-time": 250,
    "unwarned-reclaim-cycles": 5
  },
  "valid-lifetime": 4000,
  "subnet4": [
    {
      "subnet": "192.168.100.0/24", # 割り当てるIPアドレス帯域を指定する
      "pools": [
        {
          "pool": "192.168.100.100 - 192.168.100.200" # 割り当てるIPアドレスの範囲を指定する
        }
      ],
      "option-data": [
        {
          "name": "routers",
          "data": "192.168.100.1" # ラズパイのeth0のIPアドレスを指定する
        },
        {
          "name": "domain-name-servers",
          "data": "xxx.xxx.xxx.xxx" # ラズパイが使用しているドメインネームサーバを指定する
        }
      ]
    }
  ]
},

"Logging":
{
  "loggers": [
    {
      "name": "kea-dhcp4",
      "output_options": [
          {
            "output": "/var/log/kea-dhcp4.log"
          }
      ],
      "severity": "INFO",
      "debuglevel": 0
    },
  ]
}

}
```

dockerイメージをビルドします。

```shell-session
docker build ./ -t kea-dhcp4-server
```

kea-dhcp4サーバを起動します。

```shell-session
$ docker run -d --net=host --name=kea-dhcp4-server -v $(pwd)/etc/kea:/etc/kea kea-dhcp4-server
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
c5989003b329        kea-dhcp4-server    "kea-dhcp4 -d -c /et…"   4 seconds ago      Up 2 seconds                           kea-dhcp4-server
```

#IPマスカレード設定
eth0に接続している機器からのパケットはwlan0を通過するように設定します。

```shell-session
$ sudo iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT
$ sudo iptables -A FORWARD -i wlan0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
$ sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
```

iptables設定を再起動しても反映されるようにする為に iptables-persistent パッケージをインストールします。

```shell-session
$ sudo apt install iptables-persistent
```

iptables設定を保存する

```shell-session
$ sudo netfilter-persistent save
```

#動作確認
有線LAN側に接続した機器でインターネットへの接続テストなどを実施すると動作確認ができます。
私の家のテレビでは、下記の４つの確認が行われて正しく接続できていることが確認できました。

```shell
接続テスト　接続確認
-----
1. LANケーブルの接続：○ <- ここで失敗している場合は、LANケーブルが正しく接続されていない可能性があります。
2. IPアドレスの設定：○
3. ゲートウェイへの接続：○ <- ここで失敗している場合は、kea-dhcpサーバが起動していないか、IPアドレスやゲートウェイ情報などが受け取れていない可能性が高いのでkea-dhcpサーバ設定の見直しが必要です。
4. インターネットへの接続：○ <- ここで失敗している場合は、IPマスカレードの設定見直しが必要です。
-----
ネットワーク接続の確認が正しく終了しました。
```