一种场景
想象这么一种场景,你在远程主机上刚装好Docker,启动Docker Daemon之后却被断开了ssh连接。仔细一想,原来daemon启动之后创建的网桥默认是172.17.0.0/16
,正好和办公室的网段冲突了……
恭喜发财!这间办公室的电脑都不能连上你的服务器了,而且是内网服务器所以手机也是不行,但你想到你隔壁老哥的服务器是可以访问你的服务器的,可是问题是你又不好意思登录他的服务器随便乱搞。
那么端口转发就是我最后的救命稻草了。
用ssh来转发端口
赞美SSH!!
本地转发
用-L
选项来开启本地端口转发:
1 | > ssh -L [bind_address:]port:host:hostport [user@]hostname [command] |
举个例子,我们有个服务器A.com
可以访问google.com
,现在要把我们本机的9000
端口接收到的请求转发到google.com
,可以这样:
1 | > ssh -L 9000:google.com:80 user@A.com |
现在我们打开浏览器访问localhost:9000
就可以看一看谷歌首页了。
远程转发
和本地转发相反:
1 | > ssh -R [bind_address:]port:host:hostport [user@]hostname [command] |
如果我们本机在内网中且运行了一个Web服务,监听端口是9000
,现在我们想让外网机器访问这个服务但苦于没有公网IP。
除了配置NAT之外,我们可以用ssh的远程转发。假设我们在外网有一台服务器B.com
,有公网IP那种,我们可以这样:
1 | > ssh -R 9000:localhost:3000 user@B.com |
注意,上面命令中的localhost
是从B.com
的角度看的,也就是将B.com
在3000
端口接收到的请求转发到我们本机的9000
端口。所以外网机器访问B.com:3000
就可以访问到我们内网本机的服务。
另外,远程转发默认是关闭的。我们要在本地主机/etc/ssh/sshd_config
设置:
1 | GatewayPorts yes |
再重启ssh服务:
1 | > service sshd restart |
动态转发
1 | > ssh -D [bind_address:]port [user@]hostname [command] |
这个用个例子就能知道怎么用了:
1 | > ssh -D 1080 C.com |
假如C.com
能爱国上网,那么我们设置代理localhost:1080
就可以访问谷歌。当然,本来这个是用来加密连接的。
可以配合食用的选项
-n
:将标准输入重定向到/dev/null
,就是不接收输入,ssh在后台运行的时候必须设置这个;-N
:不执行命令,正适合做端口转发;-f
:让ssh在后台运行,隐式使用了-n
,适合需要输入密码再转入后台运行的情景;-T
:不分配TTY;