NatゲートウェイからNatインスタンスに変えた
EC2のNATインスタンスAMI選び方
Amazon Linux AMI 2018.03 Release Notes で希望するリージョンで amzn-ami-vpc-natに該当するAMIを検索して、一番新しい年月日のものを使う。NATのAMI選びを間違えると苦労します。かなり大事です。
AWSのEC2の仮想化方式(仮想化タイプ)はHVMとPVがある。基本的にHVMのほうがパフォーマンスもよく、料金も安い。
- PV=準仮想化
- HVM=全仮想化
ENA有効化については、ネットワーク帯域幅が大きいほうがいいという場合、ENA有効化「はい」のものを選ぶ。
NATインスタンスセキュリティグループをつくる
NATインスタンスのセキュリティグループのインバウンドは、プライベートサブネットのWEBサーバーなど、NATインスタンス経由でhttpsリクエストをパブリックネットワークにアウトバウンド送信したいEC2インスタンスのセキュリティグループをソース(sg-○△☓○△☓○△☓○△☓)に指定してHTTPSの443を開ける
NATインスタンスのセキュリティグループのアウトバウンドは、0.0.0.0/0でHTTPSの443の1つだけを開ける(VPCの10.0.0.0/16で443のHTTPSでも可能)。プライベートサブネットのAmazonLinux2のWEBサーバーなどのEC2インスタンスで yum updateなどのhttpsアウトバウンドを出来ないようにしたい場合、このアウトバウンドを閉鎖する。ただし、VPCエンドポイント経由のS3とEC2の間の経路制限をしていないと、S3の中のAmazonLinuxやAmazonLinux2のリポジトリでyum update出来てしまう場合があるので気をつけてください。
プライベートサブネットのAmazonLinux2のWEBサーバーなどのEC2インスタンスでyum updateを行い、NATインスタンス経由で外部のインターネットに接続する際、NATインスタンスのセキュリティグループはHTTPSだけでOK。
NAT経由のプライベートサブネットのWEBサーバーなどのEC2インスタンスでyum updateをするのはSSHの経路不要ですが、開発者の手元にあるリモートワーク作業場所のマシンからNATインスタンスにSSH接続したい場合、そのIPアドレスだけでインバウンドSSHを作る。
NATインスタンス経由でアウトバウンドhttpsリクエストをしたいEC2インスタンスのセキュリティグループを設定
NATインスタンス経由でアウトバウンドhttpsリクエストをしたいEC2インスタンスのセキュリティグループのアウトバウンドで、httpsの443にて送信先をNATのセキュリティグループ(sg-○△☓○△☓○△☓○△☓)に指定する。念の為、送信先がVPCのCIDRでは出来ないという事に注意する必要がある。
セキュリティグループの内部的な動作はセキュリティグループIDによるネットワークインターフェイスにおける許可/拒否であり、LocalプライベートIPのエイリアスではない
セキュリティグループにおけるインバウンドで、送信元(ソース)にセキュリティグループ(sg-○△☓○△☓○△☓○△☓)を設定する場合、VPC内のプライベートIPのエイリアスという挙動ではなく、sg-○△☓○△☓○△☓○△☓というセキュリティグループIDがアタッチされた送信元となるEC2インスタンスのネットワークインターフェイスを許可するという挙動になります。送信元に設定したセキュリティグループを、LocalのプライベートIPのエイリアスと考えてしまうのは間違いです。セキュリティグループは、基本的にネットワークインターフェイスにアタッチされます。
AMIを選んでNATインスタンス作る
太字タイトル amzn-ami-vpc-nat-2018.03.0.20200918.0-x86_64-ebs
下段細字 Amazon Linux AMI 2018.03.0.20200918.0 x86_64 VPC HVM ebs
を選んだ。念のため、AmazonLinuxは、RHEL6/CentOS6ベースの模様、つまり、iptablesだけです。firewalld+iptablesはCentOS7で、firewalldはiptablesと併用出来ないのでよく調べて設定する必要があります。
下段細字にnatの文字が入っていないのが気になりますが、きちんとNatインスタンス出来ました。
上記で作ったセキュリティグループを選んでください。
NATゲートウェイが配置してあったパブリックサブネットをそのまま使います。LocalとIGWのルートテーブルが紐付いているパブリックサブネットです。
EIPも設定します。
確認として、NATインスタンスにSSH接続し
/etc/sysctl.d/10-nat-settings.conf
にて、以下のように設定されているか?確認してください。
//IPv4フォワード(IPv4転送)を有効にする
net.ipv4.ip_forward = 1
//ICMPリダイレクトを送信しない(無効)
net.ipv4.conf.eth0.send_redirects = 0
同じ様にiptablesでIPマスカレードの設定も確認します。
sudo iptables -t nat -L --line
NATインスタンスのネットワークインターフェイス設定
NATインスタンス自己IPかホスト名へのリクエストではない場合にリクエストの受信を拒否する機能を無効化します。プライベートサブネットのWEBサーバーなどのEC2インスタンスから外部インターネットへのhttpsリクエストがパブリックサブネットのNATインスタンスを外部インターネット方向に通過できるようにします。NATインスタンスをプライベートサブネットに配置しない様に気をつけてください。
EC2ダッシュボードでNATインスタンスのネットワークインターフェイス画面に移動し、NATインスタンスのネットワークインターフェイスの「送信元/送信先の変更チェック」をfalseにする。
ルートテーブル設定を変える
プライベートサブネット用のルートテーブルのターゲットで「NATゲートウェイ」にしていた箇所で「instance」を選び、そのあとに表示されるEC2インスタンスのリストからNATインスタンスを選びます。
参考までに、ルートテーブルの削除されてしまい無くなってしまったターゲットリソースは『blackhole』と記載されます。
NATゲートウェイもNATインスタンスも、基本的に、パブリックサブネットで使うルートテーブル(Local と IGW)に配置します。ですが、ルートテーブルでは、プライベートのLocalだけなどのプライベートサブネットのルートテーブルにnat-instanceを設定します。
NATインスタンス経由でhttpsリクエスト出来るか確認
Natインスタンス経由でhttpsリクエストをパブリックネットワークに行いたいEC2インスタンスに(VPN配下で)SSH接続して次のコマンドを実行して、レスポンスが帰ってきたら成功。
curl https://www.google.com
以下のコマンドでステータス200を確認してもOK
curl -I https://www.google.com
VPCの中のプライベートサブネットから出ていくhttpsのアウトバウンドをNAT経由で細かく絞り込む
httpsとしてプロトコルまではNatで絞りこむ事を出来ますが、送信先のIPアドレスレンジや送信先のURLなどでhttpsアウトバウンドをさらに絞るには、iptablesやSquidなどのProxyサーバを検討する必要があります。エンドポイントセキュリティを意識する場合が該当するかと思います。