PAC自动代理和ios翻墙

简介

通过这篇文章,你将了解以下几点:

HTTP代理

shadowsocks翻墙

PAC自动代理

PAC的编写规则

防御端口扫描

基本原理

HTTP代理即通过指定服务器代为请求网页信息,并将response返还给客户端。代理服务器客户端和web服务器之间,扮演中间人的角色。按照使用场景划分有很多不同作用,这里我们用作翻墙。

通过在pac自动代理中指定HTTP代理服务器(也可以指定socks5代理,但部分客户端不支持),我们就可以在支持pac代理的客户端输入pac文件的url就可以愉快的翻墙了。

理想的方式是在国外直接架设一台HTTP代理服务器,然而事实并没有我们想的这么简单,因为HTTP代理并没有加密,所以会被GFW过滤掉。

这时候我们需要借助一台国内服务器和一台国外服务器,在两个服务器之间架设tunnel,流量加密穿过GFW。而国内服务器同时作为HTTP代理服务器,为国内设备提供代理服务。

我们来画图描述一下,一目了然。

这里的tunnel可以使用任何方式,包括但不限于:各种vpn(pptp/l2tp/open/shadow/anyconnet/ipsec),各种tunnel(曲径使用的qtunnel/gotunnel),以及本文使用的shadowsocks。

自动代理

Pac叫Proxy auto-config,是一个用来自动代理的技术,一个PAC文件包含一个JavaScript形式的函数,定义了一系列访问规则,用户代理根据这些规则适用一个特定的代理其或者直接访问。简单来说,就是指定一部分域名和相应的代理方式,于是我们可以定义一些被GFW block的域名来指定http代理或者socks5代理,而未被block的域名直接访问就可以了。这叫智能分流,比VPN的全局翻墙更智能快速。

对于windows/linux/android/mac os等客户端可以直接使用shadowsocks,但是未越狱的iOS则无法使用,好在iOS支持pac自动代理,于是我们可以搭建一个http代理服务器,再配合pac文件就可以智能分流翻墙了。

shadowsocks

shadowsocks是一个可穿透防火墙的快速代理。通过客户端以指定的密码、加密方式和端口连接服务器,成功连接到服务器后,客户端在用户的电脑上构建一个本地socks5代理。使用时将流量分到本地socks5代理,客户端将自动加密并转发流量到服务器,服务器以同样的加密方式将流量回传给客户端,以此实现代理上网。

这里shadowsocks的客户端是国内服务器,shadowsocks的服务器就是国外服务器。

转换、缓存和安全

shadowsocks提供了socks5代理,我们需要在国内服务器上将其转换成HTTP代理,polipo很方便的实现了该功能,并且提供了缓存的功能用于加速。除此之外,由于PAC不支持http basic认证,所以为了安全,我们需要在国内服务器上防止端口扫描,防止有坏(无聊的)人恶意扫描端口、使用代理。

详细过程

shadowsocks服务端

在境外服务器A上:

安装

Debian / Ubuntu:

apt-get install python-pip pip install shadowsocks

CentOS:

yum install python-setuptools && easy_install pip pip install shadowsocks使用

新建配置文件/etc/shadowsocks.json

{ "server":"157.7.7.7", # 服务器监听地址,可以0.0.0.0 "port_password": {"1001": "pass1","1002": "pass2", "1003": "pass3"# 可以分配为不同端口指定不同密码 },"local_address": "127.0.0.1","local_port":1080,"timeout":300, "method":"rc4-md5" # 加密方式,此种适合在openwrt路由器上使用,兼具轻量级和安全性}

运行

useradd -M ssuser ssserver -c /etc/shadowsocks.json --user ssuser -d start

更多优化和配置请参考官方wiki

shadowsocks客户端

在国内服务器B上,使用如下命令来运行

sslocal -s 157.7.7.7 -p 1001 -k pass1 -m rc4-md5 -b 0.0.0.0 -l 8888 -d start

这样B服务器就开始监听8888端口的socks5代理。

对于SwitchyOmega等代理插件是支持PAC中指定socks5代理,但是IE并不支持,iOS未测试。不过为了优化代理,我们可以通过polipo来将socks5代理转换为http代理,更重要的是polipo支持缓存。

Polipo is a caching HTTP proxy that was originally designed as a personal proxy, i.e. a proxythat is used by a single user or a small group of users. However, it has successfully been usedby larger groups.

HTTP缓存代理polipo

安装直接 yum install polipo配置文件 /etc/polipo/config

在配置文件中新增以下内容

logSyslog = truelogFile = /var/log/polipo/polipo.log# 指定日志proxyAddress = "0.0.0.0"# 监听地址proxyPort = 10001 # 监听端口socksParentProxy = "localhost:8888" # 指定一级代理为本地的8888socksProxyType = socks5 # 代理类型为socks5

启动 service polipo start

对于polipo的更多优化和配置请参考官方manual

PAC文件

一个PAC文件是一个至少定义了一个JavaScript函数的文本文件。这个函数FindProxyForURL(url, host)有2个参数:url是一个对象的URL,host是一个由这个URL所派生的主机名。按照惯例,这个文件名字一般是proxy.pac. WPAD标准使用wpad.dat。

一个最简单的PAC文件内容如下:

function FindProxyForURL(url, host) { return "PROXY proxy.example.com:8080; DIRECT"; }

指定所有流量都通过proxy.example.com的8080端口来进行http代理。

一个稍微复杂点的例子

function FindProxyForURL(url, host) {// 本地域名不进行代理,直接访问: if (shExpMatch(url,"*.example.com/*")){return "DIRECT";}if (shExpMatch(url, "*.example.com:*/*")) {return "DIRECT";}// URL在这个网络范围内时进行HTTP代理 if (isInNet(host, "10.0.0.0","255.255.248.0")){ return "PROXY fastproxy.example.com:8080"; }// 其他流量进行代理,如果失败则直连 return "PROXY proxy.example.com:8080; DIRECT"; }

如果需要socks5代理,则将PROXY改成SOCKS

这里提供我使用的pac文件供大家参考,可以使用gfwlist2pac这个工具来将gfwlist转换成pac。

在最后面我提供了我使用的PAC文件,你只需要修改var proxy = PROXY myproxy.com:10001;;这一行的内容就可以了。

再提供几个函数,大家可以自行研究并参考

//判断IP是否合法function checkip(host) {var ipValidate=/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;if (ipValidate.test(host)) {return true; }else {return false; } }//匹配特定域名function DomainProxy(url, host) {if ( shExpMatch(host, "tc.dlservice.microsoft.com") || shExpMatch(host, "qh.dlservice.microsoft.com") || shExpMatch(host, "download.microsoft.com") )return 1;else return 0; }//匹配内网IPfunction IpDirect(url, host) {if ( isInNet(host, "10.0.0.0", "255.0.0.0") || isInNet(host, "127.0.0.0", "255.255.255.0") || isInNet(host, "172.0.0.0", "255.0.0.0") || isInNet(host, "172.16.0.0", "255.240.0.0") || isInNet(host, "192.168.0.0", "255.255.0.0") )return 1;else return 0; }function FindProxyForURL(url, host) {//基于IP判断出口 if(checkip(host)) {if(IpDirect(url, host)) {return "DIRECT"; }else return "PROXY myproxy.example.com:8080"; }//基于域名判断出口 else{if(DomainByProxy(url, host)) {return "PROXY myproxy.example.com:8080"; }else if(DomainDirect(url, host)) {return "DIRECT"; }else if(DomainHKProxy(url, host)) {return "PROXY hk.myproxy.com:8080"; }else if(DomainProxy(url, host)) {return "PROXY proxy.example.com:8080"; }else return "PROXY web-proxy.example.com:8080"; } }

配置

PAC文件配置完成以后可以上传到你的web server或者OSS这样的云存储,我们假设url为https://example.com/proxy.pac

iOS

Android

可以安装ProxyDroid

Mac

依次进入「设置」->「网络」->「Wi-Fi」(或「以太网」);

点击「高级」->「代理」;

选中「自动代理配置」,然后将PAC url输入在「代理配置文件」一栏:

点击「好」->「应用」;

Windows

启动Internet Explorer浏览器

依次进入「工具」->「互联网选项」->「连接」;

如果你用当前电脑拨号连接,选中此拨号连接,然后点旁边的「设置」;

如果你用路由器,或者你的电脑通过局域网上网,选择「局域网设置」

选中「使用自动配置脚本」,然后将PAC url输入在「地址」一栏:

一路点击「确定」;

Chrome/Firefox

安装SwitchyOmega

WPAD

WPAD(web-proxy auto discovery)技术可以使用dhcp/dns来实现自动发现代理。这个我们以后再谈,一般用在企业中实现客户端代理自动部署。

端口扫描和加密

polipo支持http basic authentication,但是PAC是个js语法的文件并不支持用户名和密码认证,这就很蛋疼。如果有人在扫描你的端口,那你就很难逃脱。

所以干脆来防止端口扫描吧。

portsentry有几种工作模式,其中的的高级隐秘模式可以监听所有未占用端口,一旦发现有人试图连接这些端口,如果超过阈值,则会采取行动,所以前提是iptables没有DROP这些端口。采取的措施包括:

在/etc/hosts.deny中加入 ALL: 113.144.244.107这样的条目来block掉所有能访问的服务

或者更狠,直接route del -host 14.17.92.11 reject 丢弃指定IP的路由

可以使用自定义的脚本去处理

对于白名单我们可以记录在portsentry.ignore这个文件中自定义脚本可以在配置文件中使用KILL_RUN_CMD="/log-portsentry.sh $TARGET0.nbsp;$PORT$"来处理SCAN_TRIGGER="3" 可以指定触发block的阈值

启动

/usr/local/psionic/portsentry/portsentry -atcp /usr/local/psionic/portsentry/portsentry -audp

更多配置请自行参考portsentry的配置文件。

PAC实例

覆盖大部分大陆不能访问的网址 🙂

内容较多,请阅读原文,或者关注我的个人网站:

本文链接