こんにちは、自称ネットワークエンジニアの貝塚です。
AWS環境において、会社間でVPC同士を接続したいということはないでしょうか?
多くの場合、以下の記事で解説されているVPCエンドポイント(PrivateLink)を用いるのが最適な手段ではないかと思います。
PrivateLinkを使用すれば互いに相手側のIPアドレスは隠蔽されるので、IPアドレス被りを心配する必要もなく、私のようにネットワーク設計を考える立場の人間からするととてもありがたいサービスです。
PrivateLinkが使えない場合どうするか?
しかし、PrivateLinkはTCP通信にしか対応していないため、UDPを通したい場合には使用できません。
また、通信対象サーバが複数ある場合は、原則、サーバごとにPrivateLinkの作成が必要になりますし、逆方向の通信が発生する(A社からB社方向へコネクションを開始するだけではなく、B社からA社方向へコネクションを開始する)場合、逆方向のPrivateLinkも必要です。このように通信要件が多くなるとPrivateLinkの管理が逆に大きな負担になってきます。(PrivateLinkのエンドポイントサービス側にはELBが必要なので、料金面の負担も大きくなるかもしれません)
- NATして互いのIPアドレスを隠蔽できる。(ソースNATとデスティネーションNATが両方できる)
- UDPを通せる。
- 双方向通信に対応できる。(1対1NATができる)
- インターネットは通らないようにする。
上記条件を満たすソリューションとして
接続したいVPCの間にNAT用EC2インスタンスをデプロイした中間VPCを設け、VPC Peeringで接続する方式
を考えてみました。(下図)
今さらNATインスタンス
……非常に泥臭いですね。
EC2を1台管理する手間が増えますし、(直接聞いたことはないですが)AWSはEC2インスタンスで1対1NATすることをあまり推奨していないような感じがします。
が、必要とあらば仕方ありません。
以下、NATインスタンス以外(VPC、サブネット、ルートテーブル、VPC Peering、NATインスタンス以外のEC2インスタンス、EC2に適用するセキュリティグループ、など)は既に構築済みという前提で、NATインスタンスの構築手順を解説します。
VPC Peeringの構築やVPC Peeringした際のルートテーブルの設定などは、インターネット上にブログ記事が多数存在しますので、それらを調べてみてください。
また、インスタンスへのアクセス手段も本記事では解説しておりませんが、VPC内にエンドポイントを作成してセッションマネージャーで接続する、インターネットゲートウェイをアタッチしてインターネットからsshするなどでアクセスできるようにしてください。
EC2インスタンス作成
Linux (Amazon Linux 2023)のAMIからEC2インスタンスを作成します。
作成時に「高度なネットワーク設定」を開き、セカンダリIPを「自動で割り当てる」、IP数は今回2を指定します。
その他は特に注意事項ありません(インスタンスにアクセスできるように適切にセキュリティグループやIAMインスタンスプロファイルの指定はしてください)。
割り当てられたセカンダリIPは、EC2インスタンスの「ネットワーキング」タブから確認することができます。今回の検証では、10.33.1.145と10.33.1.151が割り当てられました。
iptablesの設定
NATインスタンスにログインしてNAT設定を行います。
今回は、NAT機能を実現するためにiptablesを使用しますが、Amazon Linux 2023にはデフォルトでインストールされていないので、yumを使用してインストールします。
sudo yum install -y iptables-services
iptablesを起動します。
sudo systemctl start iptables
IPパケットを中継する必要があるので、IPフォワーディングを有効にします。 sysctl コマンドで有効にしただけでは再起動で設定が消えてしまうので、/etc/sysctl.conf にも書き込んでおきます。
sudo sysctl -w net.ipv4.ip_forward=1 | sudo tee -a /etc/sysctl.conf
次に、NATの設定を入れます。
A社のIP 10.32.1.157を中間VPCの10.33.1.145にアドレス変換するようにします。
10.32.1.157が送信元の時に10.33.1.145に変換する設定(ソースNAT)と、10.33.1.145が宛先の時に10.32.1.157に変換する設定(デスティネーションNAT)の2行必要です。
sudo /sbin/iptables -t nat -A POSTROUTING -s 10.32.1.157 -j SNAT --to-source 10.33.1.145 sudo /sbin/iptables -t nat -A PREROUTING -d 10.33.1.145 -j DNAT --to-destination 10.32.1.157
同様に、B社のIP 10.34.1.125を中間VPCの10.33.1.151にアドレス変換するようにします。
sudo /sbin/iptables -t nat -A POSTROUTING -s 10.34.1.125 -j SNAT --to-source 10.33.1.151 sudo /sbin/iptables -t nat -A PREROUTING -d 10.33.1.151 -j DNAT --to-destination 10.34.1.125
念のためここまでに入れたNAT設定を確認してみます。以下のようになっているはずです。
[ec2-user@ip-10-33-1-124 ~]$ sudo iptables -vL -t nat Chain PREROUTING (policy ACCEPT 2 packets, 702 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT all -- any any anywhere ip-10-33-1-145.ap-northeast-1.compute.internal to:10.32.1.157 0 0 DNAT all -- any any anywhere ip-10-33-1-151.ap-northeast-1.compute.internal to:10.34.1.125 Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 422 packets, 29626 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 422 packets, 29626 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT all -- any any ip-10-32-1-157.ap-northeast-1.compute.internal anywhere to:10.33.1.145 0 0 SNAT all -- any any ip-10-34-1-125.ap-northeast-1.compute.internal anywhere to:10.33.1.151
OS再起動後もiptablesを自動起動しNAT設定が反映されるようにします。
sudo systemctl enable iptables sudo service iptables save
疎通確認
A社EC2から10.33.1.151にpingを実行してみます。
B社EC2でtcpdumpを実行してみると、10.33.1.145からpingが来ているので、意図通りのNATができていることが分かります。
B社EC2から10.33.1.145にpingを実行してA社EC2でtcpdumpを実行してみると、逆方向も確かに10.33.1.151からpingが来ており、意図通りのNATができていることが分かります。
まとめ
以上、NATインスタンスの構築手順でした。
なお、ここで示したソリューションは検証用のものであり、実際にビジネスで使用する場合にはNAT以外にも例えば以下のような考慮点があります。ご注意ください。
- 中間VPCのIPアドレスは両社で合意しておく必要がある。
- VPC間通信のセキュリティ。
- NATインスタンスは誰が管理するのか。(NATインスタンスを管理している側は容易にセキュリティ侵害できてしまう点に注意)