自从家里换了联通光纤后,联通就在我家宽带出口前搭了一个路由器,我家也彻底沦为192.168.1.0/24段的局域网了,带来的问题就是在外网无法访问家里的路由器。这对于刷了LEDE,有时候需要从外网直接管理使用路由器的我,觉得难受极了。周末有空,干脆解决这个问题。
在这之前,了解过一个ngrok项目,用于将局域网内的某一个地址的端口,映射到公网。但是研究了一下该软件,发现其在LEDE的源中,并不包含,我又是个懒的去编译的程序员,因此想看看有没有其他办法。
研究一下,发现其实程序员必备的SSH就有这个功能。SSH一共支持三种端口转发:
- 本地端口转发:就是客户端方的某个端口和服务器某个端口相连,这样访问客户端该端口,就相当于访问服务器端某个端口
- 远程端口转发:还是把客户端方的某个端口和服务器某个端口相连,只不过反向的,访问服务器端某个端口,就相当于访问到了客户端该端口
- 动态转发:SOCKS5代理模式,不多说了
更具体一些,可以参见这篇文章:https://blog.twofei.com/528/
回到我的需求,我是希望访问VPS的某个端口,就相当于访问路由器的指定端口。比如我访问VPS的2222,就相当于访问路由器的22端口。所以是第二种:远程端口转发
SSH做起来非常简单,首先,修改VPS端
/etc/ssh/sshd_config
加入GatewayPorts yes
。据说,不这样外网无法访问转发的端口,未验证。然后路由器一条命令搞定:ssh -f -NR "*:2222:localhost:22" user@vps
这样子,访问VPS的2222端口,就直接访问到了路由器
进化一:持久
用ssh命令有个问题,因为各种因素,它可能会莫名挂掉,网络不好啦,网络干扰啦,网络xxx啦,总归都是网络问题。因此,我们得祭出神奇
autossh
。在LEDE的包中,默认就有,安装之,爱死LEDE。在这之前,自己搞定SSH的密钥登录哦,否则autossh起来,也会卡在输入密码。 autossh在LEDE的配置文件是/etc/config/autossh
,配置一下config autossh 'ssh'
option gatetime '0'
option monitorport '20000'
option poll '600'
option ssh '-p 22 -NR *:2222:localhost:22 user@vps'
然后开启autossh
进化二:隐藏
在我家的运营商,我发现了一个问题,如果你ssh启动一段时间后,到目的地址的网络丢包就开始大量出现。思来想去,把ssh塞到ssr-tunnel中不就完事了。
先建立一个到VPS的22端口的ssr-tunnel隧道
ssr-tunnel -c /var/etc/shadowsocksr.json -l 2222 -L VPS:22 -f /tmp/ssr-tunnel.pid >> /tmp/ssr-tunnel.log
这样,访问本机的2222端口,就相当于走ssr流量访问远端的22端口。把autossh的配置稍微改一下,让其访问本机2222端口
config autossh 'ssh'
option gatetime '0'
option monitorport '20000'
option poll '600'
option ssh '-p 2222 -NR *:2222:localhost:22 vpsuser@localhost'
为了让ssr-tunnel隧道保持运行,需要搞个监控。不需要很复杂,放到crontab里就可以了
ps | grep [s]sr-tunnel || `ssr-tunnel -c /var/etc/shadowsocksr.json -l 2222 -L vps:22 -f /tmp/ssr-tunnel.pid >> /tmp/ssr-tunnel.log`
进化三:多射
映射了第一个端口,你就想再来一个。什么aria2映射出来,就可以做外网离线下载。其实也蛮简单的,因为autossh支持多端口映射
config autossh 'ssh'
option gatetime '0'
option monitorport '20000'
option poll '600'
option ssh '-p 2222 -NR *:2222:localhost:22 -NR *:6800:localhost:6800 vpsuser@localhost'
这样就把aria2的6800也映射出来了
就这样,结束了.
related post: http://briteming.blogspot.com/2016/04/ngrok.html
related post: http://briteming.blogspot.com/2016/04/ngrok.html
---------------
用SSH有一段时间了,自认为对ssh的操作还是有一定的了解。而今天我要介绍的是ssh的三种端口转发(隧道协议、Tunnel、Port forwarding)功能的使用与它们的使用场合。
为什么要用ssh的端口转发功能,我想大家一定明白(不明白也无所谓,既然来到了这里,你肯定是想把它弄明白的!)。一来是为了安全(数据加密传输);二来是为了突破(穿越)某些防火墙对某些主机的访问限制。
据我所知,SSH一共提供了 3 种端口转发,分别是本地转发(-L参数)、远程转发(-R参数)和动态转发(-D参数)。接下来我就一一介绍这几种不同的转发方式的使用。我尽量简明扼要地叙述主题重点,让人一看就学会(回忆起)该如何操作。
本文用到的一些“术语”和约定
既然提到转发,就应该明白:这是三台主机之间要合作干的事。不然为何不两台主机直连,而要通过第三者转发?
本地主机:形式为IP或域名,你当前正在使用的这台机器;
远程主机:形式与本地主机一样。这里的“远程”并不是指实际的距离有多远,准确地说是“另一台”;
本地转发
本地转发,顾名思义(有点)就是把本地主机端口通过待登录主机端口转发到远程主机端口上去。
本地转发通过参数 -L 指定,格式:-L [本地主机:]本地主机端口:远程主机:远程主机端口。加上ssh待登录主机,这里就有了三台主机。
举例:ssh -L 50000:www.google.com:80 user@host。例中本地主机、远程主机和待登录主机分别用颜色红绿蓝标识。
当成功执行上面的命令之后,访问本地的50000端口,就等同于访问 www.google.com 的 80 端口。但和直接访问有着本质的区别:这次是通过登录主机来安全转发数据的,没有人知道你和远程主机之间传输了何种数据。就算你不能和远程主机建立连接(而登录主机能访问),那就能突破(绕过)(防火墙的)限制。
但本例其实举得不够好。就算你能访问 www.google.com,你却依然不能其它主机,甚至是 google域 的另一台主机,比如 plus.google.com。想要更全面的端口转发功能,还需动态转发。
远程转发
远程转发是指把登录主机端口通过本地主机端口转发到远程主机。
远程转发通过参数 -R 指定,格式:-R [登录主机:]登录主机端口:远程主机:远程主机端口。
举例:ssh -R 0.0.0.0:8080:localhost:80 user@host。
当成功执行上面的命令之后,访问登录主机的 8080 端口就相当于访问 localhost:80!
不要小看这个例子,它可是有相当有用。我书读得多,不会骗你 :-)
设想这样一种情况(其实这种情况太普遍了):你在本机开发了一个web应用,想拿给别人测试,但现在你却处在内网,外网是无法直接访问内网的主机的,怎么办!?很多人可能会说,找台有公网IP的主机,重新部署一下就行了。这样可行,但太麻烦。然而自从你了解了ssh的远程转发之后,一切都变得简单了。只需在本地主机上执行一下上面例子的命令即可实现外网访问内网的web应用,相信我,我经常就这样干,屡试不爽。这简直是太好了,awesome! 让你从此对ssh爱不释手。
动态转发
相对于本地转发和远程转发的单一端口转发模式而言,动态转发有点更加强劲的端口转发功能,即是无需固定指定被访问目标主机的端口号。这个端口号需要在本地通过协议指定,该协议就是简单、安全、实用的 SOCKS 协议。FQ(你懂的)就靠她了!
动态转发通过参数 -D 指定,格式:-D [本地主机:]本地主机端口。相对于前两个来说,动态转发无需再指定远程主机及其端口。它们由通过 SOCKS协议 连接到本地主机端口的那个主机(peer,比如最常见的浏览器)指定(此属协议内容,无需深究)。
举例:ssh -D 50000 user@host。
当成功执行上面这个命令后。通过协议告诉你要访问的远程主机及端口,然后你与目标主机之间的数据就通过登录主机安全地传输了。
最常见的用途:FQ(大家都懂的)。在浏览器中设置代理类型为 SOCKS(5),主机及端口:127.0.0.1:50000。然后 gg/ytb/tt/fb 等就一丝不挂地摆在眼前了!
No comments:
Post a Comment