[OpenBSD]

[前に戻る: パケットフィルタリング] [目次] [次に進む: トラフィックリダイレクション (ポートフォワーディング)]

PF: ネットワークアドレス変換 (NAT)


目次


はじめに

ネットワークアドレス変換 (NAT) は (複数の) ネットワーク全体を、単一の IP アドレスにマップするための方法です。インターネットサービスプロバイダ (ISP) から割り当てられた IP アドレスが、インターネットアクセスのために用意しようと 考えているコンピュータの総数より少ない場合には、NAT は必須となります。NAT は RFC 1631 に記述があります。

NAT によって、 RFC 1918 に記述されている予約済プライベートアドレスのメリットを亨受できるようになります。 典型的に、内部ネットワークは、これらのネットワークブロックをひとつ以上使用して 構築されていることでしょう。これらのネットワークブロックは以下のようなものです。

	10.0.0.0/8       (10.0.0.0 - 10.255.255.255)
	172.16.0.0/12    (172.16.0.0 - 172.31.255.255)
	192.168.0.0/16   (192.168.0.0 - 192.168.255.255)

NAT を実行する OpenBSD システムは、片方がインターネット、他方が内部ネットワーク に接続された、少なくとも 2 枚のネットワークアダプタを持っていることと思います。 NAT は、内部ネットワークからの要求を、それらがすべて OpenBSD 上の NAT システム から来る要求であるように見せかけるように変換します。

NAT はどのように動くか

内部ネットワーク上のクライアントがインターネット上のマシンに接続しようとする場合、 そのマシンの IP アドレスを送信先とするパケットを、クライアントは送出します。 これらのパケットは、目的地の必要なアドレスの情報をすべて含んでいます。 NAT はこれらの情報の一部と関連づけられます。

パケットが NAT ゲートウェイを通過する際、パケットは、NAT ゲートウェイ自身から来ているかのように見えるような修正が加えられます。 NAT ゲートウェイは、a) 戻りのパケットの変更を元に戻すし、b) 確実に戻りの パケットがファイアウォールを通過し、ブロックされないようにするために、 自身の加えた変更を状態テーブルに記録します。たとえば、NAT ゲートウェイでは、 以下の例のような変更が加えられているかも知れません。

内部マシンでもインターネット上のホストの場合でもない場合には、これらの変換ステップに 注意が必要です。内部マシンに対しては、NAT ゲートウェイは単にインターネットゲートウェイに 見えます。また、インターネット上のホストに対しては、パケットは NAT システムから直接来る ように見えるので、内部のワークステーションが存在しているかどうかについては、まったく気に する必要がありません。

インターネット上のホストが内部マシンのパケットに対して応答する場合、 NAT ゲートウェイの外部 IP アドレス (24.5.0.5) の変換ポート (53136) 宛に向けて送信されます。このとき、NAT ゲートウェイは、 戻りのパケットが既に確立された接続にマッチするかどうかを決定するために、 状態テーブルを探索します。たとえば、192.168.1.35 の IP アドレスを持つ 内部マシンから開始した接続に属するパケットの IP/ポートの組み合わせがユニークにマッチすれば、 PF は送出パケットに対して行われたものと正反対の変更を戻りのパケットに加え、 そのパケットを内部マシンに対して転送します。

ICMP パケットの変換も、送信元ポートの修正が行われないことを除いて、 同様の流儀で行われます。

NAT とパケットフィルタリング

注: 変換されたパケットは、なおもフィルタエンジンに わたされる必要があり、定義されているフィルタルールに基づいてブロックされるのか 通過するのかの処理が行われます。 このルールの唯一の例外は、pass キーワードが nat ルール中に指定されている場合です。 これによって、フィルタリングエンジンに NAT 済のパケットを 正しく通過させることができます。

また、変換はフィルタリングのに行われるということ、および NAT はどのように動作するのかで述べられている概要のように、フィルタリングエンジンは変換された IP アドレスとポートを持つ変換済のパケットを見ることになるということに注意する必要があります。

IP フォワーディング

NAT は、ほぼ確実にルータやネットワークゲートウェイ上で使用されるものですので、 おそらく、パケットが OpenBSD マシン上のネットワークインターフェイス間で 行き来できるようにするため、IP フォワーディングを有効化する必要があります。 IP フォワーディングは、 sysctl(3) のメカニズムを使用して、以下のように有効化します。

# sysctl -w net.inet.ip.forwarding=1
# sysctl -w net.inet6.ip6.forwarding=1 (if using IPv6)

この変更を恒久的に有効化するには、以下のような行を /etc/sysctl.conf ファイルに加えてください。

net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1

これらの行は既に存在しているはずですが、デフォルトのインストール状態では (行頭に # がついていて) コメントアウトされているはずです。# を削除し、 ファイルを保存して、マシンのリブートすると、IP フォワーディングが有効化されるはずです。

NAT の設定

pf.conf ファイル中の NAT ルールの一般的なフォーマットは、 たとえば以下のようなものです。
nat [pass] on interface [af] from src_addr [port src_port] to \
   dst_addr [port dst_port] -> ext_addr [pool_type] [static-port]
nat
NAT ルールを開始するためのキーワード
pass
変換済パケットに、完全にフィルタリングルールをバイパスさせます。
interface
パケットを変換するネットワークインターフェイスの名前を指定します。
af
アドレスファミリであり、IPv4 用の inet か IPv6 用の inet6 のいずれかを指定します。PF は通常は、送信元/送信先の アドレスに基づいて、このパラメータを決定することができます。
src_addr
変換されるべきパケットの送信元 (内部) アドレスです。 送信元アドレスは以下のように指定することができます。
src_port
レイヤ 4 のパケットヘッダ中の送信元ポートです。 以下のポートを指定することができます。 port オプションは、通常は nat ルールでは使用されませんが、 これは、その目標が通常は、使用されるポートとは無関係に、すべてのトラフィックに NAT を行うことだからです。
dst_addr
パケットの送信先アドレスも変換対象となるものです。 送信先アドレスの指定方法は、送信元アドレスの場合と同様です。
dst_port
レイヤ 4 のパケットヘッダの送信先ポートです。 送信先ポートの指定方法は、送信元ポートの場合と同様です。
ext_addr
NAT ゲートウェイ上の外部 (変換) アドレスで、このアドレスにパケットの アドレスが変換されます。外部アドレスは以下のように指定することができます。
pool_type
変換に使用するためのアドレスプールの型を 指定します。
static-port
TCP または UDP パケットの送信元ポートを変換しないよう、PF に指示します。

以下は、NAT の最も基本的な形となる例です。

nat on tl0 from 192.168.1.0/24 to any -> 24.5.0.5

このルールは、tl0 インターフェイス上の NAT は、 192.168.1.0/24 からのすべての着信パケットの送信元アドレスの 24.5.0.5 の置換を実行するものであることを表しています。

上記のルールは正しいものではありますが、推奨できる形ではありません。 外部か内部ネットワークのアドレスが変更された場合に、この行を編集する 必要があるので、保守が大変になります。この行の保守を簡単にするための、 以下の例と比較してみてください (ここで、tl0 は外部インターフェイス、 dc0 は内部インターフェイスです)。

nat on tl0 from dc0/24 to any -> tl0

この優位性は明らかで、このルールを変更することなく、どちらのインターフェイスの IP アドレスも変更することができます。

上記の例のようなアドレス変換を行うためのインターフェイス名を指定する場合、IP アドレスは pf.conf のロード時に決定されるのであり、動作中に必要に応じて 決定されるわけではありません。これは、外部インターフェイスの設定に DHCP を使用している 場合などに、このことが問題になる可能性があります。つまり、割り当てられた IP アドレスが 変更された後も、NAT は送出パケットを古い IP アドレスで変換し続けてしまうからです。 これは、外向けの接続が、その機能を停止してしまう原因となります。 これが正しく動くようにするには、PF が自動的に変換アドレスを更新するよう、 以下の例のようにインターフェイス名を括弧で囲むと良いでしょう。

nat on tl0 from dc0/24 to any -> (tl0)

これを行うには、ひとつ大きな制限があります。それは、インターフェイス名が括弧で囲まれている場合には、 そのインターフェイス上の最初の IP のエイリアスだけが評価の対象となるということです。

双方向マッピング (1:1 マッピング)

binat ルールを使用すると、双方向のマッピングを確立することができます。 binat ルールは、内部 IP アドレスと外部アドレスとの間で 1 対 1 のマッピングを確立します。 これは便利で、たとえば、内部ネットワーク上の Web サーバを、 外部 IP アドレスで公開することも可能になります。 インターネットから外部アドレスへの接続は、内部アドレスに変換され、 Web サーバからの (DNS のリクエストのような) 接続は 外部アドレスに変換されます。 TCP および UDP のポートは、binat ルールの場合も nat ルールの場合と同様、決して変更されることはありません。

例:

web_serv_int = "192.168.1.100"
web_serv_ext = "24.5.0.6"

binat on tl0 from $web_serv_int to any -> $web_serv_ext

変換ルールの例外

no キーワードを使用すると、変換ルールの中に 例外を設けることができます。たとえば、上記の NAT の例を 以下のように修正してみましょう。
no nat on tl0 from 192.168.1.10 to any
nat on tl0 from 192.168.1.0/24 to any -> 24.2.74.79

このようにすると、192.168.1.10 を除く、192.168.1.0/24 のネットワーク全体で、 パケットは外部アドレスの 24.2.74.79 に変換されるようになります。

この場合、最初にマッチしたルールが「勝者」となることに注意してください。もし、それが no ルールであると、パケットは変換されません。この no キーワードは、 binat および rdr でもに使用されます。

NAT の状態のチェック

アクティブな NAT の変換状況を見るためには、以下のように pfctl(8)-s state オプションで使用します。 このオプションは、現在のすべての NAT セッションをリストします。
   # pfctl -s state
   TCP 192.168.1.35:2132 -> 24.5.0.5:53136 -> 65.42.33.245:22 TIME_WAIT:TIME_WAIT
   UDP 192.168.1.35:2491 -> 24.5.0.5:60527 -> 24.2.68.33:53   MULTIPLE:SINGLE

説明 (最初の行のみ):

TCP
接続に使用されているプロトコル
192.168.1.35:2132
内部ネットワーク上のマシンの IP アドレス (192.168.1.35)。 発信元ポート (2132) はアドレスの後に表示されています。 これは、IP ヘッダ中の置換されるアドレスでもあります。
24.5.0.5:53136
パケットの変換後となるゲートウェイ上の IP アドレス (24.5.0.5) とポート (53136) です。
65.42.33.245:22
内部のマシンが接続しようとしている IP アドレス (65.42.33.245) とポート (22) です。
TIME_WAIT:TIME_WAIT
これは、どの状態の TCP 接続を PF が信用すべきかを指示するものです。

[前に戻る: パケットフィルタリング] [目次] [次に進む: トラフィックリダイレクション (ポートフォワーディング)]


[back] www@openbsd.org
Originally [OpenBSD: nat.html,v 1.13 ]
$Translation: nat.html,v 1.12 2004/01/03 05:24:39 toshi Exp $
$OpenBSD: nat.html,v 1.12 2004/01/04 22:47:55 horacio Exp $