はじめに
こんにちは、株式会社エーピーコミュニケーションズ クラウド事業部の鈴木歩です。
AWS でプライベートサブネットに置いたリソースをインターネットに通信させるときには
一般的には NAT ゲートウェイを使うことが多いかと思います。
ただ、NAT ゲートウェイは気づかないうちに結構な料金がかかっているケースがよくあります。
【参考】 0.062USD/Hour + 0.062USD/GB → 1 か月で 10GB 通信した場合は約 6,473 円
本番環境ではマネージドサービスの恩恵を受けられると思いますが、検証環境では旨味は少ないかと思います。
そこで私がよく取る方法として、NAT インスタンスを作成して代用しています。
また EC2 であるメリットを活かして、外側からプライベートサブネットへアクセスするための踏み台サーバー(Bastion)も
兼任させることが多いです。自分の中では名付けてNAT-BASTIONと読んでいます。
そんな NAT-BASTION の作り方を紹介します。
説明すること
- NAT-BASTION になる EC2 の作り方
- EC2でルーティングさせる設定
- VPC の設定
- 接続方法
※ 一般的な EC2、VPC の操作は割愛します
事前準備
- インターネットに繋がっているパソコン
- 任意の Web ブラウザ
- 任意の SSH クライアント
- SSH ポートフォワーディング機能を持っていること
- 以下の認可がある IAM ユーザー
- EC2 を操作できること
- VPC を操作できること
Step1:NAT-BASTION になる EC2 インスタンスの作成
以下の条件で EC2 を作成します。
- OS
- AmazonLinux2023
- 64 ビット(Arm) ※1
- インスタンスタイプ
- t4g.nano ※1
- キーペア
- 任意のキーペア
- サブネット
- 任意のパブリックサブネット
- セキュリティグループ
- インバウンドで SSH のポート(TCP22)を許可していること
- アウトバウンドで任意の通信を許可していること
- これがプライベートサブネットに配置した EC2 の通信可能先になります
- ユーザーデータ
- 後述 ※2
※1 必須ではありませんがコストを抑えるという目的では非常に有効です。
NAT インスタンスや SSH ポートフォワーディングする程度の利用であれば性能は低くても
現状困ったことはありませんでした。
【参考】 t4g.nano(CPU:2 コア MEM:0.5GB) → 0.0054USD/Hour → 1 か月で 10GB 通信した場合は約 865 円
※2 ユーザーデータに書くスクリプト
セキュリティを意識する場合は ec2-user を無効にしたり、TCP22 ポートから変更したり
などの対策を別途行ってください。
#!/bin/bash yum install -y iptables-services systemctl enable --now iptables /sbin/iptables -t nat -A POSTROUTING -o ens5 -j MASQUERADE /sbin/iptables -F FORWARD service iptables save sysctl -w net.ipv4.conf.all.forwarding=1 >> /etc/sysctl.d/99-sysctl.conf sysctl -p /etc/sysctl.d/99-sysctl.conf cat << "EOF" >> /etc/ssh/sshd_config.d/portforward-only.conf Match User ec2-user AllowTcpForwarding yes X11Forwarding no AllowAgentForwarding no PermitTTY no EOF systemctl restart sshd
Step2:NAT-BASTION になる EC2 インスタンス作成後の設定
以下の画像の通りに設定を行い、EC2 に対して以外の通信を許可してください。
(この設定が無いと EC2 でルーティングができません)
Step3:プライベートサブネットのルートテーブルの設定
通信させたいプライベートサブネットのルートテーブルに以下のように
エントリーを追加してください。
以上で設定は完了です!
接続方法
任意の SSH クライアントで NAT-BASTION に対して SSH ポートフォワーディングを行い、
プライベートサブネット上の EC2 に SSH 接続します。
ここでは例として OpenSSH Client を使います。(最近の Windows ならデフォルトで使えます)
ターミナルを開き、以下のコマンドを入力します。
入力後は、ターミナルは閉じないでください。開いている間のみトンネルを張ります。
# 構文 ssh -L (SSHクライアントの任意ポート):(接続先プライベートIP):(接続先SSHポート) ec2-user@(NAT-BASTIONのグローバルIP) -i (NAT-BASTIONに設定した秘密鍵のPATH) # 例 ssh -L 10022:172.20.128.1:22 ec2-user@203.0.113.1 -i .ssh\key.pem
次にプライベートサブネット上の EC2 へ SSH 接続します。
別のターミナルを開き、以下のコマンドを入力します。
# 構文 ssh (接続先OSのユーザー名)@localhost -p (SSHクライアントの任意ポート) -i (接続先に設定した秘密鍵のPATH) # 例 ssh ubuntu@localhost -p 10022 -i .ssh\key2.pem
もちろん、接続先 EC2 からインターネットに出ることも可能です。
curl や dnf update などで試してみてください。
また、セキュリティ対策として NAT-BASTION に ec2-user で SSH 接続して CLI 操作はできなくしてます。
参考:vscode の Remote SSH の接続先として使う場合
詳細は割愛しますが、vscode の拡張機能で Remote SSH という便利なものがあります。
この拡張機能の接続先としても利用することが可能です。
手順は以下の設定内容を .ssh\config に書き込めば vscode の接続先一覧に表示されます。
Host natbastion HostName (NAT-BASTIONのグローバルIP) User ec2-user IdentityFile (NAT-BASTIONに設定した秘密鍵のPATH) ForwardAgent yes Host (任意の名前) HostName (接続先プライベートIP) User (接続先OSのユーザー名) IdentityFile (接続先に設定した秘密鍵のPATH) ProxyJump natbastion
まとめ
- NAT-BASTION を作れば以下のいいことがある!
- NAT ゲートウェイの料金を約 85%に削減できる
- ついでに踏み台サーバーとしても利用できる
- 欠点は、EC2 インスタンスなので自分で管理する必要がある
- セキュリティ
- AZ 障害
- などなど・・・
本番環境ではお金かかってでもNATゲートウェイを使うべきですが、
検証環境で安く済ませたい場合はとても有効だと個人的には思っています。
皆さんもぜひ試してみてください!
終わりに
APC は AWS Advanced Tier Services(アドバンストティアサービスパートナー)認定を受けております。
その中で私達クラウド事業部は AWS などのクラウド技術を活用した SI/SES のご支援をしております。
www.ap-com.co.jp
https://www.ap-com.co.jp/service/utilize-aws/
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。