Network Working Group
Request for Comments: 1631
Category: Informational
K. Egevang
Cray Communications
P. Francis
NTT
May 1994

The IP Network Address Translator (NAT)

Status of this Memo

このドキュメントは、インターネット社会のための情報を定義している。このメモは、いかなる種類のインターネット標準も規定しない。このメモの配布は制限されない。

Abstract

IP インターネットが直面している最も抵抗しがたい二つの問題は、IP アドレスの枯渇とルーティングの規模である。これらの問題に対して、長期的な解決方法と短期的な解決方法が開発されつつある。短期的な解決方法は CIDR (クラスレスドメイン間ルーティング) である。長期的な解決方法は、より大きなアドレスを持つ新しいインターネットプロトコルの様々な提案から成る。

長期的な解決方法が実施されるまで IP インターネットを維持するために、CIDR が適切でない可能性がある。このメモは、別の短期的な解決方法としてアドレスの再利用を提案しており、それは CIDR を補完するか、あるいは不要にさえするだろう。アトレス再利用の解決方法は、スタブドメインの境界にネットワークアドレス変換器 (NAT: Network Address Translators) を置くことである。各 NAT ボックスは、ローカル IP アドレスとグローバルにユニークなアドレスの組で構成されるテーブルを持つ。スタブドメインの内側の IP アドレスは、グローバルにユニークではない。それらのアドレスは他のドメインで再利用できるので、アドレス枯渇問題の解決になるのである。グローバルにユニークな IP アドレスは、現在の CIDR アドレス割り当てスキームに従って割り当てられる。CIDR は規模の問題を解決する。NAT の主要な利点は、ルータやホストを変更せずに導入できることである。このメモは、NAT の基本的な設計方針を示し、その賛否について論じている。

謝辞

このメモは、1993 年 1 月に Computer Communication Review で出版された、Paul Francis (以前は Tsuchiya) と Tony Eng によるドキュメントに基づいている。Paul は Van Jacobson からアドレス再利用の概念を得た。

Kjeld Borch Egevang は、このメモを作成するためにこのドキュメントを編集し、FTP のためのシーケンス番号の調整を導入した。そのアイデアとテキスト (そのアイデアを持っているのは我々だけだとずっと思っていたが) についてコメントしてくれた Jacob Michael Christensen に感謝したい。

Jacob Michael Christensen

Table of content

1. 導入

2. NAT の概要

3. NAT の様々な面
  3.1 アドレス空間
  3.2 NAT 超えのルーティング
  3.3 ヘッダの扱い

4. 結論

参照
セキュリティの考慮
作者のアドレス


1. 導入

IP インターネットが直面している最も抵抗しがたい二つの問題は、IP アドレスの枯渇とルーティングの規模である。これらの問題に対して、長期的な解決方法と短期的な解決方法が開発されつつある。短期的な解決方法は CIDR (クラスレスドメイン間ルーティング) [2] である。長期的な解決方法は、より大きなアドレスを持つ新しいインターネットプロトコルの様々な提案から成る。

長期的な解決方法が準備されるまで、IP アドレスの需要を抑制するための簡易な方法は、アドレス再利用を用いることである。この解決方法は、ある時間においてドメインの外側と通信しているホストは、そのスタブドメイン中で非常に小さい割合であるという事実を利用している。(スタブドメインとは例えば企業のネットワークのように、ドメイン内のホストから発生したか、あるいはドメイン内のホスト宛てのトラフィックしか扱わないドメインのことである)。実際、多くの (大半ではないが) ホストは、自分達のスタブドメインの外側とは決して通信しない。このため、外部との通信が必要な場合、スタブドメイン内の一部の IP アドレスしか、グローバルにユニークな IP アドレスに変換する必要はない。

この解決方法は、エンドツーエンドの IP アドレスの意味を無くし、ネットワークに状態を増やすことで構成されるという欠点を持つ。この潜在的な落とし穴を減らすために、様々な作業が行われている。実際のところ、コネクション型プロトコルは、本質的には全てのホップでアドレス再利用を行っているのである。

このアプローチの非常に大きな利点は、ホストかルータのいずれかに変更を加えることなく、徐々に導入できることである。(一般的ではないアプリケーションは、変更が必要かもしれない)。例えば、この解決方法は即座に実装して、実験することができる。もし他に何も無いならば、より複雑で広範囲な別の解決方法が考え出されるまで、この解決方法は一時的な救済策になりえるだろう。

2. NAT の概要

このメモに記述されている設計は、ネットワークアドレス変換器として NAT と呼ばれる。NAT は図 1 に示すように構成できるルータの機能である。修正する必要があるのはスタブ境界のルータだけである。

NAT の基本的な処理は次の通りである。スタブドメインの内側のアドレスは、他のスタブドメインによって再利用することができる。例えば、あるクラス A のアドレスを、たくさんのスタブドメインで使用することができる。スタブドメインとバックボーンの間の各々の出口点に NAT を導入する。もし出口点が一つ以上存在するならば、各 NAT が同じ変換テーブルを持つことが非常に重要である。


        \ | /                 .                                /
   +---------------+  WAN     .           +-----------------+/
   |局所ルータ     |----------------------|スタブルータw/NAT|---
   +---------------+          .           +-----------------+\
                              .                      |         \
                              .                      |  LAN
                              .               ---------------
                          スタブ境界

                      図 1: NAT 構成

例えば、図 2 の例ではスタブ A と B は、内部的にクラス A アドレスの 10.0.0.0 を使用している。スタブ A の NAT はクラス C のアドレス 198.76.29.0 を割り当てられ、スタブ B の NAT はクラス C のアドレス 198.76.28.0 を割り当てられる。クラス C のアドレスはグローバルにユニークであり、他の NAT ボックスはそれらを使用できない。

                          \ | /
                        +---------------+
                        |  地域ルータ   |
                        +---------------+
                      WAN |           | WAN
                          |           |
      Stub A .............|....   ....|............ Stub B
                          |           |
        {s=198.76.29.7,^  |           |  v{s=198.76.29.7,
         d=198.76.28.4}^  |           |  v d=198.76.28.4}
          +-----------------+       +-----------------+
          |スタブルータw/NAT|       |スタブルータw/NAT|
          +-----------------+       +-----------------+
                |                         |
                |  LAN               LAN  |
          -------------             -------------
                    |                 |
  {s=10.33.96.5, ^  |                 |  v{s=198.76.29.7,
   d=198.76.28.4}^ +--+             +--+ v d=10.81.13.22}
                   |--|             |--|
                  /____\           /____\
                10.33.96.5       10.81.13.22

                  図 2: 基本的な NAT 運用

スタブ A のホスト 10.33.96.5 がスタブ B のホスト 10.81.13.22 にパケットを送信したい時、宛先としてグローバルにユニークなアドレス 198.76.28.4 を使用して、自側の最初のルータにパケットを送信する。スタブルータはネット 198.76.0.0 のための静的経路を持ち、そのためパケットは WAN 回線に転送される。しかし、NAT はパケットを転送する前に、IP ヘッダの送信元アドレス 10.33.96.5 をグローバルにユニークな 198.76.29.7 に変換する。同様に、返却経路上の IP パケットも似たようなアドレス変換を通過する。

これはホストやルータに対して変更を必要としないことに注意されたい。例えば、スタブ A のホストに関する限り、198.76.28.4 はスタブ B のホストによって使用されるアドレスである。アドレス変換は完全に透過的である。

もちろん、これは単に簡単な例である。研究すべき数多くの問題が存在する。次のセクションで、NAT の様々な面について論じる。

3. NAT の様々な面

3.1 アドレス空間

再使用可能なアドレスと再使用不可能なアドレスの切り分け

NAT を適切に運用するために、IP アドレス空間を二つの部分、スタブドメインの内部で使用される再使用可能なアドレスと、グローバルにユニークなアドレスに切り分ける必要がある。再使用可能なアドレスはローカルアドレスと呼び、グローバルにユニークなアドレスはグローバルアドレスと呼ぶ。アドレスは、ローカルアドレスかグローバルアドレスのいずれかでなければならない。重複はない。

重複の問題は次の通りである。スタブ A のホストがスタブ B のホストにパケットを送信したいが、スタブ B のローカルアドレスがスタブ A のローカルアドレスと重複していたとする。この場合、スタブ A のルータはスタブ B のグローバルアドレスと、A 自身のローカルアドレスを区別できないだろう。

ローカルアドレスとグローバルアドレスの初期割り当て

単一のクラス A アドレスはローカルネットワークに割り当てるべきである。(RFC 1597 [3] を参照されたい)。このアドレスはインターネットに接続せずに、相互接続のために使用できる。NAT は、実験的なアドレスをグローバルにユニークなインターネットアドレスに変換することによって、実験的なネットワークを "本物の" ネットワークに変更するための容易な方法を提供する。

内部的にユニークなアドレスを割り当てているが、それらが不足して運用されている既存のスタブは、アドレスをサブネット毎にローカルアドレスに変更できる。解放されたアドレスは、外部との通信で NAT によって使用することができる。

3.2 NAT 超えのルーティング

NAT を動かしているルータは、ローカルなネットワークをバックボーンに流すべきではない。スタブの外側では、グローバルアドレスを持つネットワークしか知らないかもしれない。しかし、NAT がスタブ境界のルータから受信したグローバルな情報は、スタブの中に通常の方法で流してもよい。

バックボーンに広がるプライベートネットワーク

多くの場合プライベートネットワーク (例えば企業ネットワーク) は、異なる所在地に渡って広がり、それらの所在地間で通信するために公のバックボーンを使うだろう。この場合、アドレス変換を行うことは望ましいことではない。なぜなら、非常に多くのホストがバックボーンを渡って通信したいかもしれず、そのために大きなアドレステーブルが必要になるからである。また、ネームサーバに行くのとは違って、設定されたアドレスに依存するアプリケーションが多く存在するからである。このようなプライベートネットワークは、バックボーンで分割されたスタブと呼ばれる。

バックボーンで分割されたスタブは、あたかも分割されていないスタブであるかのように動作すべきである。すなわち、あらゆるパーティション内のルータは、全てのパーティションのローカルアドレス空間への経路を保持すべきである。もちろん、(公の) バックボーンは如何なるローカルアドレスへの経路も保持しない。従って、境界のルータはカプセル化を使用して、バックボーンを通すトンネルを作らなければならない。これを行うために、各々の NAT ボックスは、トンネル化のためにグローバルアドレスを一つ取っておく。スタブパーティション X の中にある NAT ボックス x が、スタブパーティション Y にパケットを配送したい時、NAT ボックス x は、カプセル化のために予約されている NAT ボックス y のグローバルアドレスを宛先アドレスとして設定し、IP ヘッダの中でそのパケットをカプセル化する。NAT ボックス y がその宛先アドレスを持つパケットを受信した時、IP ヘッダのカプセルを外して、そのパケットを内部に振り分ける。

3.3 ヘッダの扱い

IP アドレスを修正するのに加えて、NAT は IP チェックサムと TCP チェックサムを修正しなければならない。TCP のチェックサムは、送信元と宛先アドレスを含む疑似ヘッダもカバーすることを思い出してほしい。NAT は ICMP と FTP も見つけ出して、IP アドレスが現れる個所を修正しなければならない。修正を施さなければならない箇所は他にもあるはずである。うまくいけば、そうしたアプリケーションの大半は NAT との実験期間中に検出されるだろう。

IP と TCP のチェックサムの修正は簡単で効率がよい。両方とも 1 の補数の和を使用しているので、変換前と変換後のアドレス間の算数的な相違を算出し、これをチェックサムに加算するだけで十分である。唯一のトリッキーな部分は、その加算によってチェックサムが (正か負のいずれかの方向に) 巻き戻るか否かを決定することである。もし戻るならば、1 の補数演算を満足させるために、1 を加算あるいは減算しなければならない。このためのサンプルコード (C 言語) は以下の通り。

void checksumadjust(unsigned char *chksum, unsigned char *optr,
int olen, unsigned char *nptr, int nlen)

/* 想定: unsigned char は 8 ビット、long は 32 ビット
  - chksum はパケット中のチェックサムを指す。
  - optr はパケット中の古いデータを指す。
  - nptr はパケット中の新しいデータを指す。
*/

{
  long x, old, new;
  x=chksum[0]*256+chksum[1];
  x=~x;
  while (olen) {
    if (olen==1) {
      old=optr[0]*256+optr[1];
      x-=old & 0xff00;
      if (x<=0) { x--; x&=0xffff; }
      break;
    }
    else {
      old=optr[0]*256+optr[1]; optr+=2;
      x-=old & 0xffff;
      if (x<=0) { x--; x&=0xffff; }
      olen-=2;
    }
  }
  while (nlen) {
    if (nlen==1) {
      new=nptr[0]*256+nptr[1];
      x+=new & 0xff00;
      if (x & 0x10000) { x++; x&=0xffff; }
      break;
    }
    else {
      new=nptr[0]*256+nptr[1]; nptr+=2;
      x+=new & 0xffff;
      if (x & 0x10000) { x++; x&=0xffff; }
      nlen-=2;
    }
  }
  x=~x;
  chksum[0]=x/256; chksum[1]=x & 0xff;
}

ファイル転送プロトコル (FTP) の PORT コマンドへのアーギュメントは、(ASCII で) IP アドレスを含んでいる。もし PORT コマンド中の IP アドレスがスタブドメインにローカルならば、NAT はこれを置き換えなければならない。そのアドレスは ASCII で符号化されているので、これによりパケットのサイズが変わるかもしれない (例えば 10.18.177.42 は ASCII で 12 文字であるが、193.45.228.137 は ASCII で 14 文字である)。もし新たなサイズが前と同じならば、(再び) 調整する必要があるものは TCP チェックサムだけである。もし新たなサイズが前よりも小さいならば、ASCII の 0 を挿入してもよいが、これが動作する保証は無い。もし新たなサイズが前よりも大きいならば、TCP のシーケンス番号も変更しなければならない。

FTP の送信元ポートか FTP の宛先ポートで、TCP のシーケンス番号と肯定応答番号を修正するために特別なテーブルが使用される。テーブルのエントリは、送信元、宛先、送信元ポート、宛先ポート、初期シーケンス番号、シーケンス番号のためのデルタ、タイムスタンプを持つべきである。新しいエントリは、FTP ポートコマンドを検出した場合にのみ生成される。初期シーケンス番号は、パケットのシーケンス番号が最後の FTP PORT コマンドの前か後かを知るために使用される (デルタを 全ての FTP コマンドに加算してもよい)。シーケンス番号は加算され、肯定応答番号は減算される。もしパケットの 1 つに FIN ビットが設定されていたら、それに割当てられているエントリを間もなく削除してもよい (1 分位が安全なはずである)。例えば 24 時間使用されていないエントリもまた、削除しても安全なはずである。

シーケンス番号の調整は注意深くコーディングしなければならず、一般に TCP のパフォーマンスを損なってはならない。もちろん、もし FTP セションが暗号化されていたら、PORT コマンドは失敗するだろう。

もし ICMP メッセージが NAT を通して渡されたら、二つのアドレスの修正と三つのチェックサムの修正が必要かもしれない。これは、大半の ICMP メッセージが元の IP パケットの一部を本体の中に含むかもしれないからである。従って、NAT が完全にホストに透過的であるためには、ICMP パケットのデータ部に埋め込まれた IP ヘッダの IP アドレスを修正しなければならず、同じ IP ヘッダのチェックサムフィールドもそれに応じて修正し、ICMP ヘッダのチェックサムも ICMP 本体中の IP ヘッダとチェックサムの変更を反映して修正しなければならない。さらに、通常の IP ヘッダも既に説明してあるように修正しなければならない。

ICMP 部分の本体中の IP ヘッダ情報を修正する必要があるか否かは、完全には明確でない。これは、全てのホストのコードがこの IP ヘッダ情報をチェックしているか否かによる。実のところ、ICMP メッセージを発行したルータかホストに見える正確なヘッダを提供する方が、デバッグの補助としては有効かもしれない。如何なるイベントにおいても、エコーとタイムスタンプメッセージは修正する必要はない。また、NAT はリダイレクトメッセージを扱う必要はないはずである。

SNMP メッセージは修正してもよいが、その必要性は ICMP メッセージよりもずっと疑わしい。

IP アドレスのコンテントを持つアプリケーション

アプリケーションの中で IP アドレスを運ぶ (使用する) アプリケーションは、もし NAT がそうしたインスタンスのことを知り、適切な変換を行わなければ、NAT を通しては動作しないだろう。NAT がそうしたアプリケーションを全て知ることはできないし、必ずしも望ましいとは限らない。もし暗号化が使用されていたら、NAT が変換することは不可能である。

もし、それらのアプリケーションが動いているホストにグローバルアドレスが割当てられていれば、上記のようなシステムが NAT を使用しないことは可能である。これが可能か否かは、内部ドメインルーティングアルゴリズムと内部トポロジの能力に依存する。この理由は、グローバルアドレスは、内部ドメインルーティングアルゴリズムで通知しなければならないからである。RIP のように低機能なルーティングアルゴリズムでは、ホストが自分のクラス C のアドレス空間を必要とするかもしれず、内部に通知するだけでなく外部にも通知しなければならない (従って、グローバルな規模で害になる)。OSPF のように高機能なルーティングアルゴリズムでは、ホストアドレスを個々に渡して、NAT テーブルから取り込むことができる。

プライバシ、セキュリティ、デバッグの考慮

不幸にも、NAT はセキュリティを提供するためのオプションの数を減らす。NAT を使った場合、IP アドレスや IP アドレスに派生する情報 (例えば TCP ヘッダのチェックサム) を運ぶものは暗号化することができない。大半のアプリケーションレベルの暗号は OK なはずだが、これは TCP ヘッダの暗号化を妨げる。

一方、NAT 自身はある種のプライバシメカニズムを提供するものとして見ることができる。これは、どのホストがトラフィックを送受信しているかについて、バックボーン上にあるマシンが監視できないという事実からくる (もちろん、アプリケーションデータは暗号化されていると仮定して)。

プライバシを高めるという同じ特徴は、潜在的にデバッグの問題 (セキュリティ違反を含め) をより難しくしている。あるホストが何らかの方法でインターネットを悪用していても (別のマシンを攻撃したり、大量のジャンクメールか何かを送信する等)、トラブルの元を突き止めることはより難しい。なぜなら、ホストの IP アドレスが隠れるからである。

4. 結論

NAT は、アドレス枯渇と規模の問題に対する適切な短期的解決方法かもしれない。なぜなら、NAT はほとんど変更を必要とせず徐々に導入できるからである。NAT は、長期的な解決方法としては不適切な、あるいは短期的な解決方法としても不適切となりえる否定的な特徴を幾つか持っている。その適切さを判断するには、実装し、実験するしかないだろう。

否定的な特徴は以下の通り。

  1. NAT は、エンドツーエンドのトラフィックマトリクスを小さくする必要がある。さもなくば、NAT テーブルが大きくなり、パフォーマンスの低下を招くだろう。エンドツーエンドのトラフィックマトリクスは実際に小さくなると予想しているが、小さいか否かは、NAT を用いた経験をかさねることによって決まることである。少なくとも、将来のアプリケーションが大きなトラフィックマトリクスを必要とする可能性はある (例えば分散リソース検出)。従って、NAT を長期的に使用することは魅力的ではない。

  2. アドレス誤りの可能性を増やす。

  3. あるアプリケーションを壊す (さもなくば、少なくともより動かしにくくする)。

  4. ホストの身元を隠す。これはプライバシにとっては利点だが、概して否定的な影響をもたらす。

  5. SNMP や DNS 等に問題がある。

現在の実装

Paul と Tony は公共ドメイン KA9Q TCP/IP ソフトウェア [1] に、実験的な NAT のプロトタイプを実装した。この実装体はアドレスと IP チェックサムを扱っている。

Kjeld は、Cray Communications IP ルータに NAT を実装した。この実装体は Telnet と FTP で検証された。この実装体はアドレス、IP チェックサム、TCP シーケンス/肯定応答番号、FTP PORT コマンドを扱っている。

そのプロトタイプは、このドキュメントで説明されている制限の範囲で、IP アドレスをホストに透過的に変換できることを実証した。

参照

[1] Karn, P., "KA9Q", anonymous FTP from ucsd.edu (hamradio/packet/ka9q/docs).

[2] Fuller, V., Li, T., and J. Yu, "Classless Inter-Domain Routing (CIDR) an Address Assignment and Aggregation Strategy", RFC 1519, BARRNet, cisco, Merit, OARnet, September 1993.

[3] Rekhter, Y., Moskowitz, B., Karrenberg, D., and G. de Groot, "Address Allocation for Private Internets", RFC 1597, T.J. Watson Research Center, IBM Corp., Chrysler Corp., RIPE NCC, March 1994.

セキュリティの考慮

セキュリティの問題は、このメモでは議論されない。

作者のアドレス

Kjeld Borch Egevang
Cray Communications
Smedeholm 12-14
DK-2730 Herlev
Denmark

Phone: +45 44 53 01 00
EMail: kbe@craycom.dk

Paul Francis
NTT Software Lab
3-9-11 Midori-cho Musashino-shi
Tokyo 180 Japan

Phone: +81-422-59-3843
Fax +81-422-59-3765
EMail: francis@cactus.ntt.jp