Day 9: NAT GatewayとBastion Host:プライベートサブネットからの安全なアクセス
皆さん、こんにちは!「実践!AWSネットワーク構築・運用30日チャレンジ」のDay 9へようこそ!
Day 4でプライベートサブネットとNATゲートウェイを導入し、Day 8ではEC2インスタンスのデプロイとネットワーク設定を実践しました。これで、インターネットに公開するリソースと、内部で処理を行うリソースを異なるサブネットに配置する基礎ができましたね。
今日は、そのプライベートサブネットに配置されたリソース(アプリケーションサーバーやデータベースなど)が、どのように安全にインターネットにアクセスし、またどのように安全に管理されるのか、そのための「NAT Gateway」と「Bastion Host (踏み台サーバー)」について、より深く掘り下げていきます。セキュリティと運用の両面で非常に重要な概念です。
1. プライベートサブネットとインターネットアクセス:なぜNAT Gatewayが必要なのか?
再確認になりますが、プライベートサブネットは、インターネットからの直接アクセスができないように設計されています。これは、データベースやアプリケーションサーバーなど、機密性の高いリソースを外部の脅威から保護するために不可欠です。
しかし、プライベートサブネット内のリソースがインターネットに「全くアクセスできない」となると、困る場面が出てきます。例えば:
- OSのセキュリティアップデートやパッケージのインストール
- 外部のAPIサービス(決済API、地図APIなど)へのアクセス
- AWSのサービスエンドポイント(S3, DynamoDBなど)へのアクセス(VPCエンドポイントがない場合)
このようなプライベートサブネットからインターネットへの「アウトバウンド通信のみ」 を安全に許可するために利用するのが、NAT Gateway (Network Address Translation Gateway) です。
NAT Gatewayの仕組みとメリット
NAT Gatewayは、以下のプロセスでプライベートサブネットからのインターネットアクセスを仲介します。
- プライベートサブネット内のEC2インスタンスがインターネット上のリソース(例:
github.com)にアクセスしようとすると、その通信はルートテーブルの指示に従ってNAT Gatewayへ転送されます。 - NAT Gatewayは、EC2インスタンスのプライベートIPアドレスを、自身に割り当てられているElastic IP (EIP) のパブリックIPアドレスに変換(NAT)します。
- 変換されたパブリックIPアドレスでインターネットへ通信が送信され、インターネットからの応答はNAT Gatewayが受信します。
- NAT Gatewayは、その応答を元のEC2インスタンスのプライベートIPアドレスに再度変換し、インスタンスへ返します。
この仕組みにより、インターネットからはNAT GatewayのパブリックIPアドレスしか見えず、プライベートサブネット内のEC2インスタンスは完全に隠蔽されます。
メリット:
- セキュリティ向上: プライベートサブネットのリソースはインターネットから直接アクセスできないため、攻撃対象が限定されます。
- 運用効率化: OSアップデートや外部アクセスを一元的に管理・監視できます。
- 高可用性: 各AZにNAT Gatewayを配置することで、特定のAZ障害時もインターネット接続性を維持できます(Day 4で実践済み)。
2. Bastion Host (踏み台サーバー):プライベートサブネットへの安全な管理アクセス
プライベートサブネット内のリソースはインターネットから直接アクセスできないため、SSHなどを使って管理者が直接接続することはできません。では、どのようにしてこれらのサーバーを管理するのでしょうか?
そこで登場するのが、Bastion Host(バスティオンホスト)、通称「踏み台サーバー」です。
Bastion Hostとは?
Bastion Hostは、パブリックサブネットに配置され、インターネットからSSH(またはRDP)接続が許可された、セキュリティが厳重に強化されたEC2インスタンスです。このBastion Hostを経由することで、プライベートサブネット内のインスタンスに安全にアクセスできるようになります。
[ あなたのPC ]
| SSH (厳格なIP制限)
V
+------------------------------------+
| パブリックサブネット |
| |
| +------------------------+ |
| | Bastion Host (EC2) | |
| | (Security Group: SSHのみ) | |
| +------------------------+ |
+------------------------------------+
| SSH (VPC内部通信)
V
+------------------------------------+
| プライベートサブネット |
| |
| +------------------------+ |
| | アプリケーションサーバー(EC2) ||
| | (Security Group: Bastion HostからのみSSH) ||
| +------------------------+ |
+------------------------------------+
Bastion Hostのセキュリティ要件
Bastion Hostは、インターネットに公開されるため、非常に高いセキュリティが求められます。
-
最小権限の原則:
-
セキュリティグループ: SSH (22番ポート) またはRDP (3389番ポート) のみ許可し、ソースIPはあなたの固定IPアドレスに限定します。
0.0.0.0/0(どこからでも) は絶対に許可してはいけません。 - NACL: Bastion Hostが配置されるサブネットのNACLも、SSH/RDPに必要なポートのみを許可するように設定します。
-
セキュリティグループ: SSH (22番ポート) またはRDP (3389番ポート) のみ許可し、ソースIPはあなたの固定IPアドレスに限定します。
- 堅牢化: OSの定期的なアップデート、不要なサービスの停止、ログの監視、多要素認証(MFA)の適用などを徹底します。
- 監視: 不審なアクセスがないか、CloudWatch LogsやCloudTrailで常に監視します。
- 専用のキーペア: 他のインスタンスと共有しない、専用のSSHキーペアを使用することを推奨します。
3. Bastion Hostの構築と設定の実践
それでは、パブリックサブネットにBastion Hostを構築し、プライベートサブネットのEC2インスタンスに安全にアクセスできるように設定していきましょう。
3.1. Bastion Host用セキュリティグループの作成
まず、Bastion Host専用のセキュリティグループを作成します。
- AWSマネジメントコンソールで「VPC」サービスを開き、「セキュリティグループ」をクリックします。
- 「セキュリティグループを作成」をクリックします。
-
セキュリティグループ名:
bastion-host-sg -
説明:
Allow SSH from specific IP to bastion host - VPC: あなたのVPCを選択
-
インバウンドルール:
- タイプ:
SSH(ポート 22) - ソース:
My IPまたは あなたのオフィス/自宅の固定IPアドレス (絶対に0.0.0.0/0にしない!)
- タイプ:
-
アウトバウンドルール:
All traffic(全て許可 - デフォルト)
-
セキュリティグループ名:
- 「セキュリティグループを作成」をクリックします。
3.2. プライベートサブネット用セキュリティグループの更新
次に、プライベートサブネット内のインスタンス(例: app-server-sg が適用されるインスタンス)がBastion HostからのSSHを許可するようにルールを追加します。
- 「セキュリティグループ」リストで、
app-server-sg(またはプライベートサブネットに配置するインスタンス用のSG) を選択します。 - 「インバウンドルール」タブで「インバウンドルールを編集」をクリックします。
- 「ルールを追加」をクリックします。
- タイプ:
SSH(ポート 22) - ソース:
bastion-host-sg(作成したBastion Host用SGを選択)- ポイント: ここでBastion HostのSGを指定することで、そのSGが適用されたインスタンスからのみSSHアクセスを許可する非常にセキュアな設定になります。IPアドレスの変更を気にしなくてよくなります。
- タイプ:
- 「ルールを保存」をクリックします。
3.3. Bastion Hostの起動
Day 8と同じ手順で、新しいEC2インスタンスをBastion Hostとして起動します。
- EC2サービスを開き、「インスタンスを起動」をクリックします。
-
名前:
BastionHost -
AMI:
Amazon Linux 2023 AMIなど -
インスタンスタイプ:
t2.microまたはt3.micro(無料利用枠対象) - キーペア: Bastion Host専用の新しいキーペアを作成するか、既存のものを選択(セキュリティのため専用のものが望ましい)。秘密鍵ファイルを安全に保管。
-
ネットワーク設定:
- VPC: あなたのVPC
- サブネット: パブリックサブネットAを選択 (Bastion Hostはパブリックである必要がある)
- 自動割り当てパブリック IP: 「有効化」
-
ファイアウォール (セキュリティグループ): 「既存のセキュリティグループを選択する」を選び、
bastion-host-sgを選択。
- 他はデフォルトのままで「インスタンスを起動」。
3.4. プライベートサブネットにEC2インスタンスを起動(テスト用)
Bastion Hostからのアクセスをテストするために、プライベートサブネットにもEC2インスタンスを起動しておきましょう。(もしDay 8で既にプライベートサブネットにインスタンスを起動していれば不要です)
- EC2サービスを開き、「インスタンスを起動」をクリックします。
-
名前:
MyPrivateAppServer01 -
AMI:
Amazon Linux 2023 AMIなど -
インスタンスタイプ:
t2.microまたはt3.micro - キーペア: Bastion Hostと同じキーペア、またはプライベートインスタンス用の新しいキーペアを選択。
-
ネットワーク設定:
- VPC: あなたのVPC
-
サブネット: プライベートサブネットA (
my-vpc-private-subnet-aなど) を選択 -
自動割り当てパブリック IP: 「無効化」
- ポイント: プライベートサブネットなので、パブリックIPは不要です。
-
ファイアウォール (セキュリティグループ): 「既存のセキュリティグループを選択する」を選び、
app-server-sgを選択。
- 他はデフォルトのままで「インスタンスを起動」。
MyPrivateAppServer01 の詳細画面で、パブリックIPv4アドレスが割り当てられていないことを確認してください。
4. Bastion Host経由でのアクセス実践
いよいよ、Bastion Hostを経由してプライベートサブネットのインスタンスにSSH接続してみましょう。
4.1. Bastion HostへのSSH接続
まず、あなたのローカルPCからBastion HostへSSH接続します。
# Bastion HostのパブリックIPアドレスはEC2インスタンス詳細で確認
ssh -i /path/to/bastion_keypair.pem ec2-user@<Bastion_Host_Public_IP_Address>
接続が成功したら、Bastion Hostの中にいる状態です。
4.2. Bastion HostからプライベートインスタンスへのSSH接続
次に、Bastion HostからMyPrivateAppServer01へSSH接続します。
重要: プライベートインスタンスにSSH接続するためには、そのインスタンスにアクセスするための秘密鍵ファイル(.pemファイル)がBastion Host上に存在する必要があります。
-
秘密鍵ファイルをBastion Hostにコピー:
SCPコマンドを使って、あなたのローカルPCからBastion Hostに秘密鍵ファイルをコピーします。# ローカルPCのターミナルから実行 scp -i /path/to/bastion_keypair.pem /path/to/private_instance_keypair.pem ec2-user@<Bastion_Host_Public_IP_Address>:/home/ec2-user//path/to/private_instance_keypair.pemは、MyPrivateAppServer01を起動する際に使用した秘密鍵のパスです。 -
Bastion Host内で秘密鍵のパーミッションを設定:
Bastion HostにSSH接続した後、コピーした秘密鍵ファイルのパーミッションを設定します。# Bastion Hostのターミナルで実行 chmod 400 /home/ec2-user/private_instance_keypair.pem -
Bastion HostからプライベートインスタンスへSSH接続:
Bastion Hostのターミナルから、プライベートインスタンスのプライベートIPアドレスを使って接続します。# Bastion Hostのターミナルで実行 # <Private_Instance_Private_IP_Address> はMyPrivateAppServer01のプライベートIPアドレス ssh -i /home/ec2-user/private_instance_keypair.pem ec2-user@<Private_Instance_Private_IP_Address>接続が成功すれば、Bastion Hostを経由してプライベートサブネット内のインスタンスに安全にアクセスできたことになります!
SSH Agent Forwarding (上級者向け):
上記のように秘密鍵ファイルをBastion Hostにコピーする方法は、セキュリティ上の懸念(秘密鍵が中間サーバーに残る)があるため、より推奨されるのはSSH Agent Forwardingという機能です。これは、ローカルPCのSSH Agentに読み込んだ秘密鍵をBastion Host経由で転送し、秘密鍵自体をBastion Hostに置かずにアクセスする仕組みです。
# ローカルPCのターミナルで実行
# まずAgentに秘密鍵を追加(もし追加済みでなければ)
ssh-add /path/to/private_instance_keypair.pem
# Bastion HostへAgent Forwardingを有効にして接続
ssh -A -i /path/to/bastion_keypair.pem ec2-user@<Bastion_Host_Public_IP_Address>
# Bastion Hostに接続後、プライベートインスタンスへ接続(秘密鍵はBastion Hostに不要)
ssh ec2-user@<Private_Instance_Private_IP_Address>
この方法だと、プライベートインスタンスの秘密鍵はあなたのローカルPCから移動せず、より安全です。
5. AI時代におけるNAT GatewayとBastion Hostの考慮事項
AI/MLワークロードでは、大量のデータと計算リソースを扱うため、ネットワークアクセス管理が特に重要です。
- NAT Gatewayのスループット: 大規模なデータセットのダウンロードや、外部APIへの頻繁なアクセスがある場合、NAT Gatewayのスループットがボトルネックになる可能性があります。NAT GatewayはElastic IPがアタッチされた単一のENI(Elastic Network Interface)を使用するため、そのENIのネットワークパフォーマンスが影響します。必要に応じて、より高スペックなEC2インスタンスタイプに基づくNATインスタンスの検討、またはVPCエンドポイントの活用を検討します。
- VPCエンドポイントの活用: S3、DynamoDB、SageMakerなど、AWSの多くのサービスへのアクセスは、インターネットゲートウェイやNATゲートウェイを介さずに、VPCエンドポイントを介してプライベートにルーティングすることが可能です。これにより、セキュリティが向上し、データ転送コストを削減できる場合があります。AI/MLワークロードで頻繁に利用するAWSサービスがあれば、積極的にVPCエンドポイントを導入すべきです。
- Bastion Hostのオートスケール/冗長化: 大規模なチームで複数の管理者がアクセスする場合、単一のBastion Hostが単一障害点となったり、性能ボトルネックになったりする可能性があります。Auto Scaling Groupを使ってBastion Hostを冗長化したり、Session ManagerのようなAWSマネージドサービス(後述)の活用も検討できます。
- AWS Systems Manager Session Managerの活用: Bastion Hostを運用する手間(OSの管理、セキュリティパッチ適用、SSHキー管理など)を削減したい場合、AWS Systems ManagerのSession Managerが非常に強力な代替手段となります。Session Managerを使えば、SSHキーやポートを開放することなく、AWSマネジメントコンソールやCLIからプライベートサブネット内のインスタンスに直接接続できます。外資系AI企業では、セキュリティと運用効率の観点から、Bastion HostよりもSession Managerが推奨されるケースが多いです。今後のDayで詳しく解説する予定です。
本日のまとめと次へのステップ
今日は、AWSネットワークにおけるプライベートサブネットからの安全なアクセス経路について、以下の2つの重要な概念を学び、実践しました。
- NAT Gateway: プライベートサブネット内のリソースがインターネットに「アウトバウンド通信のみ」を行うための重要なサービス。セキュリティを確保しつつ、OSアップデートなどの必要性を満たします。
- Bastion Host (踏み台サーバー): インターネットからパブリックサブネットに配置され、そこを経由してプライベートサブネット内のリソースに安全にSSH接続するためのサーバー。多層防御の一環として、セキュリティを厳重に管理する必要があります。
これらの知識と実践は、あなたがAWS上でより堅牢でセキュアなシステムを構築するための重要なステップです。
明日のDay 10では、「VPC Peering:VPC間接続で広がる可能性」と題して、複数のVPC間でプライベートな通信を確立するための「VPCピアリング」について学びます。異なる環境やプロジェクトで分離されたVPC間で安全に通信したい場合に非常に役立つ機能です。
今日のNAT GatewayとBastion Hostの概念、そして実践はうまくいきましたか?「いいね」👍であなたの学びを共有してください!
