然后最近又有了一种新的“免流”技术,称之为“云免流”。听起来很高大上,其实原理很简单。

各大运营商为了方便用户进行流量查询、缴费等操作,设置了当用户浏览一部分运营商自己的网站时不需要耗费流量,而各大运营商识别用户访问的网址是否为这部分网址时,出现了问题,导致识别错误,主要是这个X-Online-Host字段上的问题。
当用户通过OpenVPN免流时,在你的VPS和移动设备之间打通一个隧道,你的所有网络请求都先经过OpenVPN传给VPS,然后VPS把你请求的东西拿到之后又通过OpenVPN传回来。免流的关键就在于,每次利用OpenVPN发起网络请求之前,都要对请求头进行伪装,加上X-Online-Host字段,让运营商认为你请求的是运营商自己的免流量网站。

wooyun上有相关的讨论:中国联通移动电信三大运营商流量计费系统漏洞

了解了原理就很好办了,首先就是在VPS上搭建OpenVPN服务器端,鉴于速度需要,最好是国内的VPS。

安装OpenVPN

这里以Ubuntu 14.04为例。

首先安装OpenVPN和easy-rsa。

sudo apt-get -y install openvpn libssl-dev openssl easy-rsa

安装完成好查看OpenVPN版本。

openvpn version

官方源里的最高版本目前为2.3.2,这个版本号,建议记住。确认版本无误后,我们开始制作需要的证书文件。

制作CA证书

首先,在/etc/openvpn/目录下创建easy-rsa文件夹。

sudo mkdir /etc/openvpn/easy-rsa/

然后把/usr/share/easy-rsa/目录下的所有文件全部复制到/etc/openvpn/easy-rsa/下。

sudo cp -r /usr/share/easy-rsa/* /etc/openvpn/easy-rsa/

当然,我们也可以直接在/usr/share/easy-rsa/制作相关的证书,但是为了后续的管理证书的方便,我们还是把easy-rsa放在了openvpn的启动目录下。另外,由于我们现在使用的是ubuntu系统,所以我们必须切换到root用户下才能制作相关证书,否则easy-rsa会报错。如果是centos系统,则不存在此问题。

sudo su

开始制作CA证书之前,我们还需要编辑vars文件。

sudo vi /etc/openvpn/easy-rsa/vars

export KEY_COUNTRY=”国家CN”
export KEY_PROVINCE=”省份BJ”
export KEY_CITY=”城市Beijing”
export KEY_ORG=”机构Random”
export KEY_EMAIL=”你的邮箱abc@abc.com”
export KEY_OU=”姓名Tink”
export KEY_NAME=”vpntink

vars文件主要用于设置证书的相关组织信息,具体内容可以根据自己的实际情况自行修改。其中export KEY_NAME=”vpntink”这个要记住下,我们下面在制作Server端证书时,会使用到。

然后使用source vars命令使其生效。

source vars

开始制作CA证书。

./clean-all  (执行clean-all命令会删除,当前目录下的keys文件夹。)
./build-ca

一路按回车键即可。制作完成后,我们可以查看keys目录。

ll keys/

如果以上操作无误的话应该可以看到已经生成了ca.crt和ca.key两个文件,其中ca.crt就是我们所需要的CA证书。至此,CA证书制作完毕。现在把该CA证书的ca.crt文件复制到openvpn的启动目录/etc/openvpn下。

cp keys/ca.crt /etc/openvpn/

制作Server端证书

CA证书制作完成后,我们现在开始制作Server端证书。

./build-key-server vpntink(这里的vpntink,就是我们前面vars文件中设置的KEY_NAME)
ll keys/

一路回车即可。可如果以上操作无误的话应该可以看到生成的vpntink.crt、vpntink.key和vpntink.csr三个文件。其中vpntink.crt和vpntink.key两个文件是我们所需要的。现在再为服务器生成加密交换时的Diffie-Hellman文件。

./build-dh
ll keys/

一路回车。正常情况下应该可以看到已经生成的dh2048.pem文件。

以上操作完毕后,把vpntink.crt、vpntink.key、dh2048.pem复制到/etc/openvpn/目录下。

cp keys/vpntink.crt keys/vpntink.key keys/dh2048.pem /etc/openvpn/

至此,Server端证书就制作完毕。

制作Client端证书

Server端证书制作完成后,我们现在开始制作Client端证书。

./build-key tinksvpn
ll keys/

还是一路回车。上述命令中的tinksvpn,是客户端证书的名称。这个是可以进行自定义的。
正常情况下应该可以看到已经生成的tinksvpn.csr、tinksvpn.crt和tinksvpn.key这个三个文件。其中tinksvpn.crt和tinksvpn.key两个文件是我们要使用的。

至此,Client端证书就制作完毕。

配置Server端

所有证书制作完毕后,我们现在开始配置Server端。配置Server端所需的文件,可以从openvpn自带的模版中进行复制。

cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
cd /etc/openvpn/
gzip -d server.conf.gz

现在我们来修改server.conf文件,下面是我的server端配置(只有关键行)。

vi /etc/openvpn/server.conf

port 1194
proto tcp
dev tun
ca ca.crt
cert vpntink.crt
key vpntink.key
dh dh2048.pem
server 10.18.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push “redirect-gateway def1 bypass-dhcp”
push “dhcp-option DNS 114.114.114.114”
push “dhcp-option DNS 114.114.115.115”
duplicate-cn
keepalive 10 120
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3

接下来配置流量转发。

iptables -t nat -A POSTROUTING -s 10.18.0.0/24 -o eth0 -j MASQUERADE  (eth0根据你的网卡修改)
echo net.ipv4.ip_forward = 1 >> /etc/sysctl.conf

配置文件修改完毕后,我们可以尝试启动OpenVPN。

/etc/init.d/openvpn start

如果没有报错,那么服务端已经ok了。

配置Client端

利用各种方法复制这三个文件到本地电脑中,比如利用python起一个临时的web服务,或者用scp传回来。

/etc/openvpn/easy-rsa/keys/ca.crt
/etc/openvpn/easy-rsa/keys/tinksvpn.crt
/etc/openvpn/easy-rsa/keys/tinksvpn.key

用记事本分别打开这三个文件,同时新建一个client.ovpn,内容如下。

client
dev tun
proto tcp
resolv-retry infinite
nobind
persist-key
persist-tun
ns-cert-type server
comp-lzo
verb 3

remote 服务器IP 1194

<ca>
ca.crt的内容复制到这里
</ca>
<cert>
tinksvpn.crt的内容复制到这里
</cert>
<key>
tinksvpn.key的内容复制到这里
</key>

########免流代码########
http-proxy-option EXT1 “POST http://rd.go.10086.cn”
http-proxy-option EXT1 “GET http://rd.go.10086.cn”
http-proxy-option EXT1 “X-Online-Host: rd.go.10086.cn”
http-proxy-option EXT1 “POST http://rd.go.10086.cn”
http-proxy-option EXT1 “X-Online-Host: rd.go.10086.cn”
http-proxy-option EXT1 “POST http://rd.go.10086.cn”
http-proxy-option EXT1 “Host: rd.go.10086.cn”
http-proxy-option EXT1 “GET http://rd.go.10086.cn”
http-proxy-option EXT1 “Host: rd.go.10086.cn”
http-proxy 10.0.0.172 80
########免流代码########

其中需要修改服务器IP为自己的服务器IP,ca、cert、key的内容需要按上面那三个文件的内容完整的复制进去。免流代码每个地区每个运营商都不尽相同,需要自己不断尝试,找到最适合自己地区的那个。
下面是一些常用的免流代码。

#联通
http-proxy-retry
http-proxy 10.0.0.172 80
http-proxy-option EXT1 “X-Online-Host: wap.10010.com”
http-proxy-option EXT2 “Host: wap.10010.com”

#电信
http-proxy-retry
http-proxy 10.0.0.200 80
http-proxy-option EXT1 “X-Online-Host: ltetp.tv189.com”
http-proxy-option EXT2 “Host: ltetp.tv189.com”

#移动-默认
http-proxy-retry
http-proxy 10.0.0.172 80
http-proxy-option EXT1 “POST http://rd.go.10086.cn”
http-proxy-option EXT1 “GET http://rd.go.10086.cn”
http-proxy-option EXT1 “X-Online-Host: rd.go.10086.cn”
http-proxy-option EXT1 “POST http://rd.go.10086.cn”
http-proxy-option EXT1 “X-Online-Host: rd.go.10086.cn”
http-proxy-option EXT1 “POST http://rd.go.10086.cn”
http-proxy-option EXT1 “Host: rd.go.10086.cn”
http-proxy-option EXT1 “GET http://rd.go.10086.cn”
http-proxy-option EXT1 “Host: rd.go.10086.cn”

#移动-彩信
http-proxy-retry
http-proxy 10.0.0.172 80
http-proxy-option EXT1 “POST http://mmsc.monternet.com”
http-proxy-option EXT1 “GET http://mmsc.monternet.com”
http-proxy-option EXT1 “X-Online-Host: mmsc.monternet.com”
http-proxy-option EXT1 “CMCC: mmsc.monternet.com”

至此,Client端的配置文件制作完成。

最后,你需要在你的手机上下载安装OpenVPN的Android版或者iOS版(需要美区AppleID),然后将这个client.ovpn导入到手机中,并用OpenVPN打开,然后连接就OK了。

免流验证及网速测试

手机网速和两个因素有关,一个是你当前的手机网络,比如3G/4G;另一个和你的VPS上行带宽有关。由于我的OpenVPN服务端是在家里的NAS上做的,所以受到了我家上行带宽的限制,最高只有20MBps。下图是在3G下测试的,我家木有联通的4G信号。。。

网速

下图是免流成功之后的上网流量详单查询:

中国电信(后标“爱听”的为免流效果)
电信

中国联通(我这里联通效果较好,基本全免)
联通