VPC Peeringを試してみた

VPC Peering出ましたね。(Coming Soonになりました)(復活しました)。早速試してみました。
でもちょっと癖があるというか、たぶんこの辺を本当は実現したいんですよね。1つのVPNで、複数のVPCを管理したい、というパティーン。

残念ながらあまりスマートな方法ではないですが、下記のようにして実現する事が出来ました。
もっといい方法あるよ!って方は是非教えてください。

構成

一番左がオンプレ環境、真ん中がVPNの接続されるVPC(VPC-A)、右側がVPC peeringでVPC-Aと接続されたVPC(VPC-B)。
オンプレ環境から、VPC-B内のEC2インスタンス(10.1.0.4)へ直接ssh等で通信できるようにします。
VPC-BはオンプレのIPと直接通信をする事が出来ないので、VPC-A内のVyattaでIPマスカレードをして通信を行います。
オンプレ環境からVPC内のVyattaに直接ルーティングをする事が出来ないため、OpenVPNでトンネリングしています。
今回はオンプレ側でcgwとOpenVPNを同じVyattaでやっていますが、別々でやる事も可能です。

VPC設定 - VPN

まずはVPC-A、VPC-Bを作成し、VPC-AにVPNを作成して、接続します。
ウィザードでやってもいいですし、自分でcgw、vgw、vpnを作ってもいいんです。
作成できたらダウンロードしたコンフィグをVyattaに流し込むだけで終わります。

VPC設定 - Peering設定

次にVPC-AとVPC-Bをpeeringします
この画面から接続するVPCを2つ選んでCreateを押します。別のアカウントのVPCも接続する事が可能です。

接続される方のアカウント(もしくは同一かもしれませんが)で、接続リクエストをAccept Requestします。
しかしそれだけでは通信は出来ません。RouteTableで、Peeringターゲットに経路を作成する必要があります。

もちろん、双方のVPCで設定を行う必要がありますので、お忘れなく。

OpenVPN設定

オンプレ側のVyattaとVPC内のVyattaをOpenVPNで接続します。今回は 169.254.1.0/30 の空間を使いました。
"--cipher none"を指定する事で、暗号化のオーバーヘッドを無くす事ができます。
( @naoto_matsumoto さんの記事を参考にさせて頂きました VYATTAでつなぐインター・クラウド接続 (2) – さくらインターネット研究所 )

VPC側Vyatta

SecurityGroupでOpenVPN用のポート1194/udpを開けておく必要があります。
次にVyattaにログインしてOpenVPNの鍵を作成します。

$ sudo openvpn --genkey --secret /config/auth/secret
$ sudo cat /config/auth/secret
 :  (鍵は後ほど使うので、どこかにメモっておきます)

configureして、下記のコマンドを流し込みます。

set interfaces openvpn vtun0 local-address '169.254.1.1'
set interfaces openvpn vtun0 mode 'site-to-site'
set interfaces openvpn vtun0 openvpn-option '--cipher none'
set interfaces openvpn vtun0 remote-address '169.254.1.2'
set interfaces openvpn vtun0 remote-host '192.168.0.254'
set interfaces openvpn vtun0 shared-secret-key-file '/config/auth/secret'
オンプレ側のVyata

OpenVPNの鍵を設置

$ sudo tee /config/auth/secret
(上記でコピーした鍵を貼付けてCtrl+D)
$ sudo cat /config/auth/secret
 :  (ちゃんと貼れているか確認)

続いてconfigureで下記のコマンドを流し込みます。

set interfaces openvpn vtun0 local-address '169.254.1.2'
set interfaces openvpn vtun0 local-host '192.168.0.254'
set interfaces openvpn vtun0 mode 'site-to-site'
set interfaces openvpn vtun0 openvpn-option '--cipher none'
set interfaces openvpn vtun0 remote-address '169.254.1.1'
set interfaces openvpn vtun0 remote-host '10.0.0.254'
set interfaces openvpn vtun0 shared-secret-key-file '/config/auth/secret'

オンプレから169.254.1.1にpingを飛ばして疎通がある事を確認しておきます。

オンプレからVPC-Bへの経路を設定する

大きくわけて、2つの作業が必要です。

オンプレ側Vyattaにstatic routeの設定
set protocols static route 10.0.0.0/8 next-hop '169.254.1.1'
VPC側VyattaにIP Masquaradeと経路の設定

(OpenVPN経由で入ってくる)192.168.0.0/24からの通信は、IPマスカレードでポート変換をしてeth0から送出します。

set nat source rule 10 outbound-interface 'eth0'
set nat source rule 10 source address '192.168.0.0/24'
set nat source rule 10 translation address 'masquerade'

192.168.0.0/24からの通信は、192.168.0.254を除いてOpenVPN経由とします(行きと返りの経路を揃えるため)

set protocols static route 192.168.0.0/24 next-hop '169.254.1.2'
set protocols static route 192.168.0.254/32 next-hop '10.0.0.1'

動作確認

オンプレ側のホスト(デフォルトゲートウェイがVyattaに向いている)から、10.1.0.4に向かってpingsshを試します。

$ ping 10.1.0.4
PING 10.1.0.4 (10.1.0.4) 56(84) bytes of data.
64 bytes from 10.1.0.4: icmp_seq=1 ttl=62 time=15.7 ms
64 bytes from 10.1.0.4: icmp_seq=2 ttl=62 time=15.8 ms
64 bytes from 10.1.0.4: icmp_seq=3 ttl=62 time=15.8 ms
64 bytes from 10.1.0.4: icmp_seq=4 ttl=62 time=16.2 ms
^C
--- 10.1.0.4 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3099ms
rtt min/avg/max/mdev = 15.756/15.903/16.218/0.204 ms
$ ssh ec2-user@10.1.0.4
Last login: Tue Mar 25 19:49:37 2014 from ip-10-0-0-254.ap-northeast-1.compute.internal

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2013.09-release-notes/
17 package(s) needed for security, out of 39 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-10-1-0-4 ~]$

ちゃんと疎通出来ました!ソースアドレスが10.0.0.254になっているので、SecurityGroupの設定をする時は気を付けてください。

まとめ

逆方向(PeeringされたVPCからオンプレへの通信)は、同じ要領で各VPC内にVyattaインスタンスを立ててOpenVPNでつなぎ...といった事で実現する事は可能ですが、あまりスマートではありませんね。
アプリケーションレベルのゲートウェイが可能なプロトコルであれば、VPN接続されたVPC内にゲートウェイを立てるのが楽だと思います。