DD-WRTからOpenVPNを使ってVPN接続

[DD-WRT](http://www.dd-wrt.com/site/index)とは、OpenWRTから派生して開発されたコンパクトなLinuxディストリビューションです。
ネットワークルータなどのファームウェアを書き換えて使用することができます。

# やること
自宅のDD-WRTから、さくらのVPSにOpenVPNを使ってVPN(L3トンネル)を張ります。
認証には共有鍵方式を採用します。
トンネル確立後、疎通の確認をします。
※DD-WRT自体の導入には触れません。
※OpenVPNは既にインストールしてある状態から始めます。

# 環境
## サーバ(大阪)
* [さくらのVPS](http://vps.sakura.ad.jp/) 1GBプラン<br>
 (CentOS 6.7 x86_64)
* OpenVPN バージョン2.2.2

## クライアント(東京)
* 無線LANルータ [BUFFALO WZR-HP-G300NH2](http://buffalo.jp/products/catalog/network/wzr-hp-g300nh/) <br>
 (DD-WRT v24SP2-MULTI (06/03/12) std - build 19154)
* OpenVPN バージョン2.2.1

# 事前作業
## 共有鍵の作成
サーバかクライアントのいずれかで共通鍵を生成します。
`$ openvpn --genkey --secret /tmp/static.key`
以下の形式のテキストファイルが作成されます。

```
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
 　　　　　　　(略)
-----END OpenVPN Static key V1-----
```
このファイルを共通鍵として使用します。
サーバとクライアントで同一の鍵を使用するため、相手の端末にもSCPなどでコピーしておきます。

# 設定
## 共通設定
サーバ・クライアント両方で指定するOpenVPNのパラメータです。

| パラメータ | 設定値 | メモ |
|:-----------|:---------|:------|
| dev | tun | 仮想ネットワークデバイス |
| proto | udp | 通信に使用するプロトコル |
| ifconfig | IP1 IP2| ネットワークデバイスに指定するIPアドレス (IP1:ローカル, IP2:リモート)  |
| secret | ファイルパス | 生成した共有鍵を指定 |
| auth | SHA1 | HMACアルゴリズム(デフォルト値) |
| cipher| BF-CBC | パケット暗号化アルゴリズム(デフォルト値) |
| comp-lzo | - | LZO圧縮を有効 |

## サーバ
### 設定

* 共有鍵を配置

事前設定で生成した共通鍵を設定ディレクトリ配下に移動し、所有者と権限を変更します。

```
$ sudo mkdir /etc/openvpn/ddwrt
$ sudo mv /tmp/static.key /etc/openvpn/ddwrt/static.key
$ sudo chown root:root /etc/openvpn/ddwrt/static.key
$ sudo chmod 600 /etc/openvpn/ddwrt/static.key
```


* コンフィグを投入

コンフィグファイルを作成します。

```
cat > /etc/openvpn/ddwrt.conf << EOL
dev tun
proto udp
port 11194

ifconfig 192.168.99.1 192.168.99.2
secret /etc/openvpn/ddwrt/static.key
comp-lzo

# 権限
user nobody
group nobody
persist-tun
persist-key

# ログ
log-append /var/log/static_openvpn.log
EOL
```

### 起動
OpenVPNを再起動します。

```
$ sudo service restart openvpn
openvpn を停止中:                                          [  OK  ]
openvpn を起動中:                                          [  OK  ]
$
```

起動OKを確認し、ログにエラーが出ていなければ設定完了です。
ファイアウォールはコンフィグで設定している ポート11194(UDP) を許可するようにします。

## クライアント
### 設定

* DD-WRTにログイン

ブラウザでDD-WRTへアクセスします。
ここではDD-WRTのIPアドレスを 192.168.0.77 に設定しています。
[http://192.168.0.77/](http://192.168.0.77)

ファームウェアやバージョンによってはデザインが異なります。
*(ここでは、[米BUFFALO](http://www.buffalotech.com/)がDD-WRTをカスタムして公開しているファームウェアを使用しています。)*
![dd-wrt1.png](https://qiita-image-store.s3.amazonaws.com/0/103186/30d39f02-7bfe-8660-3491-ce6663f57f7a.png)


* スクリプトの投入

ルートディレクトリ配下に作成したデータは、メモリ上にあるため電源を落とすか再起動をすると消えてしまいます。
そこで必要なファイルやコンフィグをスクリプトにして、スタートアップ用のnvramに保存します。

メニュー[Administration] -> サブメニュー[Commands] を開きます。
[Command Shell] に接続用のスクリプトを貼り付けます。

```bash
mkdir /tmp/openvpn

cat > /tmp/openvpn/vps.conf << EOL
dev tun
proto udp
remote 接続先(VPNサーバ)IP 11194
ifconfig 192.168.99.2 192.168.99.1
secret /tmp/openvpn/secret.key
daemon
nobind
comp-lzo
EOL

cat > /tmp/openvpn/secret.key << EOL
-----BEGIN OpenVPN Static key V1-----
             (中略)
-----END OpenVPN Static key V1-----
EOL

cat > /tmp/openvpn/startup << EOL
#!/bin/sh
PROCESS=\`ps w | grep openvpn | egrep -v 'grep|/bin/sh' | wc -l\`
if [ \$PROCESS -eq 0 ]; then
  /usr/sbin/openvpn --config /tmp/openvpn/vps.conf &
fi
EOL

chmod a+x /tmp/openvpn/startup

echo "* * * * * root /tmp/openvpn/startup" > /tmp/cron.d/openvpn

stopservice cron && startservice cron

exit 0

```

[Save Startup]を押下すると、スクリプトが保存されます。
スクリプトの動きはこんな感じです。

0. OpenVPN接続用にディレクトリを作成
0. コンフィグファイルを作成
0. 共通鍵を作成
0. 接続スクリプトの作成(多重接続しないようになっています)
0. 接続スクリプトを毎分実行するcronを作成
0. cronをリロード(作成したcronが実行されません)

### 起動
DD-WRTを再起動すると、cronによってOpenVPNが実行されます。

# 確認
VPNが確立すると、サーバ側に以下のログが出力されます。

```
Sun Dec  6 01:49:41 2015 Peer Connection Initiated with xxx.xxx.xxx.xxx:34579
Sun Dec  6 01:49:41 2015 Initialization Sequence Completed
```

**疎通を確認します。**

* クライアント -> サーバ

```
root@DD-WRT:~# ping 192.168.99.1
PING 192.168.99.1 (192.168.99.1): 56 data bytes
64 bytes from 192.168.99.1: seq=0 ttl=64 time=11.667 ms
64 bytes from 192.168.99.1: seq=1 ttl=64 time=11.647 ms
64 bytes from 192.168.99.1: seq=2 ttl=64 time=11.410 ms
64 bytes from 192.168.99.1: seq=3 ttl=64 time=11.319 ms
^C
--- 192.168.99.1 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 11.319/11.510/11.667 ms
root@DD-WRT:~#
```

* サーバ -> クライアント

```
[XXX@www openvpn]$ ping 192.168.99.2
PING 192.168.99.2 (192.168.99.2) 56(84) bytes of data.
64 bytes from 192.168.99.2: icmp_seq=1 ttl=64 time=12.0 ms
64 bytes from 192.168.99.2: icmp_seq=2 ttl=64 time=11.3 ms
64 bytes from 192.168.99.2: icmp_seq=3 ttl=64 time=10.9 ms
64 bytes from 192.168.99.2: icmp_seq=4 ttl=64 time=11.4 ms
^C
--- 192.168.99.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3290ms
rtt min/avg/max/mdev = 10.903/11.441/12.081/0.433 ms
[XXX@www openvpn]$
```

VPNが確立され、疎通がとれることが確認できました。
VPNを経由せず直接pingした場合、11msくらいでした。

# スループット
iperfを使って測定しました。

```
root@DD-WRT:~# iperf -c 192.168.99.1 -t 60 -i 2
------------------------------------------------------------
Client connecting to 192.168.99.1, TCP port 5001
TCP window size: 19.1 KByte (default)
------------------------------------------------------------
[  3] local 192.168.99.2 port 39459 connected with 192.168.99.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 2.0 sec  4.09 MBytes  17.1 Mbits/sec
[  3]  2.0- 4.0 sec  4.08 MBytes  17.1 Mbits/sec
[  3]  4.0- 6.0 sec  4.14 MBytes  17.4 Mbits/sec
[  3]  6.0- 8.0 sec  4.15 MBytes  17.4 Mbits/sec
[  3]  8.0-10.0 sec  4.10 MBytes  17.2 Mbits/sec
[  3] 10.0-12.0 sec  4.12 MBytes  17.3 Mbits/sec
[  3] 12.0-14.0 sec  4.05 MBytes  17.0 Mbits/sec
[  3] 14.0-16.0 sec  4.09 MBytes  17.2 Mbits/sec
[  3] 16.0-18.0 sec  4.08 MBytes  17.1 Mbits/sec
[  3] 18.0-20.0 sec  4.09 MBytes  17.2 Mbits/sec
[  3] 20.0-22.0 sec  4.11 MBytes  17.2 Mbits/sec
[  3] 22.0-24.0 sec  4.02 MBytes  16.8 Mbits/sec
[  3] 24.0-26.0 sec  4.09 MBytes  17.1 Mbits/sec
[  3] 26.0-28.0 sec  4.14 MBytes  17.4 Mbits/sec
[  3] 28.0-30.0 sec  4.08 MBytes  17.1 Mbits/sec
[  3] 30.0-32.0 sec  4.11 MBytes  17.2 Mbits/sec
[  3] 32.0-34.0 sec  4.03 MBytes  16.9 Mbits/sec
[  3] 34.0-36.0 sec  4.07 MBytes  17.1 Mbits/sec
[  3] 36.0-38.0 sec  4.13 MBytes  17.3 Mbits/sec
[  3] 38.0-40.0 sec  4.02 MBytes  16.8 Mbits/sec
[  3] 40.0-42.0 sec  4.13 MBytes  17.3 Mbits/sec
[  3] 42.0-44.0 sec  4.07 MBytes  17.1 Mbits/sec
[  3] 44.0-46.0 sec  4.09 MBytes  17.2 Mbits/sec
[  3] 46.0-48.0 sec  4.13 MBytes  17.3 Mbits/sec
[  3] 48.0-50.0 sec  4.08 MBytes  17.1 Mbits/sec
[  3] 50.0-52.0 sec  4.09 MBytes  17.2 Mbits/sec
[  3] 52.0-54.0 sec  4.00 MBytes  16.8 Mbits/sec
[  3] 54.0-56.0 sec  3.84 MBytes  16.1 Mbits/sec
[  3] 56.0-58.0 sec  4.13 MBytes  17.3 Mbits/sec
[  3] 58.0-60.0 sec  4.06 MBytes  17.0 Mbits/sec
[  3]  0.0-60.0 sec   122 MBytes  17.1 Mbits/sec
root@DD-WRT:~#
```

```text:top(DD-WRT)
root@DD-WRT:~# top
Mem: 20448K used, 40988K free, 0K shrd, 2952K buff, 7924K cached
CPU: 46.7% usr 32.4% sys  0.0% nic  8.1% idle  0.0% io  0.0% irq 12.7% sirq
Load average: 1.42 0.59 0.22 3/48 1795
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
 1788     1 root     R     3012  4.8   0 84.9 /usr/sbin/openvpn --config /tmp/o
 1793  1755 root     S     6128  9.9   0  5.9 iperf -c 192.168.99.1 -t 60 -i 2
  892     1 root     S     2332  3.7   0  0.2 hostapd -B -P /var/run/ath0_hosta
 1792  1791 root     R     1336  2.1   0  0.2 top
 1531     1 root     S     2460  3.9   0  0.0 startservice_f run_rc_startup
 1749     1 root     S     2164  3.5   0  0.0 httpd -p 80
  547     1 root     S     1720  2.7   0  0.0 watchdog
 1520     1 root     S     1708  2.7   0  0.0 wland
 1754     1 root     S     1680  2.7   0  0.0 resetbutton
 1127     1 root     S     1468  2.3   0  0.0 process_monitor
 1791  1756 root     S     1336  2.1   0  0.0 -sh
 1755  1354 root     S     1336  2.1   0  0.0 -sh
  964     1 root     S     1324  2.1   0  0.0 telnetd
    1     0 root     S     1304  2.1   0  0.0 /sbin/init
 1354  1005 root     S     1260  2.0   0  0.0 dropbear -b /tmp/loginprompt -r /
 1756  1005 root     S     1260  2.0   0  0.0 dropbear -b /tmp/loginprompt -r /
 1005     1 root     S     1196  1.9   0  0.0 dropbear -b /tmp/loginprompt -r /
  989     1 root     S      884  1.4   0  0.0 dnsmasq --conf-file=/tmp/dnsmasq.
  543     1 root     S      844  1.3   0  0.0 /sbin/mstpd
  529     1 root     S      796  1.2   0  0.0 /sbin/hotplug2 --set-rules-file /

```

60秒間測定し平均が 17.1 Mbits/sec というスコアになりました。
負荷を見た感じDD-WRTのCPUがボトルネックになっていそうです。
直接接続で測定した場合、23.8Mbits/secでした。

# まとめ
無事、疎通の確認が行えた。
OpenVPNはソフトウェアVPNのため、CPU負荷によってスループットにバラつきがでそう。
今回コンフィグで指定しなかったパラメータとかを煮詰めるとまだいい値がでたかも。

# 参考ページ
[Static Key Mini-HOWTO](https://openvpn.net/index.php/open-source/documentation/miscellaneous/78-static-key-mini-howto.html)
[OpenVPN 2.0.x](https://openvpn.net/index.php/open-source/documentation/manuals/65-openvpn-20x-manpage.html)

# おまけ
安全ではなくなりますが、認証と暗号を無効にしてスループットを測定してみました。

```
auth none
cipher none
```

```text:iperf(DD-WRT)
root@DD-WRT:~# iperf -c 192.168.99.1 -t 60 -i 2
------------------------------------------------------------
Client connecting to 192.168.99.1, TCP port 5001
TCP window size: 19.5 KByte (default)
------------------------------------------------------------
[  3] local 192.168.99.2 port 44942 connected with 192.168.99.1 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 2.0 sec  4.00 MBytes  16.8 Mbits/sec
[  3]  2.0- 4.0 sec  4.26 MBytes  17.9 Mbits/sec
[  3]  4.0- 6.0 sec  4.26 MBytes  17.9 Mbits/sec
[  3]  6.0- 8.0 sec  4.30 MBytes  18.1 Mbits/sec
[  3]  8.0-10.0 sec  4.34 MBytes  18.2 Mbits/sec
[  3] 10.0-12.0 sec  4.18 MBytes  17.5 Mbits/sec
[  3] 12.0-14.0 sec  4.25 MBytes  17.8 Mbits/sec
[  3] 14.0-16.0 sec  4.18 MBytes  17.5 Mbits/sec
[  3] 16.0-18.0 sec  4.27 MBytes  17.9 Mbits/sec
[  3] 18.0-20.0 sec  4.35 MBytes  18.3 Mbits/sec
[  3] 20.0-22.0 sec  4.35 MBytes  18.3 Mbits/sec
[  3] 22.0-24.0 sec  4.25 MBytes  17.8 Mbits/sec
[  3] 24.0-26.0 sec  4.18 MBytes  17.5 Mbits/sec
[  3] 26.0-28.0 sec  4.31 MBytes  18.1 Mbits/sec
[  3] 28.0-30.0 sec  4.27 MBytes  17.9 Mbits/sec
[  3] 30.0-32.0 sec  4.31 MBytes  18.1 Mbits/sec
[  3] 32.0-34.0 sec  4.26 MBytes  17.9 Mbits/sec
[  3] 34.0-36.0 sec  4.26 MBytes  17.9 Mbits/sec
[  3] 36.0-38.0 sec  4.38 MBytes  18.4 Mbits/sec
[  3] 38.0-40.0 sec  4.27 MBytes  17.9 Mbits/sec
[  3] 40.0-42.0 sec  4.23 MBytes  17.7 Mbits/sec
[  3] 42.0-44.0 sec  4.25 MBytes  17.8 Mbits/sec
[  3] 44.0-46.0 sec  4.21 MBytes  17.7 Mbits/sec
[  3] 46.0-48.0 sec  4.36 MBytes  18.3 Mbits/sec
[  3] 48.0-50.0 sec  4.27 MBytes  17.9 Mbits/sec
[  3] 50.0-52.0 sec  4.34 MBytes  18.2 Mbits/sec
[  3] 52.0-54.0 sec  4.28 MBytes  18.0 Mbits/sec
[  3] 54.0-56.0 sec  4.30 MBytes  18.0 Mbits/sec
[  3] 56.0-58.0 sec  4.27 MBytes  17.9 Mbits/sec
[  3] 58.0-60.0 sec  4.30 MBytes  18.1 Mbits/sec
[  3]  0.0-60.0 sec   128 MBytes  17.9 Mbits/sec
root@DD-WRT:~#
```

```text:top(DD-WRT)
Mem: 22032K used, 39404K free, 0K shrd, 3284K buff, 9200K cached
CPU: 14.0% usr 22.0% sys  0.0% nic 51.9% idle  0.0% io  0.0% irq 11.9% sirq
Load average: 0.64 0.25 0.16 3/47 2302
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
 1816     1 root     R     3004  4.8   0 35.0 /usr/sbin/openvpn --config /tmp/o
 2266  2220 root     S     6128  9.9   0  8.9 iperf -c 192.168.99.1 -t 60 -i 2
 1744     1 root     S     2660  4.3   0  0.5 httpd -p 80
 2255  2252 root     R     1336  2.1   0  0.2 top
  888     1 root     S     2332  3.7   0  0.0 hostapd -B -P /var/run/ath0_hosta
  544     1 root     S     1720  2.7   0  0.0 watchdog
 1506     1 root     S     1708  2.7   0  0.0 wland
 1749     1 root     S     1680  2.7   0  0.0 resetbutton
 1141     1 root     S     1468  2.3   0  0.0 process_monitor
 2220  2217 root     S     1336  2.1   0  0.0 -sh
 2252  2251 root     S     1336  2.1   0  0.0 -sh
  963     1 root     S     1324  2.1   0  0.0 telnetd
    1     0 root     S     1304  2.1   0  0.0 /sbin/init
 2251  1029 root     S     1260  2.0   0  0.0 dropbear -b /tmp/loginprompt -r /
 2217  1029 root     S     1260  2.0   0  0.0 dropbear -b /tmp/loginprompt -r /
 1029     1 root     S     1196  1.9   0  0.0 dropbear -b /tmp/loginprompt -r /
 1002     1 root     S      884  1.4   0  0.0 dnsmasq --conf-file=/tmp/dnsmasq.
  540     1 root     S      844  1.3   0  0.0 /sbin/mstpd
  513     1 root     S      796  1.2   0  0.0 /sbin/hotplug2 --set-rules-file /
 1566     1 root     S      792  1.2   0  0.0 cron
```

ハッシュ値を作成する処理がなくなるので、CPU負荷が下がって、速度も増加したようです。