DNAT(宛先NAT)とは?iptables・nftablesでの設定例、トラブルシューティングと実務での注意点
DNAT(Destination NAT)とは何か
DNAT(Destination Network Address Translation、宛先アドレス変換)は、パケットの「宛先アドレス(および必要に応じて宛先ポート)」を書き換える NAT の一種です。外部からルーターやゲートウェイの公開アドレスへ届いたパケットの宛先を、内部ネットワーク上のプライベートIPアドレス(およびポート)に変換して転送する用途で主に使われます。一般に「ポートフォワーディング」「リバースプロキシ(L4)」と呼ばれる操作は DNAT に相当します。
基本動作とパケット処理の流れ
典型的な Linux の実装(netfilter/iptables, nftables)では、DNAT は NAT テーブルの PREROUTING チェーンまたは OUTPUT(ローカル発)チェーンで行われます。処理の流れは以下の通りです。
- 外部クライアントからパケットが到着
- カーネルは PREROUTING(ルーティング判断前)で DNAT ルールを評価し、宛先アドレス/ポートを書き換える
- ルーティング決定に基づき、書き換え後の内部ホストへパケットを転送
- 返送パケットは逆方向で NAT テーブルの POSTROUTING または conntrack の情報を参照して元の送信元へ戻される(逆変換される)
重要なのは、NAT は接続ごとの「状態(state)」を持つ点です。最初のパケットで変換し、その後は conntrack(接続追跡)テーブルを参照してパケットを処理します。
典型的な利用例
- 家庭/SOHOルーターのポートフォワーディング(外部:80 → 内部サーバ:80)
- DMZ や複数サービスを単一パブリックIPで公開するときのポートマッピング
- コンテナ・仮想化環境(Docker の -p オプション、Kubernetes kube-proxy の iptables モード)のサービス公開
- ロードバランサ(L4)でのバックエンドノードへの転送(実装によっては DNAT を用いる)
iptables での具体例(IPv4)
代表的なコマンド例(外部パブリック 203.0.113.10 の TCP 80 を内部 192.168.1.10:80 に転送):
iptables -t nat -A PREROUTING -d 203.0.113.10 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:80
多くの場合、内部ホストから外向けの応答が NAT デバイス経由になるように POSTROUTING で SNAT または MASQUERADE を設定します:
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
nftables での DNAT の例
nftables だとテーブルとチェーンを作り、PREROUTING にルールを追加します:
nft add table ip nat
nft 'add chain ip nat prerouting { type nat hook prerouting priority 0 ; }'
nft add rule ip nat prerouting ip daddr 203.0.113.10 tcp dport 80 dnat to 192.168.1.10:80
DNAT と他の NAT タイプの違い
- SNAT(Source NAT):送信元アドレスを書き換える。通常は内部クライアントの送信元をグローバルIPに置き換えてインターネットに出すために使う。
- DNAT:宛先を書き換えて受信トラフィックを適切な内部サーバへ誘導する。
- PAT(Port Address Translation):1つのグローバルIP上でポートごとに複数の内部アドレス/ポートへ対応させる、広義ではDNAT/PATの一形態。
実装上の注意点と落とし穴
- 非対称ルーティング:内部サーバの返信が別のゲートウェイ経由で戻ると、NAT デバイスで逆変換されず接続が壊れる。対策として内部サーバのデフォルトゲートウェイを NAT デバイスに向けるか、内部サーバ側でソースを SNAT(POSTROUTING)して応答が NAT デバイス経由になるようにする。
- hairpin NAT(NAT ループバック):内部クライアントが公開アドレスでサービスへ接続する場合、ルーター側で DNAT と同時に POSTROUTING の SNAT を行わないと内部クライアントへの返りが不正になる。正しい設定が必要。
- パフォーマンス:NAT は接続ごとの状態を保持するため高スループット・多数コネクションでは CPU/メモリ負荷が問題になる。ハードウェアオフロードや専用ロードバランサの検討が必要。
- IPv6 では一般的に NAT を使わない設計が推奨される(グローバルアドレスを割り当てる)。IPv6⇄IPv4 の変換が必要な場合は NAT64(RFC6146 等)や DNS64(RFC6147)など専用技術を使う。
セキュリティ上の考慮
DNAT によって内部ホストは外部から直接到達可能になるため、以下に注意してください。
- 公開するポートは最小限に限定し、必要なアクセス元 IP を制限する(ファイアウォールでフィルタリング)。
- 可能なら TLS 終端、WAF、認証をリバースプロキシ側で行い内部サービスを保護する。
- ログ・モニタリングを有効にし、不正アクセスや異常接続を検知できるようにする。
- 脆弱な内部ホストを直接公開しない。公開は最新のセキュリティパッチ適用済みかつ最小権限で。
クラウドやコンテナ環境での DNAT の使われ方
コンテナ技術(Docker)は、ホストのポートをコンテナへ割り当てる際に内部で DNAT を作成します。Kubernetes の kube-proxy(iptables モード)も Service へのアクセスを Pod のバックエンドに転送するために iptables の NAT ルール(DNAT 相当)を生成します。
クラウドのロードバランサ(L4)や NAT ゲートウェイも内部で DNAT/SNAT 相当の処理を行い、公開IPとプライベートIPのマッピングを実現します。実装細部はプロバイダにより異なるため、運用時はプロバイダのドキュメントを確認してください。
トラブルシューティングの基本コマンド
- iptables の NAT ルール確認: iptables -t nat -L -n -v
- nftables の設定確認: nft list ruleset
- conntrack テーブル確認(接続追跡): conntrack -L または sudo cat /proc/net/nf_conntrack
- パケットキャプチャ: tcpdump -i <インタフェース> host
and port <ポート> - 接続状況確認: ss -tnp / netstat -tnp
まとめ(実務での指針)
DNAT はサービス公開やロードバランシングの基本的な仕組みであり、適切に設定すれば内部サービスを柔軟に公開できます。しかし非対称ルーティング、hairpin、パフォーマンス、セキュリティといった注意点があり、単純にルールを追加するだけでは問題が発生しがちです。設計段階でネットワーク経路(返り経路)、接続数の見積、監視・ログ設計、必要なフィルタリングを検討することが重要です。
参考文献
- RFC 2663 - IP Network Address Translator (NAT) Terminology and Considerations
- RFC 3022 - Traditional IP Network Address Translator (Traditional NAT)
- netfilter(iptables / conntrack 開発元)
- iptables man page(man7.org)
- nftables 公式ドキュメント / Wiki
- Kubernetes: Service(公式ドキュメント)
- Docker: Container networking(公式ドキュメント)
- RFC 6146 - Stateful NAT64
- RFC 6147 - DNS64


