こんにちは、SCSKでAWSの内製化支援『テクニカルエスコートサービス』を担当している貝塚です。
以前、AWSのVPC上で双方向1対1NATを実現するという記事を書きました。
今回は、オンプレミスもからんだ、やや複雑な環境で2社間をNATして接続することを考えてみます。
接続要件
接続要件は下図の通りです。
Direct Connect接続構成
A社オンプレミス環境とB社オンプレミス環境を接続したいとします。A社はAWSのアカウントを持っており、既にDirect Connectで接続しています。Direct ConnectはVPCのひとつに、仮想プライベートゲートウェイ経由で関連付けされています。
一方、B社はAWSアカウントを持っていません。キャリアの閉域網を契約しており、そのサービスの一つに閉域網とAWSを接続するサービスがあるので、それを使ってAWSアカウントに接続することができます。B社はAWSアカウントを取得する予定がないため、A社の管理するAWSアカウントにPrivate VIFで接続することを希望しています。(※)
通信要件
通信要件は大きくふたつ、以下の通りです。
1.A社オンプレミス上のクライアントからB社オンプレミス上のサーバへの通信(通信要件(1))
TCPを用いて、A社 → B社のコネクションが発生します。
2.A社AWSアカウント上のクライアント兼サーバとB社オンプレミス上のクライアント兼サーバの通信(通信要件(2))
TCPを用いて、A社 → B社、B社 → A社の両方のコネクションが発生します。
NAT要件
B社は、A社のIPアドレスを隠蔽して、B社の指定するIPアドレス(10.129.0.0/16)にNATしてもらいたいという要件があります。
A社も、B社のIPアドレスがA社で既に使用しているレンジであれば当然NATをする必要がありますが、調査の結果、B社の使用するIPアドレスはA社では使用していないと判明したため、B社のIPアドレスは隠蔽しないことにしました。
ソリューション
A社を支援する立場で構築した環境は下図の通りです。
既存VPCの仮想プライベートゲートウェイAにB社のDirect Connectを接続するのは問題があると考え、B社接続専用の新規VPCを構成し、仮想プライベートゲートウェイBとB社Direct Connectを関連付ける設計としています。
NAT要件は、EC2のLinuxインスタンスでiptablesを使用したNATインスタンスを構築することにより満たすことにしました。一見、NAT Gatewayでも要件を満たせるように思えますが、NAT GatewayではB社からA社へコネクションを開始する通信要件(通信要件(2))が満たせません。
既存VPCと新規VPCはTransit Gatewayで接続します。VPC間接続というとVPC Peeringが思い浮かびますが、VPC PeeringだとNAT構成がより複雑になってしまうという点と、Transit Gateway構成にしておくと将来的にInspection VPCを導入してセキュリティを強化するという選択肢が増えるため、Transit Gatewayを選択しました。
また、この構成ではA社オンプレからB社オンプレや新規VPCに直接通信することができないので、既存VPCにNetwork Load Balancerをはさむことでこの問題を解決しています。
以下、このような設計とした意図を解説します。
Direct Connectの接続ポイント
以下の図のような、仮想プライベートゲートウェイAにB社ダイレクトコネクトのVIFを関連付ける構成を考えてみます。
Network Load Balancerを経由してA社オンプレとB社オンプレを接続する理由は別項で解説することにして、まずはB社Direct Connectを仮想プライベートゲートウェイAに関連付けることの良し悪しについて検討します。
この構成の場合、B社側の設定ミス等により、例えばデフォルトルート(0.0.0.0/0)などをA社にアドバタイズできてしまいます。その場合、A社オンプレとA社AWS環境間の通信に問題が発生する可能性があります。
また、仮想プライベートゲートウェイAは既存VPCのCIDR全体をB社にアドバタイズしてしまいます。そのため、B社から、A社既存VPC上の、今回の通信要件と関係のないサーバに通信を試みることができます。ネットワークACLを使用することで上手く制御できるかもしれませんが、セキュリティ管理上の難易度が高くなってしまいます。
以上の理由から、B社Direct Connectを収容するための専用のVPCを構成する設計としました。(前項『ソリューション』の図参照)
この構成であれば、B社側からデフォルトルートがアドバタイズされてきたとしても経路を持ってしまうのは仮想プライベートゲートウェイBだけですから、既存VPCとA社オンプレの通信に影響が出ることはありません。
NATインスタンス
NAT要件を満たすために、A社新規VPCにNAT機能を有するデバイスを配置します。
A社 → B社 方向の通信を考えると、A社のアドレスさえ隠蔽できればよく(送信元NAT, SNAT)、A社側からはB社のIPアドレスに通信すればよいので、NAT Gatewayで通信要件を満たせるように見えます。
しかし、通信要件(2)はB社 → A社 方向のコネクションも発生します。NAT Gatewayの提供する機能はN対1 NAT(IPマスカレード)と呼ばれるものなので、B社からNAT GatewayのIPアドレスに通信を試みても、A社内のサーバと通信することはできません。
以上の理由から、EC2を用いて独自にNAT用のインスタンスを作成することにしました。(※)
LinuxのEC2インスタンスを使用して双方向のコネクションに対応したNATインスタンスを作成する方法については、以下の記事を参考にしてください。
VPC間接続(Transit Gateway)
既存VPCと新規VPCを接続する必要があります。まずはVPC Peeringで接続することを検討してみます。VPC Peeringは無料で使用できるので、要件に合うのであればVPC Peeringを採用したいところです。
VPC Peeringの特徴は、接続したVPC同士の経路情報しか持っていない点です。この図でいうと、既存VPCと新規VPCの通信はできますが、既存VPCとB社オンプレは直接通信できません。VPC PeeringがB社オンプレへの経路を持っていないからです。
これに対処する方法としては、NATインスタンスでB社オンプレのIPアドレスを隠蔽するようにNATを設定し、A社からは新規VPC上のIPアドレス(10.129.0.0/16)と通信しているように見せかけるというものがあります。
この構成を採用してもよいのですが、せっかく通信要件・NAT要件を整理した結果、B社オンプレのIPアドレスを隠蔽する必要はないという結論に至ったのに、結果としてB社オンプレのIPアドレスを隠蔽するNATを導入することになります。運用面・障害対応面から見た場合、構成はできるだけシンプルにしたいので、この構成は検討の余地があります。
また、VPC Peeringの制約事項としてよく言われることですが、二つのVPCを接続するごとに一つのVPC Peeringを設定する必要があります。この図では必要なVPC Peeringの数は1ですが、他のVPC(図に書いていないだけでいくつかあります)からB社に接続する要件が出てきたら?とか、B社以外にもC社、D社と今回の接続形態でつなぐことになったら……?と考えると、VPC Peeringの管理負荷が重くのしかかってきます。
管理のシンプル化という観点と、将来的にC社、D社……と同様の形態で接続することを考えたときに、必要に応じてInspection VPCという形ですべてのVPC間通信をひとつのNetwork Firewallで集約して検査する機能を導入することで、相対的に低い運用負荷で高度なセキュリティを実装できるという点から、Transit GatewayでVPC間を接続する構成を選択しました。
Transit Gateway構成であれば、前述の直接接続したVPC同士でしか通信できないという制約も受けないので、A社既存VPCからB社オンプレに通信するのに、B社オンプレIPを隠蔽する必要もありません。
Network Load Balancer
最後に既存VPCに配置したNetwork Load Balancerについて解説します。
実は仮想プライベートゲートウェイは、Direct Connect側(オンプレ側)に対しては比較的自由に経路を設定できるのですが、仮想プライベートゲートウェイが関連付けられているVPCの”先”のネットワークへの経路を持つことができません。
この図を例にとると、仮想プライベートゲートウェイAは、新規VPCやB社オンプレへの経路を持っていません。同様に、仮想プライベートゲートウェイBは、既存VPCやA社オンプレへの経路を持ちません。
つまりどういうことかというと、A社オンプレは、既存VPC以外とは通信できません。ここからB社オンプレにたどり着くためには、NATを駆使することになります。この場面で活躍する優秀なデバイスがNetwork Load Balancerです。
A社オンプレから既存VPC上のNetwork Load BalancerのIPアドレスに通信すると、送信先をNetwork Load BalancerのターゲットであるB社オンプレミス上の通信要件(1)サーバのIPアドレスに変換します(実質、送信先NAT, DNAT)。この時、送信元IPアドレスはA社オンプレのIPアドレスから、Network Load BalancerのIPアドレスに変換されます(実質、送信元NAT, SNAT)。
Transit Gatewayには、隣接するVPCにしか到達できないという制限がありませんので、Network Load Balancerから発信されたB社オンプレミス向けの通信はTransit Gatewayを通過し、NATインスタンスを通過していくことができます。そして仮想プライベートゲートウェイBに到達しますが、仮想プライベートゲートウェイBはB社オンプレへの経路を持っているので、無事B社オンプレ上のサーバに到達することができます。
次に、戻りの通信を考えます。B社オンプレミスからA社オンプレミスへの通信となりますが、行きの通信の時にNATインスタンスでA社のIPを隠蔽しB社体系のIP(新規VPCのCIDR)にNATされているので、送信先IPアドレスは新規VPC上のIPアドレスとなり、仮想プライベートゲートウェイBで破棄されることなく通過することができます。
NATインスタンスはNATを行って、Network Load BalancerのIPアドレスを送信先とします。VPC間はTransit Gatewayで接続しているので問題なく通過することができます。
Network Load Balancerは送信先をA社オンプレ上の通信要件(1)用クライアントのIPアドレスに変換します。送信元はNetwork Load BalancerのIPアドレスに変換されます。仮想プライベートゲートウェイAはA社オンプレへの経路を持っているので、A社オンプレ上のクライアントに戻っていくことができます。
まとめ
以上、NATを必要とする2社間のオンプレ/VPC接続構成について検討してみました。
Network Load Balancerは、実質的に送信元NAT、送信先NATを同時に行ってくれるので、仮想プライベートゲートウェイやVPC Peeringをいくつも越えないといけないときに大変重宝することが分かりました。ただし、ターゲットに定期的にヘルスチェックを実施してしまうので、他社のサーバをターゲットにする場合にはお断りを入れておくのがよいでしょう。
また、今回、双方向の通信要件に対応するためにEC2で独自にNAT機能を実装しましたが、EC2を使用するとOS以上はユーザー管理になってしまうので監視・運用の負荷が大きくなってしまう点が設計上の悩みどころです。AWSマネージドで柔軟かつ大規模なNATを実現できるサービスが出てくれると嬉しいですね。