本地ssh隧道
A是我们手上的电脑,B是外国服务器(公网我们的), C是外国服务器(如Google),
A能访问B, A不能访问C, B不能访问A, B能访问C
那么,我想想上Google,该怎么办?
在A上执行下面的命令:
-N 不执行任何命令
-f 后台运行
ssh -N -f -L 2121:C:80 userB@B
-L参数的行为。-L X:Y:Z的含义是,将IP为Y的机器的Z端口通过中间服务器B映射到本地机器的X端口
那么,在A上访问127.0.0.1:2121就是访问C的网站了
远程ssh隧道
要实现B访问A呢?
在A上执行
ssh -Nf -R 2222:127.0.0.1:22 userB@B
# 在B(公网)机器上访问2222端口就是访问内网机器A的22端口
// 或者
ssh -Nf -R B:2222:192.168.0.100:22 userB@B
然后在B上执行
ssh -p 2222 localhost #就是就登录上A这台电脑了
#在B上我们可以通过查看端口已经侦听
netstat -an|grep :2222
#查看所有侦听的端口
netstat -lantp
PS: AutoSSH 自动重连
使用SSH的方式不够稳定,使用AutoSSH可以自动在连接断开时自动重连,再把AutoSSH加入系统服务自动启动,则可以做到稳定的连接
1.安装AutoSSH
sudo apt-get install autossh
2.执行AutoSSH命令
autossh -M 5555 -NR 2222:127.0.0.1:7777 userB@B
-M:在5555端口上监听连接的变化,只要断开就重连
少了-f 参数,因为AutoSSH本来就在后台运行
注意(坑) Permalink
- 需要 root 权限,不然会提示权限错误:
Privileged ports can only be forwarded by root
- 不能使用 VPS (sshd server) 已占用的
22
端口,用作端口转发。选用 未使用 端口(比如2222
)
否则就杯具了:Warning: remote port forwarding failed for listen port 22
例子
有A,B,C 3台服务器, A,C有公网IP, B是某IDC的服务器无公网IP. A通过B连接C的80端口(A=>B=>C),
那么在B上执行如下命令即可:
//先在B上链接C,那么在B上访问6300端口就是访问C的80端口
ssh -CfNg -L 6300:127.0.0.1:80 userC@C
//在再B上再新建一个shell窗口,执行下面命令
ssh -CfNg -R 80:127.0.0.1:6300 userA@A
//那么,在A上访问127.0.0.1:80就是访问B的6300端口,变相的就是B访问了6300端口,最终就是A访问了C的80端口
SSH隧道建立SOCKS服务器
-D port
指定一个本地机器 “动态的'’ 应用程序端口转发. 工作原理是这样的,
本地机器上分配了一个 socket 侦听 port 端口, 一旦这个端口上有了连接,
该连接就经过安全通道转发出去, 根据应用程序的协议可以判断出远程主机将和哪里连接.
目前支持 SOCKS4 协议, 将充当 SOCKS4 服务器. 只有 root 才能转发特权端口. 可以在配置文件中指定动态端口的转发
在A上执行以下命令:
ssh -N -f -D 1080 userB@B # 将端口绑定在127.0.0.1上
ssh -N -f -D 0.0.0.0:1080 userB@B # 将端口绑定在0.0.0.0上
通过provixyl这样代理软件,全局代理(就是把所有的A电脑上访问所有ip,0.0.0.0 都转发到本地1080端口)
同时把访问的那些ip映射到B服务器, 让B去访问 最终就是A 利用 B作为跳板, 访问了那些IP
例子
公司上的内外开发也是如此
{办公电脑A, 公司内网服务器B(内网192.x.x.x), [AB在同一个局域网]}, 生产环境上的C(内网ip:10.144.0.x)
A能链接B,不能链接C, B能链接C(同过一台公网服务器, 上面介绍到的, 公网访问内网)
开发中要实现 A能链接C
1. 实现A链接B
#在A上执行
ssh -N -f -D 1080 userB@B # 在A上访问1080端口的所有ip, 都会转发给B
#通过A上运行其他代理软件, 过滤规则, 把访问10.144.*.*段的ip 转发给A上的 1080端口
2. 实现D(公网)链接C
实现B(192.x.x.x)链接C(通过一台公网服务器D) B通过D连接C的8000端口(B=>D=>C)
# 在C上执行
ssh -Nf -R 2222:127.0.0.1:8000 userD@D
# 建立一个远程隧道, 在D上访问它的2222端口, 就是访问C内网的8000端口
#那么任何主机通过访问公网主机D:2222就会被连接到C:8000,
#从而可以完成外网穿越NAT到内网的访问,而不需要在内网网关和路由器上做任何操作
3. 实现B(192.x..)链接D
ssh -Nf -L 1080:D:2222 userD@D // 在B上访问1080端口, 都会自动被映射到D:2222
// 或者
ssh -Nf -L B:1080:D:2222 userD@D // B可省略, B可以是它本身所在局域网的192这种ip
4. 在B上配置
接收有A访问的ip, 如10.144.0.x:80, 通过provixyl这样软件, 把接收到的10.144.0.x转发到本地1080端口