ConoHa の VPN サーバーと routerboard を OpenVPN で接続する

ConoHa の VPS サーバーを OpenVPN クライアントにして routerboard のルーターが持つ OpenVPN サーバーに接続したのでその手順メモ。
別に VPS 側は ConoHa じゃなくてもいいけど、使っているのが ConoHa なので。

# やりたいこと
LAN 内にいくつかあるサーバーを補強するために、追加サーバーを ConoHa に作ってそれを LAN内サーバーと同等に扱いたい。
また、インターネットにサービスを公開できるようにしたい。

![VPN.png](https://qiita-image-store.s3.amazonaws.com/0/50737/015134b1-8054-fc63-7a79-79552eafa5ec.png)
目的とする構成はざっくりこんな感じ。
LAN 内サーバーは現在幾つかあるのだけれども、ConoHa 上に立てた新サーバーを OpenVPN で接続して LAN から参照したり、ConoHa 側から LAN 内のサービス(NASとか)を利用したい。

具体的には LAN 内に Rancher Server があって、ConoHa 上に rancher node(docker farm) をポコポコ立てるといった事がやりたいのです。コンテナはインターネットに公開するけれども、サーバーコンソールは LAN 内にあって非公開という作り。

そのために VPN を構築しようと考えた。


# routerboard 側 OpenVPN サーバーの設定

基本的に WinBox を使用して GUI で設定。

## サーバー側の証明書作成

- System/Certificates から Certificates タブを選択し、追加ボタンで新規作成
- General タブの設定で気を付けるのは Common Name が VPS 側からアクセスできるドメイン名にすること、キーサイズは 2048 であること
- Key Usage タブは ipsec tunnel と TLS client/server にチェックを入れてみた(良く分かっていない
- Apply で保存して問題無ければ Sign を押して署名、生成、これで証明書が作成される
- Export ボタンでファイル名を付けて cert を保存、Files の中に現れるので Download を選択して手元にコピー
- これを OpenVPN サーバーの証明書として使うためクライアント側のマシンに転送しておく

## IPアドレスプール

- IP/Pool から VPN クライアントに割り当てるアドレス帯を作成
- 10.0.2.0/24 を VPN 割り当てにしようと思ったので今回は `10.0.2.8-10.0.2.199` を設定

## VPN用ブリッジ作成

- VPN クライアントが1つならば別段必要ないけれども、複数クライアントが接続する事を想定した場合 VPN 用の bridge を作成したほうが良いかも
- Bridge/Bridge タブから新規作成でブリッジを1つ作成、`vpn_bridge` と名前を付けた

## OVPN 設定

- PPP/Profile タブを開いて新規 profile を作成
 - Remote Address に先ほど作成したアドレスプールを指定
 - Local Address に自アドレスを設定、アドレスプールと同じセグメントにする
 - Bridge に vpn bridge を設定
 - Protocol タブでは Use Encription を yes に、他は default で OK
- PPP/secret タブを開いてログイン名を新規作成
  - service を ovpn に
  - profile を先ほど作成した物に
  - login名と password を設定
- PPP/Interface タブを開いて OVPN Server binding を新規作成
  - 無くても接続はできるけれども、作っておくと bridge に接続できるので便利
  - user に secret で作ったユーザー名を入力
- Bridge/Port タブに移動して bridge と PPP interface を接続
  - ports 作成で、bridge を vpn bridge に、port を先ほどの OVPN Server binding に接続
- PPP/Interface タブに移動、OVPN Server ボタンを押してサーバー設定
  - Enable に設定
  - Netmask 指定、今回は 24
  - Max MTU を 1420 くらいに設定
  - Profile を作成した物に指定
  - Certificates は先に作成したものを指定
  - Cipher に aes 256 を追加

これで一通りの設定が完了。

## ファイヤウォール設定

必要があれば設定

- IP/Firewall/Filter Rules タブを開く
  - input,tcp,port 1194 を accept で設定

# ConoHa 側 OpenVPN クライアントの設定

## 前準備

OS は Debian8 を選択。以降は Debian での手順。

念のため `/dev/net/tun` が存在することを確認しておく。

## OpenVPN のインストール

- apt-get install openvpn

## 証明書の配置

- routerboard で作成してダウンロードしておいた証明書を、scp 等で転送、`/etc/openvpn/` にコピーして配置する

## OpenVPN クライアント設定

ファイル名 `/etc/openvpn/(接続名).conf` で設定を作成。
設定ファイル例

```
daemon
dev tun
proto tcp-client
remote (routerboard のアドレス) 1194
resolv-retry infinite
nobind
persist-key
persist-tun
tls-client
ca /etc/openvpn/(サーバーの証明書).crt
cipher aes-256-cbc
auth sha1
pull
route 192.168.0.0 255.255.255.0
route 10.0.2.0 255.255.255.0
script-security 2
up /etc/openvpn/up_dns.sh
down /etc/openvpn/down_dns.sh
auth-user-pass /etc/openvpn/auth.txt
```

- routeboard の OpenVPN は UDP ではなく TCP のみなので proto は tcp-client を明示しておく
- ca で配置したサーバー証明書を指定する
- cipher と auth は routerboard の OVPN 設定で許可したものを設定
- 通常ルーティングはサーバー側で設定しておいて、pull することでクライアント側に展開されるのだけれども routerboard にはそのサーバー側設定が無いのでクライアント側で静的設定する
  - route を記述することでルーティングを追加、このインタフェースにルーティングするセグメントを記述
- VPN 越しの DNS 設定も通常 pull で設定されるのだけれども、それができない場合は up/down 時のシェルスクリプトで `resolv.conf` を書き換えて DNS を設定する
  - `script-security 2` でローカルスクリプトの実行を指定
  - up / down で実行するスクリプトを指定
  - LAN 側の DNS は 192.168.0.1 なのでそのときのスクリプト例を後記する
- routerboard の OpenVPN は鍵交換型では無くパスワード型なのでそれを指定する
  - `auth-user-pass` を付けるとパスワード認証になる
  - 通常は接続施行時にユーザー名とパスワードの入力を求められる
  - `auth-user-pass` の後ろにパスワードファイルを指定することで、入力を省略することが可能
  - パスワードファイルの中身は「ログイン名<改行>パスワード<改行>」の 2行がそのまま描かれたフォーマット
  - パスワードファイルのパーミッションは 0600 に設定しないといけない

``` up_dns.sh
!/bin/sh

sed -i '/192.168.0.1/d' /etc/resolv.conf
sed -i -e 's/^\(nameserver\)/#\1/' /etc/resolv.conf
echo 'nameserver 192.168.0.1' >> /etc/resolv.conf
```

``` down_dns.sh
#!/bin/sh

sed -i '/192.168.0.1/d' /etc/resolv.conf
sed -i -e 's/^#nameserver/nameserver/' /etc/resolv.conf
```

## 接続確認

設定ファイルが準備できたら接続を確認する。

```
# openvpn --config /etc/openvpn/(接続名).conf
```

テスト時は設定ファイル無いの `daemon` を無効にしておいたほうが良いかもしれません。

## systemd での自動起動

設定ファイルの接続名(ファイル名から .conf を削った物)を指定して、その設定ファイルを指定したユニットの実行ができる。

登録、起動は以下の様に行う。

```
# systemctl enable openvpn@(接続名).service
# systemctl start openvpn@(接続名).service
```

VPS を再起動して、起動後自動的に VPN 接続されることを確認。

# 疎通確認

ここまでの手順で、`192.168.0.*` 側と `10.0.2.*` 側で相互に通信できるようになっているはず。適当に ping を飛ばして確認する。

お互いのセグメント(サーバーの位置)を気にせずに運用するには consul をインストールして管理すると便利。名前解決も容易になる。

# おわりに

インターネットと LAN の境界に routeboard のルーターを置いて VPN サーバーにすれば、クラウドVPS と VPN が張れそうとやったものの linux 側をクライアントにする例が少なく色々と調べる必要があった。

他にも色々な躓きポイントがあったため、手順をメモしておこうと思ったのが本記事の目的。
殴り書きメモまでに。