こんにちは!クラウドやKubernetesの裏側で、日々パケットの旅立ちを見守っているSREのエンジニアです。
インフラの世界に足を踏み入れると、「プライベートサブネットにあるサーバーから、どうやって外部のインターネットへ通信するんだろう?」という疑問にぶつかりますよね。マネージドサービスであるAWSのNAT GatewayやGCPのCloud NATはボタン一つでそれを解決してくれますが、「その裏側で、Linuxカーネルは一体どんな魔法を使っているんだろう?」と気になったことはありませんか?
今回は、市販のEC2インスタンスや自前で用意したLinuxサーバーを「カスタムNATインスタンス」に仕立て上げ、パケットの宛先や送信元を書き換える iptables の世界へ、一歩ずつ優しくご案内していきたいと思います!
—
1. 秘密の「住所書き換え」:NATとSNATの役割を街の郵便配達に例えてみよう
まずは、パケットの気持ちになって考えてみましょう。
プライベートサブネットにいるサーバー(仮に 10.0.1.10 としましょう)は、いわば「外の世界に出られない秘密基地」に住んでいます。この基地から「インターネットの向こうにあるWebサイトを見たい!」と手紙(パケット)を出したとします。
ここで問題が発生します。プライベートIPアドレスである 10.0.1.10 は、インターネットという広大な世界では「架空の住所」扱い。インターネット側のサーバーから返事が返ってくるとき、どこに送ればいいか分からないため、そのままでは通信できません。
そこで登場するのが、秘密基地のゲート番であるNATインスタンスです。
郵便配達の仕組み
1. プライベートサーバーが手紙を出すとき、NATインスタンスはこう書き換えます。
- 「ふむ、送信元が
10.0.1.10になっているな。このままだと外の世界で迷子になるから、私の持っているパブリックIPアドレス(例:203.0.113.5)に書き換えちゃおう!」
2. この「送信元の住所を書き換える」魔法こそが、SNAT(Source Network Address Translation) です。
3. インターネットの向こうのWebサイトは、「お、203.0.113.5 さんからの手紙だな」と思って返事を送ります。
4. 戻ってきた手紙を受け取ったNATインスタンスは、心の中でこう思います。「あ、これはさっきの 10.0.1.10 君宛ての手紙だな」。そして宛先を元のプライベートIPに戻して、秘密基地へ届けてあげます。
この一連の流れを、Linuxカーネルの機能である Netfilter と iptables を使って設定していきましょう!
—
2. 準備運動:パケットの転送(ポートフォワード)を有効にする
iptables で住所書き換えのルールを書く前に、Linuxカーネル自体に「外から来たパケットを別の場所へスルー(転送)してもいいよ」という許可を出してあげる必要があります。これが無言だと、パケットを受け取った瞬間に「ここは中継地点じゃない!」とLinuxに捨てられてしまいます。
まずは、以下のコマンドでカーネルパラメーターを一時的に変更してみましょう。
# Linuxカーネルにパケットの転送(ルーティング)を許可します
sudo sysctl -w net.ipv4.ip_forward=1
※ 本番環境や実務では、再起動後もこの設定が消えないように /etc/sysctl.conf などの設定ファイルに net.ipv4.ip_forward = 1 を書き込んでおくのが鉄則です!
—
3. いよいよ本番!iptablesでSNAT/MASQUERADEを設定する
それでは、今回のメインテーマである iptables の設定です。
Linuxのパケット処理において、宛先や送信元を「後から書き換える」場所は、Netfilterの nat テーブルという特別なエリアで行われます。
ここでよく使われる2つのアプローチ、SNAT と MASQUERADE の違いを優しく見ていきましょう。
パターンA:送信元IPアドレスを固定する「SNAT」
NATインスタンスが持つパブリックIPアドレスが固定(Elastic IPなど)である場合、どのプライベートIPからのパケットであっても、確実にその固定IPに書き換えるのが SNAT です。
# natテーブルのPOSTROUTINGチェイン(パケットが出ていく直前のタイミング)を対象にします
# eth0 は外向きのパブリック側ネットワークインターフェースだと仮定しています
sudo iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 203.0.113.5
-t nat: 操作するテーブルをnatに指定しています。-A POSTROUTING: パケットがこのルーターから外へ送り出される「最後の瞬間」にルールを適用します。-o eth0: 外の世界へ繋がるネットワークカード(インターフェース)を指定しています。-j SNAT --to-source 203.0.113.5: 「よし、送信元のIPをこのパブリックIPに書き換えろ!」という指示です。
パターンB:動的IPの味方!「MASQUERADE(マスカレード)」
クラウド環境では、インスタンスが再起動したり、DHCPでIPアドレスがコロコロ変わったりすることがよくあります。「あらかじめ固定のIPなんて書けないよ!」というときに救世主となるのが、仮面舞踏会を意味する MASQUERADE です。
これを使うと、Linuxが「今、自分に割り当てられている外向きのIPアドレスは何だっけ?」と自動で確認し、そのIPに書き換えてくれます。
# 外向きインターフェース(eth0など)のIPアドレスが変動する場合に、自動で送信元IPを合わせて書き換えます
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
実務のクラウドインフラ(特にシングル構成のNATインスタンスや動的IPを扱う環境)では、この MASQUERADE が非常に手軽で広く使われています。一歩ずつ理解していけば、どちらも怖くないですよね!
—
4. トラブルシューティングの現場から:動かないときのチェックポイント
「設定したはずなのに、プライベートサブネットから外に出られない……!」
現場でよくあるそんなトラブルに直面したとき、SREはどこを見るのでしょうか? 現場の勘所を少しだけシェアしますね。
1. ルーティングテーブルの確認
- プライベートサブネット側のサーバーのデフォルトゲートウェイ(
0.0.0.0/0)の宛先が、ちゃんとこのカスタムNATインスタンスのプライベートIPに向いていますか?
2. セキュリティグループやファイアウォール(iptablesのfilter設定)
- 転送自体は許可されていても、
FORWARDチェインでパケットがドロップ(破棄)されていないか確認しましょう。 - 困ったときは一時的に
sudo iptables -P FORWARD ACCEPTですべての転送を受け入れる状態にしてテストしてみるのも手です。
3. 設定の保存を忘れていませんか?
iptablesの設定は、何も対策をしないとサーバーを再起動した瞬間に消えてしまいます! Ubuntuならiptables-persistentなどのパッケージを使って、設定を永続化するのを絶対に忘れないようにしましょう。
# 設定を保存する代表的なコマンドの例(Ubuntu系の場合など)
sudo netfilter-persistent save
—
まとめ
今回は、パケットの郵便配達の例えから始めて、Linuxの iptables を用いた SNAT と MASQUERADE の設定方法を紐解いてみました。
最初は難解に見えるコマンドやネットワーク用語も、「パケットの住所を書き換えているんだな」という本質的なイメージさえ掴んでしまえば、インフラの仕組みがぐっと身近で面白いものに感じられるはずです。
皆さんのクラウドライフやコンテナネットワークの構築が、もっとスムーズで楽しいものになりますように。それではまた、次の技術でお会いしましょう!
コメント