はじめに
AWS VPC にある VPN 接続機能を設定してみましたので、その内容についてシェアします。VPC と VPN 接続をするルータとしては VyOS というソフトウェアルータを使用しました。VyOS の AMI はAWS Marketplace、Community AMIs にありますので、ハードウェアルータを用意できない人でも VPN 接続を簡単に試せてオススメです。
前提
EC2、VPC についてはある程度の知識がある前提で話を進めます。たとえば、Network ACL、 Route Table というワードを聞いて全然ピンとこない場合はひと通り、ドキュメントを読んでみることをオススメします。また、Subnet 等の VPC に限らない概念についても最低限、知っておく必要はあります。と、偉そうに書きましたが、筆者も元々はアプリケーションエンジニア出身でネットワークについては素人同然なので、適宜、勉強すればなんとかなると思います。
また、VyOS のバージョンは 1.0.5 を利用しました。はじめ、1.1.0 を利用していたのですが、うまくいかず、ネットを彷徨っていたら、以下の記事をみつけました。ご注意ください。
http://www.lockon.co.jp/officialblog/engineer/10042/
※注意 VyOSのver 1.1.0, 1.1.1では、VPN経由のパケットを正しくルーティングできないという致命的なバグがありました。最新のVyOSでは確認できていませんが、もしVPN経由のパケットがルーティングできない場合には、ver.1.0.5をお使いください。
構成
今回、試してみた構成図は以下のようなものです。
左側に Oregon Region、右側に Tokyo Region があり、Oregon Region の Virtual Private Gateway (以下、VGW1) と Tokyo Region の Customer Gateway(以下、CGW) を VPN 接続します。CGW はここでは VyOS のことを指します。あなたが準備する必要があるルータのことです。ここでは便宜上、CGW も AWS 上にいますが、一般的には、オンプレだったりオフィスのネットワーク内にいるルータになるかと思います2。下部にある図は CGW と VGW 内のルータが Link-local address を利用して VPN コネクションを張っている図になります。
それでは、各コンポーネントについて説明します。
Customer Gateway
一言でいうなら、VGW に接続する IPSec トンネルのエンドポイントが CGW です。設定ファイル等は AWS マネジメントコンソールから落とせるので便利だが、今回の例では一部修正が必要なので、後ほどその点については触れます。詳細はこちらを参照ください。
Virtual Private Gateway
AWS 側にある VPN のエンドポイントになります。こちらはユーザ側は特に意識することなく、AWS 側がよしなに管理してくれます。画面からは Name Tag を入力して Create するだけです。このとき生成される vgw ID を Route Table で指定することで VPN 接続先に適切にルーティングされます。
VPN Connection
Tunnel が2つある
マネジメントコンソールから VPN 接続を Create すると VPN Tunnel が2つ生成されます。また、VGW 内の各ルータの IP Address、Status なども確認できます。CGW の設定をしていなければ、Status は DOWN のままのはずです。
Link-local address
VGW 内には2つのルータがあり、CGW は1つのルータのみです。CGW 側の設定ファイルをみると VTI (Virtual Tunnel Interface) として vti0 の address が 169.254.249.58/30、vti1 の address が 169.254.249.62/30 となっています。Link-local address を利用して CGW には仮想的にインターフェースが2つあり、その仮想インターフェースを通じて2つのトンネルをつくって VPN の通信を実現しているようです。
interfaces {
...
vti vti0 {
address 169.254.249.58/30
description "VPC tunnel 1"
mtu 1436
}
vti vti1 {
address 169.254.249.62/30
description "VPC tunnel 2"
mtu 1436
}
}
UDP 500 と IP protocol 50
VPN over IPSec では 秘密鍵の交換を安全に行うためのプロトコルとして IKE を利用し、これが UDP の500番ポートを利用します。また、パケットの認証、暗号化として ESP を利用し、これが IP プロトコル番号 50 で通信をします。IKE には Phase 1 と Phase 2があるようで、細かい話は別途参照ください。とりあえず、UDP 500 と IP protocol 50 を使うことだけを押さえておけばなんとかなると思います。下記は juniper のサイトですが、一般的な話だと思うので参考になると思います。
http://kb.juniper.net/InfoCenter/index?page=content&id=KB5671
[ScreenOS] What ports are used for a Virtual Private Network (VPN)?
...
Internet Protocol Security (IPSec) uses IP protocol 50 for Encapsulated Security Protocol (ESP), IP protocol 51 for Authentication Header (AH), and UDP port 500 for IKE Phase 1 negotiation and Phase 2 negotiations. UDP ports 500 and 4500 are used, if NAT-T is used for IKE Phase 1 negotiation and Phase 2 negotiations
ちなみに、AWS で Security Group をつくると、デフォルトでは Outbound がすべて許可されています。この状態で、VyOS の Security Group を設定すると、特に、Inbound の設定で UDP 500、Ip Protocol 50 を明示的に許可しなくても、VPN の STATUS は UP になります。はじめ、Inbound を許可してないのに、なんで VPN 接続に成功したのか不思議だったのですが、察するに、CGW 側から IKE の negotiation を開始したからだと納得しました。つまり、CGW 側から negotiation が開始する場合は、当然、Outbound はすべて許可されているので通信ができ、AWS の Security Group は Stateful なため、Outbound で出て行った通信に対する戻りの Inbound に対しては明示的に許可していなくても通信ができるようです。ためしに、Outbound の設定もすべて許可するのではなく、1つずつ明示的に許可するようにして、わざと UDP 500 を許可しないようにすれば(もしくは Network ACL で明示的に Deny する)、VPN の STATUS が DOWN のままになるはずです。
また、VPC では NAT トラバーサルはサポート外のようですので、CGW は Global IP が必須ということでしょうか。
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/NetworkAdminGuide/Introduction.html
カスタマーゲートウェイの外部インターフェイスのアドレスは、静的アドレスである必要があります。カスタマー ゲートウェイは、ネットワークアドレス変換(NAT)を実行するデバイスの背後に存在する可能性があります。ただし、NAT トラバーサル(NAT-T)はサポートされていません。VPN 接続の要件の詳細については、『Amazon VPC ユーザーガイド』の「VPN 接続に必要なもの」を参照してください。
作業内容
それでは、ざっと作業手順を紹介します。
- [Tokyo/Oregon] VPC をつくる
- [Tokyo/Oregon] Subnet をつくる
- [Tokyo/Oregon] Internet Gateway をつくって、Route Table に設定する
- [Oregon] EC2 インスタンスを1つ起動する
- [Tokyo] VyOS インスタンスと EC2 インスタンスを起動する。 VyOS は EC2 の設定で Source/Dest Check をオフる。
- [Oregon] CGW をつくる。Routing は Static で IP Address は VyOS の Global IPを。
- [Oregon] VGW をつくる
- [Oregon] VPN をつくる。CGW, VGWは上でつくったものを指定、Routing Options は Dynamic でOKです。
- [Oregon/Tokyo] VPN の config をマネジメントコンソールから落として、その内容を VyOS に反映させる。
ただし、以下の項目を修正する。デフォルトでは local-address が VyOS の Global IP になっているので、Private IP に修正する。
set vpn ipsec site-to-site peer 205.251.233.120 local-address '52.69.xx.xx'
set vpn ipsec site-to-site peer 205.251.233.122 local-address '52.69.xx.xx'
↓
set vpn ipsec site-to-site peer 205.251.233.120 local-address '172.100.0.200'
set vpn ipsec site-to-site peer 205.251.233.122 local-address '172.100.0.200'
- [Oregon] Route Table で、Tokyo リージョンへの Destination の Target が VGW になっていることを確認。
- [Tokyo] Route Table で、Oregon リージョンへの Destination の Target が VyOS になっていることを確認。
以上で VPN 接続されるはずです。各インスタンスにログインして ping を打って疎通確認しましょう。VyOS から Oregon のインスタンスに ping を打つときは以下の様に interface を指定して試しましょう。ping をうける側のインスタンスで tcpdump で icmp を watch するとわかりやすいです。
$ ping 10.10.0.39 interface 172.100.0.27
$ sudo tcpdump icmp
最後に
以上、Region 間接続を VPC の VPN 機能と VyOS でやってみるための手順でした。いかかでしょうか?ネットワーク系は Subnet だったり、VGW、CGW と作業することが多いので、図を書いて整理しながら進めるとトラブルシューティングもはかどると思います。
-
Virtual Private Gateway なんだから VPG じゃないのかよ!と突っ込みたくなりますが、マネージメントコンソールで Virtual Private Gateway を作成すると、その ID として vgw-xxxxx といったID が振られます。 おそらく Customer Gateway を CGW としてるのでそっちと統一感をもたせてるためでしょう。 ↩
-
"一般的"と書きましたが、VPC Peering は同一 Region である必要があり、VPC では Region 間接続をサポートする機能はないので(2015/6/18現在)、今回のユースケースも十分一般的かもしれません。 ↩