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
,你可以根据需求选择本地转发或远程转发,灵活实现内外网服务的桥接。