複数のVPCに対して同時に複数のOpenVPN接続を行う

AWS

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

multiple-vpn-connection

よく訓練されたアップル信者、都元です。

以前、OpenVPNを利用した2拠点のVPC間VPNの検証を行いましたが、今回はこの仕組みを発展させ、A, B, Cの3拠点をVPN接続してみようと思います。

ただし、A-B間とA-C間の直接通信はしますが、B-C間の直接通信はしないイメージです。つまり、VPN接続は同時に2本ですね。図中のOpenVPNのロゴ表示のあるインスタンスにOpenVPNをインストールし、トンネリングを担ってもらいます。

OpenVPNの接続には通常1194/udpを利用しますが、今回は2本の同時接続が必要なため、もうひとつ1195/udpも併用します。

OpenVPN 2.0より、1つのOpenVPNプロセスで複数のクライアントを制御する「サーバモード」という動作モードがサポートされましたが、今回はシンプルに2プロセスでいきます。

というわけで、検証のためにこのVPC構成を構築する必要があるのですが…。VPCが3つ、Subnetが6つ、インスタンスが6つ、しかもどれも微妙に設定が異なる…。ここにだらだらと構築手順を書いても、VPC環境構築の練習にしかなりません。やりたいのはVPN接続です。そこでCloudFormationですよ。

CloudFormationによる環境構築

まず、本チュートリアル用のCloudFormationテンプレートをダウンロードしておきます。cloneするなりwgetなり右クリックで保存なり。

$ wget https://gist.github.com/miyamoto-daisuke/5168418/raw/4dea45d19a0c08faa938678cecb213dd81a93e52/multiple-vpn-connection.template

次に、CloudFormationのManagement Consoleに移動し、Create Stackボタンを押下します。

リージョンはus-east-1を利用してください。今から使うCloudFormationのテンプレートは、他のリージョンには対応していません。

スタック名は適当に。そしてテンプレートはUpload a Template Fileを選択して先ほどDLしたテンプレートファイルを指定し、次に進みます。

mvpn-cfn1

構築にあたってのパラメータを指定します。SSH接続を許すIPアドレスの範囲(ここはデフォルトのままでも構いません)及び、SSH接続に利用するキー名を入力します。さらにこの環境ではIAMユーザを作成するため、その確認のためのチェックボックス(I acknowledge that this template may create IAM resources)をONにしつつ、Continueを押下します。後続のページはすべてデフォルトのままで構いませんので、何度かContinueを押下し続けてください。

mvpn-cfn2

これで、いま作成したスタックのステータスが CREATE_IN_PROGRESS となります。この時CloudFormationは、VPC・Subnet・SecurityGroup・EC2インスタンス等、この検証に必要なリソースを順次自動作成しています。作成はシーケンシャルに進むため、しばらく時間が掛かります。恐らく15分程度…。そう考えると結構長いですね。

さて、何度かRefreshボタンを押しつつ、ステータスが CREATE_COMPLETE となるのを待ってください。環境の構築が完了したら、少々の設定が必要です。全てをCloudFormationで設定してしまう事も可能ですが、そこまでやってしまうと、SSHでログインしてpingしてみるだけでやることが終わってしまうので。

まず、各インスタンスのSecurityGroupの設定です。mvpc-openvpn-*の3つのEC2インスタンスに対して、それぞれのVPCのdefault追加(変更ではなく追加です)してください。つまり、見えている4つのSecurityGroupを全て設定することになります。

mvpc-openvpnc-sg

さらに、mvpc-terminal-*の3つのEC2インスタンスについて、それぞれ「*-SgOpenvpn-*」以外の3つを設定してください。

mvpc-terminal-sg

続いて、CloudFormationで、Outputsのタブを確認してください。作成した6つのEC2インスタンスに対して、それぞれログインするためのSSHコマンドが手に入ります。順次SSHでサーバにログインし、設定を進めていきましょう。

mvpc-outputs

余談ですが、検証のために何度もSSH接続を繰り返す時は、ローカルマシンの/path/toを鍵ディレクトリのシンボリックリンクにしておいたらとても便利でしたw

mvpc-openvpn-Aでの作業

OpenVPNは既にインストール済みです。2本のVPN接続用に鍵も2つ生成してあるので、内容を控えておいてください。後ほど、mvpc-openvpn-(B|C)にコピーします。また、OpenVPN設定ファイル/etc/openvpn/a-to-b.conf/etc/openvpn/a-to-c.confも生成済みのため、中身を確認しておいてください。

確認ができたらOpenVPNを起動します。万一起動に失敗した場合はsudo grep openvpn /var/log/messageでログが確認できます。

$ sudo cat /etc/openvpn/openvpn-key-ab.txt
$ sudo cat /etc/openvpn/openvpn-key-ac.txt
$ less /etc/openvpn/a-to-b.conf
$ less /etc/openvpn/a-to-c.conf
$ sudo /etc/init.d/openvpn start

mvpc-openvpn-Bでの作業

このサーバでは、まずmvpc-openvpn-Aで生成されたopenvpn-key-ab.txtファイルをコピーします。scpでも構いませんが、筆者は面倒なのでコンソール間でコピペして作成しました。また、このファイルのパーミッションは600にしておきます。このサーバでもOpenVPN設定ファイル/etc/openvpn/b-to-a.confの内容をざっと眺めておきましょう。

確認ができたらOpenVPNを起動します。ログの見方は先ほどと同じです。

$ sudo vi /etc/openvpn/openvpn-key-ab.txt
$ sudo chmod 600 /etc/openvpn/openvpn-key-ab.txt
$ less /etc/openvpn/b-to-a.conf
$ sudo /etc/init.d/openvpn start

mvpc-openvpn-Cでの作業

こちらでも、mvpc-openvpn-Bとほぼ同じ作業です。鍵はopenvpn-key-ac.txtを使って下さい。

$ sudo vi /etc/openvpn/openvpn-key-ac.txt
$ sudo chmod 600 /etc/openvpn/openvpn-key-ac.txt
$ less /etc/openvpn/c-to-a.conf
$ sudo /etc/init.d/openvpn start

ping疎通確認

さて、準備は以上です。順次mvpc-terminal-*にログインし、疎通を確認していきましょう。

AからB(通信成功)

[ec2-user@ip-10-0-1-11 ~]$ ping -c3 10.1.1.21
PING 10.1.1.21 (10.1.1.21) 56(84) bytes of data.
64 bytes from 10.1.1.21: icmp_seq=1 ttl=62 time=1.99 ms
64 bytes from 10.1.1.21: icmp_seq=2 ttl=62 time=1.70 ms
64 bytes from 10.1.1.21: icmp_seq=3 ttl=62 time=1.98 ms

--- 10.1.1.21 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 1.703/1.894/1.996/0.144 ms

BからA(通信成功)

[ec2-user@ip-10-1-1-21 ~]$ ping -c3 10.0.1.11
PING 10.0.1.11 (10.0.1.11) 56(84) bytes of data.
64 bytes from 10.0.1.11: icmp_seq=1 ttl=62 time=4.38 ms
64 bytes from 10.0.1.11: icmp_seq=2 ttl=62 time=2.02 ms
64 bytes from 10.0.1.11: icmp_seq=3 ttl=62 time=1.80 ms

--- 10.0.1.11 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 1.805/2.736/4.380/1.167 ms

AからC(通信成功)

[ec2-user@ip-10-0-1-11 ~]$ ping -c3 10.2.1.31
PING 10.2.1.31 (10.2.1.31) 56(84) bytes of data.
64 bytes from 10.2.1.31: icmp_seq=1 ttl=62 time=1.76 ms
64 bytes from 10.2.1.31: icmp_seq=2 ttl=62 time=1.83 ms
64 bytes from 10.2.1.31: icmp_seq=3 ttl=62 time=1.91 ms

--- 10.2.1.31 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 1.763/1.838/1.914/0.061 ms

CからA(通信成功)

[ec2-user@ip-10-2-1-31 ~]$ ping -c3 10.0.1.11
PING 10.0.1.11 (10.0.1.11) 56(84) bytes of data.
64 bytes from 10.0.1.11: icmp_seq=1 ttl=62 time=1.82 ms
64 bytes from 10.0.1.11: icmp_seq=2 ttl=62 time=1.88 ms
64 bytes from 10.0.1.11: icmp_seq=3 ttl=62 time=2.20 ms

--- 10.0.1.11 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 1.825/1.970/2.204/0.170 ms

BからC(通信できない)

[ec2-user@ip-10-1-1-21 ~]$ ping -c3 10.2.1.31
PING 10.2.1.31 (10.2.1.31) 56(84) bytes of data.

--- 10.2.1.31 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 12016ms

CからB(通信できない)

[ec2-user@ip-10-2-1-31 ~]$ ping -c3 10.1.1.21
PING 10.1.1.21 (10.1.1.21) 56(84) bytes of data.

--- 10.1.1.21 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 12014ms

想定通りですね。

後片付け

CloudFormationを使うと、リソースの後片付けも一発です。最初に作成したスタックを選択し、Delete Stackボタンをクリックして、Yes, Deleteを選ぶだけです。

mvpc-cfn3

再び少々時間が掛かりますが、本検証で作ったリソースをすべて片付けてくれます。DELETE_IN_PROGRESSからDELETE_COMPLETEステータスになれば、削除完了です。

まとめ

CloudFormationカコイイ…。