VPC PeeringされたAWS環境に、単一のVPN接続でアクセスする

これは、ドリコム Advent Calendar 2014 - Adventarの14日目の記事です。

13日目は、@k_m_y_さんによる、Processingで体験するサウンドアートの世界 - kxmxyx.github.ioです。

自己紹介

  • @shouyu
  • 社内でのアダ名はゲーリーです*1
  • 14年に新卒で入社
  • インフラエンジニアをしています
  • 入社前は京都でRails書いてました

今日の話

唐突ですが、今日はAWSの話になります。
VPC Peeringで接続されたすべてのVPC内のインスタンスに対して
1つのVPN接続で社内から直接アクセス可能にしようとして
色々と一筋縄ではいかなかったので、そのまとめになります。

ちなみに、専用線を契約して Amazon Direct Connect を使えば解決する話です。

構成

最初に載せてしまいますが、以下のような構成が最終構成になります。

この構成で、社内から図中の Service VPC1 や、Service VPC2 のインスタンス
直接 ssh 出来れば勝ちです。
図にはありませんが、Infra VPC、Service VPC1、2はすべて別アカウントという縛りもあります。

どうして VPN 接続を一本にしたかったか

前述の通り、サービスごとに AWS のアカウントを分けるという方針であったため
サービスの立ち上げごとに、社内と各VPC で、VPN 接続を作っていくと、管理が非常に煩雑になると予想出来ました。
また、図中の Infra VPC には、LDAP サーバ等も置く予定であり、VPC Peeringは必須であったので
サービス立ち上げ時には VPC Peering の設定さえしてやれば、その他の設定はしなくてよいと言うのが理想でした。

http://www.slideshare.net/AmazonWebServices/arc403-from-one-to-many-evolving-vpc-design-aws-reinvent-2014-41528054/25

そもそも、こんなことしたい人はたぶんいないと思います。

VPN 接続

最初の図を見てもらえば分かる通り、Amazon VPC 標準の VPN 接続は利用していません。
はじめは、利用する方向で考えていたのですが、社内から Infra VPCVPC VPN で接続しても
Service VPC1、2 に対してのパケットを Infra VPC が通してくれないという問題がありました。

VPC のルートテーブルの設定を色々やってみたのですが、結局解決ができず VPC VPN の使用はあきらめました。

内部構成がわからないので、あくまで推測にはなってしまいますが
VPC VPNで接続した際は、パケットのデスティネーションアドレスが 対象VPC(今回は Infra VPC)の CIDR の
範囲内ではないパケットは VPC 側の Virtual Gateway が落としているのではないかと考えています。

結果、Infra VPC内にOpenVPNインスタンスを作成し、社内と接続することにしました。

ちなみに、VPC VPNLinux で接続する方法に関しては、こちらをご参照ください。
AWS VPN (1) between VPC VPN G/W and Debian Linux (racoon, setkey, quagga) with NAT | 外道父の匠
AWS VPN (2) between VPC VPN G/W and Debian Linux (racoon, setkey, quagga) with monit for Non-NAT | 外道父の匠

VPC Subnet のルートテーブル設定

Infra VPC 内のサブネットのルートテーブルに

Dest: 10.110.0.0/16 Targe: pcx-aaaaaaa(VPC Peering Gateway to Service1)
Dest: 10.120.0.0/16 Targe: pcx-bbbbbbb(VPC Peering Gateway to Service2)

というようなルールを追加します。
こちらは、VPC が増える毎に設定が必要です。
もちろん、対向の Service VPC1、2 でも同様の設定が必要です。
この設定は、VPC Peering するうえで必須の設定になるので、特筆すべき点はないです。

AWSVPNサーバのiptablesの設定

社内ネットワークと、OpenVPN を接続し、ip_forward を有効にして勝った!
と思いましたが、まだ勝てません。

という状態になりました。
初めの図で言うと、VPC Peering Gatewayで引っ掛かっている状態です。

またまた推測にはなりますが、VPC Peering Gateway もパケットのソース、デスティネーション
をしっかりチェックしているのかなと思います。

そこで、AWS 側の VPN サーバでトンネルから入ってくるパケットを以下のように、iptables で NAT してやりました。

-A POSTROUTING -s 172.168.0.0/24 -d 10.110.0.0/16 -j MASQUERADE
-A POSTROUTING -s 172.168.0.0/24 -d 10.120.0.0/16 -j MASQUERADE

ルールを2つ追加していますが、AWS 環境で使う CIDR をうまく切ってやれば、1つですみます。

これで、無事パケットが届き、社内から各サービスインスタンスへ直接sshすることができるようになりました!
セキュリティグループの設定もお忘れなく。

ちなみに、今回の構成では、Service VPCインスタンスから社内へは接続できません。
するならAmazon Direct C(ry

*1:アダ名がげろしゃぶになりそうだった所、心優しい先輩が助けてくれました