Apple 在 OS X 上推行沙盒之后,发现原来能用 PAC 代理配置不能用于所有程序了,原因是因为启用沙盒的程序无法访问 PAC 文件。除此之外,也发现了 SOCKS5 的兼容问题(如 Safari、Tweetbot),也就意味着在日益严峻的天朝网络环境里某些提高生产力的工具,如 shadowsocks ,就半残废了,只能走全局的 SOCKS 代理,而想要访问大陆站点的时候,比如优酷,这明显不科学,只能想办法解决。
沙盒的权限问题
虽然沙盒政策不让程序访问未授权的文件,不过对于「远程」文件倒没限制,所以我们可以把 PAC 文件部署在本地的服务器上。
安装 Pow 或 Anvil(参考),使用 Apache/nginx 也可以,总之可以通过类似 http://localhost/proxy.pac
的方式访问本地的 PAC 文件即可。
以 Anvil 为例,安装并启动后,将 PAC 文件所在目录拖曳到状态栏的图标即可,得到如 http://pac.dev/
的地址。将加上文件名后的完整地址,如 http://pac.dev/proxy.pac
,复制到 Network Proxies 设置里 Automatic Proxy Configuration 的文本框里:
SOCKS5 的问题
虽然绕过了沙盒的限制,但是 Safari 和 Tweetbot 是不支持 SOCKS5 的,而 Chrome/Firefox 却只支持 SOCKS5,这里就有两种方法。
第一种,PAC 里这样写:
'SOCKS5 127.0.0.1:8080;SOCKS 127.0.0.1:8080'
第二种,把 SOCSK5 转换成都支持的 HTTP 代理,这就需要使用 Privoxy。Privoxy 非常强大,但是比 PAC 复杂,如非需要,建议还是用第一种方法处理。
注意:本文是通过 homebrew 来安装 Privoxy,配置方式和通过官方安装指南安装的有所区别。
打开命令行依次执行以下命令:
brew install privoxy
cd /usr/local/etc/privoxy/
echo 'listen-address 0.0.0.0:8118\nforward-socks5 / localhost:8080 .' >> config
0.0.0.0
可以让别的设备用,如果不需要,可以用 127.0.0.1
;8118
是默认端口;localhost:8080
是我的 SOCKS5 地址,根据需要自行修改。
需要注意的是,Privoxy 读取配置文件只会在当前目录读取,所以运行时建议用这个命令:privoxy /usr/local/etc/privoxy/config
,没看到任何信息就代表成功了。
把 PAC 文件里的 SOCKS5 地址改成 HTTP 地址:
function FindProxyForURL(url, host) {
proxy = 'PROXY 127.0.0.1:8118'
if (shExpMatch(url, "*.twitter.com/*")) {
return proxy;
}
return 'DIRECT'
}
好了,配合之前解决的沙盒问题,PAC 又可以正常工作了。
如果需要自启动,在命令行执行如下命令:
cd ~
touch org.privoxy.plist | echo '<?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>org.privoxy.launchd.privoxy</string><key>ProgramArguments</key><array><string>/usr/local/sbin/privoxy</string><string>/usr/local/etc/privoxy/config</string></array><key>RunAtLoad</key><true/></dict></plist>' >> org.privoxy.plist
sudo chown root:wheel org.privoxy.plist
sudo cp org.privoxy.plist /Library/LaunchDaemons/org.privoxy.plist
launchctl load /Library/LaunchDaemons/org.privoxy.plist
launchctl start org.privoxy.launchd.privoxy
Privoxy 的进阶内容
其实 Privoxy 并不只是把 SOCKS5 转换成 HTTP 代理,她本身还有很强大的功能,比如 action
和 filter
,在这仅仅简单介绍一下,具体用途看官方文档。
Action
可以起到 PAC 文件的作用,也可以当成 AdBlock、user script 和 Stylebot 来使用。
默认的文件分别是 /usr/local/etc/privoxy/user.action
和 /usr/local/etc/privoxy/user.filter
。
大概的语法如下:
direct = +forward-override{forward .}
ssh = +forward-override{forward-socks5 127.0.0.1:8080 .}
default = direct
{default}
/
{direct}
.youku.com
.twitter.com
{ssh}
.twitter.com
# 后面的规则优先级比前面的高
{+block}
.weibo.com # 屏蔽微博
{-block}
.weibo.com/chrisyipw # 但是不屏蔽自己
{+block-as-image}
.weibo.com # 屏蔽微博下所有合法图片,即使扩展名不是图片扩展名也会被屏蔽
可以通过不同的 alias
配置不同的代理程序,如果是用 SSH 而不是 shadowsocks,可以考虑链接多个服务器进行分流,毕竟 SSH 并发性能不高。
还有更高级的,比如结合 filter
修改页面内容,比如重定向 URL 什么的:
{+filter{filter_name}}
.weibo.com
{+fast-redirects{check-decoded-url}}
news.google.com/news/url.*&url=http.*&
具体看 user.action
里的注释吧,而 filter
是需要结合 user.filter
来用的,如果想要使用多个 action
文件,在 config
加入 actionsfile name.action
就行。