默认情况下 SSH 远程转发只监听本地回环地址,若需外部访问,需在服务端开启 GatewayPorts 选项,但要注意暴露服务的风险。
先说结论:外部无法访问是因为 SSH 服务端默认将远程转发端口绑定在 127.0.0.1,修改服务端配置即可解决,但需评估安全影响。
- 适合:需要从公网访问内网服务且信任网络环境的场景
- 先准备:确认服务端 sshd_config 权限及防火墙规则
- 验收:使用外部机器测试端口连通性并检查监听地址
命令速用版
若你已确认安全风险,可在 SSH 服务端执行以下操作快速开启(含配置去重检查):
# 检查是否存在配置,不存在则追加,存在则修改避免重复
if grep -q "^GatewayPorts" /etc/ssh/sshd_config; then
sed -i 's/^GatewayPorts.*/GatewayPorts yes/' /etc/ssh/sshd_config
else
echo "GatewayPorts yes" >> /etc/ssh/sshd_config
fi
# 重载 SSH 服务配置
systemctl reload sshd
# 检查端口监听状态(请替换<端口号>为实际端口)
ss -tlnp | grep <端口号>
安全建议:开启后建议配合防火墙限制源 IP,避免服务直接暴露公网:
# firewalld 示例:仅允许特定 IP 访问转发端口
firewall-cmd `--add-rich-rule`='rule family="ipv4" source address="信任 IP" port port="<端口号>" protocol="tcp" accept'
为什么会这样
SSH 的远程端口转发(RemoteForward)功能,默认出于安全考虑,会将服务端监听的转发端口绑定在本地回环接口(127.0.0.1)。这意味着只有服务端本机才能访问该端口,外部机器发起的连接会被拒绝。
要允许外部访问,必须更改 SSH 服务端的行为,使其将转发端口绑定到所有网络接口(0.0.0.0)。这一行为由服务端的 GatewayPorts 配置项控制。
分步处理
1. 备份配置文件
修改前务必备份,防止配置错误导致无法远程连接:
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
2. 编辑服务端配置
使用编辑器打开 /etc/ssh/sshd_config,查找 GatewayPorts 行。如果没有则新增,确保设置为 yes:
GatewayPorts yes
该选项有三个值:no(默认,仅本地)、yes(允许外部)、clientspecified(允许客户端指定)。一般场景选 yes 即可。注意:确保文件中只存在一行 GatewayPorts 配置,避免重复导致服务重载警告。
3. 重启或重载服务
配置生效后需重载服务:
# systemd 系统
systemctl reload sshd
# 或旧版 init 系统
service ssh restart
4. 检查防火墙
即使 SSH 配置正确,系统防火墙也可能拦截外部请求。检查 iptables 或 firewalld 是否放行了对应端口,并建议限制源 IP。
怎么验证是否生效
1. 检查监听地址
在服务端执行以下命令,确认转发端口是否绑定在 0.0.0.0 而非 127.0.0.1:
ss -tlnp | grep <转发端口号>
# 请替换<转发端口号>为实际端口,例如 8080
若显示 0.0.0.0:端口 或 *:端口,说明监听配置已生效;若显示 127.0.0.1:端口,则配置未生效。
2. 外部连通性测试
找一台与 SSH 服务端不同网络的机器,使用 telnet 或 curl 测试:
telnet 服务端 IP 转发端口号
若能连通,说明外部访问已打通。
常见坑
1. 安全风险暴露
开启 GatewayPorts 后,原本仅限内网访问的服务可能直接暴露在公网。如果转发的是数据库或未加密服务,容易被扫描攻击。强烈建议配合防火墙限制源 IP 访问,不要对所有 IP 开放。
2. 配置项重复
直接使用 echo 追加配置可能导致 sshd_config 存在重复项,引发服务重载警告或配置冲突。修改前请先 grep 检查是否存在。
3. 客户端配置混淆
GatewayPorts 是服务端配置,不是在发起转发的客户端配置。很多用户在客户端 ssh_config 中修改无效。
4. SELinux 拦截
在开启 SELinux 的系统上,SSH 端口转发可能受策略限制。若配置生效但仍无法连接,可尝试临时 setenforce 0 排查是否为 SELinux 问题。
5. 端口冲突
确保服务端该端口未被其他程序占用,否则 SSH 转发会建立失败。
参考来源
- OpenSSH Manual, sshd_config Man Page, GatewayPorts option description
- Linux ss command documentation, socket statistics