Saturday, July 21, 2012

在DD-WRT下面建立 SSH Tunnel (Socks5 Dynamic Port Forwarding) 翻墙

在DD-WRT下面建立 SSH Tunnel (Socks5 Dynamic Port Forwarding)

1 看标题就知道了,通常情况下建立SSH Tunnel都是用一些电脑上的软件,比如bitvise tunnelier,putty,myentunnel,以及Linux和OS X上的openssh,现在我要在安装了DD-WRT的路由器上建立,这样无论你连接路由器的设备是什么,都可以很方便的用上这个Tunnel翻墙或者看一些国内无法访问的网站。

2 首先需要的软件和硬件:
 2.1 一个位于国外的服务器,且提供ssh接入,这里假设为 server.com, 用户名密码分别为: username, password
 2.2 一台刷了DD-WRT的路由器,这里假设路由器的ip地址为 192.168.2.1,路由器能够连接外网
 2.3 路由器里面需要安装的软件 zlib, libopenssl,openssh-client,autossh (顺次安装)
 2.4 安装这些软件的工具: ipkg (DD-WRT自带)
 2.5 安装这些软件的条件:开启jffs支持,进入dd-wrt网页界面-管理-jffs开启(因为dd-wrt的系统是只读的,装了任何软件重启就消失了,而jffs是将路由器的空闲空间挂在到dd-wrt上,第三方软件都装在这里)

3 安装软件
 3.1 telnet 192.168.2.1 or ssh root@192.168.2.1,两种方式都可以登入dd-wrt内部,用户名为root,密码为设置的路由器密码
 3.2 cd /jffs && mkdir -p tmp/ipkg && ipkg update
 3.3 ipkg -force-depends  install zlib libopenssh (这两个软件自动安装)
 3.4 wget http://downloads.openwrt.org/whiterussian/packages/openssh-client_4.4p1-1_mipsel.ipk && ipkg -force-depends install openssh-client_4.4p1-1_mipsel.ipk (这个软件要手动安装且加上 -force-depends,否则会出错)
 3.5 wget http://downloads.openwrt.org/backports/rc5/autossh_1.3-1_mipsel.ipk && ipkg -force-depends install autossh_1.3-1_mipsel.ipk  (同上原因)
 3.6 以上软件都安装在 /jffs/usr/bin/

4 配置dd-wrt端的ssh
 4.1 配置有点纠结,因为autossh和openssh是作为第三方软件安装的,且安装路径不一定在系统的path里面,所以所有命令的运行都要指定绝对路径
 4.2 先运行一个ssh命令试试看是否能够作tunnel
 /jffs/usr/bin/ssh -D 192.168.2.1:7070  username@server.com
等几秒,输入password,连接成功,表示可以连接
 4.2 总不能每次都输入密码把,所以这里要建立一个 id_rsa文件 (详见 ssh-keygen),且放到/jffs/etc/ssh/这里,然后无须输入密码实现tunnel的ssh命令就变成这样:
  /jffs/usr/bin/ssh -D 192.168.2.1:7070 -Nfqn -i /jffs/etc/ssh/id_rsa username@server.com,加入了几个参数,这样程序就后台运行,且不执行其它命令。
 4.3 openssh的命令是不支持断线重新连接的,所以这里需要 autossh,首先4.1提到的,要先定义autossh能够使用的ssh的绝对路径,这里用export:
 export AUTOSSH_PATH="/jffs/usr/bin/ssh" ,然后运行:
 /jffs/usr/bin/autossh autossh -M  20000 -D 192.168.2.1:7070 -Nfqn -i /jffs/etc/ssh/id_rsa username@server.com
4.4 综合以上,执行一个ssh tunnel需要敲入两次命令,一次是export 定义变量,一次是autossh,为了方便,这里建立一个脚本文件:
 vi /jffs/usr/bin/startssh.sh 里面内容如下:
 #! /bin/sh
 export AUTOSSH_PATH="/jffs/usr/bin/ssh"
 /jffs/usr/bin/autossh  -M  20000 -D 192.168.2.1:7070 -Nfqn -i /jffs/etc/ssh/id_rsa username@server.com
 保存后让这个脚本变成可执行文件:
 chmod +x  /jffs/usr/bin/startssh.sh
4.5 ok,基本上成功了要启动ssh tunnel,只需要运行 /jffs/usr/bin/startssh.sh
4.6 路由器重启了怎么办?将以上的脚本改名为 startssh.startup 放入: /jffs/etc/config/ 下面,路由器开机就会自动启动,注意扩展名(参考这里

5 电脑连接上路由器之后的一些代理设置:
 firefox : 安装 foxyproxy,代理设置为 socks5 192.168.2.1 端口 7070
 chrome: 安装 switchy, 代理设置为  socks5 192.168.2.1 端口 7070

6 ipad,iphone 也可以用的上吗?
当然,这里要用到pac文件,将ssh tunnel的socks5代理转换为http代理,方法如下
 6.1 生成文件 pac.pac ,内容如下:
   
function FindProxyForURL(url, host) 
return "SOCKS 192.168.2.1:7070"; 
  6.2 将这个pac.pac文件保存到http web服务器上去,保证能访问,比如保存到这个地方:
 
 http://server.com/pac.pac
  6.3 打开iphone/ipad的wifi设置,进入你连接的哪个wifi设置,设置自动代理,地址填入:
 http://server.com/pac.pac

至此,所有连接到这台dd-wrt的路由器的设备,都可以无缝的翻墙了!


7 补充说明:

另外的方式启动脚本
建立文件 abc.sesbutton
内容:

#! /bin/sh
 export AUTOSSH_PATH="/jffs/usr/bin/ssh"
 /jffs/usr/bin/autossh  -M  20000 -D 192.168.2.1:7070 -Nfqn -i /jffs/etc/ssh/id_rsa username@server.com
将这个文件放入 /jffs/etc/config/
然后就可以通过按路由器上的那个一键加密的键启动这个脚本
参考这里
试过了 wanup, startup,prewall 等方式都不行。

update:

DDWRT真的不适合干这事情,还是openwrt方便

3 comments:

  1. 继续补充:

    路径这部分其实还可以使用:
    mount --bind /jffs/usr/bin/ssh /usr/bin/ssh
    这样openssh就取代了默认的dropbear的ssh

    ReplyDelete
  2. 补充:
    本想试试 ln -s 的方式的,但是因为系统文件是只读的,原来建立的默认的symbolic 无法删除。所以放弃。

    ReplyDelete
  3. 有没有办法不需要再在浏览器里设置Proxy,直接路由翻墙出去的?

    ReplyDelete