pfによる透過的proxy実装 on Mojave
更新履歴
- 2021.04.14
はじめに
- このドキュメントでは,macOSに標準搭載しているpf(Packet Filter)を使って,HTTP/HTTPSへの通信をローカルで動作するプロキシサーバに直接転送する仕組みを定義して実行させる.
pf.confに定義を追加する
- pf.confを確認.
$ cat /etc/pf.conf🆑
#
# Default PF configuration file.
#
# This file contains the main ruleset, which gets automatically loaded
# at startup. PF will not be automatically enabled, however. Instead,
# each component which utilizes PF is responsible for enabling and disabling
# PF via -E and -X as documented in pfctl(8). That will ensure that PF
# is disabled only when the last enable reference is released.
#
# Care must be taken to ensure that the main ruleset does not get flushed,
# as the nested anchors rely on the anchor point defined here. In addition,
# to the anchors loaded by this file, some system services would dynamically
# insert anchors into the main ruleset. These anchors will be added only when
# the system service is used and would removed on termination of the service.
#
# See pf.conf(5) for syntax.
#
#
# com.apple anchor point
#
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"
anchor "com.apple.server-firewall/*"
load anchor "com.apple.server-firewall" from "/etc/pf.anchors/com.apple.server-firewall"
$
- 最終行に,以下を追加.
anchor "proxy"
load anchor "proxy" from "/etc/pf.anchors/proxy"
- これは,proxyという名前の設定ファイルを指定し,それを読み込むという意味.
ポートフォワード用の定義ファイルを作成する
- 次のようなproxyのファイルを作成する.
$ cat /etc/pf.anchors/proxy🆑
ext_if = "en1"
table <rfc1918> const { 192.168.20.0/16 }
rdr on lo0 inet proto tcp from any to any port 80 -> lo0 port 8888
rdr on lo0 inet proto tcp from any to any port 443 -> lo0 port 8888
pass out quick on $ext_if inet proto tcp from any to <rfc1918>
$
- 192.168.20.0/16という定義は,以下のポート転送を行わないアドレス帯域.
- ここでは,en1(macのWiFi)に対して,HTTP(80)とHTTPS(443)ポートに関する通信を,lo0(ループバック)の8888ポートに転送している.
- 自分のMac上で8888ポートでプロキシが稼働している前提.
pfを起動させるための定義
- pf が自動起動するように設定.
- /Library/LaunchDaemons/pf.plist
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple Computer/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>pf.plist</string>
<key>Program</key>
<string>/sbin/pfctl</string>
<key>ProgramArguments</key>
<array>
<string>/sbin/pfctl</string>
<string>-e</string>
<string>-f</string>
<string>/etc/pf.anchors/proxy</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceDescription</key>
<string>FreeBSD Packet Filter (pf) daemon</string>
<key>StandardErrorPath</key>
<string>/var/log/pf.log</string>
<key>StandardOutPath</key>
<string>/var/log/pf.log</string>
</dict>
</plist>
- ログは/var/log/pf.logに記録される模様.
pfの起動と停止
- pfをlaunchctlで起動する.
sudo launchctl load /Library/LaunchDaemons/pf.plist
- うまく動作したら,この時点からポート転送が行われているので,プロキシサーバ上にHTTP/HTTPSのリストが表示される.
- 検証が終わったら停止する.
sudo launchctl unload /Library/LaunchDaemons/pf.plist
- これで終了.