転載・引用について

ユーザ用ツール

サイト用ツール


tweet:2014:0812_01

NetBSD and pf

あとで整理して書き直す。

# 溜まってきているのが辛い。

NetBSD pfでさんざんハマったので、メモ書き。

NATとPacket Filter

NetBSD 6系に載っているpfの挙動で少しハマったので、メモ。

  • pfの処理順序
    1. Packet incoming
    2. rdr処理
    3. nat処理
    4. packet filter処理
    5. Packet outgoing

つまり、Packet filterは「NAT処理された後」に適用される。Packet filter rule書く時に大ハマりするポイントなので注意。 (なお、当然、Packet filterを書けるI/Fも注意が必要)

---------------| pf |---------------|server|
         ext_if      int_if

この構成の時に、以下の1 NATルール、4パケットフィルタールールを使って実験

rdr pass on $if_ext proto { tcp,udp } from any    to $ext_if -> $server
block drop quick on $if_ext proto {tcp,udp} from any to $ext_if		# Rule 1
block drop quick on $if_int proto {tcp,udp} from any to $ext_if		# Rule 2
block drop quick on $if_ext proto {tcp,udp} from any to $server		# Rule 3
block drop quick on $if_int proto {tcp,udp} from any to $server		# Rule 4

それぞれのFilterルールをコメントアウトしたりしながら調べると、Rule 4のみが反映される。

  • パケットが入ってくる$ext_ifではFilteroutできない。
  • NAT前のアドレスではFilteroutできない。

Hair-Pin NAT

----------| pf |----------+----------|server-A|
    ext_if      int_if    |
                          +----------|server-B|

rdr pass on $if_ext proto { tcp,udp } from any    to $ext_if -> $server
<code>

この構成において、Server-Bからpfの$ext_ifのアドレス(いわゆるGlobal Address)に対してQueryを投げるとうまく動作しない。
これは、Server-Bからpfのext_ifにパケットを投げると、pfはint_ifから受け取ったパケットなので、NAT処理をしないから。

この状況は、いわゆるLoad Balancer構成を組んでいて、Multi tenantのサービスをしている時に困る場合がある。

このような時に、Server-B → int_if → Server-A に通信が出来れば良いと考えて、以下のruleを突っ込む
<code>
rdr pass on $if_int proto { tcp,udp } from $serverB to $ext_if -> $serverA

これで一見動きそうに見えるが、実はそうは問屋が卸さない。

何が起こるかを表にすると、こんな感じ。

node Src Addr Dest Addr 備考
ServerB ServerB if_ext
pf ServerB if_ext → ServerA に変換 NAT処理
ServerA ServerB ServerA
ServerAで内部処理
ServerA ServerA ServerB
pf ServerA/Bは同一セグメントなので、pfにパケットがこない
ServerB ServerA ServerB

これでは、TCPでもUDPでも「正しく」通信出来ているとは云えない。通常は、このようなパケットは破棄され、通信出来ない。

本来は、こうなって欲しい

node Src Addr Dest Addr 備考
ServerB ServerB if_ext
pf ServerB → if_int if_ext → ServerA に変換 NAT処理
ServerA if_int ServerA
ServerAで内部処理
ServerA ServerA if_int
pf ServerA → if_ext if_int → ServerB NAT処理
ServerB if_ext ServerB

というわけで、突っ込むべきRuleはこうなる

rdr pass on $if_int proto { tcp,udp } from $serverB to $ext_if -> $serverA
nat      on $if_int proto { tcp,udp } from $serverB to $serverA -> $if_int

全ポートを処理すれば良いのなら、binatでいいのだが、port 53だけ、このような処理をしたい場合には、nat(Src-NAT)とrdr(Dest-NAT)を組み合わせて二重変換を行わなければならない。

ちょいと特殊な設定なので、まぁ、普通は必要ないよね。

このウェブサイトはクッキーを使用しています。 Webサイトを使用することで、あなたはあなたのコンピュータにクッキーを保存することに同意します。 また、あなたはあなたが私たちのプライバシーポリシーを読んで理解したことを認めます。 同意しない場合はウェブサイトを離れてください。クッキーに関する詳細情報
tweet/2014/0812_01.txt · 最終更新: 2014/08/12 01:00 by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki