Total Pageviews

Thursday, 7 April 2016

Netgear WNDR4300路由器翻墙手册(openwrt+shadowsocks)


该文仅仅适合程序员阅读,除非你至少明白什么是telnet和ssh,否则就去找更适合的教程吧

1.背景介绍:什么是gfw

gfw的定义可以参见维基百科。最直观的感受,就是google,facebook等一票网站访问不了。但是作为程序员,我们有必要知道为什么这些网站访问不了?当然这些网站被阻止访问了,但是是如何阻止的??
作为程序员,你可能会首先想到,不就是这个网站ip被阻止访问了嘛。但实际上,这只是原因之一,gfw手段中最不起眼的一个。因为google和facebook这样的大公司有成千上万的ip,且每天都在变化,因此,封ip根本来不及。其实,更大的原因是:DNS污染
来做个实验(在家中,在单位代理上网的情况下无法进行),调出终端,打入以下命令
nslookup twitter.com
nslookup是用来查看某个域名真实ip的命令
各系统返回稍有不同,但基本上都是如下:
Server: 172.25.23.1
Address: 172.25.23.1#53
Non-authoritative answer:
Name: twitter.com
Address: 37.61.54.158
可以看到twitter.com被解析到了37.61.54.158,如果进一步用whois跟踪,你会发现这个地址的详细信息






keyvalue
IP LocationAzerbaijan Azerbaijan Bakixanov Baktelekom
ASNAzerbaijan AS28787 BAKINTER-AS Baktelekom,AZ (registered Feb 24, 2003)
Whois Serverwhois.ripe.net
IP Address37.61.54.158
那么问题来了,你觉得twitter.com这样的公司,会使用一个阿塞拜疆的ip地址吗,这就是问题所在,gfw把要屏蔽的网站的域名都解析到了类似于37.61.54.158这样的空地址上,且在你家的宽带,手机等等所有设备上蔓延。
程序员可能会想到,不是可以指定dns地址嘛,我用第三方的dns是不是就没有问题了,那我们再来做个实验
nslookup twitter.com 8.8.8.8
nslookup可以指定第二个参数,强制使用这个dns解析
8.8.8.8是google提供的公共dns服务
但返回结果依然是
Non-authoritative answer:
Name: twitter.com
Address: 37.61.54.158
这是为什么,还是这个地址。原因是dns使用的是udp的协议,基本逻辑是本机先发往本机的53端口进行查询,如果本机不知道,就向dns查询,依次向上。upd协议是不建立连接的,且是明文传递,非常容易被伪造。gfw就利用了这一点,你发向8.8.8.8的dns查询,gfw先给你一个假回执,就诱骗了你的机器。(实际上,8.8.8.8的回执稍后也会到来,但是本机会认为已经拿到回执,就把它忽略了)
其实从这里就可以看出,在一些公共wifi下,如果你忽略证书有问题的警告,被钓鱼是一件多么容易的事情,亲们
程序员可能会想,那有没有办法用tcp协议查询,答案是肯定的:
nslookup -vc twitter.com 8.8.8.8
你会得到如下应答
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
Name: twitter.com
Address: 199.59.150.7
Name: twitter.com
Address: 199.59.150.39
Name: twitter.com
Address: 199.59.149.198
Name: twitter.com
Address: 199.59.149.230
这才是真实的ip
亲们看完是不是一身冷汗,其实网络世界确实挺可怕的,小白被骗钱简直分分钟的事情,所以,程序员们有必要学习有关知识

开始我们的实践吧,基于以上的认识,我们要科学上网,至少需要做两件事情

  • 解决ip被阻断问题
  • 解决dns污染问题

我们的使用的方法:将被墙的站点通过dnsmasq+ipset打标记,然后通过iptables的路由功能将这些ip通过shadowsocks转发出去,其中这些名词,下面一步一步做完,你就会熟悉


2.准备工作

  • 我们需要一个shadowsocks服务帐号,用来通过加密通道访问网站。我目前使用的http://my.ssh91.net 的服务,一个月10RMB,可以流畅看720p的youtube。购买后,会收到确认邮件,内含密码等信息。几个节点自己选一个,我目前使用ss02台湾节点。
  • 一台路由器,理论上能刷openwrt的内存足够的路由器都可,但这里针对Netgear wndr4300写的。我在京东活动时购买的,299RMB
  • 一个adsl上网环境,或者静态ip的也可以,再复杂的上网认证方式,我就不保证有效了
  • 一根网线,openwrt刚刷好时,是关闭wifi的,只能通过网线连接
  • 没有了

3.刷新ROM

首先从openwrt官网下载适合wndr4300的rom,openwrt的官网下载地址是:http://downloads.openwrt.org , 在写该文时,最新的版本是14.07,因此对应的下载地址是http://downloads.openwrt.org/barrier_breaker/14.07/ar71xx/nand/openwrt-ar71xx-nand-wndr4300-ubi-factory.img ,注意一定不能下载错了,否则就变砖了。下载好了之后,就可以通过路由器控制台的系统更新,将该ROM刷进去。正常情况下,路由器自动重启后,就刷新完毕了。
这里要注意一下,带有factory的版本是从官方固件升级时使用的,而带有sysupgrade标志的,是给已经刷了openwrt的用户升级用的

4.设置openwrt上网环境

刚刷好openwrt,系统默认关闭了wifi,只能通过网线连接。插好网线,浏览器输入http://192.168.1.1
即可进入控制台。默认的用户名为root,密码为空,因此直接点击login就可以进入了。进入后,注意到上半部分有change password的提示,点击进入后,就可以设置新的登录密码。设置时,只需要填写好密码并点击Save & Apply保存幷应用设置即可。
登录密码设置后,默认系统终端就从telnet转为了ssh登录方式
设置好之后,重新进入http://192.168.1.1 ,就来到了主界面。主界面显示的都是当前路由器的状态。接下来我们设置wifi。找到wireless部分,应该可以看到两个disabled的节点。上面一个是2.4GHz的,下面一个是5GHz的。首先设置上面一个2.4GHz的,点击默认的SSID(一般为openwrt),设置新的SSID,第二个Security页签,Encryption建议选择WPA2-PSK,Cipher选择Force CCMP,Key填写您的密码。以上是标准部分设置,接下来我们再进行一些优化设置。页面上半部分有个Advanced Setting,其中HT Mode选择40MHz,Force 40Mhz选中,Country选择US。好了,点击Save & Apply保存幷应用设置。最后,点击页面上半部分中的General Setup中的Enable,打开wifi就可以了。5GHz的设置一模一样,只不过SSID不同即可。
现在wifi应该已经正常工作了,可以拔掉网线,连接wifi使用。接下来设置宽带pppoe。菜单中选择Network-Interfaces,点击WAN端的Edit进行编辑。首先选择protocol为PPPoE,再点击Switch Protocol进行应用。出现了username和password字段,填入您的宽带帐号和密码,点击Save & Apply保存幷应用设置。过一会,回到主页面,应该可以在WAN Status看到宽带分配的IP等信息,证明联网成功了。好了,暂时可以享受正常的上网生活了。

5.尝试ssh登录

Windows默认没有ssh命令,因此需要下载其它软件登录,推荐PuTTY,其它系统ssh肯定是内建命令。Windows下,打开PuTTY,输入192.168.1.1,用户名root,密码是你刚才设置的登录密码。其它系统下,直接命令行输入ssh root@192.168.1.1即可。这时候,你就进入了openwrt的系统,openwrt是基于Linux的系统,因此,什么ls,vi等命令都是直接可以用的,你可以先把玩把玩

6.升级dnsmasq

Dnsmasq 提供 DNS 缓存和 DHCP 服务功能。作为域名解析服务器(DNS),dnsmasq可以通过缓存 DNS 请求来提高对访问过的网址的连接速度。作为DHCP 服务器,dnsmasq 可以为局域网电脑提供内网ip地址和路由。
默认的dnsmasq为base版本,该版本不能对特定的域名地址进行标记操作(因为我们需要对一些特定域名如twitter等进行标记),因此,首先我们需要升级为更高版本的dnsmasq-full,运行如下命令即可重新安装高级版的dnsmasq:
#更新软件列表

opkg update

#运行remove命令后,会提示有一个文件被改动,无法删除,请手工删除

opkg remove dnsmasq

#安装新软件

opkg install dnsmasq-full

#重新启动dnsmasq

/etc/init.d/dnsmasq restart
opkg是openwrt的包管理器,如果只熟悉WIndows的同志,你就理解为360软件中心吧。update命令刷新最新的软件列表,一般重启路由器后,要使用opkg安装包,都需要先运行update。remove就是删除已经安装的软件。install是安装软件
之后,运行如下命令
dnsmasq -v
确认版本信息中有ipset字样

7.安装chinadns

chinadns项目主页:https://github.com/clowwindy/ChinaDNS-C ,该项目就是为了阻止dns污染而开发的。
因为chinadns并没有登记到opkg软件列表中,因此只能手动下载安装。从http://sourceforge.net/projects/chinadns/files/dist/ 找到属于ar71xx的最新版本并下载,之后上传到路由器的/tmp目录下。Windows下,可以用WinScp软件进行上传;其它系统,可以直接用scp命令上传。当然,也可以在路由器用wget命令直接下载到/tmp目录。之后运行如下命令进行安装
cd /tmp

opkg install chinadns-xxx.ipk
安装好了之后,用vi编辑/etc/init.d/chinadns文件,找到含有iptables字样的两行,删除或者用#注释掉
之所以要删除iptables两行,是因为默认chinadns利用路由表直接拦截dns请求,但是因为我们要用dnsmasq配合chinadns打标记,因此要禁用其iptables功能
之后运行如下命令
#启动chinadns

/etc/init.d/chinadns restart

#设置chinadns为开机自动启动

/etc/init.d/chinadns enable

#确认chinadns已经启动

netstat -an|grep 5353
之后配置dnsmasq,让其用chinadns作为上游dns。vi编辑/etc/dnsmasq.conf,在最后加入如下内容
no-resolv
server=127.0.0.1#5353
log-queries
这三行的意思是:1.禁用宽带提供商提供的dns 2.设置上游dns为127.0.0.1#5353 3.开启日志功能
之后,重启dnsmasq
/etc/init.d/dnsmasq restart
好了,可以试一试dns是不是有污染了,在路由器上运行
nslookup twitter.com
看看是不是得到了真实的ip
再来试一试局域网内的机器。首先需要清除本机的dns缓存。Windows下输入
ipconfig /flushdns
其它系统可以关闭wifi再打开即可

有问题如何调试

  • 确认chinadns已经启动,netstat -an|grep 5353
  • 确认chinadns可以工作,电脑上运行如下命令,nslookup -p 5353 twitter.com 192.168.1.1,确认得到正确解析
  • 确认dnsmasq可以工作,电脑上运行如下命令,nslookup -p 53 twitter.com 192.168.1.1,确认得到正确解析
  • 清楚本机缓存,或者重启

8.安装ipset

我们一直说要把特殊的域名打标记,但是至今还没有做什么嘛。是的,这就做起,就用ipset。首先安装他
opkg install ipset iptables-mod-nat-extra 
安装时,可能会提示如下
kmod: failed to insert /lib/modules/3.10.44/ip_set.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_bitmap_ip.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_bitmap_ipmac.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_bitmap_port.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_hash_ip.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_hash_ipport.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_hash_ipportip.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_hash_ipportnet.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_hash_net.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_hash_netiface.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_hash_netport.ko

kmod: failed to insert /lib/modules/3.10.44/ip_set_list_set.ko

kmod: failed to insert /lib/modules/3.10.44/xt_set.ko  
这个没有关系,需要重启一下路由器,再重启前,我们先把ipset初始化命令加入开机启动
编辑/etc/firewall.user,加入ipset -N setmefree iphash
之后运行reboot命令重启即可
重启好之后,登录路由器,然后运行
ipset list 
可以看到一个名为setmefree的节点,但是members为空
是时候加入需要打标签的域名了,vi编辑dnsmasq.conf,再到后面加入以下内容
#Google

ipset=/.google.com/setmefree

ipset=/.google.com.hk/setmefree

ipset=/.google.com.tw/setmefree

ipset=/.google.com.jp/setmefree

ipset=/.gstatic.com/setmefree

ipset=/.ggpht.com/setmefree

ipset=/.googleusercontent.com/setmefree

ipset=/.appspot.com/setmefree

ipset=/.googlecode.com/setmefree

ipset=/.googleapis.com/setmefree

ipset=/.google-analytics.com/setmefree

ipset=/.youtube.com/setmefree

ipset=/.googlevideo.com/setmefree

ipset=/.youtube-nocookie.com/setmefree

ipset=/.ytimg.com/setmefree

ipset=/.blogspot.com/setmefree

ipset=/.blogger.com/setmefree



#FaceBook

ipset=/.facebook.com/setmefree

ipset=/.thefacebook.com/setmefree

ipset=/.facebook.net/setmefree

ipset=/.fbcdn.net/setmefree

ipset=/.akamaihd.net/setmefree


#Twitter

ipset=/.twitter.com/setmefree

ipset=/.t.co/setmefree

ipset=/.bitly.com/setmefree

ipset=/.twimg.com/setmefree

ipset=/.tinypic.com/setmefree

ipset=/.yfrog.com/setmefree

#Flickr

ipset=/.flickr.com/setmefree

ipset=/.staticflickr.com/setmefree



#Wordpress

ipset=/.wordpress.org/setmefree

ipset=/.wordpress.com/setmefree

ipset=/.w.org/setmefree

ipset=/.wp.com/setmefree



#Others

ipset=/.dropbox.com/setmefree

ipset=/.github.com/setmefree

ipset=/.hk/setmefree

ipset=/.tw/setmefree

ipset=/.btdigg.org/setmefree

ipset=/.keepvid.com/setmefree

ipset=/.feedly.com/setmefree

ipset=/.godaddy.com/setmefree

ipset=/.digicert.com/setmefree

ipset=/.gravatar.com/setmefree

ipset=/.live.com/setmefree

ipset=/.zdassets.com/setmefree

ipset=/.cloudfront.net/setmefree

ipset=/.instagram.com/setmefree

ipset=/.playstation.net/setmefree

ipset=/.akadns.net/setmefree  
这些域名包括了经常访问的域名地址
解释一下ipset规则,该规则为泛域名结构,即如果.google.com会包括www.google.com,mail.google.com等一切子域名,所以如果你不爽,甚至可以.com,哈哈
你可能注意到google部分没有gmail,因为我的shadowsocks服务商,似乎不支持gmail的imap协议,导致邮件客户端无法访问gmail。因此我把它拿掉了,如果要访问gmail,可以用mail.google.com
重新启动dnsmasq
/etc/init.d/dnsmasq restart
之后,我们再来试一试
#查询一次域名查找

nslookup twitter

#看看ipset里面有什么

ipset list
如果不出意外的话,已经可以看到members下面有twitter.com的ip了

有问题如何调试

  • nslookup twitter.com后,确认ipset list结果中有ip
  • ipset flush setmefree,可以清除列表

9.配置shadowsocks

shadowsocks客户端主页: https://github.com/aa65535/openwrt-shadowsocks
有了打标记的ip,我们只需要将这些ip的访问通过shadowsocks转发出去即可
shadowsocks同样不在opkg软件列表中,需要手动下载,下载地址http://sourceforge.net/projects/openwrt-dist/files/shadowsocks-libev/ ,找到最新版本的ar71xx下的shadowsocks-libev-polarssl-xxx.ipk,下载并上传路由器并安装,方法同chinadns
默认该客户端是代理模式(socks5),我们需要使用转发模式
因此,编辑/etc/init.d/shadowsocks,将两行ss-local用#注释掉,再将ss-redir两行前的注释拿掉
编辑shadowsocks的配置文件 /etc/shadowsocks.json,按照服务提供商提供的信息,配置它,如
{

        "server": "ss02.8ke.co",

        "server_port": xxx,

        "local_port": 8964,

        "password": "xxxx",

        "method": "rc4-md5"

}
记录你的local_port,可以尝试启动一下
ss-redir /etc/shadowsocks.json
如果没有报错,就说明shadowsocks启动正常,ctrl-c杀掉他,用如下命令启动shadowsocks
#启动

/etc/init.d/shadowsocks restart

#加入开机启动

/etc/init.d/shadowsocks enable

#确认已经启动

netstat -an|grep 8964
有些版本的shadowsocks依赖有问题时,会报错缺少libpolarssl.so.5的错(版本有时候不是5),这时候只需要做一个符号链接即可
ln -s /usr/lib/libpolarssl.so /usr/lib/libpolarssl.so.5
最后,设置路由规则,让打标记的ip都去shadowsocks端口,运行如下命令
iptables -t nat -A PREROUTING -p tcp -m set --match-set setmefree dst -j REDIRECT --to-port 8964
注意端口用你配置的端口
然后将该命令加入/etc/firewall.user,让其随着开机一起启动

有问题如何调试

  • 确认shadowsocks已经启动,netstat -an|grep 8964
  • 确认路由表规则已经加入,iptables -t nat -L

到这里,所有的工作都完成了,打开浏览器,访问一下www.facebook.com,世界应该被还原了。

其实就是将被墙的站点通过dnsmasq+ipset打标记,然后通过iptables的路由功能将这些ipset通过shadowsocks转发出去。明白原理,一步一步弄,应该没有问题,如果有问题,看看每一步的如何调试,确认问题是出在哪里。总归,openwrt是个伟大的系统,自己动手,搭个站点在路由器上,也没有问题。感谢程序员们。
from https://story.tonylee.name/netgear-wndr4300-fan-qiang-shou-ce/ 
-----------------------------------------------

netgear R7000 shadowsocks客户端

各种不爽,最近拿到款netgear r7000路由器几个月,竟然无法翻墙。

第三方dd-wrt,刷了之后却无法安装软件,等于废了120%,还各种不稳定。 至于openwrt,不用提了,满脸伤心泪,早知道当初就弄个openwrt列表中的了。 后来实在受不了openwrt raspberry pi的各种问题(虽然最后有可能是个伤心的误会),决 定试试tomato了。刷了之后,还是一堆问题,最后却没办法直接刷回去了。

既然tomato也是开源的,那就找找源代码吧,结果竟然找到了完整的源代码,感谢shibby

我之前也找了dd-wrt源代码,由于不在官方列表中,各种不爽,各种缺失,最后不了了之。 在和GFW的激烈战斗中,终于下完整了所有源代码。首先编译检查,没有任何问题。我并不 想将shadowsocks编译到固件中,这样不利于更新,因此,我决定放到jffs2中。

结果与使用方法

shadowsocks客户端 将jffs挂载到opt下,我的这个版本的选项在Administration->JFFS中,对tomato不熟悉, 没有发言权,enable JFFS, 然后format/erase, 填入”当挂载的时候执行命令”以下内容
mount -o bind /jffs/opt /opt && /opt/bin/start_cron.sh
start_cron.sh在压缩包的bin目录下,之所以这样弄是为了将检查shadowsocks和pdnsd的脚 本加入到定时任务中,这样一旦由于某种原因挂了之后,可以自动的重新启动。之所以这样 弄是因为在我的这个版本中,计划任务的这个无论如何都无法启动执行,不知道tomato的这 个问题原因在那儿,而tomato又使用的是cru,并非常用的cron,反正就这样,能用就行。 pdnsd和shadowsocks的配置都在etc中,自己酌情配置,pdnsd中我配置的是google的dns,走 tcp。

自己编译

我编译出来的shadowsocks可能比较老旧,如果你想自己编译的话,这里就是方法了:
  1. 将shadowsocks和pdnsd的源代码放置到源代码的router目录下。
  2. 在router/Makefile中添加如下内容:
obj-y += shadowsocks-libev
obj-y += pdnsd

shadowsocks-libev:
    cd shadowsocks-libev && CC=$(CC) STRIP=$(STRIP) \
        CPPFLAGS="-Os -Wall $(EXTRACFLAGS) -ffunction-sections -fdata-sections -I$(TOP)/zlib" \
        LDFLAGS="-L$(TOP)/zlib -ffunction-sections -fdata-sections -Wl,--gc-sections -fPIC" \
        $(CONFIGURE) --prefix=$(INSTALLDIR)/shadowsocks-libev

shadowsocks-libev-install: shadowsocks-libev
    $(MAKE) -C shadowsocks-libev install

pdnsd: 
    cd pdnsd && CC=$(CC) STRIP=$(STRIP) \
        CPPFLAGS="-Os -Wall $(EXTRACFLAGS) -ffunction-sections -fdata-sections -I$(TOP)/zlib" \
        LDFLAGS="-L$(TOP)/zlib -ffunction-sections -fdata-sections -Wl,--gc-sections -fPIC" \
        $(CONFIGURE) --prefix=$(INSTALLDIR)/pdnsd --with-cachedir=$(INSTALLDIR)/pdnsd

pdnsd-install: pdnsd
    $(MAKE) -C pdnsd install
  1. 编译路由器代码,在我这边是这样子的:
make r7000e
  1. 编译后的那两个软件包在arm-uclibc/install下的各自的目录中.
from  https://4096.info/2015/02/16/netgear-r7000-shadowsocks%E5%AE%A2%E6%88%B7%E7%AB%AF/