pf reply-to

pfのreply-toの必要性、やっと分かった。NetBSDのpfの話。

マルチホームしたい。こんな感じ。

network topology

NetBSD Boxに PPPoE が2口ある。defualt route は ISP-1 のほう。

Host A の default route は NetBSD Router で、 デフォルトではISP-1からパケットが出ていく。その状態で、 たとえば以下のようなISP切り替えをしたい。

  1. Host A からインターネットに出ていく25番ポートだけは ISP-2 に行かせたい。
  2. ISP-1から来た HTTP(80/tcp)アクセスも、 ISP-2 側に来たHTTPアクセスも Host Aにリダイレクトするが、 ISP-1 から来たものはISP-1へ、ISP-2から来たものはISP-2へ返す。

のようにしたいとする。

この場合、NetBSD RouterではPFで以下のように記述する。

  1. 基本となるNATの設定
    isp1_if=pppoe0
    isp2_if=pppoe1
    lan_if=lan0
    nat on $isp1_if from any to !192.168.0.0/24 -> ($isp1_if)
    nat on $isp2_if from any to !192.168.0.0/24 -> ($isp2_if)
    
  2. 25番ポートはISP-2へ
    pass in quick on $lan_if route-to ($isp2_if 0.0.0.0) from any to \
    !($lan_if) port 25
    
  3. ISP-1、ISP-2 それぞれからの80番を Host A へ
    hosta=192.168.0.10
    rdr proto tcp from any to ($isp1_if) port 80 -> $hosta
    rdr proto tcp from any to ($isp2_if) port 80 -> $hosta
    

    ただし、これだけではrdrでマッチしたものの帰りパケットが stateルールによってpfを通らず、常に普通のルーティング規則に従い ISP-1 側に出て行く。 そこで reply-to の出番である。

  4. ISP-2から入って来たものの帰り道をpfに導く
    pass in quick on $isp2_if reply-to ($isp_if 0.0.0.0) from any to $hosta
    

そうかそうか、そういうことね。route-to は中から行くときの artificial routeでおおむね nat とセットで使い、 reply-to は外から入って来たときのartificial routeで rdr とセットで使うのか。納得。今までは reply-to 使ってなくて、 入口と出口が違うままうまくTCP通信できてて問題に気付かなかった。

ちなみに、reply-to や route-to は、(IF IP.ADD.RE.SS) の形式で指定するので、IPアドレス部分には PPPoE の先のものを指定するのだが、普通接続先のアドレスなんか繋いでみないと分からん。 てときは、0.0.0.0 でいいようだ。