ipfw

FreeBSD 11 から table name が使える。以前は table num

firewall_type を使う方法
冒頭の表にあるとおり、firewall_typeにファイルパスを指定するとrc.firewalでルールファイルの読み込みが行われるようになる。
https://decomo.info/wiki/freebsd/freebsd_11_ipfw

FreeBSDにはIPFW,IPF,PFという3つのファイアウォール実装があります。PFは後発でありOpenBSDで開発されたということもあって,比較的人気のある実装です。しかしながら4.5よりも後の実装はシンタックスに互換性がないこと,現在のPFの実装はコアに対してスケールしにくいという問題があります。コアに対してスケールするのは,FreeBSDのデフォルトのファイアウォール実装であるIPFWです。

これまでの開発の流れを見ると,FreeBSDでもっともサポートが厚いのはIPFWということになります。

2011年7月19日 FreeBSD 9.0にはPF 4.5導入 | gihyo.jp

/etc/rc.firewall

FreeBSD には、/etc/rc.firewall という、パケットフィルタのサンプルが準備されていますが、今回は、まったくのオリジナルで、比較的単純、かつ、そこそこ役に立つパケットフィルタ(私が使っているもの(^^;;)を作ってみます。
パケットフィルタ (ipfw) の設定: むらさきのくも 2009

established, frag, setup, keep-state

18行目:${fw_add} allow tcp from any to any established
 TCP パケットのうち、すでに接続が確立している(established)ものを許可します

19行目:${fw_add} allow all from any to any frag
 大きすぎて、複数のパケットに分割された(frag)パケットを許可します

29行目:${fw_add} allow udp from ${my_net} to me 53 keep-state
 FreeBSD 上で動いている、DNS サーバ(unbound)への接続を許可する設定。
 LAN 内部から(from ${my_net}) FreeBSD の 53番ポートへの(to me 53) UDP 接続を受け付け、動的ルールに追加(keep-state)します。

 発信元と送信先が「合意」したあとで本番の通信が始まる TCP とは異なり、UDP は、送信元が受信先へパケットを一方的に送りつけて終わり、という通信方式ですが、もし、通信相手の IPアドレスとポート番号を記憶しておくことができれば、その相手だけを選んで、パケットのやりとりを許可することができます。

 この、通信相手の IPアドレスとポート番号、そしてパケットの種類を(ある意味、PC の搭載メモリ量と CPU パワーにものを言わせて、力まかせで(^^;;)記憶して、一定時間だけ通信を許可するしくみを、動的ルールと呼びます

31行目:${fw_add} allow tcp from ${my_net} to me setup
 LAN 内部から FreeBSD への、TCP 接続開始要求(setup)を受け付けます。
 TCP の接続が確立したあとは、その接続が切断されるまで、前述の established のルールにより、発信元と接続先 (FreeBSD) 間の通信が許可されます

パケットフィルタ (ipfw) の設定: むらさきのくも

「もしかして check-state って必須?でも keep-state 単体でも動いてる…」

と思ってしまったので調べてみました。


結論から言えば man ipfw

check-state

Checks the packet against the dynamic ruleset. If a match is
found, execute the action associated with the rule which gener-
ated this dynamic rule, otherwise move to the next rule.
Check-state rules do not have a body. If no check-state rule is
found, the dynamic ruleset is checked at the first keep-state or
limit rule.

パケットを動的ルールと照合します。
マッチしたらそのルールに応じたアクションを実行し、そうでないなら次のルールへ進みます。
check-state ルールに body はありません。
もし、check-state ルールが見つからなかった場合、動的ルールの照合は
最初の keep-state ルールか limit ルールが見つかった時点で行われます。
ということで、check-state ルールがなくても正常に動くみたいです。

NTP とか DNS みたいな UDP に使いたいだけなら

add pass udp from 192.168.XXX.YYY to any 53 keep-state
だけで十分なわけですね。便利便利。
ipfw で動的ルールを設定する - ほっしーの技術ネタ備忘録

table
ipfw table 1 flush
cat list.txt | xargs ipfw table 1 add

http://www.libre.lv/Notes/ipwf-block-ip-or-subnet-persistent-rules

traceroute

From Wikipedia https://en.wikipedia.org/wiki/Traceroute:
On Unix-like operating systems, traceroute employs User Datagram Protocol (UDP) datagrams by default, with destination port numbers ranging from 33434 to 33534.
IPFW - traceroute sendto: Permission denied | The FreeBSD Forums

# traceroute
${fwcmd} add pass udp from any 32768-65535 to me 33434-33623 keep-state
https://systemix.ne.jp/info/54

http://www.cisco.com/warp/public/105/traceroute.shtml
http://lists.freebsd.org/pipermail/freebsd-security/2004-February/001585.html

# TRACEROUTE - Allow outgoing
${fwcmd} add pass udp from any to any 33434-33523 out via ${oif}
https://freebsd-security.freebsd.narkive.com/sFObbPfb/ipfw-and-icmp