SSH Tunnel解决无公网IP 80被封等问题
有了一个CB3,一个树莓派B,外加一堆功耗很小的电脑,扔那扔着可惜,爬虫的话,一个就够了
于是想折腾怎么把这些“废品”给利用起来。
其实,用3322.org或者花生壳之类的DDNS都可以,因为我现在用的还是电信的宽带,除了80端口被封,还是可以拿到动态的公网IP的,但是呢,心里总是感觉不爽,凭啥非要再输入个端口号呢。而且放web服务这种事,最好还是别那么张扬。大环境下,指不定哪天就被查水表了。
从网上找到以下几种解决方案:
一、新花生壳/Nat123
看上去很美好,但是新花生壳的免费版帐号每天11点抢,正好是我比较忙的时间段,而且这种营销方式我很是不喜,最最主要的是这俩货都不支持Linux、Mac的客户端,只有Windows,除了玩游戏的一台台式机(而且功耗还很高),一个公司的笔记本以外,我就没有windows了,而且很明显,这两个都不能保证24小时开机,所以 Pass
其实,花生壳现在有一个叫花生棒的东西,内置了一个免费的新花生壳内网版,但是以为一个卖200+的玩意,居然只能映射2个端口,每个月还就1G的流量,我只能说:我勒个去,在我的概念里,那个小硬件其实就是一个嵌入式Linux,采用下面说的方案三来实现的。
二、树莓派VPN拨入VPS,通过VPS上的Nginx将“内网”中的树莓派做端口转发
这个方案的可行性倒是不错,但是看看可怜的树莓派,512Mb内存,还得跑服务,还得跑VPN客户端,而且最主要的,电信大概1-2天会重置一次网络,网络会间断一段时间,那么VPN的监控与重播又是一个麻烦事。
三、使用SSH Tunnel来建立本机/局域网与VPS的隧道,从而完成端口映射
具体的实施步骤如下:
1、先在VPS上打开openssh服务器的GatewayPorts支持
vi /etc/ssh/sshd_config
注意是sshd_config哦,在尾部添加:
GatewayPorts yes
保存,退出后,重启openssh服务器
2、在树莓派上:
ssh -fNR 0.0.0.0:80:localhost:8080 root@xxx.xxx.xxx -p 2112
上述的含义为:以root用户ssh连接到xxx.xxx.xxx,其中xxx.xxx.xxx的ssh端口为2112,然后建立一个隧道把localhost的8080端口绑定到xxx.xxx.xxx的80端口,xxx.xxx.xxx的监听IP为0.0.0.0,即所有地址。
下面是V友给的原文解释:
ssh的-R A.A.A.A:XXXX:B.B.B.B:YYYY 意思是: 在远程机器打开监听A.A.A.A:XXXX端口,该端口管道到本机,以本机的身份链接B.B.B.B:YYYY,而建立的管道。
还有个-L是类似的: -L A.A.A.A:XXXX:B.B.B.B:YYYY 意思是:在本机打开监听A.A.A.A:XXXX端口,该端口管道到远程机,以远程机的身份链接B.B.B.B:YYYY,而建立的管道。
这样访问http://xxx.xxx.xxx就可以访问到树莓派8080端口上的应用啦。
3.监控脚本(非aotussh)
在树莓派上安装screen和expect
将下面的脚本保存为autossh.sh,打开screen,然后执行:authssh.sh
#!/bin/sh
if [ "$1x" != "connectx" ]; then
if [ -z $1 ]; then
echo "Usage: $0 [username@]host[:port]" 2>&1
exit 0
fi
echo -n "Password: "
stty -echo; read pass; stty echo; echo ""
expect -- << EOF
spawn $0 connect $1
while 1 {
expect {
"password:" {
send "$pass\r"
}
"yes/no" {
send "yes\r"
}
"Permission denied" {
puts "Password error."
break
}
}
}
EOF
else
shift
port=`echo $1 | perl -nle 'print /\:(\d+)$/ ? $1 : "22"'`
while [ 1 ]
do ssh -p $port -CN -D 0.0.0.0:80 $1 target "while nc -zv localhost 80; do sleep 20; done"
sleep 20
done
fi
4.监控断线(使用autossh)
请参考 http://yuanxiao.sinaapp.com/pages/122/132/377/article_index.html
使用命令:autossh -M 7890 -NR 0.0.0.0:8080:localhost:8080 root@xxx.xxx.xxx -p 2112
可以看到,多了一个M参数,该参数是指使用本地的7890端口来监听SSH连接是否正常
以daemon方式执行,相当于root去执行autossh, ssh,这时刚才普通用户目录下的.ssh/authorized_keys文件会不起效。有两种办法解决,一种是用autossh的参数指定.ssh路径;另外一种是以普通用户身份执行daemon,下面是第二种方式。
/bin/su -c '/usr/bin/autossh -M 7890 -NR 0.0.0.0:8080:localhost:8080 root@xxx.xxx.xxx -p 2112 -f' - tan9le
注意:如果需要远程服务器直接监听0.0.0.0地址的话,需要将 远程 服务器的ssh服务配置文件(如/etc/sshd_config)中修改GatewayPorts no为GatewayPorts yes来打开它,否则远程服务器将只能够监听127.0.0.1
将上面命令放入下面各启动方式中,根据自己系统自己配置:
SysV:/etc/inid.d/autossh
Upstart: /etc/init/autossh.conf
systemd: /usr/lib/systemd/system/autossh.service