SSH 隧道的 -L 和 -R
SSH 隧道支持两种主要方向的端口转发:本地转发(-L)和 远程转发(-R)。两者的功能和限制略有不同,以下分别详细介绍其语法、各部分含义及使用限制。
-L:本地转发
功能
-L 用于将本地端口上的请求转发到远程主机上的指定端口。
语法
bash复制代码ssh -L [bind_address:]local_port:target_host:target_port user@ssh_server
参数含义
bind_address(可选):- 本地监听的地址。
- 默认值是
127.0.0.1,表示仅允许本地主机访问。 - 可以设置为
0.0.0.0,允许其他主机通过网络访问本地监听的端口。 - 例子:
127.0.0.1:仅本地访问。0.0.0.0:所有网络接口都可以访问。
local_port:- 本地端口号。
- 这是隧道会监听的端口,客户端通过该端口访问隧道。
target_host:- 数据实际转发到的远程目标主机。
- 通常是
ssh_server所能访问的内部网络地址,也可以是localhost(相对于ssh_server而言)。
target_port:- 数据实际转发到的远程目标端口。
user@ssh_server:- 用于建立隧道的 SSH 服务器。
ssh_server是隧道的中继服务器,通过它将请求从本地传输到目标主机。
限制
- 如果
bind_address是127.0.0.1,隧道只能在本地访问,其他主机无法访问。 - 本地端口号
local_port不应被其他服务占用,否则会失败。 - 目标主机(
target_host)必须是ssh_server可访问的主机。
例子
- 简单本地转发:
将本地8080端口的流量转发到ssh_server上的localhost:3306(MySQL 端口):bash复制代码ssh -L 8080:localhost:3306 user@ssh_server - 跨网络访问:
将本地0.0.0.0:8080绑定为公网可访问,转发到远程192.168.1.10:80:bash复制代码ssh -L 0.0.0.0:8080:192.168.1.10:80 user@ssh_server
-R:远程转发
功能
-R 用于将远程主机上的端口请求转发到本地主机上的指定端口。
语法
bash复制代码ssh -R [bind_address:]remote_port:target_host:target_port user@ssh_server
参数含义
bind_address(可选):- 远程服务器监听的地址。
- 默认值是
127.0.0.1,表示只能在 SSH 服务器上本地访问该端口。 - 设置为
0.0.0.0,允许其他主机通过网络访问 SSH 服务器的这个端口。
remote_port:- 远程主机上的端口号。
- SSH 服务器会监听这个端口,将接收到的流量转发到本地。
target_host:- 本地主机上实际接收请求的目标主机。
- 相对于运行 SSH 客户端的主机。
target_port:- 本地目标主机的端口号。
user@ssh_server:- 用于建立隧道的 SSH 服务器。
- SSH 客户端会在该服务器上打开
remote_port,并将流量转发回本地。
限制
- 如果
bind_address是127.0.0.1,远程端口只能由ssh_server本机访问,外部无法访问。 - 如果远程端口(
remote_port)需要公网访问,则ssh_server必须允许GatewayPorts。- 在
ssh_server的/etc/ssh/sshd_config中需要设置:plaintext复制代码GatewayPorts yes
- 在
remote_port不应被其他服务占用,否则会失败。
例子
- 简单远程转发:
将ssh_server的9000端口转发到本地localhost:8080:bash复制代码ssh -R 9000:localhost:8080 user@ssh_server - 允许外部访问:
将ssh_server的0.0.0.0:9000绑定为公网可访问,转发到本地192.168.1.10:22:bash复制代码ssh -R 0.0.0.0:9000:192.168.1.10:22 user@ssh_server
区别总结
| 特性 | -L(本地转发) | -R(远程转发) |
|---|---|---|
| 隧道监听端口的位置 | 本地主机监听端口 | SSH 服务器监听端口 |
| 隧道目标 | 远程主机上的目标端口 | 本地主机上的目标端口 |
| 常用场景 | – 访问内网服务 – 数据库连接隧道 | – 暴露本地服务 – P2P 数据传输 |
| 绑定公网限制 | – 本地可设置 0.0.0.0(开放所有接口) | – 必须在 SSH 服务器中启用 GatewayPorts |
| 默认监听范围 | 127.0.0.1(本地回环接口) | 127.0.0.1(远程回环接口) |
常见问题与解决方法
- 远程转发无法被外部访问:
- 检查
GatewayPorts是否启用。 - 在
/etc/ssh/sshd_config中设置:plaintext复制代码GatewayPorts yes - 重启 SSH 服务:bash复制代码
sudo systemctl restart sshd
- 检查
- 端口被占用:
- 检查是否有其他服务正在监听该端口:bash复制代码
sudo ss -tuln | grep <port> - 如果被占用,选择其他未使用端口。
- 检查是否有其他服务正在监听该端口:bash复制代码
- 访问被防火墙阻止:
- 确保本地或远程服务器的防火墙允许相应端口通信。
通过合理设置 -L 和 -R,你可以根据需求选择本地转发或远程转发,灵活实现内外网服务的桥接。