pf でルーティング

FreeBSD で pf を使ってルータを作るメモ。
 
目的:
ネットワークインターフェイスが二つあり、それぞれのインターフェイスに外部ネットワーク、内部ネットワークとして割り当てるとする。
内部→外部の通信は IP マスカレード(NAPT)で透過的に通信できるようにし、外部→内部の通信は特定のポートのみ NAT でサーバにマッピングする。
 
適用例:
A. FreeBSD をルータとして動作させる。
B. (応用) jail を仮想プライベートネットワークに入れ、外への通信を制御する。
 


設定方法(A):
…外部ネットワークインターフェイスを fxp0, 内部ネットワークインターフェイスを fxp1 としてルータとして設定する場合
/etc/rc.conf:

defaultrouter=”192.168.1.1″ # 外部のデフォルトゲートウェイ
 
# 外部インターフェイス
ifconfig_fxp0=”inet 192.168.1.2 192.168.1.255 netmask 255.255.255.0″
# 内部インターフェイス
ifconfig_fxp1=”inet 10.0.0.1 10.0.0.255 netmask 255.255.255.0″
 
# pf を有効化
pf_enable=YES
pf_rules=”/etc/pf.conf”
pf_flags=””
pflog_enable=”YES”
pflog_logfile=”/var/log/pflog”
pflog_flags=””

/etc/pf.conf:

# 外部ネットワークインターフェイス
ext_if=”fxp0″
# 内部ネットワークインターフェイス
int_if=”fxp1″
####
 
table <private> const { 10.0.0/24 }
 
# IP マスカレード
nat on $ext_if inet from ($int_if) to ! <private> -> ($ext_if)
 
# NAT 設定。外からの http(80), https(443) は内部の 10.0.0.5 に、smtp(25) は内部の 10.0.0.6 に割り当て
rdr pass on $ext_if proto tcp from any to ($ext_if) port {80, 443} -> 10.0.0.5
rdr pass on $ext_if proto tcp from any to ($ext_if) port 25 -> 10.0.0.6
 
# パケットフィルタ: 説明を簡単にするため全許可に。
pass in quick all
pass out quick all

 


設定方法(B):
…外部ネットワークインターフェイスを fxp0, 内部ネットワークインターフェイスを lo1 (ループバック) として jail を内部ネットワークインターフェイスで管理する場合。
/etc/rc.conf:

defaultrouter=”192.168.1.1″ # 外部のデフォルトゲートウェイ
 
# 外部インターフェイス
ifconfig_fxp0=”inet 192.168.1.2 192.168.1.255 netmask 255.255.255.0″
# 内部インターフェイス
ifconfig_lo1=”inet 10.0.0.1 10.0.0.255 netmask 255.255.255.0″
ifconfig_lo1_alias=”inet 10.0.0.2″
ifconfig_lo1_alias=”inet 10.0.0.3″
ifconfig_lo1_alias=”inet 10.0.0.4″
ifconfig_lo1_alias=”inet 10.0.0.5″
ifconfig_lo1_alias=”inet 10.0.0.6″
# : 以下略
 
# pf を有効化
pf_enable=YES
pf_rules=”/etc/pf.conf”
pf_flags=””
pflog_enable=”YES”
pflog_logfile=”/var/log/pflog”
pflog_flags=””
 
####
### Jail の設定 ###
jail_enable=”YES”
jail_list=”j1 j2 j3″ # 立ち上げる jail の名前のリスト
jail_set_hostname_allow=”NO”
jail_sysvipc_allow=”YES”
## jail_list で設定した jail インスタンスそれぞれについて設定 ##
# j1:
jail_j1_rootdir=”/var/jail/j1″
jail_j1_hostname=”jail_1″
jail_j1_ip=”10.0.0.2″
jail_j1_exec_start=”/bin/sh /etc/rc”
jail_j1_exec_stop=”/bin/sh /bin/rc.shutdown”
jail_j1_devfs_enable=”YES”
jail_j1_fdescfs_enable=”NO”
jail_j1_procfs_enable=”YES”
jail_j1_mount_enable=”NO”
# j2, j3 も同様に。

/etc/pf.conf:

# 外部ネットワークインターフェイス
ext_if=”fxp0″
# 内部ネットワークインターフェイス
int_if=”lo1″
####
# 以下 設定方法 A とまったく同じ
table <private> const { 10.0.0/24 }
 
# IP マスカレード
nat on $ext_if inet from ($int_if) to ! <private> -> ($ext_if)
 
# NAT 設定。外からの http(80), https(443) は内部の 10.0.0.5 に、smtp(25) は内部の 10.0.0.6 に割り当て
rdr pass on $ext_if proto tcp from any to ($ext_if) port {80, 443} -> 10.0.0.5
rdr pass on $ext_if proto tcp from any to ($ext_if) port 25 -> 10.0.0.6
 
# パケットフィルタ: 説明を簡単にするため全許可に。
pass in quick all
pass out quick all

 


参考:
FreeBSDでPacketFilter(pf)を使う