10月 222021
 

以前のエントリで、FreeBSD の VRF (setfib) は正しく使えない。と、書いたことがありました。エントリ的には「FreeBSD でポリシールーティング。」と、いうヤツですね。

setfib 0 の中に setfib 1 のルーティング情報が載ってしまい、ルーティングテーブルがインターフェースと結びついていない。と、いうのが問題点だ。と、書いています。

しかし、設定の詳しい人に聞いてみるとちゃんとそーいう設定ができるらしいんですね。ちょっと、今更感満載なんですけども・・f(^^;;。
/etc/rc.conf に以下のように書くと良いみたいです。

#defaultrouter="192.168.22.1"
#ipv6_defaultrouter="2001:470:fe36:beef::1"

static_routes="0:vmx0 1:em0"
route_0="-net -inet default -gateway 192.168.22.1 -fib 0"
route_1="-net -inet default -gateway 192.168.1.1  -fib 1"

ipv6_static_routes="0:vmx0 1:em0"
ipv6_route_0="-net -inet6 default -gateway 2001:470:fe36:beef::1  -fib 0"
ipv6_route_1="-net -inet6 default -gateway 3ffe:6580:aa40::ffff:1 -fib 1"

ifconfig_vmx0="inet 192.168.22.20 netmask 255.255.255.0 fib 0"
ifconfig_em0="inet 192.168.1.20   netmask 255.255.255.0 fib 1"

ifconfig_vmx0_ipv6="inet6 2001:470:fe36:beef::20:1 prefixlen 64"
ifconfig_em0_ipv6="inet6 3ffe:6580:aa40::20:1      prefixlen 64"

 
defaultrouter の設定は必要ありません。
static_routes= と、 setfib が IPv6 対応になったので ipv6_static_routes= の二つのオプションがインターフェース名と setfib 番号を紐つけてくれます。そして、route_?= で default gateway を指定してあげれば良い。

この設定で起動したときのネットワークテーブルは以下の通り。

$ setfib 0 netstat -nr -f inet
Routing tables (fib: 0)
Destination        Gateway            Flags     Netif Expire
default            192.168.22.1       UGS         vmx0
127.0.0.1          link#1             UH          lo0
192.168.22.0/24    link#2             U           vmx0
192.168.22.20      link#3             UHS         lo0

$ setfib 1 netstat -nr -f inet
Routing tables (fib: 1)
Destination        Gateway            Flags     Netif Expire
default            192.168.1.1        UGS         em0
127.0.0.1          link#1             UH          lo0
192.168.1.0/24     link#2             U           em0
192.168.1.20       link#3             UHS         lo0

 
良い感じですねぇ。これで 192.168.1.30 辺りの PC から ping を打つと em0 から入ってきて、em0 から抜けていきます。良かったですねぇ。

 
しかし、問題なのは上記の設定を施したサーバ側です。

なんか、僕は思いっきり勘違いしていたか安直に考えすぎていました。 setfib した PC はなんでもかんでも setfib 0 側から出て行ってしまいます。これは想定していなかった・・。

em0 側に 192.168.1.0/24 が付いているのに、とある PC に対して ping 192.168.1.30 すると setfib 0 側、つまり、vmx0 側から出ていきます。
192.168.1.30 側では 192.168.22.20 に返すんだけど、返ってきていないことになっていて、到達性がない状態・・。orz

setfib を利用した VRF でルーティングテーブルが二つに分かれるのは良いんだけど、コネクテッドな IP アドレスに対するアクセスは setfib 0 のルーティングテーブルに関係なく、コネクテッドなインターフェースからパケットが出て行ってほしかった・・。

と、いうか、出ていくモノだと、思っていた。ここが、考えが甘かった点です・・。orz
うーむ・・。世間一般の VRF って、こーいう仕様なのか?

sysctl でコネクテッドな IP アドレスの場合はコネクテッドなインターフェースからパケットが出ていく。と、いうオプションはないものかのぉ・・。orz

 
この仕様のおかげで色々なものが動作しない・・。今悩んでいるのは MRTG。
ウェブ UI は setfib 0 を向いているんだけど、MRTG で情報を取得したいのは em0 なコネクテッドな IP アドレスを持つ宛先。 em0 側はそもそも LAN-ZONE でメンテナンスインターフェースという想定だしねぇ・・。

setfib 1 snmpwalk -v2c -c ICMPv6 192.168.1.30 system

 
これは動くんだけど、 MRTG.cfg に 192.168.1.30 にアクセスする設定を書いた mrtg を動作させようとしても動かない・・。

setfib 1 /usr/local/bin/mrtg /pathto/MRTG.cfg

 
mrtg は setfib 1 を無視して setfib 0 側から出ていくようです。まぁ、perl の内部構造に対して setfib 1 を食わせてあげないとどうしようもない状態かな。

似たようなのに httpd と MySQL の関係もありますな。 httpd は vmx0 側に開いているのは良いことで、別のサーバのコネクテッドな IP アドレスを持つ mysqld へのアクセスは em0 側で行いたい。だけど setfib 0 側から mysqld へのアクセスが出ていくのでこれはアクセスできんぞぉ・・

ansible も動かなくなった・・。AWX と ansible-playbook の関係も似たようなもん。もう、ヒサンすぎる・・。 orz

NFS マウントも /etc/fstab 内ではできなくて、 /etc/rc.clocal 内で setfib 1 mount_nfs -o tcp -o rw hoge と記載すると良いよ。なんてのが、どこかのフォーラムに書かれていたなぁ。 /etc/fstab が setfib に対応していない。

 
と、いうことでやっぱり FreeBSD の VRF は利用するのをやめる予感。

今のように出ていくパケット (established なパケット。と、いう意味かな) は何でもかんでも setfib 0 から出ていく。と、いうのとは別に、コネクテッドな IP アドレスの場合はコネクテッドなインターフェースからパケットが出ていく。と、いうオプションを用意してくれても良いと思うのだけどなぁ・・。

やっぱり pf のポリシールーティングに戻るかねぇ・・。

 
と、いうか、最後に書くんだけど、ネットワーク構成がまちがっている。と、いうことかな。

  • setfib 0 : em0 : サービス提供用ネットワーク
  • setfib 0 : em1 : バックヤード用ネットワーク
  • setfib 1 : em2 : ssh でのメンテナンス専用ネットワーク

 
FreeBSD で setfib な VRF を利用するにはこのように三つのネットワークが必要で「バックヤード用ネットワーク」は MRTG とか snmp、MySQL へのアクセス、と、いう感じでその目的をにして、「ssh でのメンテナンス専用ネットワーク」はリモート管理用に setfib をわけてあげる。と、いう感じですかねぇ。