[ Top > FreeBSD > Packet Filterでブロードバンドルーター ]

Packet Filterでブロードバンドルーター

2006年9月24日

FreeBSD 6.0でルーターを製作した.NIC 2枚差したPCを用いる.PPPoEで外部と接続し,ファイアウォールにはPacket Filterを用いた.FreeBSDではファイアウォールにipfwを使用するのが主流のようであるが,今回はPFを用いた.

ネットワークの全体図

ハードウェアの準備

PCはIntel(互換)マシン.ネットワークカードを2枚装着しておく.

PPPoEの設定

カーネルの再構築

以前のカーネルでは以下のようなオプションを指定して再構築を行ったが,現在のカーネルでは必要ない

options NETGRAPH
options NETGRAPH_ETHER
options NETGRAPH_PPPOE
options NETGRAPH_SOCKET

設定ファイル /etc/ppp/ppp.conf の編集

rootのままで,ファイル /etc/ppp/ppp.conf を編集する.
なお,以下のファイルで,

とする.

default:
 set log Phase Chat LCP IPCP CCP tun command
 set device PPPoE:rl1
 set speed sync
 set mru 1454
 set mtu 1454
 set ctsrts off
 set timeout 0
 accept CHAP
 add default HISADDR
# enable dns
so-net:
 set authname xxxx@yyy.so-net.ne.jp
 set authkey password

外部への接続テスト

接続テストをしてみる.

# ppp -ddial so-net
Working in ddial mode
Using interface: tun0

ifconfig コマンドで,tun0にアドレスが割り当てられていれば成功.

# ifconfig
(略)
tun0: flags=8051 mtu 1454
inet XXX.XXX.XXX.XXX --> YYY.YYY.YYY.YYY netmask 0xffffffff
(上のようにアドレスが表示されればOK)
(略)

自動接続の設定

起動時に自動接続するために,/etc/rc.conf に以下の内容を追加する.

ppp_enable="YES"
ppp_mode="ddial"
ppp_profile="so-net"
ppp_nat="NO"

最後の行は,ppp内蔵のNAT機能を無効にするため(あとでPacket Filterを使ってアドレス変換を実現するのでこの機能は使わない).

Packet Filterの設定

Pakcet Filterを有効にする

/etc/rc.conf に以下を付け加える.

pf_enable="YES"
pf_rules="/etc/pf.conf"
pflog_enable="YES"

ファイアウォールの設定

/etc/pf.conf を編集する.以下はあくまで設定の一例であり,セキュリティ向上のためこれ以外にも行なっておいたほうがよいものもある.

# Macros: define common values, so they can be referenced and changed easily.
# Macroとは変数のようなものである.よく使用するもの(あるいは今後変化する
# 可能性のあるもの)を設定しておく.

internal_net="192.168.10.0/24"  # LANのアドレス.
ext_if="tun0"    # 外向きのインターフェース.ここではtun0になる.
int_if="rl0"     # 内向きのインターフェース.

# Tables: similar to macros, but more flexible for many addresses.
# Tableとは複数のアドレスを記したもの.ここではプライベートアドレスを列挙.

table <privates> { 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }

# Options: tune the behavior of pf, default values are given.
# 各種オプション.タイムアウト関係が多い.

set timeout { interval 10, frag 30 }
set timeout { tcp.first 120, tcp.opening 30, tcp.established 86400 }
set timeout { tcp.closing 900, tcp.finwait 45, tcp.closed 90 }
set timeout { udp.first 60, udp.single 30, udp.multiple 60 }
set timeout { icmp.first 20, icmp.error 10 }
set timeout { other.first 60, other.single 30, other.multiple 60 }
set timeout { adaptive.start 0, adaptive.end 0 }
set limit { states 10000, frags 5000 }
set loginterface tun0         # ログを取る対象のIF.ここは設定しておく.
set optimization normal
set block-policy drop         # パケットを通さない(block)とき,
                              # RST(切断)を返さずそのまま捨てる
#set require-order yes
#set fingerprints "/etc/pf.os"

# Normalization: reassemble fragments and resolve or reduce traffic ambiguities.
# 通信の正規化.指定しておいたほうが良いらしい.

scrub in all

# Queueing: rule-based bandwidth control.
# 帯域の調整.ここでは行なわない.

# Translation: specify how addresses are to be mapped or redirected.
# アドレス変換.ここではNATの指定を行なう.ポートフォワーディングがあれば
# このセクションで行なう.

nat on $ext_if from $internal_net to any -> ($ext_if)

# Filtering: the implicit first two rules are
# パケットフィルタリング.

# 基本ルールはすべてブロック.
block log all

# ルーターマシンのループバックを許可.
pass in quick on lo0 all
pass out quick on lo0 all

# ルーターとLAN内部との通信はすべて許可.
pass in quick on $int_if all
pass out quick on $int_if all

# 外部からプライベートアドレスを名乗って来るパケットは通さない.
block in quick on $ext_if from <privates> to any

# 外部からプライベートアドレス宛にやって来るパケットは通さない.
block in quick on $ext_if from  any to <privates>

# Windows関係のパケットが外部に出て行かないようにする.
block out quick on $ext_if proto {tcp udp} from any to any port 135
block out quick on $ext_if proto {tcp udp} from any to any port 137:139
block out quick on $ext_if proto {tcp udp} from any to any port 445

# 内部どうしのパケットが外部に出て行かないようにする.
block out quick on $ext_if proto {tcp udp} from any to 

# ルーターから外に出るパケットはすべて許可.
pass out quick on $ext_if proto tcp all modulate state
pass out quick on $ext_if proto udp all keep state
pass out quick on $ext_if inet proto icmp all keep state

# 外部からのssh,http,ntpを許可する.
#(ルーターでこれらのサービスを行なっている場合)
pass in on $ext_if proto tcp from any to $ext_if port 22 flags S/SA modulate state
pass in on $ext_if proto tcp from any to $ext_if port 80 flags S/SA modulate state
pass in on $ext_if proto udp from any to $ext_if port 123 keep state

Packet Filterのコントロール

/etc/pf.conf を変更したときは,以下のコマンドで新しいルールが有効になる.

# pfctl -f /etc/pf.conf

現在のルールを表示させるには以下のコマンドを使用する.

# pfctl -s rules

ログは /var/log/pflog として作られるが,テキストファイル形式ではないので,以下のコマンドで見る.

# tcpdump -n -e -ttt -r /var/log/pflog

ログをリアルタイムで監視するには,以下のようにする.なおpflog0はデバイスである.

# tcpdump -n -e -ttt -i pflog0

付記

/etc/rc.conf に上述したような指定(pf_enable="YES"など)をすればマシン起動時にPacket Filterが有効になるはずであるが,私の場合 Syntax error が出てダメだった.マシン再起動後に

# pfctl -f /etc/pf.conf

を入力する必要があった.原因は不明で,現在も解決していない.


[ Top > FreeBSD > Packet Filterでブロードバンドルーター ]