Total Pageviews

Sunday, 3 January 2016

在OpenWrt路由器上,安装最新版的shadowsocks,自动的路由翻墙

路由翻墙成功,颇有一种装修时把墙砸掉,瞬间阳光照进来的感觉。
之前入手了一个安装openwrt的路由(OYE-0001路由器),一直有是实现路由翻墙的想法,确碍于懒惰,一直没有实施。
开始折腾路由翻墙的方法。
最初参照网上找的这个教程: https://www.gitbook.io/book/softwaredownload/openwrt-fanqiang
折腾到后半夜,google翻墙没问题。但是facebook和twitter翻墙依然不行,发现是防DNS劫持没配置好。
原想今天继续配置,没想到回来后,发现路由莫名其妙的上不了网。只好还原出厂状态。重新下载shadowsocks-libev的安装包。
搜索排名较高的shadowsocks网站:http://shadowsocks.org/en/download/clients.html
由于我的路由是MT7620A的处理器,且ssl包依赖openssl。上面网站并没有提供oepnssl版本的shadowsocks。之前是通过百度网盘找的一个,目前找不到了。在寻觅过程中,发现了一个shadowsocks-dist的项目。有各种版本编译好的shadowsocks。太棒了。
可以看到有各种版本的shadowsocks。 首先选最新版本的,然后发现同样依赖包,同样CPU的竟然有两种版本,下面找到了解释说明。
shadowsocks-libev 为官方原版
包含 ss-{local,redir,tunnel} 三个可执行文件
默认启动 ss-local 建立本地 SOCKS 代理
shadowsocks-libev-spec 为针对 OpenWrt 路由器的优化版本
包含 ss-{redir,rules,tunnel} 三个可执行文件
ss-redir 建立透明代理, ss-tunnel 做 DNS 查询转发
ss-tunnel 默认转发 127.0.0.1:5353 至 8.8.4.4:53
通过 ShadowSocks 服务器查询 DNS 用于线路优化
ss-rules 可设置 ignore.list 中的 IP 流量不走代理
ss-rules 可支持 ipset 和 iptables 两种转发规则
默认使用性能更好的 ipset 规则, 对不支持的设备使用 iptables
果断使用shadowsocks-libev-spec版本,墙是在升级的,工具同步到最新还是好的。 针对我的路由CPU和依赖包,我选择了shadowsocks-libev-spec1.4.7-2ramips_24kec.ipk (MT7620A的CPU选ramips版本)
继续下面之前,首先你要有自己的shadowsocks账号,没有的可以淘宝,可以自己VPS搭建。VPS安装shadowsocks参照:http://softwaredownload.gitbooks.io/openwrt-fanqiang/ebook/03.2.html
由于shadowsocks升级了,使用方法也简单了,这里我就直说路由安装最新版的shadowsocks,其余都可以参照上面的教程。
1.通过winscp把shadowsocks-libev文件放到路由的/root/tmp/下。
2.ssh登录到到路由器(windows用户通过putty),安装shadowsocks-libev。
cd /var/tmp; opkg shadowsocks-libev-spec1.4.7-2ramips_24kec.ipk
3.配置shadowsocks文件。shadowsocks配置文件是/etc/shadowsocks/config.json。 
{
"server":"[服务器IP地址]",
"serverport":[服务器端口],
"local
port":[本地端口,稍后iptables会用到],
"password":"[密码]",
"timeout":1500(大一点,翻墙过程几次dns查询用时挺长),
"method":"[加密方式]"
这里看到的/etc/shadowsock/ignore.list是翻墙的规则文件,最新版的ignore.list文件已经够用,有需要的自己去看项目吧。 github地址https://github.com/aa65535/openwrt-shadowsocks
4.启动shadowsocks。 
/etc/init.d/shadowsocks start 
shadowsocks常用命令 
/etc/init.d/shadowsocks start //启动
/etc/init.d/shadowsocks stop //停止
/etc/init.d/shadowsocks enable //设置开机启动
/etc/init.d/shadowsocks disable //取消开机启动
5.打开浏览器,愉快的浏览twitter,facebook吧。
最新版的shadowsocks在openwrt路由上配置就是这么简单,没有繁琐的防dns污染配置,也没有手动配置iptable,也没有自己修改脚本。各位手里有openwrt路由的同学,欢快的上吧.
----------
相关帖子:http://briteming.blogspot.com/2015/02/openwrtdns.html
-------------

使用路由器自动翻墙

目前来说用得最稳定的当属Shadowsocks。刚开始的时候只是在一个 Shadowsocks 服务提供商处购买了一个账号,在我的 Macbook 上试用,后面发现翻墙速度快且稳定,就萌生了在路由器上安装 Shadowsocks 的想法,正好家中的主路由器是 EdgeRouter Lite 3(Unix 架构,完美!),于是:Let’s do it!

概述

在搜索引擎中输入Shadowsocks+路由器关键字,可以搜索出很多安装教程,采用的方案也不尽相同,建议不想太折腾的话就买一个可以刷 OpenWRT 的路由器,按照这个博客(https://cokebar.info/archives/978)的教程安装配置就可以了。如果你和我一样入了 EdgeRouter 的坑,那我们继续~。
我采用的方案是使用 Shadowsocks + ChinaDNS + DNSMasq + iptables 来实现路由器智能翻墙,即国内流量走正常网络,国外流量走 Shadowsocks 代理,总体流程如下图:
流程图

所需软件

shadowsocks-libev

项目地址:https://github.com/shadowsocks/shadowsocks-libev,可下载源码在路由器上进行编译,或者直接下载安装包,请注意这个安装包只适用于 EdgeRouter Lite 3,其他 EdgeMax 产品需要自行编译。

ChinaDNS

项目地址:https://github.com/shadowsocks/ChinaDNS,可下载源码在路由器上进行编译,或者直接下载安装包,请注意这个安装包只适用于 EdgeRouter Lite 3,其他 EdgeMax 产品需要自行编译。

DNSMasq

EdgeMax 中已经集成了 DNSMasq 无需另外安装。

配置

shadowsocks-libev

shadowsocks-libev 安装好后,会在/etc/init.d/中安装一个启动脚本:shadowsock-libev,在路由器启动时会默认启动ss-redir服务,如果需要重启 Shadowsocks,可以使用命令:sudo /etc/init.d/shadowsock-libev [start|stop|restart]。Shadowsocks 的配置在文件/etc/shadowsocks-libev/config.json中,在这个文件中配置 Shadowsocks 需要链接的服务器信息:

{
"server":"127.0.0.1",
"server_port":8388,
"local_address": "0.0.0.0",
"local_port":1080,
"password":"barfoo!",
"timeout":60,
"method":null
}
配置完成后,sudo /etc/init.d/shadowsock-libev restart,这样 Shadowsocks 就在你的路由器上运行了。

ChinaDNS

使用源码编译后,会生成一个二进制文件:chinadns,可以将这个文件复制到/usr/bin中方便后面使用。ChinaDNS 需要一个文件来标识哪些 IP 属于国内,这个文件可以从这里下载

# 下载 ip 列表到: /tmp/chnroute.txt
curl 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | grep ipv4 | grep CN | awk -F| ‘{ printf(“%s/%dn”, $4, 32-log($5)/log(2)) }’ > /tmp/chnroute.txt
下载完成后,将文件移动到/etc/chinadns/chnroute.txt,接着我们就可以尝试启动 ChinaDNS 了:

chinadns -s 223.5.5.5,223.6.6.6,127.0.0.1:5300 -c /etc/chinadns/chnroute.txt -p 35353 -m
需要注意的是-s参数后面的127.0.0.1:5300,这个代表将ss-tunnel转发的国外可信DNS站点作为上游DNS服务器。

ChinaDNS参数详解

  • -l:虚假IP列表:默认值:/etc/chinadns_iplist.txt
是GFW常见的DNS污染用IP列表,解析出列表中的IP结果时候,ChinaDNS会自动抛弃,保留默认即可;
  • -c:chnroute文件:默认值:/etc/chinadns_chnroute.txt
此文件标识哪些IP属于国内。用于ChinaDNS判断解析结果。ChinaDNS要求解析结果与DNS要匹配,国内网站采用国内DNS解析的结果,国外网站采用国外DNS解析结果,等等规则;确保以上两个文件内容完整无误,否则会造成无法启动;
  • -p:本地端口:默认值:5353
ChinaDNS所监听的端口。根据实际情况更改,注意不能和其他服务的端口重复(特别是DNSMasq和shadowsocks);
  • -s: 上游服务器:默认值:114.114.114.114,8.8.8.8
可填入一系列的上游DNS服务器,根据实际情况来,可以保留默认,格式为”DNS_IP:PORT,DNS_IP:PORT”注意逗号后面不能有空格。有些ISP会封杀公共DNS,此时请将114DNS改为ISP的DNS;此处必须至少填入一个国内IP的DNS和一个国外IP的DNS,否则会造成ChinaDNS启动失败。额外的用法:ChinaDNS添加可信DNS避免一些异常
  • -y:等待时间: 默认值:0.3
为防止GFW的DNS污染抢答,而设置一个等待时间,请根据自己填写的国外DNS延迟值来填写,留下一定的裕度。GoogleDNS在国内延迟一般在100-200ms,留0.3比较合适。过大的值会造成DNS解析较大的延迟时间,过小的值可能导致无法接收正确的解析结果。
  • -d:双向过滤: 默认:开启
勾选时,当国外DNS服务器返回的查询结果是国内IP,或者当国内DNS服务器返回的查询结果是国外IP,则过滤掉这个结果(较为严格的模式);去掉勾选的话只是过滤国内DNS的国外IP结果。
  • -m:启用压缩指针: 默认:不开启
利用GFW遇到压缩指针时的一个bug来精确识别来自GFW的抢答污染,从而极大提高识别的准确性和识别的效率,推荐启用,启用后,IPList和等待时间将禁用(因为用不到了)。 (已强制开启)

ss-tunnel

ss-tunnel 是 Shadowsocks 的一个模块,可以用于 UDP 转发,为了防止 GFW 的 DNS 污染,我们用它来转发国外 DNS,可以通过下面命令来启动 ss-tunnel:

ss-tunnel -c /etc/shadowsocks-libev/config.json -u -b 0.0.0.0 -l 5300 -L 8.8.8.8:53
为了让 ss-tunnel 在每次重启路由器的时候自动重启,我们可以写个脚本放在/config/scripts/post-config.d目录下。

DNSMasq

首先需要将系统的 DNS 服务器设置为本地

configure
# 停止通过pppoe更新dns设置,如果pppoe绑定在其他网口上,eth0需要变更为对应网口
set interfaces ethernet eth0 pppoe 0 name-server none

# 设置 DNSMasq 使用 ChinaDNS
# 需要注意的是,这里无法设置服务器端口,只能先这样设置后,再手工变更配置文件
edit service dns forwarding
set name-server 127.0.0.1

# 告诉路由器使用本地 DNSMasq 来解析域名
set system name-server 127.0.0.1

commit
save
exit
修改/etc/dnsmasq.conf,去除你之前自定义的规则,在最后加入conf-dir=/etc/dnsmasq.d,并将server=127.0.0.1修改为server=127.0.0.1#35353。新建并进入目录/etc/dnsmasq.d,下载 accelerated-domains.china.confforeign_list.conf两个文件后复制两个文件到/etc/dnsmasq.d目录。这两个文件都会有更新,建议隔段时间更新一下。分别修改两个文件,将accelerated-domains.china.conf(ChinaList)文件中所有的的114.114.114.114修改为自己ISP的DNS或者其他效果更好的国内DNS的IP地址(也可以保留114DNS),格式为:server=/0-6.com/IP;将foreign_list.conf(GFWList)文件中所有的 127.0.0.1#5300 修改为自己所用国外DNS,格式为:server=/.lsxszzg.com/IP#PORT,如果你使用shadowsocks的UDP转发来提供国外DNS解析,UDP转发的端口号为5300,那么就是默认的 127.0.0.1#5300 ,如果你使用一个非标端口的国外DNS服务,如3.4.5.6,端口5353,那么就改为 3.4.5.6#5353 。注意不要使用国外公共DNS,因为会被污染!最后重启 dnsmasq:

sudo /etc/init.d/dnsmasq restart

iptables

上面所做的一切都是为了防止 GFW 的 DNS 污染,从而拿到正确的 IP 地址,那么拿到 IP 地址后,又如何将国外的流量转发到 Shadowsocks 呢?现在该 iptables 登场了,使用下面的代码设置 iptables 转发规则:

# Setup the ipset
ipset -N chnroute hash:net maxelem 65536

for ip in $(cat '/etc/chinadns/chnroute.txt'); do
  ipset add chnroute $ip
done

# 其他请求:
# shadowsocks
iptables -t nat -N SHADOWSOCKS

iptables -t nat -A SHADOWSOCKS -p tcp --dport 23596 -j RETURN
# 23596 是 ss 代理服务器的端口,即远程 shadowsocks 服务器提供服务的端口,如果你有多个 ip 可用,但端口一致,就设置这个
iptables -t nat -A SHADOWSOCKS -d 123.456.789.111 -j RETURN
# 123.456.789.111 是 ss 代理服务器的 ip, 如果你只有一个 ss服务器的 ip,却能选择不同端口,就设置此条

# ignore internal ip
iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN

# ignore asia ip

# Allow connection to chinese IPs
iptables -t nat -A SHADOWSOCKS -p tcp -m set --match-set chnroute dst -j RETURN

iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 1080
iptables -t nat -I PREROUTING -p tcp -j SHADOWSOCKS
iptables 配置完后,你应该可以再浏览器中正常的打开 Google 首页了。

一键式 DNS 配置脚本

使用下面的脚本可以在重启路由器时(需要将脚本放在/config/scripts/post-config.d目录下)更新foreign_list.confaccelerated-domains.china.conf两个文件,并配置好 iptables:

#!/bin/sh

deleteFile() {
  local filePath=$1
  if [ -f "$filePath" ]; then
   rm "$filePath"
  fi
}
# get chinadns ignore list
updateChnroute() {
  deleteFile /tmp/chnroute.txt

  curl 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' >  /tmp/chnroute.txt
  mv -f /tmp/chnroute.txt /etc/chinadns/
  chmod 644 /etc/chinadns/chnroute.txt

  if pidof chinadns>/dev/null; then
      /etc/init.d/chinadns restart
  fi
}

updateDnsmasqConf() {
  deleteFile /tmp/accelerated-domains.china.conf
  # download accelerated-domains.china.conf
  local DNS=223.5.5.5
  curl 'https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf' > /tmp/accelerated-domains.china.conf
  sed -i "s|^\(server.*\)/[^/]*$|\1/$DNS|"  /tmp/accelerated-domains.china.conf
  mv -f /tmp/accelerated-domains.china.conf /etc/dnsmasq.d/
  chmod 644 /etc/dnsmasq.d/accelerated-domains.china.conf

  # download foreign_list.conf
  python ../gfwlist2dnsmasq_noipset.py

  if pidof dnsmasq>/dev/null; then
      /etc/init.d/dnsmasq restart
  fi
}


configIptables() {
  # Setup the ipset
  ipset -N chnroute hash:net maxelem 65536

  for ip in $(cat '/etc/chinadns/chnroute.txt'); do
    ipset add chnroute $ip
  done

  # 其他请求:
  # shadowsocks
  iptables -t nat -N SHADOWSOCKS

  iptables -t nat -A SHADOWSOCKS -p tcp --dport 33348 -j RETURN
  iptables -t nat -A SHADOWSOCKS -d 103.192.224.122 -j RETURN

  # ignore internal ip
  iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
  iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
  iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
  iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
  iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
  iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
  iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
  iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN

  # ignore asia ip

  # Allow connection to chinese IPs
  iptables -t nat -A SHADOWSOCKS -p tcp -m set --match-set chnroute dst -j RETURN

  iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 1080
  iptables -t nat -I PREROUTING -p tcp -j SHADOWSOCKS
}

updateChnroute
updateDnsmasqConf
configIptables
gfwlist2dnsmasq_noipset.py:
#!/usr/bin/env python
#coding=utf-8
#
# Generate a list of dnsmasq rules with ipset for gfwlist
#
# Copyright (C) 2014 http://www.shuyz.com
# Ref https://code.google.com/p/autoproxy-gfwlist/wiki/Rules

import urllib2
import re
import os
import datetime
import base64
import shutil
import ssl

mydnsip = '127.0.0.1'
mydnsport = '5300'
# Extra Domain;
EX_DOMAIN=[ \
'.google.com', \
'.google.com.hk', \
'.google.com.tw', \
'.google.com.sg', \
'.google.co.jp', \
'.google.co.kr', \
'.blogspot.com', \
'.blogspot.sg', \
'.blogspot.hk', \
'.blogspot.jp', \
'.blogspot.kr', \
'.gvt1.com', \
'.gvt2.com', \
'.gvt3.com', \
'.1e100.net', \
'.blogspot.tw' \
]

# the url of gfwlist
baseurl = 'https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt'
# match comments/title/whitelist/ip address
comment_pattern = '^\!|\[|^@@|^\d+\.\d+\.\d+\.\d+'
domain_pattern = '([\w\-\_]+\.[\w\.\-\_]+)[\/\*]*'
ip_pattern = re.compile(r'\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b')
tmpfile = '/tmp/gfwlisttmp'
# do not write to router internal flash directly
outfile = '/tmp/dnsmasq_list.conf'
rulesfile = '/etc/dnsmasq.d/foreign_list.conf'

fs =  file(outfile, 'w')
fs.write('# gfw list ipset rules for dnsmasq\n')
fs.write('# updated on ' + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + '\n')
fs.write('#\n')

print 'fetching list...'
if hasattr(ssl, '_create_unverified_context'):
truessl._create_default_https_context = ssl._create_unverified_context
content = urllib2.urlopen(baseurl, timeout=15).read().decode('base64')

# write the decoded content to file then read line by line
tfs = open(tmpfile, 'w')
tfs.write(content)
tfs.close()
tfs = open(tmpfile, 'r')

print 'page content fetched, analysis...'

# remember all blocked domains, in case of duplicate records
domainlist = []


for line in tfs.readlines():
trueif re.findall(comment_pattern, line):
truetrueprint 'this is a comment line: ' + line
truetrue#fs.write('#' + line)
trueelse:
truetruedomain = re.findall(domain_pattern, line)
truetrueif domain:
truetruetruetry:
truetruetruetruefound = domainlist.index(domain[0])
truetruetruetrueprint domain[0] + ' exists.'
truetruetrueexcept ValueError:
truetruetruetrueif ip_pattern.match(domain[0]):
truetruetruetruetrueprint 'skipping ip: ' + domain[0]
truetruetruetruetruecontinue
truetruetruetrueprint 'saving ' + domain[0]
truetruetruetruedomainlist.append(domain[0])
truetruetruetruefs.write('server=/.%s/%s#%s\n'%(domain[0],mydnsip,mydnsport))
truetrueelse:
truetruetrueprint 'no valid domain in this line: ' + line

tfs.close()

for each in EX_DOMAIN:
truefs.write('server=/%s/%s#%s\n'%(each,mydnsip,mydnsport))

print 'write extra domain done'

fs.close();
print 'moving generated file to dnsmasg directory'
shutil.move(outfile, rulesfile)

print 'done!'
-------------------------------

基于OpenWrt路由器的全自动翻墙方案

此方案DNS部分已经失效,请参考https://github.com/felixonmars/dnsmasq-china-list
这个全自动翻墙方案有如下特点:
  • 本方案基于路由器,所以任何连接该路由器的主机都可以自动翻墙。
  • 本方案使用shadowsocks翻墙,速度优于VPN和SSH。
  • 本方案基于目标IP的地理位置,决定是直接连接目标IP还是翻墙连接。对于所有中国IP会直接连接,所以不影响访问国内网站的速度。即使是根据DNS查询做优化的网站也不会有影响,因为该方案优先使用国内DNS服务器的结果。所有非中国的IP都会选择翻墙连接。有人觉得这样不是最有效率的因为不是所有国外IP都是被封的,但是我觉得凡是流过GFW的流量,都要翻墙加密才是安全的,否则就有可能遭遇各种不幸。
  • 这个方案最大优点是可以使你完全感觉不到GFW的存在,这会使你的上网习惯有很大的变化。
  • 缺点是UDP包不能翻墙。这是Shadowsocks的特性决定的。
准备工作
  • 在路由器上安装OpenWrt。OpenWrt支持这些硬件。以TP-LINK TL-WDR4300为例,在硬件列表上可以找到它的链接,点击后有详细的安装步骤。
    • 配置OpenWrt可以正常上网。这里有刚安装完成第一次登录的帮助。这里有基本配置帮助。
    • 准备一台安装了Shadowsocks的国外服务器。如果没有的话,可以去任何VPS提供商那里买一台最廉价的VPS,在上面装上shadowsocks。安装步骤在这里有。
    • 要会用基本的VI编辑器操作,会最简单的打开编辑保存功能就可以了。
    翻墙方案安装步骤
    • 远程登录OpenWrt路由器。如果不知道如何登录,看之前的第一次登录帮助。
    • 编辑/etc/init.d/dnsmasq文件,在一堆append_bool开始的行中间,加如下这一行: append_bool "$cfg" allservers "--all-servers"
    • 编辑/etc/config/dhcp添加如下一行          option allservers '1'
    • 编辑/etc/config/network文件,在wan配置(config interface 'wan')中,国外公开DNS服务器(比如8.8.8.8,8.8.4.4,208.67.222.222等)加入DNS 服务器的列表,放在ISP提供的DNS服务器后面(ISP提供DNS可以在/tmp/resolv.conf.ppp 文件中看到),比如:(这里180.168.255.18是ISP提供的DNS。) config interface 'wan'         option peerdns    '0'         option dns '180.168.255.18 8.8.4.4 208.67.222.222'
    • 重启网络 # /etc/init.d/network restart
    • 下载安装ShadowSocks for OpenWrt。在这里(可能需要翻墙才能打开)可以找到源代码和编译好的安装包(只支持部分架构)。比如我的路由器是ar71xx架构,直接下载编译好的shadowsocks-libev-polarssl_1.4.6_ar71xx.ipk就可以了,可以运行:
    # wget  http://shadowsocks.org/nightly/shadowsocks-libev-polarssl_1.4.6_ar71xx.ipk # opkg  update # opkg  install  libpolarssl # opkg  install  shadowsocks-libev-polarssl_1.4.6_ar71xx.ipk
    • 尝试在路由器上运行ss-redir命令,如果打印出一堆帮助信息,说明安装正确了。如果打印出类似下面找不到链接库的错误:
    # ss-redir ss-redir: can't load library 'libpolarssl.so.5' 
    这时就需要创建一个符号链接来解决这个问题:
    # cd /usr/lib #  ln -s libpolarssl.so.1.3.4 libpolarssl.so.6
    • 配置shadowsocks。编辑配置文件/etc/config/shadowsocks.json,将shadowsocks服务器参数写在这个配置文件里面。修改/etc/init.d/shadowsocks,把所有ss-local替换为ss-redir。
    • 然后重启shadowsocks。
    # /etc/init.d/shadowsocks enable # /etc/init.d/shadowsocks restart
    • 安装iptables nat-extra、geoip和u32模块。
    # opkg update # opkg install iptables-mod-geoip # opkg install iptables-mod-nat-extra # opkg install iptables-mod-u32 
    • 生成IP国家信息数据库。在某台Mac或者Linux上下载并解压缩xtables-addons源码,然后按照这篇文档的步骤生成IP数据库。
    • 将中国的IP信息(CN开始的文件)拷贝到路由器/usr/share/xt_geoip/BE或者/usr/share/xt_geoip/LE。是BE还是LE取决于你的路由器的CPU架构是Big Endian还是Little Endian。如果你不确定你的路由器是什么架构类型,可以两个目录都放进去。
    • 将如下防火墙规则写入 /etc/firewall.user 。前面一半用以将TCP流量重定向到shadowsocks,后面一半用来解决DNS污染。粗体部分替换为你的shadowsocks的服务器地址和ShadowSocks本地端口(默认1080)。
    iptables -N fuckgfw -t nat iptables -F fuckgfw -t nat #bypass DNS servers iptables -A fuckgfw -t nat -p tcp -d 8.8.8.8 -j RETURN iptables -A fuckgfw -t nat -p tcp -d 8.8.4.4 -j RETURN iptables -A fuckgfw -t nat -p tcp -d 208.67.222.222 -j RETURN iptables -A fuckgfw -t nat -p tcp -d 208.67.220.220 -j RETURN #bypass local connections iptables -A fuckgfw -t nat -p tcp -d 192.168.0.0/16 -j RETURN iptables -A fuckgfw -t nat -p tcp -d 172.16.0.0/12 -j RETURN iptables -A fuckgfw -t nat -p tcp -d 10.0.0.0/8 -j RETURN iptables -A fuckgfw -t nat -p tcp -d 127.0.0.0/8 -j RETURN #bypass iOS notification, PPTP and other connections iptables -A fuckgfw -t nat -p tcp -d 17.0.0.0/8 --dport 5223 -j RETURN #iOS notification iptables -A fuckgfw -t nat -p tcp --dport 1723 -j RETURN #PPTP connection #Redirect all others to Shadowsocks iptables -A fuckgfw -t nat -p tcp -j REDIRECT --to-port  #goto fuckgfw chain if the destination is not China IP iptables -A prerouting_rule -t nat -m geoip -p tcp ! --destination-country CN -j fuckgfw 
    iptables -N dnsfilter -t mangle iptables -F dnsfilter -t mangle iptables -t mangle -I dnsfilter -p udp -m udp -m u32 --u32 "0&0x0F000000=0x05000000 && 22&0xFFFF@16=0x00000000,0x042442b2,0x0807c62d,0x253d369e,0x2e52ae44,0x3b1803ad,0x3cbf7cec,0x402158a1,0x4021632f,0x4042a3fb" -j DROP iptables -t mangle -I dnsfilter -p udp -m udp -m u32 --u32 "0&0x0F000000=0x05000000 && 22&0xFFFF@16=0x4168cafc,0x41a0db71,0x422dfced,0x480ecd63,0x480ecd68,0x4a7d2771,0x4a7d7f66,0x4a7d9b66,0x4e10310f,0x5d2e0859" -j DROP iptables -t mangle -I dnsfilter -p udp -m udp -m u32 --u32 "0&0x0F000000=0x05000000 && 22&0xFFFF@16=0x80797e8b,0x9f6a794b,0xa9840d67,0xb4a829af,0xc043c606,0xca6a0102,0xcab50755,0xcb620741,0xcba1e6ab,0xcf0c5862" -j DROP iptables -t mangle -I dnsfilter -p udp -m udp -m u32 --u32 "0&0x0F000000=0x05000000 && 22&0xFFFF@16=0xd0381f2b,0xd1244921,0xd155e58a,0xd1913632,0xd1dc1eae,0xd35e4293,0xd5a9fb23,0xd8ddbcb6,0xd8eab30d,0xf3b9bb1e" -j DROP iptables -t mangle -I dnsfilter -p udp -m udp -m u32 --u32 "0&0x0F000000=0x05000000 && 22&0xFFFF@16=0xf3b9bb27,0xffffffff,0x4a7d2766" -j DROP iptables -t mangle -I PREROUTING -m udp -p udp --sport 53 -j dnsfilter
    • 重启firewall
    # /etc/init.d/firewall restart
    • 这时可以测试自动翻墙功能是否工作。可以打开这个网页看看现在IP是不是你的国外ShadowSocks服务器的IP。然后打开这个网页看显示的是不是ISP提供的国内IP地址。测试是否能打开facebook和youtube。如果都可以,大功告成!
    变化
    • 可以用SSH Tunnel代替ShadowSocks。优点是国外的SSH服务器更容易找到,缺点是速度不如ShadowSocks。
    • 可以用VPN代替Shadowsocks。优点是UDP也能翻墙,缺点是,速度较慢,配置比较复杂。
    • 可以在ShadowSocks之上架设HTTP Proxy(比如polipo),然后在浏览器和其它应用中手动配置代理翻墙。
      • 可以配置自动代理发现,让浏览器不复杂配置就可以自动翻墙。路由器上添加一个主机名wpad,指向路由器的IP。在路由器 /www/ 目录下添加一个wpad.dat文件,内容类似:
    function FindProxyForURL(url,host) {     if( isPlainHostName(host) ||         isInNet(host, "10.0.0.0", "255.0.0.0") ||         isInNet(host, "192.168.0.0", "255.255.0.0") ||         isInNet(host, "127.0.0.0", "255.0.0.0") ||         dnsDomainIs(host, ".cn")     )  return "DIRECT;";     return "SOCKS 192.168.1.1:1080; PROXY 192.168.1.1:3128;"; 
        //shadowsocks地址和http代理地址 }
      • IE、Mac或者iPhone上都可以打开自动代理配置选项来自动发现这个配置。
      • 可以在ShadowSocks和Http代理之间,加一个 smartproxy: https://github.com/ch3n2k/smartproxy ,功能类似iptables geoip,让目标IP是国外的走上层ShadowSocks,否则就直连。