有时候我们需要从公网访问内网的机器。现在一般家里都会有个路由器,路由器一般都会带防火墙,所以从墙外要访问内部的机器,都需要设置防火墙,做端口映射。
今天我看到ssh有一个有趣的功能,可以在不设置端口影射的情况下直接建立一个隧道,允许从外部访问内网的机器。
假设我们有两台机器,一台在内网中,IP是192.168.1.2,命名为dest;另一台在公网上,地址是pub.server.net,命名为src。我们需要从pub.server.net去访问内网那台192.168.1.2.
一、从dest发起ssh连接到pub.server.net,建立一个反向隧道
ssh -R 19999:localhost:22 user@pub.server.net
二、从src发起ssh连接
ssh localhost -p 19999
因为之前dest到src的ssh反向隧道建立之后,src上的本地19999端口就被转发到dest的22端口了,所以上面这个ssh命令就建立了从src到dest:22的连接。
其中第一步可以加上-fN参数,这样就可以把ssh进程放到后台运行,且无需打开服务器端的shell。
本文参考:
http://my.oschina.net/Thinkeryjgfn/blog/177283
示例脚本:
自动开启反向脚本
#!/bin/bash if [ $# -ne 3 ] then echo "$0 <server ipaddr> <passwd> <src_port>" exit 1 fi DECT_IPADDR=localhost DECT_POAT=22 SRC_IPADDR=$1 SRC_USER=gino SRC_PASSWD=$2 SRC_PORT=$3 /usr/bin/expect -c " set timeout 10 spawn ssh -fN -R $SRC_PORT:$DECT_IPADDR:$DECT_POAT $SRC_USER@$SRC_IPADDR expect { \"*(yes/no)\" {send \"yes\r\"; exp_continue} \"*password\" {send \"$SRC_PASSWD\r\";exp_continue} \"*\$ \" {send \"bash\r\"; interact} } " ##参数说明 ## server_ipaddr 可连接的公网IP ## passwd 连接公网ssh服务密码 ## src_port 远程映射的端口
自动连接映射好的机器脚本
#!/bin/bash if [ $# -ne 3 ] then echo "$0 <ipaddr> <passwd> <src_port>" exit 1 fi SERVER_IPADDR=$1 SERVER_USER=gino SERVER_PASSWD=$2 SRC_PORT=$3 /usr/bin/expect -c " set timeout 10 spawn ssh $SERVER_USER@$SERVER_IPADDR expect { \"*(yes/no)\" {send \"yes\r\"; exp_continue} \"*password\" {send \"$SERVER_PASSWD\r\";exp_continue} \"*\$ \" {send \"bash\r ssh localhost -p $SRC_PORT\r\"; interact} } " ## 参数说明 ## ipaddr 上一个脚本中的公网IP ## passwd 上一个脚本中连接公网ssh服务的密码 ## src_port 上一个脚本中的端口号