NetBSD+Raspberry PiでPCルータを作る(ユーザランド設定編)

[昨日の記事](http://qiita.com/furandon_pig/items/35164d2ccc4e1dda160e)では[Raspberry Pi](https://ja.wikipedia.org/wiki/Raspberry_Pi)に[NetBSD](http://www.netbsd.org)をインストールし、PCルータとして利用するためのコンフィグを追加してカーネルの再ビルドを行う手順を紹介しました。

今日はRaspberry Pi上のNetBSDをPCルータとして動作させるための設定手順を紹介していこうと思います。

## ネットワークルータの構成

構築するPCルータのネットワークトポロジは以下のようになります。LAN側のNICはRaspberry PiのオンボードNICで、インターネット側の物理的なNICはaxe0(USB接続のNIC)です。

```
 ご家庭LAN-------+------ 192.168.10.0/24
                |
                |usmsc0
        +-------+--------+
        |     NetBSD     |
        | (Raspberry Pi) |
        +-------+--------+
                |pppoe0(axe0)
                |
           -----+-------インターネット
```

## PCルータ周りの設定

### パケットフォワーディングを有効にする

先述したネットワークトポロジにおいて、usmsc0からpppoe0にネットワークパケットを転送(フォワーディング)するための設定を行います。/etc/sysctl.confに以下の設定を記述し、起動時にパケットフォワーディングが有効になるようにしておきます。mss_ifmtuについては後ほど説明します。

```text:/etc/sysctl.conf
net.inet.ip.forwarding=1
net.inet.tcp.mss_ifmtu=1
```

### LAN側NICの設定

LAN側のNIC(usmsc0)の設定を行います。起動時に固定IPアドレスを設定するため、/etc/ifconfig.usmsc0に以下の設定を記述しておきます。

```text:/etc/ifconfig.usmsc0
192.168.10.1 netmask 255.255.255.0 up
```

### PPPoEの設定

まずはインターネット接続サービスに接続するための設定から。接続は[PPPoE(Point-to-Point Protocol over Ethernet)](https://ja.wikipedia.org/wiki/PPPoE)で行われるため、事前に以下のカーネルコンフィグを有効にしてカーネルを再ビルドしていたのでした。

```
pseudo-device  ppp                     # Point-to-Point Protocol
pseudo-device  pppoe                   # PPP over Ethernet (RFC 2516)
```

先ほどのusmsc0のように/etc/ifconfig.pppoe0に設定を記述しておくことで、起動時にインターネットに接続する処理が走ります。

私も各記述内容の意味を理解しきれていませんが、内容としては物理NIC(axe0)と仮想デバイスであるpppoe0を紐付け、PPPoEプロトコルでプロバイダに接続する、というものです。プロバイダから渡されたユーザ名とパスワードはpppoectlコマンドのmyauthnameとmyauthsecretに記述します。

```text:/etc/ifconfig.pppoe0
!ifconfig axe0 up
!sleep 3
!/sbin/pppoectl -e axe0 pppoe0
!/sbin/pppoectl pppoe0 myauthproto=chap 'myauthname=＜ユーザ名＞' 'myauthsecret=＜パスワード＞ hisauthproto=none
!/sbin/ifconfig pppoe0 0.0.0.0 0.0.0.1 netmask 255.255.255.255 up
!sleep 2
!/sbin/route add default `ifconfig pppoe0 | grep 'inet ' | awk '{ print $4 }'`
```

### NATの設定

次に[NAT(Network Address Translation)](https://ja.wikipedia.org/wiki/ネットワークアドレス変換)の設定を行います。

```text:/etc/rc.conf
ipfilter=YES
ipnat=YES
```

NATの設定では、ipfilter.confとipnat.confに設定を記述します。それぞれ以下のような内容になります。
実際の我が家の環境ではipf.confにはファイアウォール周りのルールをもがーっと記述しているので、それは後日紹介できればと思います。

```text:/etc/ipf.conf
pass in from any to any
pass out from any to any
```

ipnat.confではNAT設定に加えて、[MSS(Maximum Segment Size)](https://ja.wikipedia.org/wiki/最大セグメントサイズ)クランプの設定も行っています。MSSクランプについては[Setup NAT with MSS-clamping](http://www.netbsd.org/docs/network/pppoe/#clamping)にて詳しく紹介されています。

```text:/etc/ipnat.conf
map ppp0 192.168.10.0/24 -> 0/32 proxy port ftp ftp/tcp
map ppp0 192.168.10.0/24 -> 0/32 portmap tcp/udp 40000:60000 mssclamp 1400
map ppp0 192.168.10.0/24 -> 0/32
```

## LAN向けの設定

### dnsmasqの設定

プロバイダから教えられたDNSアドレスをLAN内のPCが参照するよう設定しても良いのですが、ここはPCルータを[DNSキャッシュサーバ](https://ja.wikipedia.org/wiki/DNSサーバ#DNS.E3.82.AD.E3.83.A3.E3.83.83.E3.82.B7.E3.83.A5.E3.82.B5.E3.83.BC.E3.83.90)として動作させ、LAN内のPCはDNSとしてPCルータを参照するようにしてみます。たぶん市販のブロードバンドルータもそんな使い方ができるはず(ずっとPCルータでまかなっているので世間ズレしている……)。

#### dnsmasqのインストール

DNSキャッシュサーバとして[dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html)を使用してみます。さっそく設定を行いたいところですが、NetBSD-7.0_RC1+Raspberry Pi向けのdnsmasqがパッケージとして提供されていないため、自前でビルドします。

```
# tar zxvf dnsmasq-2.71.tar.gz
# cd dnsmasq-2.71
# gmake
# gmake install
# cd /opt
# sudo ln -s dnsmasq-2.71 dnsmasq
```

併せてdnsmasq用のrcスクリプトを作成します。

```text:/etc/rc.d/dnsmasq
#!/bin/sh

# PROVIDE: dnsmasq
# REQUIRE: LOGIN

$_rc_subr_loaded . /etc/rc.subr

name="dnsmasq"
rcvar=$name
command="/opt/dnsmasq/sbin/${name}"
pidfile="/var/run/${name}.pid"
required_files="/etc/dnsmasq.conf"

load_rc_config $name
run_rc_command "$1"
```

/etc/rc.confに以下を記述し、起動時にdnsmasqが起動するようにします。

```text:/etc/rc.conf
dnsmasq=YES
```

dnsmasq.conf.exampleを元に/etc/dnsmasq.confを作成します。以下に差分のみ紹介します。

```diff
$ diff -u dnsmasq.conf.example /etc/dnsmasq.conf | egrep '(^\-|^\+)' 
--- dnsmasq.conf.example        2014-05-17 04:21:55.000000000 +0900
+++ /etc/dnsmasq.conf   2015-06-25 09:17:30.000000000 +0900
-#domain-needed
+domain-needed
-#bogus-priv
+bogus-priv
-#resolv-file=
+resolv-file=/etc/resolv.conf
-#local=/localnet/
+local=/furandon.net/
-#listen-address=
+listen-address=192.168.10.1
-#expand-hosts
+expand-hosts
-#domain=thekelleys.org.uk
+domain=furandon.net
```

#### 「オープンリゾルバじゃないよね」確認を行う

[オープンリゾルバ(Open Resolver)に対する注意喚起](https://www.nic.ad.jp/ja/dns/openresolver/)を読むと、自分が設定したdnsmasqがオープンリゾルバになっているのではと心配になってきます。念のため、以下のコマンドでインターネット側に対して53番ポートがLISTEN状態に**なっていない**ことを確認します。

```text
# netstat -an | grep LISTEN | grep '\.53 '
tcp        0      0  192.168.10.1.53        *.*                    LISTEN
```

これでOKですね。

### DHCPサーバの設定

LAN内部のPCはDHCPでアドレスを取得するようにしたいので、DHCPサーバの設定を行います。

```text:/etc/dhcpd.conf
default-lease-time 600;
max-lease-time 7200;

ddns-update-style none;

log-facility local7;

subnet 192.168.10.0 netmask 255.255.255.0 {
  range dynamic-bootp 192.168.10.200 192.168.10.250;
  option routers 192.168.10.1;
  option domain-name-servers 192.168.10.1;
  option domain-name "furandon.net";
}
```

ちなみに、dhcpdが参照する/var/db/dhcpd.leasesを事前に作成しておく必要があるので、touchコマンドでファイルを作成しておきます。

```text
# touch /var/db/dhcpd.leases
```

あとは/etc/rc.confに以下を記述します。

```text:/etc/rc.conf
dhcpd=YES
```

## VPNの設定

出先からLAN内のPCに接続したいことがあるので、VPNの設定も行っておきます。VPNサーバは[OpenVPN](https://ja.wikipedia.org/wiki/OpenVPN)で構築します。

### OpenVPNのビルド

が、先ほどのdnsmasqと同様にパッケージが用意されていないので、OpenVPNを自分でビルドします。OpenVPNは[lzo](https://ja.wikipedia.org/wiki/LZO)のライブラリを必要とするので、これもビルドします。

#### LZOのビルド

```
# tar zxvf lzo-2.09.tar.gz
# cd lzo-2.09
# ./configure \
        --prefix=/opt/lzo-2.09 \
        --enable-static \
        --enable-shared
# gmake
# gmake install
```

#### OpenVPNのビルド

```
# export LZO_CFLAGS=-I/opt/lzo/include
# export LZO_LIBS="-L/opt/lzo/lib -llzo2"
# ./configure \
        -prefix=/opt/openvpn-2.3.6 \
        --disable-debug \
        --disable-dependency-tracking \
        --enable-password-save \
        --disable-pkcs11
# gmake
# gmake install
```

### OpenVPNの設定

OpenVPNでテスト接続するところまで確認しておきます。

#### 事前共有鍵の作成

OpenVPNでVPN接続を行う時の認証方法は何種類かあるのですが、今回は事前共有鍵方式を使用します。以下の手順で鍵を作成します。

```text
# cd /opt/vpn/tmp
# /opt/openvpn/sbin/openvpn --genkey --secret test.key
```

#### サーバ・クライアント用設定ファイル

```text:test_server.ovpn
local ＜pppoe0にプロバイダから割り当てられたIPアドレス＞
port 25252
verb 3

secret test.key

link-mtu 1200
dev tun

ifconfig 10.7.0.1 10.7.0.2
ifconfig-nowarn
```

```text:test_client.ovpn
remote ＜pppoe0にプロバイダから割り当てられたIPアドレス＞
port 25252
verb 3

secret test.key

link-mtu 1200
dev tun

ifconfig 10.7.0.2 10.7.0.1
ifconfig-nowarn
```

### 接続テスト

以下の手順でサーバを起動し、クライアント側から接続してみます。

#### サーバの起動

```
# /opt/openvpn/sbin/openvpn test_server.ovpn
```

#### クライアントから接続

```
$ sudo openvpn test_server.ovpn
```

これでNetBSD+Raspberry PiをPCルータとして利用できるようになりました。

## まとめ

NetBSD+Raspberry PiでPCルータを構築するための設定手順を紹介しました。思っていたよりも設定する項目が多く、あれこれ調べなおしながら記事を書く感じになっていました。とりあえず自分が必要とするPCルータ機能は設定できたのですが、NTPやファイアウォール等、他にも設定を入れておきたいものはたくさんあり、地味にPCルータ作成は遊びがい(?)があるような気がしています。

## 参考URL

 * [PPPoE(Point-to-Point Protocol over Ethernet)](https://ja.wikipedia.org/wiki/PPPoE)
 * [PPPoE 【 PPP over Ethernet 】](http://e-words.jp/w/PPPoE.html)
 * [NAT(Network Address Translation)](https://ja.wikipedia.org/wiki/ネットワークアドレス変換)
 * [MSS(Maximum Segment Size)](https://ja.wikipedia.org/wiki/最大セグメントサイズ)
 * [DNSキャッシュサーバ](https://ja.wikipedia.org/wiki/DNSサーバ#DNS.E3.82.AD.E3.83.A3.E3.83.83.E3.82.B7.E3.83.A5.E3.82.B5.E3.83.BC.E3.83.90)