利用SSH加密隧道,将原本不安全的网络通信封装起来,安全地穿过不可信任的网络(如互联网),实现对特定网络服务的访问或代理。
特性 |
本地端口转发 (-L ) |
远程端口转发 (-R ) |
动态端口转发 (-D ) |
命令发起端 |
本地客户端 |
本地客户端(通常在内网) |
本地客户端 |
转发方向 |
本地 -> 远程网络 |
远程 -> 本地网络 |
本地 -> 任意远程 |
绑定目标 |
固定的单一目标主机和端口 |
固定的单一目标主机和端口 |
动态的,不固定目标 |
本质 |
端口映射 |
端口映射 |
SOCKS代理服务器 |
适用场景 |
从外访问内网特定服务 |
内网穿透,暴露本地服务 |
全局代理,加密所有流量 |
应用程序配置 |
直连localhost:本地端口 |
直连SSH服务器:远程端口 |
配置SOCKS代理 |
本地端口转发(常用)
创建一个本地端口,使发往该端口的通信都通过ssh转发到远程服务器的端口
- 访问位于公司内网(通过公网跳板机)的数据库、Web管理界面等。
- 绕过防火墙限制,访问只允许内网IP访问的服务。
比如目标服务器上开了一个服务80端口,但绑定的是localhost,即只有自己能访问自己。此时在本地上打ssh隧道,转发到目标服务器的80端口,就可以在本地主机上访问目标的80端口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ssh -N -f -L [localip:]localport:target-host:target-port tunnel-host ssh -L [本地IP:]本地端口:目标主机:目标端口 SSH服务器
-L 转发本地端口 -N 只建立连接,不发生命令,不会打开shell -f 后台连接
我在192.168.10.102:80有一个服务 使用192.168.10.100的2345端口去访问它
ssh -N -f -L 2345:192.168.10.102:80 192.168.10.102
ss -tunlp | grep ssh tcp LISTEN 0 128 127.0.0.1:2345 0.0.0.0:* users:(("ssh",pid=2446875,fd=5))
curl 127.0.0.1:2345 ws test
|
远程端口转发
在远程SSH服务器建立的转发规则
与本地端口转发相反,远程转发是通过远程ssh服务器访问本地计算机
访问公网服务器,使其开一个端口,使其他主机通过这个端口来访问本地环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| ssh -N -f -R [remote-ip:]remote-port:target-host:target-port remotehost -R 使用远程端口转发 一般来说远端服务器和ssh服务器就是同一个
我在本地192.168.10.100:8082有一个web服务 使用公有云主机ip为114.55.64.10作为远程服务器,使用其2345端口
先修改下公有云sshd配置 vim /etc/ssh/sshd_config GatewayPorts yes systemctl restart sshd
ssh -f -N -R 2345:127.0.0.1:8082 git@114.55.64.10
netstat -tlnp | grep 2345 tcp 0 0 0.0.0.0:2345 0.0.0.0:* LISTEN 12014/sshd: git tcp6 0 0 :::2345 :::* LISTEN 12014/sshd: git
curl localhost:8082 ws is very pool curl http://114.55.64.10:2345 ws is very pool
|
ssh动态端口转发
ssh动态端口转发指的是本机与ssh服务器之间建立了加密连接,本机内部针对某个端口的通信,都通过加密连接进行转发。
动态转发需要把本地端口绑定到ssh服务器,至于ssh服务器要去访问哪里完全动态
实现与代理服务器类似的功能
1 2 3 4 5 6 7 8
| 例: ssh -N -f -D 2111 remote-host curl +x socks5://localhost:2111 remote-host
也就是localhost的2111端口可以代理流量,将流量转发到www.example.com 那么只要www.example.com能访问到的资源,本地与代理的流量也可以访问到
但现在使用socks5代理已经会被识别了,所以无法使用这种方式来科学上网
|
用于复杂网络环境的跳板
ssh服务器为跳板机的情况下,如果使用本地端口转发,那一个本地端口只能转发到一个对端服务
但内网服务很多的情况下,本地端口转发就不合适了。而动态端口转发之于本地端口转发,就类似于NAPT之于NAT的关系
外部客户端只需要访问其中一台的端口,就可以通过ssh转发到内网的服务
1 2 3 4 5 6 7 8 9 10 11
| 本机192.168.10.100,使用12222端口 将流量转发到192.168.10.102 ssh -f -N -D *:12222 root@192.168.10.102
ss -tunlp | grep 12222 tcp LISTEN 0 128 0.0.0.0:12222 0.0.0.0:* users:(("ssh",pid=2467211,fd=4)) tcp LISTEN 0 128 [::]:12222 [::]:* users:(("ssh",pid=2467211,fd=5))
curl --socks5 192.168.10.100:12222 http://192.168.10.102 ws test
|
需要AllowTcpForwarding yes允许端口转发