O、前言

前几天在互联网冲浪的时候发现了一个好玩的东西:SSH 。在这之前,我以为 SSH 就单纯连接服务器用的,但看完文章我才发现,原来 SSH 这么好玩!!!

一、三种端口转发

SSH 一共提供了3种端口转发,分别是 本地转发(-L)远程转发(-R)动态转发(-D) 。接下来详细介绍三种端口转发食用方式。

0、一些术语和约定

既然是转发,就要明白这是三台主机干的事情。(发送主机、转发主机、接收主机。)

本地主机 : 发送主机,即当前使用的机器。形式为 IP 或域名。

远程主机 : 转发主机,即远程用户名所在的主机。形式为 IP 或域名。

注:远程主机 还可充当接收主机。比如要转发的服务就在远程主机上面。

下文的命令格式参数部分略看:

SSH -[] [发送主机:]发送主机端口:接收主机:接收主机端口 转发主机用户名@转发主机

命令执行打开的窗口不能关闭,否则转发一起失效。

1、本地转发(-L)

访问本地主机端口时,将访问请求转发到远程服务上去。

格式:SSH -L [本地主机:]本地主机端口:远程主机:远程主机端口 远程用户名@远程主机地址

举例:SSH -L 8080:127.0.0.1:80 [email protected]

解释:将 example.com 主机中的 127.0.0.1:80 服务映射到本地主机的 8080 端口。

验证:在远程主机上开启 80 端口服务,本地主机不做操作,本地主机执行上述命令。此时,访问 http://127.0.0.1:8080 等同于访问 example.com 主机中的 http://127.0.0.1:80

应用:

  • 本地调试远程服务
  • 访问受限环境的某个服务 (远程主机中 mysql 服务端不开放外网访问的情况下,在本地主机直接连接 mysql 服务)

2、远程转发(-R)

访问远程主机端口时,远程主机将访问请求转发到本地主机服务上。

格式:SSH -R [远程主机:]远程主机端口:本地主机:本地主机端口 远程用户名@远程主机地址

举例:SSH -R 80:127.0.0.1:8080 [email protected]

解释:将本地的 8080 端口服务映射到 example.com 主机中的 localhost:80 端口。

验证:在本地主机开启 8080 端口服务,远程主机不做操作,本地主机执行上述命令。此时,访问 http://example.com 等同于访问本地主机中的 http://127.0.0.1:8080

应用:

  • 让远程主机能够通过本地主机的某个代理访问到外网。(服务器访问 GitHub 都是泪)
  • 将本地开发的应用映射到有公网 IP 的远程主机,实现外网访问内网的应用。(内网穿透)

注意: 要实现远程转发需要在远程主机上配置一些信息

  • /etc/ssh/sshd_config 中把 AllowTcoForwarding 选项设置为 yes
  • /etc/sysctl.conf 中把 net.ipv4.ip_forward 设置为 1

多说一点:

默认转发到远程主机绑定的是 127.0.0.1 ,也就是只能本机访问。

/etc/ssh/sshd_config 中把 GatewayPorts 设置为 yes ,就会绑定到 0.0.0.0

如果没有修改权限,办法也比困难多:

本地主机执行: SSH -R 80:127.0.0.1:8080 [email protected]

远程主机执行: SSH -L 0.0.0.0:8080:127.0.0.1:8080 [email protected]


有没有一种可能,一条命令就行:SSH -R 0.0.0.0:80:127.0.0.1:8080 [email protected]

3、动态转发(-D)

本地转发和动态转发都是针对单一端口转发,而动态转发不受端口限制。换言之,一些没有端口号的应用,比如浏览器等就能使用了。

格式:SSH -D [本地主机:]本地主机端口 远程用户名@远程主机地址

举例:SSH -D 50000 [email protected]

解释:该命令创建一个 SOCKS 代理,通过该代理发出的数据包都经过 example.com 转发出去。

验证:远程主机不做操作,本地主机执行上述命令。

  • 浏览器:在本地主机浏览器中设置使用 SOCKS 代理 127.0.0.1:50000 ,然后浏览器就能访问 example.com 中任何 IP 或服务。
  • 终端:export http_proxy="socks5://127.0.0.1:50000" , export https_proxy="socks5://127.0.0.1:50000"
  • SSH:ssh -o ProxyCommand='/usr/bin/nc -X 5 -x 127.0.0.1:5000 %h %p' user@host2 未验证。

应用:

  • 访问受限网络中的多种服务
  • FQ

二、总结

知识虽小却有大用处。解决了我的一些痛点:

  • 想在本地直接连接服务器的数据库,但是又不想暴露数据库到外网。
  • 在服务器上下载 GitHub 代码一言难尽,以前都是先本地下载,再上传到服务器。
  • 本地部署,外网临时访问。其实就是内网穿透。

参考: