MacOS配合pfctl实现dnat以及filter:修订间差异

来自三线的随记
(创建页面,内容为“=== 摘要 === 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…”)
 
无编辑摘要
第1行: 第1行:
=== 摘要 ===
===摘要===
Packet Filter (from here on referred to as PF) is OpenBSD's system for filtering TCP/IP traffic and doing Network Address Translation.
Packet Filter (from here on referred to as PF) is OpenBSD's system for filtering TCP/IP traffic and doing Network Address Translation.


第6行: 第6行:
pf的规则语法非常遵循行为顺序: Rules must be in order: options, normalization, queueing, translation, filtering
pf的规则语法非常遵循行为顺序: Rules must be in order: options, normalization, queueing, translation, filtering


=== 通过pf在macOS上实现dnat ===
===通过pf在macOS上实现dnat===
1. 首先需要允许IP转发
1. 首先需要允许IP转发
  sysctl -w net.inet.ip.forwarding=1
  sysctl -w net.inet.ip.forwarding=1
第66行: 第66行:
5. 启用pf并加载规则
5. 启用pf并加载规则
  pfctl -vF all ; pfctl -vef /etc/pf.conf
  pfctl -vF all ; pfctl -vef /etc/pf.conf
(临时保存,still wrinting...)
6. [debug] 这个时候使用tcpdump之类的抓包工具能够在lo0网卡上看到相关流量,以及在流量出口网卡能够看到被dnat后的报文<br />
<br />


=== Related commands ===
===Related commands===


==== 通过command传递rule ====
====通过command传递rule====
  echo "pass out route-to (lo0 127.0.0.1) proto tcp and port 80 from any to any" | sudo pfctl -ef -
  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 all


=== 从文件中加载规则 ===
===从文件中加载规则===
  pfctl -vf /etc/pf.conf
  pfctl -vf /etc/pf.conf
<br />
<br />


=== 附 ===
===附===
如上文规则example所示,pf结合dnat可以实现很多玩法,而且pf的规则定义能力还是相当强大的甚至规则能够指定到某些user视角上
如上文规则example所示,pf结合dnat可以实现很多玩法,而且pf的规则定义能力还是相当强大的甚至规则能够指定到某些user视角上


包括但不限于:
包括但不限于:


# 在一些网络需要登陆认证才能使用的场所(如麦当劳 星爹爹等),同时这些网络的53端口是全白名单端口随意通讯的话,可以将你的流量通过53端口转发出去绕过认证(例如如果你有zerotier网络,可以将你的MOON节点流量以及一些有动态公网IP的流量通过53端口转发出去以建立直连通道,然后将未认证网络的设备的默认网关改为你的zt网络当中的其他设备即可绕过认证上网)
#在一些网络需要登陆认证才能使用的场所(如麦当劳 星爹爹等),同时这些网络的53端口是全白名单端口随意通讯的话,可以将你的流量通过53端口转发出去绕过认证(例如如果你有zerotier网络,可以将你的MOON节点流量以及一些有动态公网IP的流量通过53端口转发出去以建立直连通道,然后将未认证网络的设备的默认网关改为你的zt网络当中的其他设备即可绕过认证上网)
# 通过pf实现类似iptables效果的透明代理(将全部80和443端口的流量转发到某些proxy服务上)
#通过pf实现类似iptables效果的透明代理(将全部80和443端口的流量转发到某些proxy服务上)
# (发挥脑洞..)
#(发挥脑洞..)
 
<br />
__无编辑段落__
__无新段落链接__
[[分类:Linux]]
[[分类:MacOS]]
[[分类:Tcpdump]]

2021年6月19日 (六) 22:58的版本

摘要

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上实现dnat

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/*"
nat-anchor my-redirect

rdr-anchor "com.apple/*"
rdr-anchor my-redirect

dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"


# my-redirect
anchor "my-redirect"
load anchor "my-redirect" from "/etc/pf.anchors/my_anchor"

5. 启用pf并加载规则

pfctl -vF all ; pfctl -vef /etc/pf.conf

6. [debug] 这个时候使用tcpdump之类的抓包工具能够在lo0网卡上看到相关流量,以及在流量出口网卡能够看到被dnat后的报文

Related commands

通过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视角上

包括但不限于:

  1. 在一些网络需要登陆认证才能使用的场所(如麦当劳 星爹爹等),同时这些网络的53端口是全白名单端口随意通讯的话,可以将你的流量通过53端口转发出去绕过认证(例如如果你有zerotier网络,可以将你的MOON节点流量以及一些有动态公网IP的流量通过53端口转发出去以建立直连通道,然后将未认证网络的设备的默认网关改为你的zt网络当中的其他设备即可绕过认证上网)
  2. 通过pf实现类似iptables效果的透明代理(将全部80和443端口的流量转发到某些proxy服务上)
  3. (发挥脑洞..)