SSH 隧道配置如何指定 IPv6 地址进行端口转发?

文章导读
在 SSH 隧道中指定 IPv6 地址进行端口转发,关键在于使用方括号将 IPv6 地址括起来,以区分地址中的冒号和端口分隔符。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 参考来源
A A

在 SSH 隧道中指定 IPv6 地址进行端口转发,关键在于使用方括号将 IPv6 地址括起来,以区分地址中的冒号和端口分隔符。

先说结论:SSH 原生支持 IPv6 端口转发,但必须在配置中用方括号包裹 IPv6 地址,否则解析会失败。

  • 适合:需要在 IPv6 网络环境下进行本地或远程端口映射的场景
  • 先准备:确认本地和服务端均已启用 IPv6 栈且地址可达,远程转发需检查服务端 GatewayPorts 配置
  • 验收:使用 ss 或 netstat 命令检查监听地址是否为 IPv6 格式

命令速用版

本地端口转发(Local Forwarding)指定 IPv6 监听地址和目标 IPv6 地址的通用格式如下:

ssh -L [本地 IPv6 地址]:本地端口:[目标 IPv6 地址]:目标端口 用户名@SSH 服务器

例如,将本地的 8080 端口通过隧道转发到目标服务器的 2001:db8::1 的 80 端口:

ssh -L [::1]:8080:[2001:db8::1]:80 user@example.com

如果是远程端口转发(Remote Forwarding),语法逻辑相同,但需确保服务端 sshd_config 中开启了 GatewayPorts 才能监听非本地地址:

ssh -R [::]:8080:[2001:db8::1]:80 user@example.com

为什么会这样

IPv6 地址本身包含冒号(:),而 SSH 端口转发语法中也是用冒号来分隔地址和端口。如果不加方括号,SSH 客户端无法判断哪里是地址的结束、哪里是端口的开始。方括号的作用是明确界定地址范围,这是网络编程中处理 IPv6 地址的标准惯例,不仅限于 SSH,很多支持 IPv6 的服务配置都遵循这一规则。

分步处理

1. 确认 IPv6 环境

在执行隧道命令前,先确认本地机器和目标机器都有 IPv6 地址。在 Linux 下可以使用以下命令查看:

ip -6 addr

确保你打算绑定的 IPv6 地址出现在列表中。如果是要绑定到所有 IPv6 接口,通常使用 ::[::]

2. 构造 SSH 命令

SSH 隧道配置如何指定 IPv6 地址进行端口转发?

根据需求选择 `-L`(本地转发)或 `-R`(远程转发)。记得给 IPv6 地址加上方括号。如果目标地址是域名,且该域名解析出 IPv6 地址,通常也需要方括号包裹,但建议直接使用 IPv6 字面量以减少 DNS 解析不确定性。

3. 检查服务端配置(仅限远程转发或特定绑定)

如果你使用 `-R` 或者希望 SSH 服务端监听特定的 IPv6 地址,需要检查服务器上的 /etc/ssh/sshd_config 文件。确保 ListenAddress 没有强制限制为 IPv4。默认情况下,许多配置会监听所有地址,但为了安全或明确性,有时会显式配置:

ListenAddress ::

注意:若希望远程转发端口能被外部主机访问(而非仅限服务端 localhost),必须启用 GatewayPorts。修改配置前建议先备份:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

编辑配置文件,添加或修改以下行:

GatewayPorts yes

修改后需要重启 sshd 服务生效(建议先开启新会话测试,避免中断当前连接):

sudo systemctl restart sshd

怎么验证是否生效

1. 检查监听状态

在建立隧道后,在本地(对于 -L)或服务器(对于 -R)使用 ss 命令查看监听端口。IPv6 的监听地址通常会显示为 :: 或具体的 IPv6 地址:

sudo ss -tlnp | grep 8080

如果看到 [::]:8080[2001:db8::1]:8080,说明 IPv6 绑定成功。如果看到 0.0.0.0:8080,则可能只绑定了 IPv4。

SSH 隧道配置如何指定 IPv6 地址进行端口转发?

2. 测试连通性

使用 curl 测试隧道是否通畅。注意 curl 访问 IPv6 地址时也需要方括号,或者使用 -g 参数关闭 glob 解析:

curl -g http://[::1]:8080

如果能看到目标服务的响应,说明隧道转发正常。

常见坑

1. 忘记加方括号

这是最常见的错误。写成 ssh -L 2001:db8::1:80... 会导致 SSH 解析端口号失败,直接报错。

2. 远程转发权限限制(GatewayPorts)

默认情况下,SSH 远程转发(-R)绑定的端口仅监听服务端 localhost(127.0.0.1 或 ::1)。若需让外部机器通过 IPv6 访问该转发端口,必须在服务端 sshd_config 中设置 GatewayPorts yes,否则隧道建立成功但外部无法连接。

3. 防火墙拦截

IPv6 的防火墙规则(如 ip6tablesnftables)是独立于 IPv4 的。即使隧道配置正确,如果防火墙放行了 IPv4 但拦截了 IPv6,连接也会超时。检查时请专门查看 IPv6 的防火墙规则。

参考来源

  • OpenSSH ssh_config 手册页,说明端口转发语法及地址格式,https://www.man7.org/linux/man-pages/man5/ssh_config.5.html
  • OpenSSH sshd_config 手册页,说明 ListenAddress 配置项,https://www.man7.org/linux/man-pages/man5/sshd_config.5.html