OpenVPNをpolicy-based routingによる複雑なルーティングで使う

あるサーバを中継していろんなサーバへのVPNを試みる。同時接続の制限があったり、いろんなところのVPNに一気につなぐときのためのメモ。
![multihome.png](https://qiita-image-store.s3.amazonaws.com/0/19148/b8328ee8-ef1c-9af8-81ce-7dd211b22edf.png)

# OpenVPNサーバ
まず、複数のVPNを張るにあたって注意することは、tunデバイスが複数作られるため、名前を固定するほうがよい。
まず端末から受ける接続用インターフェイスをtunVpnとするために、OpenVPNサーバー用設定に以下の設定を施す。

```
;dev tap # もしあればコメントアウト
;dev tun # もしあればコメントアウト
dev-type tun
dev tunVpn
```
この設定によりまず tunVpn インターフェイスが作られる。このインターフェイスから端末がやってくる。
お好みで、`client-to-client`を設定すると、クライアント同士（図の左の黒い枠、端末同士）で通信ができる。

# Linuxのルーティング設定
NAPTによるアドレス・マスカレード(forwarding)やVPNサーバとしての設定。
こちらが詳しい。
https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-ubuntu-14-04
が、以下のようにしておくと楽になる。

```
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o tun+ -j MASQUERADE
COMMIT
```
`tun+` というのはtun*にマッチするネットワーク・インターフェイスのこと。
このあと大量に tunなんちゃら というインターフェイスを作るので必要な設定である。
これにより同じ設定を何度も書かずによくなる。
クライアントから受けた接続をLinuxがNAPTで身代わりになって、ほかのVPNへつないでくれる。

# OpenVPNクライアントとしての別のVPNにつなぐ設定
## まずは普通につないでみる
一般的な会社VPNの例。このVPNは、デフォルトゲートウェイを提供せず、社内LANへのアクセスを提供する。

```
client

# 重要！
;dev tun
dev-type tun
dev tunMax

proto udp
remote hostname.example.com 1194 # 変えて
resolv-retry infinite
nobind
persist-tun
auth-nocache

# インラインにしたので、これらファイルはもはや要らない
#ca ca.crt
#key private.key
#cert client.crt

comp-lzo
verb 3
;mssfix 1300

<ca>
-----BEGIN CERTIFICATE-----
略
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
略
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN RSA PRIVATE KEY-----
略　というかプライベートなので。
-----END RSA PRIVATE KEY-----
</key>
```

`<ca>`～`</ca>`のようなものは、別のファイルではなくインラインにできるのでファイルがごちゃごちゃしないので便利である。
以上のように tun デバイスの名前を変えるのがポイントである。

ほかにも、接続するVPN先の分だけ設定ファイルを用意する。同じように名前を変えつつ、tunインターフェイスを適当に設定する。こちらの環境ではトップの画像のように、`tunMax` `tunTkb` `tunPia` がある。

## デフォルトゲートウェイとして使うVPN
`tunPia`は www.privateinternetaccess.com に接続してある。このサービスはユーザー名＆パスワード認証であり、自動起動の際の認証のため、IDとパスワードを一行ずつに書いた `auth-user-pass <ファイル名>` という設定で勝手に認証させる。
ただし、PrivateInternetAccessのような匿名VPNは、ルーティングテーブルを勝手にpushしてくるため、これをブロックするため `route-nopull` が必要である。

このようにしたあとは、次にルーティングを設定する。

# ポリシーベース・ルーティング (PBR: policy-based routing)
いろいろなサイトでPBRについて説明されているので、設定だけを載せる。

```
ip rule add from 10.8.0.0/24 table 200 # VPNクライアントからの接続はルール200である
ip route add 10.8.0.0/24 dev tunVpn table 200 # VPNクライアント（図の黒枠）のIPセグメント
ip route add 133.51.0.0/16 dev tunTkb table 200 # 大学のIPセグメント
ip route add 130.158.0.0/16 dev tunTkb table 200 # 大学のIPセグメント
ip route add 172.31.0.0/16 dev tunMax table 200 # 会社のIPセグメント
ip route add default dev tunPia table 200 # 匿名VPN用のデバイスがデフォルトとなる
```
この設定を行うと、VPNクライアントのIPセグメントから来た接続はルール200で裁かれる。そのルール200とは、上記2行目以降のルーティングテーブルである。最終的にルーティングテーブルにないIPアドレスへは `tunPia` インターフェイスからインターネットへつながる匿名化VPNサービスへ行く。これで端末群は匿名化IPアドレスでインターネットに出られる。

一方サーバ自体はサーバのデフォルトゲートウェイから出ることになる。パッケージのアップデートなどくらいでしかインターネットを利用しないサーバは匿名化する必要はない。

この設定は再起動で消えるのでうまくVPN接続確立時に設定されるよう `up` で設定ファイルに書かないといけないと思う。
man page: https://openvpn.net/index.php/open-source/documentation/manuals/65-openvpn-20x-manpage.html

# Ubuntu 15.10でのサービス (systemd)
https://fedoraproject.org/wiki/Openvpn#Working_with_systemd
/etc/openvpn/nantoka.conf だけをスタートさせたいなら、`systemctl start openvpn@nantoka`とする。一方、`systemctl start openvpn`とするとディレクトリ中すべてのconfig
が開始される。
OpenVPNはサーバーもクライアントも似たような設定ファイルであり、同時に両方を動かせる。