1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

NetBSDAdvent Calendar 2022

Day 5

NPF(NetBSD Packet Filter)のパケットフィルタルールを見てみる

Last updated at Posted at 2022-12-05

NetBSD Advent Calendar 2022 2日目の記事です。今年もNetBSDの記事を増やして行きましょう!
今日はnpf(7)におけるフィルタルールの記法を紹介しようと思います。

NPFのフィルタルール

NPFに限らず、ファイアウォールを設定する際には何らかの記法でフィルタルールを設定します。FreeBSDのipf(5)では以下のような記述を用います。ipfではフィルタルールとルールのグルーピングを一行で指定する形になっています。

# ICMPパケットをブロックする例
block in log quick proto icmp all group 100

同等のフィルタルールをNPFに置き換えると以下のようになります。一行でルールを表現するのはipfと同じなのですが、フィルタルールをグルーピングしたうえでルールを記述できる記法になっています。このように
、NPFは他のファイアウォール実装におけるフィルタルールと比べてわかりやすいルール記述が可能となっています。

group "icmp rule" {
  block in on $ext_if proto icmp all apply "log"
}

また、ルールのグルーピング以外にも、変数やインタフェースからIPv4/v6アドレスの取得、IPアドレスのリスト(特定のポート疎通を許可する等で使用)といった、便利な記法(文法)がサポートされています。

NPFのフィルタルール文法

NPFのフィルタルールの文法を見てみます。文法の全てを紹介しているわけではありませんが、通常設定するフィルタルールを記述する場合は、ここで紹介する内容で十分かと思います。

変数

NPFのフィルタルールでは変数を使用可能で、先頭に $ をつけると変数として扱われます。変数に代入可能な値は以下となっており、 $var2 = { 10.0.0.1, 10.0.0.2 } のように値をリストとして代入することも
可能です。

  • IPアドレス
  • ネットワーク
  • ポート
  • インタフェース
$var1 = 10.0.0.1
$var2 = { 10.0.0.1, 10.0.0.2 }

インタフェース

インタフェースに降られているIPアドレスの取得も文法でサポートされています。 inet4() , inet6() でそれぞれIPv4,IPv6アドレスが取得できます。また、 ext_addrs() を使用すると、IPv4,IPv6両方のアド
レスを取得できます。

ちなみに、 inet4() 等はインタフェースに紐づくIPアドレスを返す拡張関数として実装されているとのことです。

$ext_if = "wm0"  # LANの外側のインタフェース

$ext_v4 = inet4($ext_if)  # IPv4アドレスを取得する
$ext_v6 = inet6($ext_if)  # IPv6アドレスを取得する

$ext_addrs = ifaddrs($ext_if)  # IPv4/IPv6両方のアドレスを取得する

グループ

NPFでは「グループ」という単位でフィルタルールを定義します。 default グループは最初から存在しているグループになっており、パケットがどのグループにもマッチしなかった場合は、この default グループ
のルールがマッチングされます。
そのため、 default グループでは不要なパケットを全てブロックする設定にしておき、他のグループで疎通させたいパケットのルールを記述する、という使い方が良さそうです。

グループは複数定義することも可能なうえ、入れ子の形でも定義できます。このあたりの記法を活用すると、フィルタルールのメンテナンスが楽になりそうです。

$ext_if = "wm0"  # LANの外側のインタフェース
$int_if = "wm1"  # LANの内側のインタフェース

# グループに名前をつけることも可能。
# このグループには"icmp rule"という名前が付けられている
group "icmp rule" {
  # LANの外側からのICMPパケットは全てブロックする
  block in  on $ext_if proto icmp all apply "log"
  block out on $ext_if proto icmp all apply "log"

  # LANの内側から出てゆくICMPパケットは許可する
  pass in  on $int_if proto icmp all
  pass out on $int_if proto icmp all
  pass stateful out all
}

group default {
  # defaultグループのルール
}

また、グループにインタフェースを紐づけておくことも可能です。以下の例ではLANの外側のインタフェースに対するsshアクセスをブロックする設定です。group "external" on $ext_if という記述で、"external"
グループのフィルタルールがLANの外側のインタフェースにのみ適用される形になります。

$ext_if = "wm0"  # LANの外側のインタフェース

group "external" on $ext_if {
  block in on $ext_if from any to $ext_v4 port 22 apply "log"
}

ルール

パケットフィルタルールを指定する、一番肝心な文法です。ルールの例はこれまでにいくつか挙げていますので、ここではルールのシンタックスを示します。

ルールのマッチング動作としては、複数ルールが存在した場合は最初に一致したルールが適用されます。NPFの挙動としては、フィルタルールを一通り当てはめたのち、一致するルールを適用しますが、 final キー
ワードを指定することで、そのルールにマッチした時点でパケットを処理させることも可能です。基本的にはルールにマッチした時点でパケットを処理したいはず(?)なので、 final 指定は頻繁に使用するような気
がします。
また、 proto キーワードを指定することで、任意のプロトコル(TCP,ICMP等)をフィルタすることも可能です。

 group           = "group" ( "default" | group-opts ) "{" rule-list "}"
 group-opts      = name-string [ "in" | "out" ] [ "on" interface ]
 rule-list       = [ rule new-line ] rule-list

 npf-filter      = [ "family" family-opt ] [ proto ] ( "all" | filt-opts )
 static-rule     = ( "block" [ block-opts ] | "pass" )
                   [ "stateful" | "stateful-ends" ]
                   [ "in" | "out" ] [ "final" ] [ "on" interface ]
                   ( npf-filter | "pcap-filter" pcap-filter-expr )
                   [ "apply" proc-name ]

 dynamic-ruleset = "ruleset" group-opts
 rule            = static-rule | dynamic-ruleset

アドレス変換(NAT)

アドレス変換、いわゆるNAT(Network Address Translation)です。 -> で外に出てゆくパケット(outbound)のアドレス変換、 <- で外から入ってくるパケット(inbound)のアドレス変換を行います。以下の例ではLANの内側( 192.168.0.0/24 のネットワーク)からLANの外側に出てゆくパケットのアドレス変換ルールを設定しています。

また、 <-> でoutbound/inboundのアドレス変換ルールも設定可能です(ちょっと具体的なユースケースが思いつかない...)。

$ext_if = "wm0"  # LANの外側のインタフェース
$int_if = "wm1"  # LANの内側のインタフェース

まとめ

NPFにおける、パケットフィルタルールの文法を紹介しました。ここで紹介した文法を用いることで、最低限のフィルタルールを記述できるようになるかと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?