Ubuntu
OpenVPN

Ubuntu Server 14.04をVPNサーバーにしてみた。

More than 3 years have passed since last update.

折角家に自宅サーバーがあるので、VPNサーバー機能組み込んでみました。

目的

  • 勉強も兼ねて自宅のネットワークを外で使いたい。
  • STBの番組(WA-7000)で撮った番組を外で見たい。
  • MarkdownとQiitaの練習

結果

  • うまい事ルーティング出来て接続できた。
  • STBの番組が見れない!(WA-7000自体認識されなかった。 同じネットワーク下として認識されてないのかも?)

方法

必要なソフトを用意

次をaptでgetする
sudo apt-get install openvpn libssl-dev openssl easy-rsa

認証モノを発行する

aptでgetした後スーパーユーザーに切り替え、
make-cadir /etc/openvpn/easy-rsa
でRSAディレクトリを作成した後に、varsを修正する。
だいたいは64行目以降のこの部分を修正するだけで十分だと思う。

vars
export KEY_COUNTRY="(国)"
export KEY_PROVINCE="(都市)"
export KEY_CITY="(街)"
export KEY_ORG="(組織名)"
export KEY_EMAIL="(メールアドレス)"
export KEY_OU="(組織単位らしいので適当に)"

先ほどのvarsをソースにし、一旦綺麗にした後にCAを作成。
source vars && ./clean-all && ./build-ca
varsの値が読み込まれているはずなので、基本Enter連打で大丈夫。
次にpkitoolを通す。
./pkitool --initca && ./pkitool --server server

次にサーバー用の鍵を生成する
./build-key-server (サーバー用鍵の名前。サーバー名でいいかも?)
ここまで出来たら共有鍵を生成する
./build-dh
どうやら「Diffie-Hellman」という方式らしい。生成に結構時間がかかるので軽くストレッチでもしましょう。
(Celeron j1900で2分弱)
出来上がった鍵はkeysディレクトリに保存されているので、そのうち

  • crt
  • key
  • ca.crt
  • dh2048.pem

を、一つ上のディレクトリ(/etc/openvpn)にコピーしておく。
(後のOpenVPNの設定ファイルでは絶対参照できるけど書くのが面倒なので)

コピーしたら続いてVPN接続させたい機械の数だけ鍵を生成。
./build-key (鍵の名前)
生成された鍵ファイルは同じkeysの中にあるので、これを安全な方法でそれぞれのマシンにコピーしましょう。

最後にVPN自体の鍵(TLS)を作るために
openvpn --genkey --secret ta.key
と実行し、出来上がったta.keyを同じく/etc/openvpnの中に入れておく。

OpenVPNの設定

/etc/openvpn/server.confを編集・・・したいけどインストールしたての状態だとないため、

  • サンプルをコピー
    cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/

  • そして解凍
    gzip -d server.conf.gz

server.confの中身はだいたいこんな感じで動きました。より詳しいことは別途調べましょう。

server.conf
mode server
tls-server
tls-cipher DHE-RSA-AES256-SHA
cipher AES-256-CBC
keysize 256
auth SHA256

port 443
proto tcp

dev tun # iOS/Androidと繋げたかったためTUN方式

ca ca.crt
cert (build_key_serverにて作成したファイル名).crt
key (build_key_serverにて作成したファイル名).key
dh dh2048.pem

server (VPNにて使いたいIPアドレス 例:192.168.1.0) (ネットマスク)
ifconfig-pool-persist ipp.txt
push "route (実際にサーバーが使用しているネットワーク 例:192.168.0.0) (ネットマスク)"
push "redirect-gateway def1 bypass-dhcp"

push "dhcp-option DNS (DNSサーバのIPアドレス)"
push "dhcp-option DNS (必要であればサブDNSサーバのIPアドレス)"

client-to-client
tls-auth ta.key 0
comp-lzo
user nobody
group nogroup
persist-key
persist-tun

verb 3

# 必要ならばログをとる
status openvpn-status.log
log         openvpn.log

management localhost 17505 # telnetで入ると強制切断やステータスが確認できる

この状態でopenvpn --config server.confと実行してエラーが出ないか確認をする。
Initialization Sequence Completedで待機中になったら成功。

ルーティング設定

iptablesで
iptables -t nat -A POSTROUTING -s (VPNで使用するIPアドレス)/24 -o (使用するNICの名前) -j MASQUERADE
でそのままパケットをリレーさせる状態にし、
/sbin/iptables-save -c > /etc/iptables.rule
で保存。
/etc/network/if-pre-up.d/にiptablesを読み込ませるために適当なファイルを作成する

iptables_restore
#!/bin/sh
/sbin/iptables-restore < /etc/iptables.rule
exit

同じく/etc/network/if-up.dにroute用のシェルスクリプトを作成しておく。

routes
#!/bin/bash
/sbin/route add -net (VPNで使用するIPアドレス) netmask (ネットマスク) gw (ルーターのIPアドレス)
exit

作成後、忘れずにchmod +xで2つに実行権限を付けておく。
最後にsysv-rc-conf openvpn onをして起動時に実行するよう設定したら完成。

クライアントの設定

コピーしてきたファイルをひと通り揃え、適当な設定ファイルを作成する。

myvpn.ovpn
client
tls-auth ta.key 1
dev tun
proto tcp
remote (サーバーへのグローバルアドレスかドメイン) 443
ca ca.crt
cert (build_keyで使用した名前).crt
key (build_keyで使用した名前).key
resolv-retry infinite
nobind
persist-key
persist-tun
comp-lzo
verb 3

tls-cipher DHE-RSA-AES256-SHA
cipher AES-256-CBC
keysize 256
auth SHA256

といった内容で作成し、MacOSXならTunnelBrick、iOS/AndroidならOpenVPN for iOS/Androidを使用する。
TunnelBrickの場合は~/Library/Application Support/Tunnelblick/Configurations/の中に一式を入れ、起動して変換する。
iOS/Androidの場合は一式をそれぞれの端末に入れて読み込ませる。

上手くつながれば大成功です。お疲れ様でした。