GbEが4ポートもあるのならばVPNルータにしたいよなぁ、ということでOpenVPN
サーバにしてみる。
ネットワーク構成
今回は、二つのサブネット(10.3.93.0/24, 10.39.3.0/24)の上に
VPN(10.3.9.0/24)を構築する。
各ホストのハード・ソフトは以下の通りである。
各ホストのハード・ソフトは以下の通りである。
- server(OpenBlocks AX3)
- Kernel: 3.0.6 #1 SMP Thu Apr 18 12:26:22 JST 2013 armv7l
- OpenVPN: 2.1.3-2+squeeze1(Debian squeezeパッケージ)
- hatsune
- CPU: AMD Opteron(tm) Processor 3280
- NIC: Intel Corporation 82574L Gigabit Network Connection
- Kernel: 3.8.7-1-ARCH #1 SMP PREEMPT Sat Apr 13 09:01:47 CEST 2013 x86_64
- OpenVPN: 2.3.0-2(Arch Linuxパッケージ)
- kagamine
- CPU: AMD E-450 APU with Radeon(tm) HD Graphics
- NIC: Atheros AR8151 v2.0 Gigabit Ethernet (rev c0)
- Kernel: 3.8.7-1-ARCH #1 SMP PREEMPT Sat Apr 13 09:01:47 CEST 2013 x86_64
- OpenVPN: 2.3.0-2(Arch Linuxパッケージ)
鍵ファイルの生成
まず、認証に必要な公開鍵を作成する必要がある。OpenVPN公式にて用意して
いる公開鍵基盤を管理するスクリプト群としてeasy-rsaが存在するので、これ
を用いる。
easy-esaの各スクリプトを実行する前に、varsファイルを元に有効期限や証明 書の情報を環境変数に設定する。初期化する場合はclean-allスクリプトの実 行が必要である(clean-allを実行するとkeysディレクトリ以下の全ての鍵ファ イルが削除されるので注意)。
その後buildスクリプトを実行しCA鍵、サーバ鍵、クライアント鍵、DHパラメー タの生成を行う。ビルド作業はウィザード形式で行われるが、基本的にvarsファ イルと引数に渡した名前を元にデフォルト値が設定されているため、特に値を 指定し直す必要がある箇所はない。また、今回は秘密鍵にパスフレーズは付与 しない。
easy-esaの各スクリプトを実行する前に、varsファイルを元に有効期限や証明 書の情報を環境変数に設定する。初期化する場合はclean-allスクリプトの実 行が必要である(clean-allを実行するとkeysディレクトリ以下の全ての鍵ファ イルが削除されるので注意)。
その後buildスクリプトを実行しCA鍵、サーバ鍵、クライアント鍵、DHパラメー タの生成を行う。ビルド作業はウィザード形式で行われるが、基本的にvarsファ イルと引数に渡した名前を元にデフォルト値が設定されているため、特に値を 指定し直す必要がある箇所はない。また、今回は秘密鍵にパスフレーズは付与 しない。
% git clone https://github.com/OpenVPN/easy-rsa.git % cd easy-rsa/easy-esa/2.0 % vi vars % source ./vars % ./clean-all % ./build-ca ... % ./build-key-server server ... % ./build-key hatsune ... % ./build-key kagamine ... % ./build-dh ...生成した鍵ファイルはサブディレクトリkeys以下に全て保存される。 easy-rsaの詳細に関してはdoc/README-2.0やスクリプトのソースを参照すると よい。
サーバ設定
サーバのネットワーク設定とOpenVPNの設定ファイルの作成を行う。
miku@obsax3% sudo sysctl net.ipv4.ip_forward=1 miku@obsax3% sudo ip link set eth1 up miku@obsax3% sudo ip addr add 10.3.93.1/24 dev eth1 miku@obsax3% sudo ip link set eth2 up miku@obsax3% sudo ip addr add 10.39.3.1/24 dev eth2OpenVPNサーバの最小限の設定ファイルは以下のようになる。
port 1194 proto udp dev tun0 ca key/ca.crt cert key/server.crt key key/server.key dh key/dh2048.pem server 10.3.9.0 255.255.255.0 ifconfig 10.3.9.1 255.255.255.0 client-to-client client-config-dir ccd/ comp-lzo keepalive 10 60 ping-timer-rem persist-key persist-tun今回はクライアント毎にIPアドレスを固定で割り当てる為、 client-config-dirにて設定したディレクトリ(ccd)にCN毎のファイル (hatsune, kagamine)を置き、それぞれにIPアドレスの割り当てオプションを 記述する。
# hatsune ifconfig-push 10.3.9.2 10.3.9.1
# kagamine ifconfig-push 10.3.9.3 10.3.9.1
クライアント設定
hatsune
miku@hatsune% sudo ip link set enp4s0 up miku@hatsune% sudo ip addr add 10.3.93.2/24 dev enp4s0 miku@hatsune% sudo ip route add 10.39.3.0/24 via 10.3.93.1クライアントhatsuneの設定ファイルは以下の通りである。
client dev tun0 proto udp remote 10.3.93.1 1194 persist-key persist-tun ca key/ca.crt cert key/hatsune1024.crt key key/hatsune1024.key ns-cert-type server comp-lzo
kagamine
miku@kagamine% sudo ip link set enp2s0 up miku@kagamine% sudo ip addr add 10.39.3.2/24 dev enp2s0 miku@kagamine% sudo ip route add 10.3.93.0/24 via 10.39.3.1クライアントkagamineの設定ファイルは以下の通り。 hatsuneの設定ファイルとの違いは、リモートのIPアドレスと証明書・秘密鍵 のファイル名である。
client dev tun0 proto udp remote 10.39.3.1 1194 persist-key persist-tun ca key/ca.crt cert key/kagamine.crt key key/kagamine.key ns-cert-type server #comp-lzo fragment 1472 mssfix 1472
各ホスト毎のファイルのリスト
各ホスト毎に必要なファイルは以下の通りである。
- hatsune
- client.conf (クライアント設定ファイル)
- key/ca.crt (CA証明書)
- key/hatsune.key (クライアント秘密鍵)
- key/hatsune.crt (クライアント証明書)
- kagamine
- client.conf (クライアント設定ファイル)
- key/ca.crt (CA証明書)
- key/kagamine.key (クライアント秘密鍵)
- key/kagamine.crt (クライアント証明書)
- server
- server.conf (サーバ設定ファイル)
- key/ca.crt (CA証明書)
- key/server.key (サーバ秘密鍵)
- key/server.crt (サーバ証明書)
- key/dh2048.pem (DHパラメータ)
- ccd/hatsune (クライアントhatsune設定ファイル)
- ccd/kagamine (クライアントkagamine設定ファイル)
デーモンの起動
各ホスト毎に先ほど準備したファイルを転送し、OpenVPNデーモンを起動する。
それぞれInitialization Sequence Completedとなれば接続が確立できている
筈である。
miku@obsax3% sudo openvpn server.conf Fri Apr 19 22:19:05 2013 OpenVPN 2.1.3 arm-unknown-linux-gnueabi [SSL] [LZO2] [EPOLL] [PKCS11] [MH] [PF_INET6] [eurephia] built on Feb 21 2012 Fri Apr 19 22:19:05 2013 NOTE: OpenVPN 2.1 requires '--script-security 2' or higher to call user-defined scripts or executables Fri Apr 19 22:19:05 2013 /usr/bin/openssl-vulnkey -q -b 2048 -m <modulus omitted> Fri Apr 19 22:19:06 2013 TUN/TAP device tun0 opened Fri Apr 19 22:19:06 2013 /sbin/ifconfig tun0 10.3.9.1 pointopoint 10.3.9.2 mtu 1500 Fri Apr 19 22:19:06 2013 UDPv4 link local (bound): [undef] Fri Apr 19 22:19:06 2013 UDPv4 link remote: [undef] Fri Apr 19 22:19:06 2013 Initialization Sequence Completed Fri Apr 19 22:19:15 2013 10.3.93.2:1194 Re-using SSL/TLS context Fri Apr 19 22:19:15 2013 10.3.93.2:1194 LZO compression initialized Fri Apr 19 22:19:15 2013 10.3.93.2:1194 [hatsune] Peer Connection Initiated with [AF_INET]10.3.93.2:1194 Fri Apr 19 22:19:22 2013 10.39.3.2:1194 Re-using SSL/TLS context Fri Apr 19 22:19:22 2013 10.39.3.2:1194 LZO compression initialized Fri Apr 19 22:19:22 2013 10.39.3.2:1194 [kagamine] Peer Connection Initiated with [AF_INET]10.39.3.2:1194
性能測定
VPNクライアント間の通信が確立できていることを確認し、性能を測定する。
クライアントの1つ(hatsune)にて性能測定用のファイルを生成し、tmpfsがマ
ウントされたディレクトリに置きHTTPとSCPでダウンロード可能な状態にして
おく。(tmpfs上に置くのは、ディスクアクセス速度がボトルネックとならない
ようにするため)
測定用ファイルの生成は以下のように行った。
SCPの場合、以下のように/dev/nullを宛先として指定する。
予想以上に暗号化処理の負荷が大きいようで、VPN経由だと非VPN経由の1/24ま
でスループットが低下した。ファイル転送の際には、OpenBlocks上のopenvpn
デーモンのCPU使用率が100%に張り付いていた。
OpenVPNは今のところ単一プロセスでのSMP対応はされていないため、2core以 上を活かしたい場合はサーバ・クライアント双方を–remote-random等で分割 し利用できるよう準備する必要がある。
似た構成のIPSecだとどの程度になるのか気になるところ。
測定用ファイルの生成は以下のように行った。
miku@hatsune% dd if=/dev/urandom of=/tmp/dummy.img bs=1M count=1000 miku@hatsune% dd if=/dev/zero of=/tmp/zero.img bs=1M count=1000今回は、VPNを用いずに通信した場合、VPN上にてLZO圧縮を有効にし通信した 場合、VPN上にてLZO圧縮を無効にし通信した場合について比較を行う。 LZO圧縮を無効にする場合は、サーバとクライアント全ての設定ファイルから comp-lzoオプションを取り除く。
SCPの場合、以下のように/dev/nullを宛先として指定する。
miku@kagamine% scp 10.3.9.2:/tmp/dummy.img /dev/null dummy.img 100% 1000MB 5.0MB/s 03:22HTTPの場合もSCPと同様に、/dev/nullを宛先として指定する。
% wget -O/dev/null http://10.3.9.2:3939/dummy.img --2013-04-19 23:07:34-- http://10.3.9.2:3939/dummy.img 10.3.9.2:3939 に接続しています... 接続しました。 HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 1048576000 (1000M) [application/octet-stream] `/dev/null' に保存中 100%[============================>] 1,048,576,000 5.01MB/s 時間 3m 21s 2013-04-19 23:10:55 (4.98 MB/s) - `/dev/null' へ保存完了 [1048576000/1048576000]それぞれ10回づつ計測を行った場合の平均は以下のようになった。
テスト内容 | 非VPN | VPN | VPN(lzo) |
---|---|---|---|
転送(1GB, HTTP, ZERO) | 112MB/s | 5.0MB/s | 7.8MB/s |
転送(1GB, HTTP, RANDOM) | 112MB/s | 5.0MB/s | 4.9MB/s |
転送(1GB, SCP, RANDOM) | 16.7MB/s | 5.1MB/s | 5.0MB/s |
ping rtt min/avg/max/mdev | 0.557/0.699/0.765/0.080 | 1.471/1.520/1.582/0.058 | 1.525/1.558/1.638/0.031 |
ping(-s 1472 -M do) | 0.628/0.802/0.846/0.071 | 2.119/2.180/2.276/0.077 | 1.544/1.689/1.737/0.050 |
OpenVPNは今のところ単一プロセスでのSMP対応はされていないため、2core以 上を活かしたい場合はサーバ・クライアント双方を–remote-random等で分割 し利用できるよう準備する必要がある。
似た構成のIPSecだとどの程度になるのか気になるところ。
OpenVPNのバージョンを上げてみる
試しにOpenBlocks上にてOpenVPN-2.3.1を野良ビルドし比較してみたが、今回
のテストにおける速度に関してはほとんど同じだった。
野良ビルドの手順は以下の通り。
野良ビルドの手順は以下の通り。
miku@obsax3$ aptitude install liblzo2-dev libssl-dev libpam0g-dev miku@obsax3$ wget http://swupdate.openvpn.org/community/releases/openvpn-2.3.1.tar.gz miku@obsax3$ tar xzf openvpn-2.3.1.tar.gz miku@obsax3$ cd openvpn-2.3.1 miku@obsax3$ ./configure --prefix=/usr/openvpn && make && sudo make install
beta版ファームウェア(wheezy)を試す
そうこうしているうちにdebian wheezyがOpenBlocks AX3に入ったようなので、
早速アップデートして比較してみる。wheezyでのカーネルのバージョンは3.2.36、OpenVPNのバージョンは2.2.1-8となっ
ている。
一気に速くなるのかなぁとわくわくしながら実行したのだが、結果は地味に遅くなってしまった。OpenVPN経由でない場合も遅くなっているようなので、
原因はOpenVPN以外(kernel側?)に存在する可能性が高そうである。
テスト内容 | 非VPN | VPN | VPN(lzo) |
---|---|---|---|
転送(1GB, HTTP, ZERO) | 112MB/s | 4.7MB/s | 7.6MB/s |
転送(1GB, HTTP, RANDOM) | 112MB/s | 4.7MB/s | 4.7MB/s |
転送(1GB, SCP, RANDOM) | 16.4MB/s | 4.7MB/s | 4.7MB/s |
ping rtt min/avg/max/mdev | 1.096/1.596/1.767/0.264 | 2.035/2.553/2.693/0.202 | 2.052/2.589/2.863/0.208 |
ping(-s 1472 -M do) | 1.203/1.738/1.828/0.182 | 2.694/3.109/3.285/0.213 | 2.805/2.846/3.110/0.107 |
その他
kagamineのAtheros AR8151が、同時に蟹wlanを利用している状態である程度通
信すると突然死する謎の症状に悩まされる事があった。wlanを止めると死なな
い。原因は不明。