Thinking_Out_Loud

SSH端口转发

2018-10-08

一种场景

想象这么一种场景,你在远程主机上刚装好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.com3000端口接收到的请求转发到我们本机的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;

参考资料

  1. https://blog.trackets.com/2014/05/17/ssh-tunnel-local-and-remote-port-forwarding-explained-with-examples.html
  2. https://blog.csdn.net/blade2001/article/details/8877250
  3. https://stackoverflow.com/questions/42505339/why-use-t-with-ssh
Tags: tools