NAPT(IPマスカレイド)環境において、内部ネットワークから外部ネットワークに対してpingをしたときの処理の流れを教えてください。
NAPTは、
「ポート番号を用いて、外部ネットワークからの戻りパケットを内部ネットワークのどの端末に返せばよいかを判別している」
と理解しています。
このような場合、ポート番号を利用しないping(ICMP)はどのように処理を行っているのでしょうか?
調べてみたところ、
> ただし、ポート番号の変換が行なわれるため、インターネット側から内部のマシンに接続を開始するような使い方はできず、ICMPも利用できないなどの制限がある。
> 最近のブロードバンドルータなどではこうした制限を緩和するための独自の実装を行なっているものもある。
http://e-words.jp/w/NAPT.html
私の自宅では、PLANEXのブロードバンドルータを使っていて、外部ネットワークにpingができたような気がします。
なので、上記の「独自の実装」の内容を教えてください。
どうぞ、よろしくお願いいたします。
RFC3022(Traditional IP Network Address Translator (Traditional NAT))によりますと、ICMPのqueryについては、ペイロードにある識別子をTCPやUDPのポート番号のように扱うことで、NAPTを実現することが想定されているようです。
RFC792で示されているquery/responseタイプのICMPメッセージは、エコー(ping)、タイムスタンプ、情報リクエストの三種類ありますが、そのいずれもフォーマットの中に識別子を持っており、それを利用することになっているようです。
ただし、RFC792では識別子は"may be zero"なんて書いてありますので、TCPやUDPのように確実に変換できる保証はないです。
ICMPをサポートしているNAPTルータであっても"多分できる"程度と考えておくのがよいと思います。
また、ICMPついでですが、ICMP未到達メッセージなどは、そのペイロードにエラーの発生原因であるパケットを内包しています。そのパケットのIPヘッダについてもNAPTテーブルに基づいて変換しなければならないとあります。
ICMPもインターネットの基本プロトコルとして、NAPTでも一通りのことは考えているようです。
RFC3022
http://www.rfc-editor.org/rfc/rfc3022.txt
http://www5d.biglobe.ne.jp/~stssk/rfc/rfc3022j.html
RFC792
PLANEXのルーターがどのような実装になっているかは知りませんが、CISCOの例では、
ICMP header の identify field を見ています。
機械翻訳のようで訳がだいぶ怪しいですが。
2009/10/2記入:
ありがとうございます。
確かに、微妙な日本語ですね……。
とりあえず、YAMAHA RTX1100があったので、NAPTを構築し、
LAN内のクライアント(A,B)とインターネット内のサーバの双方でWireSharkを使ってみてみました。
クライアントA:
Identificationフィールド 0x0200
Checksumフィールド 0xb25b
サーバ(クライアントAからのパケット):
Identificationフィールド 0xea73
Checksumフィールド 0xd3e7
クライアントB:
Identificationフィールド 0x0200
Checksumフィールド 0x2be6
サーバ(クライアントBからのパケット):
Identificationフィールド 0xea75
Checksumフィールド 0x346e
確かに、Identificationフィールドで制御してそうなカンジですね。
で、ヘッダ情報を書き換えてるせいで、Checksumフィールドもルータ側で書き換えているみたいですね。
もう少し、ご紹介いただいた文書を読んでみます。
2009/10/5追記:
いろいろ混乱していたのですが、ようやく整理できてきました。
まず、IPヘッダ内のIdentify fieldと、ICMPヘッダ内のIdentify fieldが別物としてあるのですね。
で、
・IPヘッダ内のIdentify fieldは、中継ルータがパケット分割をした際の再構築用
・ICMPヘッダ内のIdentify fieldは、NAPT機が送受信を判断する(トランスポート層のポート番号と同じように使う)ため
なのですね。
(今、読み返してみると、そう書いてありますね……)
RFC3022(Traditional IP Network Address Translator (Traditional NAT))によりますと、ICMPのqueryについては、ペイロードにある識別子をTCPやUDPのポート番号のように扱うことで、NAPTを実現することが想定されているようです。
RFC792で示されているquery/responseタイプのICMPメッセージは、エコー(ping)、タイムスタンプ、情報リクエストの三種類ありますが、そのいずれもフォーマットの中に識別子を持っており、それを利用することになっているようです。
ただし、RFC792では識別子は"may be zero"なんて書いてありますので、TCPやUDPのように確実に変換できる保証はないです。
ICMPをサポートしているNAPTルータであっても"多分できる"程度と考えておくのがよいと思います。
また、ICMPついでですが、ICMP未到達メッセージなどは、そのペイロードにエラーの発生原因であるパケットを内包しています。そのパケットのIPヘッダについてもNAPTテーブルに基づいて変換しなければならないとあります。
ICMPもインターネットの基本プロトコルとして、NAPTでも一通りのことは考えているようです。
RFC3022
http://www.rfc-editor.org/rfc/rfc3022.txt
http://www5d.biglobe.ne.jp/~stssk/rfc/rfc3022j.html
RFC792
コメントにて補足までありがとうございます。
ご紹介いただいたRFC3022の二番目のURLの中にも
> NAPT翻訳はIPアドレスとトランスポート識別子(TCP/UDPポートやICMP問合せ識別子)を含むように拡張されます。
とあるので、RFCの中でICMPの識別子フィールドを使うように決められているようですね。
RFC792でも、確かに「may be zero.」とありますね。
ただ、その前に、
If code = 0, an identifier to aid in matching echos and replies,
(コード = 0 の場合、リクエストとリプライとを対応させる手助けとなる識別子である。)
ともあるので、このフィールドを使ってアドレス変換を行うのは理想的な気もします。
ただ、ICMPでidentify fieldがあるのが、リクエストとリプライだけですね。
ということは、コメントでJULY様が書かれていますが、他のメッセージをやり取りする場合には、
別途、何らかの方法が必要になってくる(ここが独自実装の部分?)のですかね。
コメントにて補足までありがとうございます。
ご紹介いただいたRFC3022の二番目のURLの中にも
> NAPT翻訳はIPアドレスとトランスポート識別子(TCP/UDPポートやICMP問合せ識別子)を含むように拡張されます。
とあるので、RFCの中でICMPの識別子フィールドを使うように決められているようですね。
RFC792でも、確かに「may be zero.」とありますね。
ただ、その前に、
If code = 0, an identifier to aid in matching echos and replies,
(コード = 0 の場合、リクエストとリプライとを対応させる手助けとなる識別子である。)
ともあるので、このフィールドを使ってアドレス変換を行うのは理想的な気もします。
ただ、ICMPでidentify fieldがあるのが、リクエストとリプライだけですね。
ということは、コメントでJULY様が書かれていますが、他のメッセージをやり取りする場合には、
別途、何らかの方法が必要になってくる(ここが独自実装の部分?)のですかね。