基于OpenWRT路由器的IPv6 SSH Tunnel解决方案

 March 14, 2012, 8:51 p.m.   10 comments    IPv6 ssh Tunnel OpenWRT Dropbear

寒假的时候入了一台Linksys WRT54G,并将其刷成了OpenWRT系统,开学之后考虑到蛋疼的校园网认证系统,打算在路由器上搭建基于IPv6的SSH Tunnel,用来给移动设备提供网络接入以及外网代理服务。

准备工作

需要

给OpenWRT增加IPv6支持

关于OpenWRT上的IPv6配置,可以参考OpenWRT的官方wiki http://wiki.openwrt.org/doc/howto/ipv6.essentials

简而言之,通过SSH登录到OpenWRT,然后使用opkg安装IPv6模块

root@OpenWrt:/# opkg install kmod-ipv6

然后重启network服务

root@OpenWrt:/# /etc/init.d/network restart

这时,使用ifconfig命令应该能够看到成功获取IPv6地址了

配置SSH的免密码登录

有了IPv6,应该能通过SSH直接连接到服务器而不用经过校园网的认证,然而,为了让路由器实现自动登录,SSH的免密码登录当然是必须的了。

而OpenWRT上默认的SSH是Dropbear,配置方法和通常使用的OpenSSH有所不同。

使用Dropbear生成Public Key

dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key > id_rsa.pub

然后使用vi编辑一下生成的id_rsa.pub,删除掉第一行和第三行,只留下以ssh-rsa开头的第二行,这才是我们需要的Public Key

Public Key上传到服务器

scp id_rsa.pub root@server:id_rsa.pub

Public Key导入到authorized_keys

登录到服务器,然后执行

cat id_rsa.pub >> ~/.ssh/authorized_keys

测试一下免密码登录

ssh -i /etc/dropbear/dropbear_rsa_host_key root@server

如果能够直接登录成功,就说明已经配置成功

OpenWRT端的端口转发配置

既然要使用SSH Tunnel作为socks代理,端口转发是必须的了,而Dropbear不支持动态端口转发(Dynamic Port Forwarding),所以使用静态端口转发替代

/etc/init.d里新建一个服务,命名为sockstunnel(/etc/init.d/sockstunnel),其作用是在192.168.1.1:70070进行监听,然后将这个端口的所有数据通过SSH Tunnel静态转发到服务器的7070端口

#!/bin/sh /etc/rc.common
START=85
STOP=5

DAEMON=/usr/bin/ssh
PIDFILE=/var/run/sockstunnel.pid

start() {
echo -n "Start Socks Tunnel Daemon: "
start-stop-daemon -S -b -q -m -p $PIDFILE -x $DAEMON \
-- -i /etc/dropbear/dropbear_rsa_host_key -g -N -L 192.168.1.1:7070:localhost:7070 root@server
echo -n "Socks Tunnel Daemon Started."
}

stop() {
if [ -f $PIDFILE ]; then
PID=$(cat $PIDFILE)
kill $PID
while [ -d /proc/$PID ];
do
sleep 1
done
fi
rm -rf $PIDFILE
echo -n "Socks Tunnel Daemon Stoped."
} 

服务器端的端口转发配置

sockstunnel的作用仅仅是将数据通过我们建立的SSH Tunnel静态转发到服务器的7070端口,而网络应用却可能使用到各种端口,显然不可能为每一个应用单独配置端口转发,因此,就要使用到服务器端的动态端口转发。

登录到服务器,执行命令

ssh -qTfnN -D 7070 root@localhost

效果是在7070端口进行监听,将OpenWRT路由器通过SSH Tunnel静态转发的数据再动态转发出去。

这其实是一种迂回的方案,因为OpenWRT上的Dropbear不支持动态端口转发,就先将数据通过SSH Tunnel静态转发到服务器,然后再在服务器进行动态端口转发。

下图应该可以很好地解释其中的原理:

如果你的OpenWRT路由器Flash存储器容量足够大,则完全可以在OpenWRT上安装OpenSSH直接使用动态转发,而没必要像我这么做了。

启动/停止SSH Tunnel

在OpenWRT上可以很容易地启动SSH Tunnel,只需要执行

/etc/init.d/sockstunnel start

如果需要停止的话,只需要执行

/etc/init.d/sockstunnel stop

在终端设备上使用Socks代理

如果需要使用Socks代理,仅仅连接到OpenWRT路由器是不够的,还需要在设备上配置socks代理。

如果使用的是电脑,只需要将浏览器的socks代理修改为:192.168.1.1:7070,但是需要注意的是,这里只能使用Socks4,如果使用Socks5将会出现拒绝连接的状况。

如果使用的是手机,比如Android,推荐使用ProxyDroid软件(手机需要取得root权限),可以很方便地设置socks4代理,并且可以根据当前连接的网络自动开启/关闭代理,实现一连接到路由器便自动开启代理的效果。


天一

天一 April 13, 2012, 7:33 p.m. Reply

你的固件是下载的还是自己刷的?我最近一直想过滤掉ipv4的包当作纯ipv6交换机使用但是下载的版本不支持ebtables...

天一

天一 April 13, 2012, 7:34 p.m. Reply

我是说自己编译

Chon

Chon April 13, 2012, 9:54 p.m. Reply

下载的固件
为什么一定要去掉IPv4呢,不用就可以了啊

天一

天一 April 13, 2012, 10:40 p.m. Reply

实验室组网,双线双路由,一线v4,一线v6。openwrt设成交换机模式,会漏流量,所以必须过滤掉openwrt的ipv4流量。刚才已经编译刷机成功了,还是自己编译的靠谱~


Ivan Chou

Ivan Chou Sept. 11, 2013, 12:32 a.m. Reply

我有个疑问
START=85
STOP=5
定义这个两个参数是做什么用的呢? 一直没搞懂。。。 烦请讲解

Chon

Chon Sept. 11, 2013, 12:34 a.m. Reply

这个是指启动和终止时的优先级(先后顺序)


Ivan Chou

Ivan Chou Sept. 13, 2013, 12:55 a.m. Reply

关于SSH断线重连问题 我发现无论是 检测进程 还是 检测端口 都不太科学,有时进程在依旧不通(是不是成生了僵尸进程...)
于是我想用 通过 Tunnel 向某网站发个请求的方式来判断 tunnel 是否正常
但是openwrt默认只有 wget 不能直接支持sock proxy,这个有什么好的解决思路么?博主 O.O

Chon

Chon Sept. 13, 2013, 1:14 a.m. Reply

openwrt应该可以安装curl吧?curl就可以支持socks proxy了。另外如果flash足够大还可以安装tsocks以及proxychains等工具一样可以让wget用socks proxy,还有一些socks代理转http代理的软件。
当然这一切的前提都是你的flash足够用。


dajiangyou

dajiangyou April 2, 2014, 3:15 p.m. Reply

大牛啊,问下openwrt的OPENVPN能支持IPV6么,WIN下的已搞定


x

x Nov. 3, 2014, 2:48 p.m. Reply

lz 我宿舍人多用的交换机 自己win下转发并监听localhost的 所以只和你交流下境外服务器的事情可以吗 my q 四1八四①零八⑥二 谢谢