home FreeBSD Bike Misc Memorandum About

IPFilter

カーネルの再構築を行う

 最近のFreeBSDではModuleによってカーネルの機能は動的に追加できるので、カーネルの再構築は必ずしも必要というわけではありません。ただし、IPFilterを利用する場合現在の所カーネルの再構築が不可欠になっています。PFIL_HOOKS というオプションが必ず必要となっています。

すべてカーネルに組み込む場合

options NETGRAPH        # NETGRAPHが必要
options IPFILTER
options IPFILTER_LOG      # LOG取り可能とする
options IPFILTER_DEFAULT_BLOCK # デフォルト(ルールに一致しない
                # パケット)は拒否
options TCP_DROP_SYNFIN    # SYN+FIN FLAGのTCPパケットを
                # 落す
options PFIL_HOOKS

モジュールを動的に組み込む場合

カーネルコンフィグファイル(/sys/i386/conf/内)

options TCP_DROP_SYNFIN
options PFIL_HOOKS

/boot/loader.conf 内

ipl_load="YES"
netgraph_load="YES"

 ちなみに、後者のモジュールを動的に組み込む場合 IPFILTER_LOG は設定されていますが、IPFILTER_DEFAULT_ACCEPT になってしまい、ルールに一致しないパケットは通過してしまいます。これを避けるためにカーネルをコンパイルする前に /sys/modules/ipfilter/Makefile を書き換えます。
-DIPFILTER_DEFAULT_BLOCK を CFLAGS に追加します。

/sys/modules/ipfilter/Makefile 内

CFLAGS+ = -I${.CURDIR}/../../contrib/ipfilter
CFLAGS+ = -DIPFILTER=1 -DIPFILTER_LKM -DIPFILTER_LOG -DIPFILTER_DEFAULT_BLOCK
#
# If you don't want log functionality remove -DIPFILTER_LOG
#

 上の赤字の部分を加えるとモジュール内で IPFILTER_DEFAULT_BLOCK が有効になります。これはcvsupを行うと元に戻ってしまうので、その都度書き換えないといけません。

/etc/rc.conf の書き換え

ipfilter_enable="YES"
ipfilter_rules="/etc/ipf.rules"    # IPv4 のためのルール
ipv6_ipfilter_rules="/etc/ipf6.rules" # IPv6 のためのルール
ipmon_enable="YES"          # ログを取るためにipmonを起動
ipmon_flags="-D /var/log/ipf.log"   # ログは/var/log/ipf.log
tcp_drop_synfin="YES"         # DROP SYN+FIN Packet

 もちろんNATを利用したいなら他にも設定が必要ですし、そもそもルータにしていることが必要です(gateway_enable="YES"など)。必要なら FreeBSDをルータにする を参照してください。

ルールの作成

 すべてのパケットを通過させる設定は以下になります。とりあえず動作テストに使います。ipf.rules ipf6.rules に記述します。

pass in all
pass out all

 これでは意味がないので、ルールを記述します。私は以下の設定を ipf.rules に記述しています。ipf6.rules もそれに準じた内容です。ちなみに IPFW ではファーストマッチですが、IPFilter ではラストマッチなので最後にマッチしたルールがパケットに対して設定されます。ルールは基本的に外側NICに入るパケット・外側NICから出て行くパケット・内側NICに入るパケット・内側NICから出て行くパケットの4種類をグループ分けして設定します。想定しているネットワーク

# IPF+NAT 用のルールファイル(静的ルール)
# (group を指定していないルールはグループ 0)
#
# IP オプションが指定されたもの、断片化されたもの、
# 短いパケットなどはここで破棄
block in log quick from any to any with ipopts frag
block in log quick proto tcp from any to any with short

############################################
# 外部(Internet)からの入力(グループ 100)
pass in on tun0 all head 100

# アドレス偽装防止
block in from 127.0.0.0/8 to any group 100
block in from 192.168.1.1/24 to any group 100

# プライベートアドレスやマルチキャストなどの破棄
block in from 10.0.0.0/8 to any group 100
block in from 172.16.0.0/12 to any group 100
block in from 192.168.0.0/16 to any group 100
block in from 0.0.0.0/8 to any group 100
block in from 169.254.0.0/16 to any group 100
block in from 192.0.2.0/24 to any group 100
block in from 224.0.0.0/4 to any group 100
block in from 240.0.0.0/4 to any group 100

# NetBIOS (port 137-139)
block in quick from any port 136 >< 140 to any group 100
block in quick from any to any port 136 >< 140 group 100

# UDP パケットをデフォルトで拒否
block in proto udp all group 100

# 接続された TCP パケットを許可
pass in quick proto tcp all flags A/A group 100

# FTP サーバ 接続開始を許可
pass in quick proto tcp from any to any port 19 >< 22 flags S/SA group 100

# 外部からの SSH 接続開始を許可
pass in quick proto tcp from any to any port = 22 flags S/SA group 100

# 外部からの SMTP 接続開始を許可
pass in quick proto tcp from any to any port = 25 flags S/SA group 100

# IDENT には答えない
block return-rst in quick proto tcp from any to any port = 113 group 100

# DNS サーバ 接続開始を許可
pass in quick proto tcp from any to any port = 53 flags S/SA group 100
pass in quick proto udp from any to any port = 53 group 100

# WWW サーバ 接続開始を許可
pass in quick proto tcp from any to any port = 80 flags S/SA group 100

# IMAP サーバ 接続開始を許可
pass in quick proto tcp from any to any port = 143 flags S/SA group 100

# DHIS to nantoka.com
pass in quick proto udp from any to any port = 58800 group 100

# それ以外の外部からの TCP 接続を拒否し、ログに残す
block in log quick proto tcp all flags S/SA group 100

# 外部の DNS に問い合わせた帰りのパケット
pass in proto udp from any port = 53 to any group 100

# NTP の帰り
pass in proto udp from any port = 123 to any group 100

# ICMP を許可
pass in proto icmp all group 100

# RFC2979
pass in proto icmp all icmp-type 3 group 100

############################################
# 外部への出力(グループ 200)
pass out on tun0 all head 200

# アドレス偽造防止
block out from 127.0.0.0/8 to any group 200
block out from any to 127.0.0.0/8 group 200

# プライベートアドレスやマルチキャストなどの破棄
block out from any to 10.0.0.0/8 group 200
block out from any to 172.16.0.0/12 group 200
block out from any to 192.168.0.0/16 group 200
block out from any to 0.0.0.0/8 group 200
block out from any to 169.254.0.0/16 group 200
block out from any to 192.0.2.0/24 group 200
block out from any to 224.0.0.0/4 group 200
block out from any to 240.0.0.0/4 group 200

# NetBIOS (port 137-139)
block out from any port 136 >< 140 to any group 200
block out from any to any port 136 >< 140 group 200

# 接続された TCP パケットを許可
pass out proto tcp all flags A/A group 200

# 外部の DNS サーバへの問い合わせを許可
pass out from any to any port = 53 group 200

# 外部への接続開始を許可
pass out proto tcp all flags S/SA group 200

# 外部の NTP サーバへの問い合わせを許可
pass out proto udp from any to any port = 123 group 200

# ICMP を許可
pass out proto icmp all group 200

############################################
# 内部から来るパケット(グループ 300)
pass in on rl1 all head 300
block in from 127.0.0.0/8 to any group 300

############################################
# 内部へ出ていくパケット(グループ 400)

pass out on rl1 all head 400
block out from 127.0.0.0/8 to any group 400
block out from any to 127.0.0.0/8 group 400

############################################
# ループバックへのルール(グループ 0)
pass in quick on lo0 all
pass out quick on lo0 all

Firewallのルールはネットワークの仕組みに応じて十人十色です。あくまで参考としてごらんください。

IPFの起動

マシンを再起動してもいいですが、5-RELEASEらしい起動の方法としては

# /etc/rc.d/ipfilter start

です。

参考URL: IP Filter

説明

FreeBSDに標準で装備されているFirewallの仕組みとしてはIPFWとIPFilterがあります。IPFWについては FreeBSDをルータにする を参照してください。

FreeBSD 5.1-RELEASE

Creative Commons License
This work is licensed under a Creative Commons License.