MacOS配合pfctl实现dnat以及filter:修订间差异
小 (Admin移动页面MacOS配合pfctl实现dnat至MacOS配合pfctl实现dnat以及filter:content added) |
小无编辑摘要 |
||
(未显示同一用户的5个中间版本) | |||
第1行: | 第1行: | ||
===摘要=== | ===摘要=== | ||
pf是OpenBSD的产物 | *Packet Filter (from here on referred to as PF) is OpenBSD's system for filtering TCP/IP traffic and doing Network Address Translation. | ||
*pf是OpenBSD的产物 | |||
*pf的规则语法非常遵循行为顺序: Rules must be in order: options, normalization, queueing, translation, filtering | |||
*pf 在 macOS 默认不会开机自启,在 macOS 中可以配合自定义的launchctl实现开机自启 | |||
<br /> | |||
===利用pf在macOS上实现dnat=== | |||
ps: macOS 12 (Monterey) 也许是有bug,关联pf中的route-to指令工作不正常,会看到流量已经被DNAT成功,但是没有从网卡发出去 | |||
参考: https://github.com/mitmproxy/mitmproxy/issues/4835 https://openradar.appspot.com/FB9658819 | |||
1. 首先需要允许IP转发 | 1. 首先需要允许IP转发 | ||
sysctl -w net.inet.ip.forwarding=1 | sysctl -w net.inet.ip.forwarding=1 | ||
第52行: | 第59行: | ||
scrub-anchor "com.apple/*" | scrub-anchor "com.apple/*" | ||
nat-anchor "com.apple/*" | nat-anchor "com.apple/*" | ||
## 调用my-redirect anchor | |||
nat-anchor my-redirect | nat-anchor my-redirect | ||
rdr-anchor "com.apple/*" | rdr-anchor "com.apple/*" | ||
## 调用my-redirect anchor | |||
rdr-anchor my-redirect | rdr-anchor my-redirect | ||
第62行: | 第73行: | ||
# | # 引入my-redirect anchor | ||
anchor "my-redirect" | anchor "my-redirect" | ||
load anchor "my-redirect" from "/etc/pf.anchors/my_anchor" | load anchor "my-redirect" from "/etc/pf.anchors/my_anchor" | ||
*注意: 这里对于nat-anchor 和 rdr-anchor 起到的效果其实不是非常清楚,实测发现load anchor 以后部分rule已经生效,不一定需要调用的样子(如下文) | |||
5. 启用pf并加载规则 | 5. 启用pf并加载规则 | ||
pfctl -vF all ; pfctl -vef /etc/pf.conf | pfctl -vF all ; pfctl -vef /etc/pf.conf | ||
6. [debug] 这个时候使用tcpdump之类的抓包工具能够在lo0网卡上看到相关流量,以及在流量出口网卡能够看到被dnat后的报文<br /> | 6. [debug] 这个时候使用tcpdump之类的抓包工具能够在lo0网卡上看到相关流量,以及在流量出口网卡能够看到被dnat后的报文<br /><br /> | ||
< | ===利用pf在macOS上实现filter=== | ||
与上一个dnat玩法相似,这里利用pf实现禁止自en0网卡连接本机的ssh(即不能在通过无线网访问ssh) | |||
1. 通过anchor的形式引入自定义规则方便维护, 当然也可以将需要的规则直接写入/etc/pf.conf文件中,注意macOS在升级的时候会覆盖<code>/etc/pf.conf</code>文件 | |||
cat << \EOF > /etc/pf.anchors/ssh-filter | |||
block in on en0 proto tcp from any to any port = 22 | |||
EOF | |||
2. 加载规则 | |||
# | |||
# 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" | |||
# ssh secure | |||
anchor "ssh-deny" | |||
load anchor "ssh-deny" from "/etc/pf.anchors/ssh-filter" | |||
*注意: 这里只是单纯load anchor ,但是filter rule同样能生效 | |||
3. 启用pf并加载规则 | |||
➤ '''sudo pfctl -vF all ; sudo pfctl -vef /etc/pf.conf''' | |||
No ALTQ support in kernel | |||
ALTQ related functions disabled | |||
rules cleared | |||
nat cleared | |||
dummynet cleared | |||
0 tables deleted. | |||
6 states cleared | |||
source tracking entries cleared | |||
pf: statistics cleared | |||
pf: interface flags reset | |||
pfctl: Use of -f option, could result in flushing of rules | |||
present in the main ruleset added by the system at startup. | |||
See /etc/pf.conf for further details. | |||
No ALTQ support in kernel | |||
ALTQ related functions disabled | |||
scrub-anchor "/*" all fragment reassemble | |||
nat-anchor "/*" all | |||
rdr-anchor "/*" all | |||
anchor "/*" all | |||
anchor "ssh-deny" all | |||
dummynet-anchor "/*" all | |||
Loading anchor com.apple from /etc/pf.anchors/com.apple | |||
anchor "/*" all | |||
anchor "/*" all | |||
Loading anchor ssh-deny from /etc/pf.anchors/ssh | |||
block drop in on en0 proto tcp from any to any port = 22 | |||
pfctl: pf already enabled | |||
4. 在同一无线网测试ssh连接会发现Connection timeout,即filter规则生效 | |||
===Related commands=== | ===Related commands=== |
2022年5月3日 (二) 20:37的最新版本
摘要
- Packet Filter (from here on referred to as PF) is OpenBSD's system for filtering TCP/IP traffic and doing Network Address Translation.
- pf是OpenBSD的产物
- pf的规则语法非常遵循行为顺序: Rules must be in order: options, normalization, queueing, translation, filtering
- pf 在 macOS 默认不会开机自启,在 macOS 中可以配合自定义的launchctl实现开机自启
利用pf在macOS上实现dnat
ps: macOS 12 (Monterey) 也许是有bug,关联pf中的route-to指令工作不正常,会看到流量已经被DNAT成功,但是没有从网卡发出去
参考: https://github.com/mitmproxy/mitmproxy/issues/4835 https://openradar.appspot.com/FB9658819
1. 首先需要允许IP转发
sysctl -w net.inet.ip.forwarding=1
2. 然后这里通过anchor的形式引入自定义规则方便维护, 当然也可以将需要的规则直接写入/etc/pf.conf文件中,注意macOS在升级的时候会覆盖/etc/pf.conf
文件
touch /etc/pf.anchors/my_anchor
3. my_anchor文件中写入如下规则实现DNAT(pf规则允许定义使用变量)
zt_peer_wanip = 223.5.5.5 zt_peer_wanport = 21089 ## 将发往114.114.114.114 9988端口的udp报文DNAT到114.114.114.114:53 rdr pass on lo0 proto udp from any to 114.114.114.114 port 9988 -> 114.114.114.114 port 53 ## 通过变量的形式定义DNAT规则 rdr pass on lo0 proto udp from any to $zt_peer_wanip $zt_peer_wanport -> $zt_peer_wanip port 53 # change route to local interface pass out route-to lo0 proto udp from any to 114.114.114.114 port 9988 # 通过变量的形式定义重路由规则 pass out route-to lo0 proto udp from any to $zt_peer_wanip port $zt_peer_wanport
4. 将/etc/pf.conf文件改写以加载anchor(下文所示规则中一部分的规则是macOS原有的规则,保留不动)
# # 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/*" ## 调用my-redirect anchor nat-anchor my-redirect rdr-anchor "com.apple/*" ## 调用my-redirect anchor rdr-anchor my-redirect dummynet-anchor "com.apple/*" anchor "com.apple/*" load anchor "com.apple" from "/etc/pf.anchors/com.apple" # 引入my-redirect anchor anchor "my-redirect" load anchor "my-redirect" from "/etc/pf.anchors/my_anchor"
- 注意: 这里对于nat-anchor 和 rdr-anchor 起到的效果其实不是非常清楚,实测发现load anchor 以后部分rule已经生效,不一定需要调用的样子(如下文)
5. 启用pf并加载规则
pfctl -vF all ; pfctl -vef /etc/pf.conf
6. [debug] 这个时候使用tcpdump之类的抓包工具能够在lo0网卡上看到相关流量,以及在流量出口网卡能够看到被dnat后的报文
利用pf在macOS上实现filter
与上一个dnat玩法相似,这里利用pf实现禁止自en0网卡连接本机的ssh(即不能在通过无线网访问ssh)
1. 通过anchor的形式引入自定义规则方便维护, 当然也可以将需要的规则直接写入/etc/pf.conf文件中,注意macOS在升级的时候会覆盖/etc/pf.conf
文件
cat << \EOF > /etc/pf.anchors/ssh-filter block in on en0 proto tcp from any to any port = 22 EOF
2. 加载规则
# # 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" # ssh secure anchor "ssh-deny" load anchor "ssh-deny" from "/etc/pf.anchors/ssh-filter"
- 注意: 这里只是单纯load anchor ,但是filter rule同样能生效
3. 启用pf并加载规则
➤ sudo pfctl -vF all ; sudo pfctl -vef /etc/pf.conf No ALTQ support in kernel ALTQ related functions disabled rules cleared nat cleared dummynet cleared 0 tables deleted. 6 states cleared source tracking entries cleared pf: statistics cleared pf: interface flags reset pfctl: Use of -f option, could result in flushing of rules present in the main ruleset added by the system at startup. See /etc/pf.conf for further details. No ALTQ support in kernel ALTQ related functions disabled scrub-anchor "/*" all fragment reassemble nat-anchor "/*" all rdr-anchor "/*" all anchor "/*" all anchor "ssh-deny" all dummynet-anchor "/*" all Loading anchor com.apple from /etc/pf.anchors/com.apple anchor "/*" all anchor "/*" all Loading anchor ssh-deny from /etc/pf.anchors/ssh block drop in on en0 proto tcp from any to any port = 22 pfctl: pf already enabled
4. 在同一无线网测试ssh连接会发现Connection timeout,即filter规则生效
Related commands
enable pf
pfctl -e
disable pf
pfctl -d
通过command传递rule
echo "pass out route-to (lo0 127.0.0.1) proto tcp and port 80 from any to any" | sudo pfctl -ef -
清空所有
pfctl -vF all
从文件中加载规则
pfctl -vf /etc/pf.conf
附
如上文规则example所示,pf结合dnat可以实现很多玩法,而且pf的规则定义能力还是相当强大的甚至规则能够指定到某些user视角上
包括但不限于:
- 在一些网络需要登陆认证才能使用的场所(如麦当劳 星爹爹等),同时这些网络的53端口是全白名单端口随意通讯的话(也就是未认证前全网53端口放行),可以将你的流量通过53端口转发出去绕过认证( 例如如果你有zerotier网络,可以将你的MOON节点流量以及一些有动态公网IP的DIRECT通道建立流量通过udp 53端口转发出去以建立直连通道,然后将未认证网络的设备的默认网关改为你的zt网络当中的其他设备即可绕过认证上网) [为什么要这么大费周章去绕过认证上网?对于公共场合的网络,如果采用绕过认证的方式去联网的话,其实你的联网方式就会起到类似使用VPN的效果,除了能够防止你的个人信息因在wifi认证页面填写而导致泄漏以外,还能给你的联网通讯叠加一定程度的安全buff]
- 通过pf实现类似iptables效果的透明代理(将全部80和443端口的流量转发到某些proxy服务上)
- (发挥脑洞..)