PFを使用したアドレス変換の例

仕事で必要になりそうなんで、予備実験の後ちょびっと書いてみた備忘録

要件

  • 異なるネットワークに属するホストA、ホストB間で通信したい。
  • 通信は両方のネットワークに接続されたゲートウェイで中継する。
  • ホストA、ホストBのルーティング設定などをいじりたくないため;
    • Host Aは同一ネットワーク内に属するゲートウェイのL側(下図参照)と通信しているように見せかけたい。
    • 同様に、Host BからはゲートウェイのR側と通信しているように見せかけ、実際にはHost Aと通信するようにしたい。
  • 使用プロトコルはHTTP及びFTPを想定。
    • Host A及びBではproxyの存在などを意識せず、透過的に通信できるようにしたい。
  • プロトコルとして、アクティブモードのFTPを使用することが予想される。
    • そのため、Host A, Host BのどちらからでもTCPのセッションを開始できるようにする必要がある。

システム構成

下図のとおり

   addr_A                    addr_B
+------+        +-------+        +------+
|Host A|------->|GateWay|------->|Host B|
|      |<-------|       |<-------|      |
+------+        +-------+        +------+
             if_L    if_R
           addr_L  addr_R

           ネットワーク構成図

(表記)

  • Host A, Host BのIPアドレスをそれぞれ、addr_A, addr_Bとする
  • GatewayのHost A側のネットワークインターフェース名をif_L、そのIPアドレスをaddr_L。 同様に、Host B側のネットワークインターフェース名をif_R、そのIPアドレスをaddr_Rとする。

ソリューション

  • A->B方向の変換
    • 始点 addr_A, 終点 addr_L のパケットを if_L にて Host Bに向けなおす。/etc/pf.confの記述行は以下のようになる;
      rdr pass on if_L from addr_A to addr_L -> addr_B
      passは、フィルタリングルールをバイパスするための指定
    • rdrによって向け直されたパケットは始点アドレスがaddr_Aのままなので、 Host Bからの復路のパケットの終点アドレスがaddr_Aとなり、このままでは戻りパケットがHost Aに到達しない。
      よって往路のパケットがif_Rを通過する時に、始点アドレスを書き換える。
      binat pass on if_R from addr_A to addr_B -> if_R
      binatを使用するのは、アドレス変換に伴いポートが変ってしまわないための意味もある。
  • B->A方向の変換
    • B->A方向にもセッションを張れるようにするためには、 A->Bで挙げた例と対称な記述を付け加える。
      rdr pass on if_R from addr_B to addr_R -> addr_A
      binat pass on if_L from addr_B to addr_A -> if_L

実行結果

  • HTTPに関しては、問題なく実行できた
  • FTPは、ログインまでは可能であったが、ディレクトリの一覧やファイルの送受信は不能。
    • FTPではデータコネクションを張るときにPORTコマンドを相手に送るが、このパラメータに生のIPアドレスが含まれているため、それに対して直接接続を張ろうとする。このため、うまく行かない
      → FTPに関してだけは ftp-proxy(8)を使用する必要がある。

感想とか

  • PFでは、フィルタリングルールはlast matchだが、nat ruleはfirst matchらしい
  • FTPマンドクセ

Reload  New Edit Freeze Diff Attach Copy Rename  Top Index Search Recent Backups  Help  RSS
Last-modified: 2006-03-11 (Sat) 08:24:58 (4544d)