複数のVPCをVPN接続してみる

記事タイトルとURLをコピーする

こんにちはAWSチームの柳瀬です。 12月になって技術系のAdvent Calendarが盛り上がっておりますが、私もAWS Advent Calendar 2012の6日目を担当しているので、こちらで更新させて頂きます! 最近、ここのブログエントリーの様子が変なのですが、私は気の利いたブログやタイトルをつける事は苦手なので、いつもどおり書きたいと思います。 元ネタはこちらとなっており、以下にまとめた内容を記載していきます。

トピックス

  • 概要
    • Amazon VPCの構成要素
    • VPCの設定例
    • その他のポイント
  • 構成チュートリアル
    • EC2インスタンスの起動方法
    • EC2上でVPNサーバを構成する方法
    • 接続テスト
  • さらに他のVPCと接続する場合
  • 付録 VPNのインスタンスのHAアーキテクチャ
    • VPNとVPNインスタンスの監視
  • まとめ

概要

Amazon Virtual Private Cloud (Amazon VPC)は顧客に驚異的に柔軟なルーティングを提供します。 このドキュメントはVPC内のインスタンスがシームレスにプライベートIPアドレスを使って相互に接続する事ができ、より大きな仮想プライベートネットワークに複数のVPCを接続するための安全なSSLトンネル(Open VPNを使用します)を作る方法を示します。

Amazon VPCの構成要素

Amazon VPCのマニュアルについてはAmazon Virtual Private Cloud管理者ガイドを参照して下さい。 とはいえ下記の定義、構成例、図なども管理者ガイドの内容を理解するために参考になると思います。 Internet Gateway (IGW) IGWはElastic IPとVPCインスタンスをマッピング出来るようにするために必要な、VPCからの出口となります。 IGWは各VPCインスタンスが互いに通信できるようにように、パブリックアドレスへのマッピングを提供する役割を持ちます。 異なるAWSリージョン間でVPC同士が通信する時に、IGWはインターネットを使用して通信をルーティングします。 しかし、同一AWSリージョンでVPC同士が通信する時には、IGWはAWS内のネットワークで通信をルーティングします。 SSL Connection 2つのVPCネットワークの接続には、EC2インスタンスを使用したOpenVPNによるSSL通信が使われます。 このガイドでは例として以下の設定を使用します。

VPCの設定例

このガイドは設定例として以下のものを使用します。

VPN ComponentVPC #1VPC #2
CIDR10.0.0.0/16172.16.0.0/16
Public Subnet10.0.0.0/24172.16.0.0/24
Private Subnet10.0.1.0/24172.16.1.0/24
VPN Instance Private IP10.0.0.5172.16.0.5
VPN Instance EIPEIP #1EIP #2


その他のポイント

  1. SSL通信をする各VPCインスタンスはPublicサブネットに配置し、EIPを付与します。
  2. VPNインスタンスが単一障害点になります。冗長化する場合は付録を参照して下さい。
  3. 本ガイドではAmazon Linuxとそのパッケージを使用した例で紹介します。
  4. 既に2つのVPCを作成してある事が前提です。VPCの作成手順はスタートガイドをご覧ください。
  5. AWSがIGWを管理し、ユーザーは起動したEC2インスタンスとのVPN接続を管理します。

構成のチュートリアル

このチュートリアルでは以下のステップで実行していきます。

  1. EC2でVPN用インスタンスを起動
  2. VPNサーバソフトウェアをEC2インスタンスに設定
  3. 必要に応じてさらに他のVPCと接続

EC2でVPN用インスタンスを起動

    1. 各VPCのPublic Subnetに以下のようにAmazon LinuxのEC2インスタンスを起動します
      1. VPNインスタンスに静的にプライベートIPアドレスを割り当てます。
      2. 2つのEIPを起動した各VPNインスタンスに割り当てます。
      3. EIP間のUDP1194ポートの通信を許可するようにセキュリティグループの設定をします。
    2. VPNインスタンスを右クリックしてChange Source/Dest. Checkをdisableにします。

    1. もう一方のVPCと通信する場合はVPNインスタンスを経由するようにルーティングをします。

EC2インスタンスにVPNサーバを設定

VPNサーバ #1 1. VPNインスタンスに接続してopenvpnをインストール

$ sudo yum install openvpn

2 OpenVPN用の鍵を作成

$ cd /etc/openvpn/
$ sudo openvpn --genkey --secret ovpn.key
  1. vpc1-to-vpc2.confを以下のように作成する
$ sudo vi /etc/openvpn/vpc1-to-vpc2.conf

 

# Sample OpenVPN configuration file using a pre-shared static key
# Port to use: 1194 is the official IANA port number
port 1194

# Use a dynamic tun device.
dev tun

# Remote peer and network
remote EIP #2
route 172.16.0.0 255.255.0.0

# Configure local and remote VPN endpoints
ifconfig 169.254.255.1 169.254.255.2

# The pre-shared static key
secret ovpn.key

VPNサーバ #2 1. VPNサーバ #1で作成した/etc/openvpn/ovpn.keyを安全にコピーしておきます 2. VPNインスタンスに接続してopenvpnをインストール

$ sudo yum install openvpn
  1. vpc2-to-vpc1.confを以下のように作成する
$ sudo vi /etc/openvpn/vpc2-to-vpc1.conf

 

# Sample OpenVPN configuration file using a pre-shared static key
# Port to use: 1194 is the official IANA port number
port 1194

# Use a dynamic tun device.
dev tun

# Remote peer and network
remote EIP #1
route 10.0.0.0 255.255.0.0

# Configure local and remote VPN endpoints
ifconfig 169.254.255.2 169.254.255.1

# The pre-shared static key
secret ovpn.key

両方のVPNインスタンスで以下の設定を行います。 1. OpenVPNを起動します

$ sudo service openvpn start
  1. OpenVPNの自動起動設定をします
$ sudo chkconfig openvpn on
  1. /etc/sysctl.confのnet.ipv4.ip_forwardを0から1に変更します
$ sudo cp -R /etc/sysctl.conf /etc/sysctl.conf-org
$ sudo vi /etc/sysctl.conf

 

$ diff -u /etc/sysctl.conf-org /etc/sysctl.conf
--- /etc/sysctl.conf-org    2012-11-21 07:14:26.399544018 +0000
+++ /etc/sysctl.conf    2012-11-21 07:14:48.546369761 +0000
@@ -4,7 +4,7 @@
 # sysctl.conf(5) for more details.

 # Controls IP packet forwarding
-net.ipv4.ip_forward = 0
+net.ipv4.ip_forward = 1

 # Controls source route verification
 net.ipv4.conf.default.rp_filter = 1
  1. ネットワークを再起動して設定を反映させます
$ sudo service network restart

 

接続テスト

VPC間の接続テストをするときには適切なセキュリティグループのルールを設定して下さい。 また、VPNインスタンスからトンネルを介して接続テストをする場合に、VPNインスタンスはその送信元アドレスとしてトンネルのIPアドレスを使用する事に注意して下さい。 これによりトンネルネットワークでルートテーブルを更新する事なくリモートノードとのテストをする事が出来ます。 ご参考までにVPNサーバのネットワーク情報は以下のようになると思います。

$ ifconfig
eth0      Link encap:Ethernet  HWaddr 02:BD:B1:21:81:C9
          inet addr:10.0.0.5  Bcast:10.0.0.255  Mask:255.255.255.0
          inet6 addr: fe80::bd:b1ff:fe21:81c9/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:36718 errors:0 dropped:0 overruns:0 frame:0
          TX packets:34122 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:6093487 (5.8 MiB)  TX bytes:3051189 (2.9 MiB)
          Interrupt:26

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:169.254.255.1  P-t-P:169.254.255.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:19 errors:0 dropped:0 overruns:0 frame:0
          TX packets:40 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:1596 (1.5 KiB)  TX bytes:3288 (3.2 KiB)

 

$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         10.0.0.1        0.0.0.0         UG    0      0        0 eth0
10.0.0.0        *               255.255.255.0   U     0      0        0 eth0
169.254.169.254 *               255.255.255.255 UH    0      0        0 eth0
169.254.255.2   *               255.255.255.255 UH    0      0        0 tun0
172.16.0.0      169.254.255.2   255.255.0.0     UG    0      0        0 tun0

 

さらに他のVPCと接続する場合

さらに他のVPCと接続したい場合は、各接続毎に異なるポートを指定する形で/etc/openvpn以下の設定ファイルを作成することで追加が出来ます。 例えば、VPC1上に存在するEIP1を割り当てられたVPNインスタンスをVPC3、VPC4と接続する場合は/etc/openvpn以下に次のようなファイルを設置します。

vpc1-to-vpc2.conf
vpc1-to-vpc3.conf
vpc1-to-vpc4.conf

これら追加のVPNインスタンスを接続させる場合は、ovpn.keyファイルのコピーだけではなく上記#2に該当するファイルが必要(ポート番号は変更します)となります。 さらにOpenVPNは単一のプロセスを使用して複数のトンネル接続が出来るサーバ/クライアント・モデルを持っています。 この構成にした場合はOpenVPNのサーバとクライアントを設定するようになりますが、ドキュメントの範囲を超えているので割愛します。

付録A:VPNインスタンスに使用するHAアーキテクチャ

2つのVPC上で完全な冗長構成を作成するとなると、4台のVPNインスタンスとVPN接続をチェックする監視インスタンスを構築する必要があります。

同一AZ内にあるサブネットからのトラフィックは、同一AZ内で稼働させたVPNインスタンスにルーティングして全てのVPNインスタンスを同時に活用する事を推奨します。 各VPNインスタンスは同じAZを共有するように、VPCをクロスするような接続を提供します。 構成図ではEC2が全てPublic Subnetで稼働していますが、もちろんPrivate Subnetで稼働させる事も可能です。

VPN監視インスタンス

VPNモニタ用インスタンスは監視スクリプトを作成して実行させるインスタンスとなります。 このインスタンスの用途はVPNの接続監視とVPNインスタンスの稼働監視です。 VPNインスタンスやVPN接続がダウンした場合、復旧するまではトラフィックをもう一方のVPNインスタンスにルーティングするようにしつつ、VPNインスタンスを再起動するようにします。 障害時に通知したり自動復旧させるロジックを開発する必要があるかはサービスによりますので、AWS側で監視インスタンスに必要なドキュメントやスクリプト等は提供しおりません。

まとめ

それぞれ異なるVPC上で稼働してるインスタンス同士で通信する要件が発生した場合など、手軽にVPC同士で通信させる事が出来るので参考になりました。 また、要件によっては冗長構成を組んで通信を最適化しつつ耐障害性を高めてみるのも面白そうです。