背景
- 组网拓扑:本机(Mac)通过 EasyTier 虚拟网连接一台 Linux 网关节点,该节点所在局域网内有一台 GitLab 服务器。
- 目标:在 Mac 浏览器中直接访问 GitLab 的 Web 页面和 git 服务。
- 方案选型:使用 EasyTier 的子网代理(subnet proxy)功能,让网关节点把 GitLab 地址代理进虚拟网。相比逐端口转发,一次配置全局受益,浏览器、HTTP、SSH 全部透明可用。
过程
(1)声明代理网段
在已通过 easytier 连接的 Linux 节点上的 easytier 配置文件中加入:
| |
需要注意的是:子网代理支持多个 cidr(多个 [[proxy_network]] 段),掩码为 /32 时可以只代理单台主机。
修改后重启服务,并在两个层面确认配置真正生效:
| |
(2)开启内核 IP 转发
子网代理的本质是网关节点把虚拟网流量转发到局域网,Linux 默认不转发数据包,必须显式开启:
| |
验证:
| |
(3)配置防火墙地址伪装
来自虚拟网的流量源地址是虚拟网段(如 10.x.x.x),局域网内的被代理主机不认识这个网段,通常会因为路由不可达或防火墙策略丢弃。需要在网关节点把转发流量的源地址伪装成网关自己的内网地址。
以 firewalld 为例:
| |
注意:firewalld 使用 nftables 后端,iptables 命令看不到这些规则,验证要用 sudo nft list ruleset 查找 masquerade 条目。
另外一个容易忽略的点:虚拟网卡(如 tun0)默认没有被 firewalld 划入任何 zone,如果流量被默认丢弃策略拦下,可显式将其加入 public zone:
| |
配置生效后,Mac ping GitLab 地址正常,但 curl 访问 Web 端口直接超时,分层排查为:
- Mac 本机:无代理环境变量干扰,路由表已正确学到代理网段(目标地址指向 EasyTier 虚拟网卡)。
- 网关节点:已开启 IP 转发并持久化,firewalld 已开启 masquerade(ICMP 抓包确认源地址伪装正常)。
- 关键实验:从网关节点本机 curl GitLab 正常返回,从另一台虚拟网节点 curl 同样超时,且在网关节点物理网卡上完全抓不到 TCP 包,即 SYN 包根本没到达网关。
现象特征: ICMP 能走通整条链路并被正确伪装转发,TCP 的 SYN 却在 EasyTier 内部凭空消失。
查证后确认这是 EasyTier 的已知缺陷(issue #1355):子网代理节点使用内核网络栈时,内置 NAT 在处理 TCP 回包时会改错源地址和端口,导致内核 TCP 连接跟踪不匹配、会话被 RST 终止;ICMP 不走 TCP 连接跟踪,所以幸免。
(4)启用用户态网络栈
解决方案: 在网关节点配置的 [flags] 中启用用户态网络栈:
| |
修改后重启服务,Mac 访问 GitLab 的 80 端口立即恢复,git SSH 端口也验证连通。
(5)端到端验证
回到发起访问的客户端节点逐项验证:
| |
常见异常对照:
- ping 不通:检查网关节点 proxy_cidrs 是否同步(easytier-cli route)、内核 IP 转发是否开启
- ping 通但 TCP 超时:大概率命中内核栈 NAT 缺陷,启用 use_smoltcp;同时确认防火墙 masquerade 已开启
- TCP 通但页面跳转到错误地址:GitLab 的 external_url 配置的是内网主机名或 IP,需在客户端 /etc/hosts 增加解析,或调整 external_url