SoftEther VPNを使いRaspberry PiをVPNサーバにする

# 準備
SoftEtherVPNさんの力を借りて「(DHCPからアドレスが振ってくれば)ケーブルを繋げるだけで動くVPN拠点」を作ろうと思います
DHCPがある場所にザクッとEthernetを繋いで電源を入れれば、あとはSoftEtherVPNがNAT トラバーサルやらVPN over HTTPSやらVPN AzureでVPNが繋がるようにしてくれる、という感じにしたいです

## セットアップ
### 購入
Raspberry Piは全く初めてなので買うところからです

ケースが欲しかったので本体はこれにしました
[Raspberry Pi 3 Model B ボード＆ケースセット](https://www.amazon.co.jp/gp/product/B01CSFZ4JG/)

長期間安定動作してほしいので電源は公式のを買いました
2.5A出る電源ってあんまりないんですね
[Raspberry Pi 3 Model B 専用電源 ACアダプタ](https://www.amazon.co.jp/gp/product/B01MQGO2BC/)

microSDHCは家にあった適用な32GB Class10を使います

### OS
VPNとして使うため、X不要のLite版を選びます
ぼくがインストールしたのはRaspbian Jessie Lite 2017-04-10版です
[Download Raspbian](https://www.raspberrypi.org/downloads/raspbian/)

### インストール
[DD for Windows](http://www.si-linux.co.jp/techinfo/index.php?DD%20for%20Windows)を使います
Bash on Windowsはハードウェアを触れないのでmicroSDHCへのDDができません

`DDWin.exe`を**管理者として実行**で起動し`2017-04-10-raspbian-jessie-lite.img`を書き込みます
管理者権限でないとディスク書き込みができません

![image](https://qiita-image-store.s3.amazonaws.com/0/125525/32b89687-66f0-73ed-8965-3cb262ab20fd.png)

書き込み自体は5分程度で終わりました

### SSHの有効化
2017/04/15現在のRaspbianはデフォルトではSSHがオフになっているため、
そのままではヘッドレス環境でのセットアップができません
しかし、ディスクを直接書き換えることでSSHを有効にする手段が提供されているので利用します

[SSH (Secure Shell) - Raspberry Pi Documentation](https://www.raspberrypi.org/documentation/remote-access/ssh/)
> 3. ENABLE SSH ON A HEADLESS RASPBERRY PI
> 
> For headless setup, SSH can be enabled by placing a file named ssh, without any extension, onto the boot partition of the SD card. When the Pi boots, it looks for the  ssh file. If it is found, SSH is enabled, and the file is deleted. The content of the file does not matter: it could contain text, or nothing at all.

bootパーティションに**ssh**という名前のファイルを作ればいいみたいです
拡張子のないただのsshファイルであることに注意して下さい

![3cae33ae-6976-67f2-b526-4d1e570e85a8.png](https://qiita-image-store.s3.amazonaws.com/0/125525/bade7ba4-6e24-692b-ee5d-ed763de01c85.png)


### 起動
できたmicroSDHCカードをRaspberry Piに挿入してEthernetケーブルを接続し、電源を接続します
dhcpとsshdが自動起動しているはずなのでDHCPサーバがあればIPが振ってきてSSHできるはずです

ただし、ディスプレイが無いのでRaspberry PiのIPをどうにかして調べないといけません
ぼくはルータ管理画面のDHCPの払い出し状況からIPを調べました

デフォルトのユーザ名は`pi`、パスワードは`raspberry`だそうです

```bash
$ ssh pi@192.168.0.12
The authenticity of host '192.168.0.12 (192.168.0.12)' can't be established.
ECDSA key fingerprint is XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX.Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.12' (ECDSA) to the list of known hosts.
pi@192.168.0.12's password:

The programs included with the Debian GNU/Linux system are free software;the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.

pi@raspberrypi:~ $
```

無事つながりました

## 初期設定
UbutuやDebianと同じ部分はメモ程度にしておきます
 
* `pi`ユーザの削除とユーザ新規追加
[ubuntu ユーザを追加して sudo 権限をつける](http://qiita.com/white_aspara25/items/c1b9d02310b4731bfbaa)
[Ubuntuサーバー管理チートシート](http://qiita.com/shunichi/items/c7744878f5c02eaab18d)

* ホスト名の変更
[Ubuntu14.04でホスト名を変更する](http://qiita.com/mogulla3/items/17b323f48846fa3f6dac)

### 使用VRAM削減
```
$ sudo raspi-config
```
-> Advanced Option->Memory Split
最小値は16MBらしく、16MB以下にしても反映されないみたいです
[Memory split with less video memory ?
](https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=39764)

### swapの無効化
swapでmicroSDHCを使うと寿命が縮まりそうなのでswapを無効にします
今回はVPNだけに使うのでメモリには余裕があると思います
自分の使い方と相談で
[Raspberry Pi -RASPBIAN- のswapを無効化](http://qiita.com/michimaru/items/25608100f871a2a3cf58)

完全に使わないなら削除してもいい

```bash
$ sudo apt-get remove dphys-swapfile
```

### パッケージの削除
このあたりを参考に要らなそうなパッケージを削除しました
今回はVPNだけに使うのでガリガリ消します

[GithubGist/minimal-raspbian2.sh](https://gist.github.com/Akkiesoft/9873563)
[【Rasbian】CUI運用しているので色々して軽量化する](http://variedtastefinder.jp/blog/?p=742)

ただしSoftEtherVPNをmakeするのでgccとかは削除してはダメです
面倒なら要らないものをぜーんぶ削除した後に

```bash
$ sudo apt-get install build-essential
```
で開発環境を入れるのもありだと思います

### 初期設定後
最終的にこんな感じになりました

```
$ free -h
             total       used       free     shared    buffers     cached
Mem:          973M        68M       904M       6.4M       5.7M        33M
-/+ buffers/cache:        29M       944M
Swap:           0B         0B         0B
```
```
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        29G  659M   28G   3% /
devtmpfs        483M     0  483M   0% /dev
tmpfs           487M     0  487M   0% /dev/shm
tmpfs           487M  6.5M  481M   2% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           487M     0  487M   0% /sys/fs/cgroup
/dev/mmcblk0p1   41M   21M   21M  51% /boot
```

## SoftEtherVPN
### ネットワーク設定
DHCPがある前提で設定をします

まずはブリッジに必要な`bridge-utils`をインストールします

```
$ sudo apt-get install bridge-utils
```

[Raspberry Pi 2とSoftEther VPNを使ってVPNサーバーを構築しよう！](http://qiita.com/neronplex/items/84162ec1de520bb75a11)

DHCPでIPが振られるNICをeth0からbr0に変更し、eth0とbr0をブリッジします
tapデバイスはSoftEther起動時にSoftEther自身が毎回作るため、ここで設定せずスクリプトにするそうです

* `hwaddress ether XX:XX:XX:XX:XX:XX`について

MACアドレスを固定せずにブリッジを作ると再起動時にMACアドレスが変わるため
DHCPから降ってくるアドレスが変わってしまうことが結構あります
`arp`テーブルがうまくいかないこともあるので固定してしまったほうが良いようです

```bash:/etc/network/interfaces
# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

iface eth0 inet manual

allow-hotplug wlan0
iface wlan0 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
allow-hotplug wlan1
iface wlan1 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

auto br0
iface br0 inet dhcp
        hwaddress ether XX:XX:XX:XX:XX:XX
        bridge_ports eth0
```

再起動後`ifconfig`でbr0ができているか確認します

```bash
$ ifconfig |grep Ethernet
br0       Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX
eth0      Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX
wlan0     Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX
```

### ダウンロード

以下からSoftEther VPN Serverをダウンロードします
[SoftEther ダウンロード センター
](http://www.softether-download.com/ja.aspx)

ソフトウェア:SoftEtherVPN(Freeware)
コンポーネント:SoftEther VPN Server
プラットフォーム:Linux
CPU:ARM EABI(32bit)

sshクライアント側でURLをコピーしてwgetすると簡単だと思います
展開したらどこかに置きます
今回は`/usr/local/bin/`に置きました

```bash
$ wget http://jp.softether-download.com/files/softether/v4.22-9634-beta-2016.11.27-tree/Linux/SoftEther_VPN_Server/32bit_-_ARM_EABI/softether-vpnserver-v4.22-9634-beta-2016.11.27-linux-arm_eabi-32bit.tar.gz
$ tar -zxvf softether-vpnserver-v4.22-9634-beta-2016.11.27-linux-arm_eabi-32bit.tar.gz
$ sudo mv vpnserver/ /usr/local/bin/
```

### make
```bash
$ sudo cd /usr/local/bin/vpnserver/
$ sudo make
```
makeにコケたら`sudo apt-get install build-essential`すれば必要物が入ると思います
`binutils`と`gcc`があれば大丈夫です

```bash
$ sudo chmod 600 *
$ sudo chmod 700 vpncmd
$ sudo chmod 700 vpnserver
```

### 起動スクリプト

これを参考にしました というかパス以外同じです
[Raspberry Pi 2とSoftEther VPNを使ってVPNサーバーを構築しよう！ - 起動スクリプトを用意する](http://qiita.com/neronplex/items/84162ec1de520bb75a11#%E8%B5%B7%E5%8B%95%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E7%94%A8%E6%84%8F%E3%81%99%E3%82%8B)
`sudo modprobe tun`がミソみたいです

```bash:/etc/init.d/vpnserver
#!/bin/sh
### BEGIN INIT INFO
# Provides:                 vpnserver
# Required-Start:           $local_fs $network
# Required-Stop:            $local_fs $network
# Default-Start:            2 3 4 5
# Default-Stop:             0 1 6
# Short-Description:        SoftEther VPN RTM
# Description:              Start vpnserver daemon SoftEther VPN Server
### END INIT INFO

DAEMON=/usr/local/bin/vpnserver/vpnserver
LOCK=/var/lock/vpnserver

# tun/tapモジュールのロード
sudo modprobe tun

. /lib/lsb/init-functions
test -x $DAEMON || exit 0

case "$1" in
start)
sleep 3
log_daemon_msg "Starting SoftEther VPN Server" "vpnserver"
$DAEMON start >/dev/null 2>&1
touch $LOCK
log_end_msg 0
sleep 3

# SoftEther VPNで追加した仮想tapデバイス名を調べる
tap=`/sbin/ifconfig -a| awk '$1 ~ /^tap/ {print $1}'`
/sbin/brctl addif br0 $tap
;;

stop)
log_daemon_msg "Stopping SoftEther VPN Server" "vpnserver"
$DAEMON stop >/dev/null 2>&1
rm $LOCK
log_end_msg 0
sleep 2
;;

restart)
$DAEMON stop
sleep 2

$DAEMON start
sleep 5
# SoftEther VPNで追加した仮想tapデバイス名を調べる
tap=`/sbin/ifconfig -a| awk '$1 ~ /^tap/ {print $1}'`
/sbin/brctl addif br0 $tap
;;

status)
    if [ -e $LOCK ]
    then
        echo "vpnserver is running."
    else
        echo "vpnserver is not running."
    fi
;;
*)

echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac
exit 0
```
スクリプトができたら実行権限を与え自動起動登録し
再起動します

```bash
$ sudo chmod +x /etc/init.d/vpnserver
$ sudo insserv vpnserver
$ sudo reboot
```

ちゃんと起動できているか確認します

```bash
$ ps aux| grep vpn
root       764  0.0  0.0   5580   612 ?        S<s  15:34   0:00 /usr/local/bin/vpnserver/vpnserver execsvc
root       765  3.2  1.3  29328 13400 ?        S<l  15:34   0:01 /usr/local/bin/vpnserver/vpnserver execsvc
```

大丈夫そうです

### 設定
ここからはSoftEther VPN Server Manager for Windowsを使用して設定を行います
IPアドレスを入力して管理したいVPN Serverを登録します
初回接続なので管理者パスワードの設定を行います
![image](https://qiita-image-store.s3.amazonaws.com/0/125525/59fa5e5c-fbdb-f140-42ee-e4d08206dcd3.png)

☑リモートアクセスVPNサーバー
![image](https://qiita-image-store.s3.amazonaws.com/0/125525/82edb9d7-1602-a811-a120-cf9ad720c689.png)

SoftEther VPN Clientが使えない/使わない場合や
iPhoneやAndroidから接続したい場合はL2TP/IPSecを有効にします
![image](https://qiita-image-store.s3.amazonaws.com/0/125525/390aa903-58b8-413d-65fb-a1e2cc558af7.png)

今回はケーブルをつなぐだけで接続できちゃう、という拠点を作るためにVPN Azureも有効にします
ただしVPN AzureはSoftEther VPN Clientからでないと繋がりません
![image](https://qiita-image-store.s3.amazonaws.com/0/125525/ba6cc58f-d36f-90e7-8512-f5b5bca672f2.png)


次にローカルブリッジ設定を行います
これをしないと
**クライアントからVPN Sererへの接続、VPN ServerのあるLANへの接続ができません**
tapデバイスを作ってブリッジを行う必要があります

![image](https://qiita-image-store.s3.amazonaws.com/0/125525/d2e33e68-5f9c-2aa0-9279-be450fd7ac1e.png)

ここで再起動します
再起動後、`brctl`でブリッジが正しく動作しているか確認します

* interfasesで作成したbr0がある
* Ethernetのeth0がある
* SoftEtherVPNのローカルブリッジで作成したtapがある(tap_NAMEという名前で作成される)

ならば問題ないはずです

```bash
$ brctl show br0
bridge name     bridge id               STP enabled     interfaces
br0             XXXX.XXXXXXXXXXXX       no              eth0
                                                        tap_vlan
```

### セットアップ後のリソース
ここまででメモリ使用量が100MB以下、ディスク使用量が800MB強にできました
build-essentialを消してしまえばもう少し削減できそうです
今後は接続速度やCPU使用率を計測したいところですが回線が無いので今はできません

```bash
$ free -h
             total       used       free     shared    buffers     cached
Mem:          973M        94M       878M       6.5M       6.9M        42M
-/+ buffers/cache:        45M       927M
Swap:           0B         0B         0B
```

```bash
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        29G  814M   27G   3% /
devtmpfs        483M     0  483M   0% /dev
tmpfs           487M     0  487M   0% /dev/shm
tmpfs           487M  6.5M  481M   2% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           487M     0  487M   0% /sys/fs/cgroup
/dev/mmcblk0p1   41M   21M   21M  51% /boot
```

### ログ保存無効
microSDHCカードへの書き込みを抑えるためにログを保存しないようにします
![image](https://qiita-image-store.s3.amazonaws.com/0/125525/3f6b6af8-3b0f-d9a8-be70-4a0985ec2026.png)

### 速度測定

| | サーバ| クライアント |
|:-------|------------|------------|
| 回線    | 光 1Gbps | 光 1Gbps     |
| OS      | Raspbian Jessie Lite 2017-04-10 | Windows 10 Pro 1607 |
| VPN     | SoftEther VPN Server (Ver 4.22, Build 9634, beta) | SoftEther VPN Client (Ver 4.22, Build 9634, beta) |
|方法 |iperf version 2.0.5 |iperf version 2.0.5(Windows Subsystem for Linux) |


```bash
$ iperf -c 192.168.X.X
------------------------------------------------------------
Client connecting to 192.168.X.X, TCP port 5001
TCP window size:  512 KByte (default)
------------------------------------------------------------
[  3] local 192.168.X.X port 62071 connected with 192.168.X.XX port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec  64.1 MBytes  53.6 Mbits/sec
```
50Mbps超えとなかなか高速です
測定中はCPU使用率が90～100%でした
やはりボトルネックはCPUのようです

測定中のCPU使用率は`vpnserver`が9割、`iperf`が1割程度でした
そのため実使用の最高速度は1割程度の向上があるかもしれません