0
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?

【PF】macOSでIPアドレスによるアクセス制限を行う

Last updated at Posted at 2025-04-06

はじめに

macOSでは、ネットワークへのアクセスを制御する手法として、BSD系のOSで利用されてきたPF(packet filter)が採用されている。この設定をカスタマイズすることで、アクセス制限が可能になる。

筆者はネットワークに関する知識が乏しく、根本的に間違っている箇所があるかもしれませんので、十分に注意して自己責任で設定してください。macOSのPFに関する日本語の情報があまり多くないので、本稿はその一助とするための記事です。有識者の方はぜひより詳しいことを教えて下さい。

設定を行った環境:macOS Sequoia 15.4

PFの設定ファイルを作成する

PFのデフォルトの設定ファイルは、 /etc/pf.conf である。しかし、このファイルはOSアップデート時などに上書きされる。そこで、本稿では、 /usr/local/etc/pf.conf を設定ファイルとする。

まず、PFの設定ファイルなどを置くためのディレクトリを作成する。

$ sudo mkdir -p /usr/local/etc /usr/local/bin

設定ファイルとして、 /usr/local/etc/pf.conf を以下のように作成する。

pf.conf の最後の行には、空白行を入れる必要がある?

/usr/local/etc/pf.conf
# IPアドレスによるアクセス制限を行うためのPFの設定ファイル
# !!!! このファイルの最後の行は、空白行にする必要がある? !!!!

# このコンピュータのIPアドレス(適宜変更する)
my_ip = "xxx.xxx.xxx.xxx"

# アクセス可能なIPアドレスリストの例
allowed_ips = "{ yyy.yyy.yyy.yyy, zzz.zzz.zzz.zzz/24 }"

# ループバックは常に許可する(他の設定よりも優先される)
pass quick on lo0 all

# 許可されたIPアドレスから下で設定するポートに対して入力される接続以外のすべてはブロックする
block in all  # ブロックされた接続のログも取るには、 block in log all とする

# 既存の接続は維持する(外向きの接続はそのまま通過させる)
pass out all keep state

# 許可されたIPアドレスからのSSH/SFTP(22番ポート)を許可する
pass in log on en0 proto tcp from $allowed_ips to $my_ip port 22 keep state

# 許可されたIPアドレスからのXXXX番ポートに対する通信を許可する
# pass in log on en0 proto tcp from $allowed_ips to $my_ip port XXXX keep state

このファイルの所有者と権限を以下のように設定する。

$ sudo chown root:wheel /usr/local/etc/pf.conf
$ sudo chmod 644 /usr/local/etc/pf.conf

PFの設定を読み込むためのスクリプトを作成する

次に、OS起動時にこの設定でPFを起動するためのシェルスクリプト( /usr/local/bin/load_pf.sh )を以下のように作成する。

/usr/local/bin/load_pf.sh
#!/bin/bash
# pflog0インタフェースを作成する
/sbin/ifconfig pflog0 create

# pfの設定を読み込む
/sbin/pfctl -f /usr/local/etc/pf.conf
# pfを有効化する
/sbin/pfctl -e

# pfのログを保存するためのディレクトリを作成する(存在しない場合)
mkdir -p /var/log/pflog
# pfのログを書き出す(/var/log/pflogにpflog_YYYYmmddHHMMの命名形式のバイナリファイルが作成される)
tcpdump -n -e -w /var/log/pflog/pflog_$(date +%Y%m%d%H%M).log -ttt -i pflog0

このスクリプトに実行権限を付与する。

$ sudo chmod +x /usr/local/bin/load_pf.sh

BSD系のOSでは、PFのログは pflog0 というインターフェイスに出力され、これをリッスンしている pflogd というデーモンがログファイルを生成する。しかし、macOSで pflogd を使用する方法が不明なので、暫定的に tcpdump によってログファイルを生成する。

このスクリプトでは、OSが再起動するごとにログファイルが生成され、 tcpdump のバイナリフォーマットで書き込まれる。このログファイルを読むときには、

$ tcpdump -n -e -ttt -r /var/log/pflog/pflog_*YYYYmmddHHMM*.log

というコマンドを使用する。また、例えば22番ポートに対する通信のみを表示するには、

$ tcpdump -n -e -ttt -r /var/log/pflog/pflog_*YYYYmmddHHMM*.log port 22

のようにする。

前節のPFの設定では、許可された接続のみをログするようにしている。もし、ブロックされた接続も含めてすべてのログを取るには、 pf.confblock in all となっている箇所を、 block in log all とする。

OS起動時に自動的に起動させる

macOSでは、デーモンの管理・実行をLaunchDaemons( launchd )が行っている。したがって、上のスクリプトの実行をLaunchDaemonsに登録すれば、OS起動時に自動的に起動することができる。

このために、以下のような /Library/LaunchDaemons/local.pf.plist を作成して、上のスクリプトの実行を登録する。

/Library/LaunchDaemons/local.pf.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>local.pf</string>

    <key>ProgramArguments</key>
    <array>
      <string>/usr/local/bin/load_pf.sh</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <true/>
  </dict>
</plist>

このファイルの所有者と権限を以下のように設定する。

$ sudo chown root:wheel /Library/LaunchDaemons/local.pf.plist
$ sudo chmod 644 /Library/LaunchDaemons/local.pf.plist

local.pf.plist を、LaunchDaemonsに読み込む。

$ sudo launchctl load -w /Library/LaunchDaemons/local.pf.plist

local.pf.plist では、 RunAtLoad<true/> としているので、上のコマンドを実行することで、読み込みと同時にプロセスが起動する。

0
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
0
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?