ちょっと話題の記事

NAT Gatewayによるアクセス元IPアドレスの固定

2016.02.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

雪山ジャンキー渡辺です。 今年もクラスメソッド雪山部は絶賛活動中ですよ。

さて、少し前ですが、AWS NAT Gateway(以下、NAT Gateway)がリリースされました(【新機能】ついに登場!Amazon VPC NAT GatewayでNATがAWSマネージドに)。 NAT Gatewayは、プライベートサブネットからインターネットへの通信を実現する仕組みです(外向きのみ)。 今日は、このNAT Gatewayを利用するひとつのパターンを紹介します。

サブネットを構成する3つのパターン

サブネットは種別として、パブリック・プライベート・プロテクトの3つの形態が選択できます。

外部アクセス可能なパブリックサブネット

パブリックサブネットは、ルートテーブルがインターネットゲートウェイと関連付けられたサブネットです。 パブリックサブネットでは、インスタンスにEIPを付与する事により外部(インターネット)からのアクセスが可能です。 SSHログイン対象となるサーバや、Webサイトとして公開するサーバなどはパブリックサブネットに配置しなければなりません。 パブリックサブネットでは、自然にインスタンスから外へのアクセスも可能です。

外部アクセスができないプライべートサブネット

プライベートサブネットは、ルートテーブルがインターネットゲートウェイと関連付けられていないサブネットです。 インターネットゲートウェイと通信できないため、外部からアクセスはできません。 また、外部への通信もできません

外向きの通信だけを許可するプロテクトサブネット

プライベートサブネットはでは、VPC内のインスタンスにしか繋がらないため、セキュリティは強固になります。 しかし、インターネット通信が前提となるyumなどのパッケージ管理ツールも利用できません

現実としては、プライベートサブネットでも外部へ通信だけは許可したいため、NATを利用して外部通信だけを許可します。 これがプロテクトサブネットです(定義によって少々異なる事もあります)。 これまでは、EC2のNATインスタンスを立てていましたが、NAT Gatewayがリリースされたため、NAT Gatewayを利用してプロテクトサブネットを構築できます。

NAT Gatewayでアクセス元のIPアドレスを制限する

外部WebAPIを利用するウェブシステムは少なくありません。 利用するWebAPIがTwitter APIのようなオープンAPIであるならば問題となりませんが、クローズドAPIの場合、アクセス元のIPアドレスを制限していることがあります。 接続元IPアドレスを申請し、前段のセキュリティグループやファイヤウォールに許可するIPアドレスを登録しなければならないというケースです。

外部WebAPIを叩くEC2インスタンスにEIP、すなわち固定のPublicIPが付与されているのであれば、そのIPアドレスを申請すれば良いでしょう。 しかし、AutoScalingを利用している場合など、PublicIPが動的であったり、PublicIPを持たない場合には接続元IPを固定する必要があります。 同様に、多数のインスタンスがある場合や、インスタンスの数が増減するような場合も、申請と管理が煩雑になってしまいます。

NAT GatewayにはEIPをバインドする

VPCにNAT Gatewayは、パブリックサブネットにEIPを指定して作成します。 これまでのNATインスタンスにEIPを付与していたのと、ほとんど同じでしょう。 違う点は、NAT Gatewayでは死活監視などを裏で行っており、NATサーバの状態を意識しなくて良くなったことです。

NAT Gatewayを作成したならば、サブネットのルートテーブルをNAT Gatewayに向けて設定します。

NAT Gateway経由で外部APIを叩く

インスタンスからの外部通信が、NAT Gateway経由の場合、外から見ると、すべてのアクセスはNAT Gatewayからのアクセスとなります。 したがって、NAT GatewayのEIPを外部APIの許可IPアドレスとして登録すれば、NAT Gateway経由でどれだけのEC2インスタンスがアクセスしても、許可IPアドレスを修正せずに済む、というわけです。

NATGW

AZ障害に対応する

NATインスタンスの問題のひとつは可用性でした。 NATインスタンスはEC2インスタンスでしかないため、障害が発生した場合に、システムの単一障害点になる可能性があります。 これは、NAT Gatewayとなることで解決したようにみえます。

しかし、NAT Gatewayはサブネットに配置することに注意してください。 つまり、AZ障害が発生した場合に、NAT Gatewayが利用できなくなる可能性があるということです。 (NATインスタンスの冗長化も可能だが、構成が複雑になる)

これを回避するためには、各AZにNAT Gatewayを配置します。 AZ毎にプライベート(プロテクト)サブネットのルーティングを各AZのNAT Gatewayに向けてください。 これで、可用性の高いプロテクトサブネットを構成できます。

まとめ

NAT Gatewayを利用することで、AutoScaling時のインスタンスからのアクセス元IPアドレスを固定化することができます。 機能がサービス化されることで、抽象度があがり、より適した構成を選択していくことがAWS環境のキモですね。

なお、サブネットについては、「サブネットとインターネット通信」も参照ください。