macOS网络共享会绕过系统代理,需通过PF规则重定向、改用有线共享+透明代理、注入HTTP头或DHCP分发PAC文件来修复。

如果您在 macOS 系统中启用网络共享(Internet Sharing)后,发现已配置的代理(如 HTTP/HTTPS/SOCKS 代理)无法正常转发流量,则可能是由于共享服务绕过了系统代理设置并直接使用原始路由表与 PF 规则进行数据包转发。以下是修复此问题的步骤:
一、理解网络共享与代理共存失效的根本原因
macOS 的“互联网共享”功能基于 PF(Packet Filter)防火墙和 natd 或 pfctl 实现 NAT 转发,其工作在内核网络栈的较低层级,**完全绕过用户态的网络代理配置(如系统偏好设置中的代理或环境变量 http_proxy)**。所有来自共享客户端的流量均被 PF 规则重写目标地址并直接转发至上游接口,不经过任何代理进程监听的端口或 SOCKS 代理链路。因此,即使在共享主机上全局启用代理,共享子网内的设备仍走直连路径。
二、启用 PF 规则级代理重定向
该方法通过修改 PF 配置,在 NAT 转发前将指定端口的出站流量重定向至本地代理监听端口。需确保代理服务(如 Squid、Privoxy 或 mitmproxy)已在 localhost:8080 启动并接受非本地连接(绑定 0.0.0.0 或关闭访问控制)。
1、执行 sudo nano /etc/pf.anchors/com.apple.internet-sharing,定位到包含 rdr-anchor "com.apple/internet-sharing" 的行下方。
2、在该 anchor 块内追加规则:rdr on bridge100 inet proto tcp from any to any port {80,443} -> 127.0.0.1 port 8080(bridge100 请替换为实际共享桥接接口名,可通过 ifconfig | grep -A5 'inet.*broadcast' 查得)。
3、执行 sudo pfctl -f /etc/pf.conf 重载规则。
4、确认规则生效:sudo pfctl -s nat | grep 8080 应输出对应 rdr 条目。
三、切换共享模式为“仅共享至以太网”并禁用自动 DHCP
macOS 默认为 Wi-Fi 共享启用内置 DHCP 服务(bootpd),其分配的 DNS 和网关信息不包含代理配置,且客户端不会读取系统代理设置。改用有线共享可强制客户端依赖主机路由,便于结合透明代理方案。
1、进入“系统设置 > 网络 > 互联网共享”,将“共享以下来源的连接”设为 USB 以太网适配器或 Thunderbolt 桥接接口(非 Wi-Fi)。
2、点击“详细信息 > DHCP”,取消勾选 “创建 DHCP 服务器”。
3、手动为共享接口(如 bridge100)配置静态 IP:192.168.2.1/24,并在客户端手动设置网关为该地址、DNS 为 192.168.2.1。
4、启动本地透明代理服务(如 mitmdump -s inject.py --mode transparent --showhost),并确保其证书已安装至客户端信任库。
四、注入代理头至 HTTP 流量(针对非 TLS 加密请求)
当无法部署透明代理或客户端不支持 PAC 时,可在 PF 层对未加密的 HTTP 请求注入 Proxy-Connection 与 Via 头,诱导上游服务器识别代理链路,避免部分 Web 服务因检测到直连而拒绝响应。
1、启用 ipfw 替代 PF(仅限 macOS Monterey 及更早版本):sudo ipfw add 100 fwd 127.0.0.1,8080 tcp from any to any 80。
2、编写 Lua 脚本(需配合 nginx 或 envoy 作为反向代理前端),在 request_headers 阶段插入:Proxy-Connection: keep-alive 与 Via: 1.1 localhost (squid/6.0)。
3、重启 nginx:sudo nginx -s reload,验证请求头是否出现在 upstream access_log 中。
五、强制客户端使用 PAC 文件而非系统代理
macOS 网络共享本身不传播代理设置,但可通过伪造 DHCP Option 252(PAC URL)使 Windows/Linux 客户端自动获取代理配置脚本,从而绕过共享层对系统代理的屏蔽。
1、创建 PAC 文件 pac.js,内容包含 return "PROXY 192.168.2.1:8080";,托管于共享主机的 Python HTTP 服务:python3 -m http.server 8000。
2、编辑 /etc/bootpd.plist,在 <key>dhcp_configuration</key> 下添加:<key>252</key><string>http://192.168.2.1:8000/pac.js</string>。
3、重启 bootpd:sudo launchctl unload -w /System/Library/LaunchDaemons/bootps.plist && sudo launchctl load -w /System/Library/LaunchDaemons/bootps.plist。
4、在客户端执行 ipconfig /release && ipconfig /renew(Windows)或 dhclient -r && dhclient(Linux),检查是否获取到 WPAD URL。

















