Amazon Linux 2023でNAT Instanceを手作りしてみた

Amazon Linux 2023でNAT Instanceを手作りしてみた

Clock Icon2023.03.21

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

しばたです。

私は昔から検証環境でNAT Instanceを利用しているのですが、先日Amazon Linux 2023が正式リリースされたのを受け「流石にそろそろインスタンスを更新するか」という気分になりAmazon Linux 2023でNAT Instanceを作成してみました。

本記事ではその手順を紹介します。

作成手順

Amazon Linux 2以降のディストリビューションにおいてはAWS公式でNAT Instance AMIは提供されておらず、以下の記事にある様に自分で手作りする必要があります。

https://dev.classmethod.jp/articles/nat-instance-handmaid/

こちらの記事はAmazon Linux 2のものであり、当然ながらまだAmazon Linux 2023向けの公式手順といったものは存在してません。(現在は公式手順が存在します)
とはいえ、そこまでディストリビューション独自の作業は少ないため「多分Amazon Linux 2の手順と同じで大丈夫だろう。」との考えで作業を進めていきます。

【2023年11月13日 追記】AWS公式ドキュメントの手順

具体的にいつ頃ドキュメントが更新されたかは不明ですが、現在はAWS公式ドキュメントにAmazon Linux 2023での手順が記載されています。

内容としてはiptablesコマンドを追加インストールしてAmazon Linux 2と同じ手順を行う形になっています。

「公式の手順」が欲しい方は上記ドキュメントを参照してください。
本記事の内容はnftablesコマンドを使った実装例としてお使いください。

注意事項

基本方針とAmazon Linux 2023独自の事情

基本方針としてはAmazon Linux 2の時と同様に、

  1. 当該インスタンスでnet.ipv4.ip_forwardカーネルパラメーターの設定およびiptablesを設定する
  2. 当該インスタンスのENIで「送信元/送信先チェック」を無効にする

を行います。

ただ、Amazon Linux 2023の初期状態ではiptablesコマンドがインストールされていません。
このため今回は代わりに後継のnftablesコマンドをインストールしてNATの設定を行います。

1. EC2インスタンスの作成

今回は私の検証アカウントの東京リージョンに以下の条件でEC2インスタンスを用意しました。

  • AMIは ami-00cd61829b9bb9eca : al2023-ami-2023.0.20230315.0-kernel-6.1-arm64
  • インスタンスタイプは t4g.micro
  • EBSボリュームは最低容量の gp3 8GiB
  • セキュリティグループは事前準備済みのものを使用 (作成手順は割愛)
    • インバウンドルールはVPC内からHTTP, HTTPSを許可
    • アウトバウンドは全ての通信を許可
  • SSM Sessionで接続可能なIAMロールをアタッチ

2. インスタンス内部設定 (net.ipv4.ip_forward)

SSM Sessionでインスタンスに接続し、以下のコマンドを実行してnet.ipv4.ip_forwardカーネルパラメーターを設定します。

sudo sysctl -w net.ipv4.ip_forward=1 | sudo tee -a /etc/sysctl.conf

ここはAmazon Linux 2の時と変わりません。

3. インスタンス内部設定 (nftables)

続けてiptablesの代わりにnftablesをインストールしてNATの設定を行います。

# Amazon Linux 2023の初期状態ではiptablesは未インストール
# このため今回はnftablesをインストール
sudo yum install -y nftables

nftablesでNATするための基本設定は以下のRed Hatのドキュメントを参考にしています。

基本的にはドキュメント通りの内容ですが、一点ハマったところがあり、Amazon Linux 2023ではNICが予測可能なデバイス名となっておりeth0固定では無いのでご注意ください。(代わりにENI IDやdevice-munber-0といった代替名が与えられています)
下記手順ではip -o link show device-number-0コマンドを使いデバイス名を取得しています。

あとは設定内容を/etc/nftables/al2023-nat.nftファイルに保存しサービス起動時にロードする様にしています。

# NAT設定追加 : NICデバイス名がeth0ではないので注意。今回の環境では ens5 だった
sudo nft add table nat
sudo nft -- add chain nat prerouting { type nat hook prerouting priority -100 \; }
sudo nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
sudo nft add rule nat postrouting oifname "$(ip -o link show device-number-0 | awk -F': ' '{print $2}')" masquerade
# NAT設定保存
sudo nft list table nat | sudo tee /etc/nftables/al2023-nat.nft
echo 'include "/etc/nftables/al2023-nat.nft"' | sudo tee -a /etc/sysconfig/nftables.conf

# サービス起動+自動起動設定
sudo systemctl start nftables
sudo systemctl enable nftables

ちなみに/etc/nftables/al2023-nat.nftの中身はこんな感じになります。

/etc/nftables/al2023-nat.nft (環境によってoifnameは変わります)
table ip nat {
        chain prerouting {
                type nat hook prerouting priority dstnat; policy accept;
        }

        chain postrouting {
                type nat hook postrouting priority srcnat; policy accept;
                oifname "ens5" masquerade
        }
}

4. インスタンスの送信元/送信先チェックの無効化

続けて当該インスタンスのENI設定を開き「送信元/送信先チェック」を無効にします。

これもAmazon Linux 2の時と同様ですね。
以上でインスタンスの設定変更は完了です。

5. ルートテーブルの更新

あとはルートテーブルを更新してやれば完了ですが本記事では説明を割愛します。
こちらは環境に応じてよしなにやってください。

動作確認

別途動作確認用のEC2インスタンスを用意しcheckip.amazonaws.comへアクセスして動作確認すると以下の結果となりました。

いい感じですね。

最後に

以上となります。

ちょっとハマりましたがなんとかなりました。
次は古いNAT Instanceからの切り替え手順について解説する予定です。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.