2026年7月5日
2026年7月5日
NAPT 越えができない場合の対処|NAPT ルーターの変換表・ポート転送・戻り経路をパケットで切り分ける
NAPT 越えができないときは、パケットが「NAPT ルーターの外側に届いているか」「内側へ転送されているか」「戻りが同じルーターを通っているか」を順にパケットキャプチャで確かめると、原因の場所を絞り込めます。この記事は、自分で管理できる NAPT ルーター(Linux ゲートウェイ、業務用ルーター、家庭用ルーター)を前提に、外から内側のサーバーへ接続できない場合と、内側から外への接続が不安定な場合の両方について、見るべき場所と対処を起こりやすい順に説明します。CGNAT や対称型 NAT など回線側の事情の見分け方は、別の記事で扱っています。
NAPT で接続が止まる仕組み
NAPT(Network Address and Port Translation、機器によっては PAT や IP マスカレードと呼ばれます)は、内側の「プライベート IP:ポート」と外側の「グローバル IP:ポート」の対応を変換表に記録して通信を通します。この表は原則として内側から始まった通信で作られます。
そのため、つまずく場面は大きく次の2つに分かれます。
- 外から始まる接続:変換表に対応が無いので、ルーターは受け取ったパケットをどこへ送ればよいか分からず捨てる。ポート転送(静的な NAPT)の設定が必要
- 内側から始まる接続:表のエントリが消える、表があふれる、ポートが足りなくなるなどで、途中で切れたり新しい接続が作れなくなったりする
どちらの場合も、ルールを眺めるより、実際のパケットがどこまで届いて、どこで消えたかを見るほうが早く解決します。
まずパケットの通り道を確かめる
Linux ゲートウェイなら、外側と内側の両方のインターフェースで同時に tcpdump を動かし、外部から接続を試します。ここでは外側を eth0、内側を eth1、公開したいサーバーを 192.168.10.20:80、外側で受けるポートを 8080 とします。
# 端末1:外側に届いているか
sudo tcpdump -ni eth0 tcp port 8080
# 端末2:内側へ転送されているか
sudo tcpdump -ni eth1 host 192.168.10.20 and tcp port 80
外部からの接続テストは、スマートフォンのモバイル回線など、本当に外側にある端末から行ってください。同じ LAN の中から自分のグローバル IP へ接続すると、後述するヘアピン NAT の問題が混ざって判断を誤ります。
結果は次のように読みます。
- 端末1に何も出ない:パケットがルーターまで来ていない。上流(回線事業者、手前のルーター、クラウドのファイアウォール)を疑う
- 端末1に SYN が出るが端末2に出ない:ルーター内の転送ルールかフィルタで止まっている
- 端末2に SYN が出て SYN-ACK も出るが、端末1に SYN-ACK が出ない:戻りの経路がこのルーターを通っていない
- 端末2に SYN が出るのにサーバーが応答しない:サーバー側のファイアウォールかサービスの待ち受け
家庭用ルーターのように中でキャプチャできない機器では、内側のサーバーで tcpdump を動かし、SYN が届くかどうかだけでも確認すると切り分けが進みます。
原因と対処(起こりやすい順)
1. ポート転送が無い、または宛先が違う
最も多いのは、ポート転送の設定漏れか、転送先の IP アドレスが変わっていることです。サーバーが DHCP でアドレスを受け取っていると、再起動後に別のアドレスになり、転送設定が空振りします。
家庭用ルーターでは「ポート転送」「ポートマッピング」「静的 IP マスカレード」など、機種によって名前が違います。表記にとらわれず、外側のポートと内側の IP・ポートの対応を作る設定を探してください。サーバー側は固定 IP にするか、ルーターの DHCP で同じアドレスを割り当てる設定にします。
Linux ゲートウェイでは、DNAT のルールにパケットが当たっているかをカウンターで確かめます。外部から接続を試した直後に pkts の値が増えていなければ、ルールの条件(インターフェース名、ポート、プロトコル)が実際のパケットと合っていません。
sudo iptables -t nat -L PREROUTING -n -v --line-numbers
# nftables を使っている場合
sudo nft list ruleset
2. 転送は設定したのにフィルタで落ちている
NAT のルールとフィルタのルールは別物です。DNAT で宛先を書き換えても、転送(FORWARD)を許可していなければパケットは捨てられます。また、Linux ではカーネルのパケット転送が無効だと、ルールがあっても内側へ流れません。
# 1 なら転送が有効
sysctl net.ipv4.ip_forward
# FORWARD チェーンの既定ポリシーとカウンター
sudo iptables -L FORWARD -n -v
ufw や firewalld を使っている場合は、それぞれの設定で転送を許可する必要があります。Docker が動いているホストでは Docker が独自に iptables のルールを追加するため、想定外のルールが先に評価されていないかも見てください。
3. 戻りの通信が NAPT ルーターを通らない
内側のサーバーのデフォルトゲートウェイが、ポート転送をしているルーターと違う場合に起こります。行きはルーター A で宛先が書き換えられて届きますが、サーバーは応答を別のルーター B へ送ってしまい、変換を元に戻せないため相手には届きません。ルーターを2台並べた構成や、VPN を張ったサーバーでよく起こります。
サーバーで ip route get 外部のIP を実行し、応答がどのゲートウェイへ出るかを確認します。対処は、デフォルトゲートウェイを転送元のルーターにそろえるか、ルーターで送信元も書き換える(SNAT / MASQUERADE)か、ポリシールーティングで「このポートの応答は A へ返す」ようにするかのいずれかです。送信元を書き換える方法は手軽ですが、サーバーのログに接続元として常にルーターの IP が記録されるようになり、ログイン試行の制限など IP 単位の制御が効かなくなる点に注意してください。
4. 内側から自分のグローバル IP で試している
同じ LAN から自分のグローバル IP やドメイン名で接続すると、ルーターが折り返し(ヘアピン NAT、NAT ループバック)に対応していない限り届きません。外からは接続できているのに「越えられない」と誤解しやすい原因です。外側の端末で確認し直すか、内側では内部 DNS や hosts ファイルでプライベート IP を引くようにします。
5. 二重の NAPT になっている
回線事業者が設置したルーターの内側に自分のルーターをつなぐと、NAPT が2段になります。手前のルーターにもポート転送が必要で、片方だけの設定では外から届きません。自分のルーターの WAN 側アドレスがプライベート IP(192.168.x.x など)なら二重になっています。片方をブリッジモードにするか、両方に転送を設定してください。WAN 側が 100.64.0.0/10 の範囲なら、回線側の CGNAT の可能性が高く、ルーターの設定では解決できません。
6. ALG が通信を書き換えている
SIP(IP 電話)や FTP のように、データの中に IP アドレスやポートを書き込むプロトコルは、NAPT と相性が良くありません。ルーターの ALG(アプリケーション層ゲートウェイ)機能がこれを補おうとして、かえって通話が片方向になる、登録が外れるなどの問題を起こすことがあります。SIP の不具合では、ルーターの SIP ALG を無効にして改善するかを試すのが定番の確認です。FTP はパッシブモードと待ち受けポートの範囲を固定し、その範囲を転送する方法が扱いやすくなります。
7. 変換表のタイムアウト・あふれ・ポート不足
内側から始めた接続が、しばらく無通信の後に切れる場合は、変換表のエントリがタイムアウトで消えています。SSH ならクライアント側の ServerAliveInterval、アプリなら keepalive の間隔をタイムアウトより短くします。
Linux ゲートウェイでは、変換表があふれるとカーネルログに nf_conntrack: table full, dropping packet が出ます。
# 現在の件数と上限
cat /proc/sys/net/netfilter/nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max
# カーネルログを確認
sudo dmesg | grep -i conntrack
上限を上げる前に、大量の短い接続を作っているプロセス(クローラー、監視、外部 API の連打など)が無いかを調べてください。多数のサーバーが1つのグローバル IP を共有して同じ宛先へ大量に接続する構成では、使えるポートが足りなくなることもあります。その場合は接続の再利用(keepalive やコネクションプール)を進めるか、外側のアドレスを増やします。
作業時の注意
リモートからゲートウェイのルールを変えると、自分の接続を切ってしまうことがあります。変更前に sudo iptables-save > ~/iptables-backup.txt や sudo nft list ruleset > ~/nft-backup.txt で現在の状態を保存し、コンソール接続など戻す手段を用意してから作業してください。ポートを外へ開ける場合は、公開する範囲を必要なポートだけに絞り、サーバー側のソフトウェアを最新に保つことも同時に進めます。ルーターの画面や項目名は機種とファームウェアで変わるため、操作の詳細は各機種の説明書で確認してください(2026年10月現在)。
まとめ
- NAPT の変換表は内側からの通信で作られるため、外からの接続にはポート転送が要る
- 外側と内側の両方で
tcpdumpを動かし、どこでパケットが消えるかを先に確かめる - 多い原因は、転送設定の漏れや宛先の変化、FORWARD の不許可、戻り経路の不一致
- LAN 内からの確認はヘアピン NAT の影響を受けるので、外側の端末で試す
- 内側からの接続が切れるときは、タイムアウト、conntrack のあふれ、ポート不足を疑う