香港服务器运行 Linux 时,如何结合 OpenVPN + CN2 专线实现企业分支高速互联

凌晨 2:40,香港荃湾机房客户上海分部的 ERP 写入延迟忽然飙到 600ms,跨城同步几乎停摆。公网走 BGP 混线抖动明显,我当机立断切到我们早先拉好的 CN2 GIA 专线 作为底座,再把 OpenVPN 叠在上面做统一的加密与路由编排。三分钟后,延迟回落到 38ms,业务恢复。
那一刻我意识到:“CN2 做底,OpenVPN 做脑” 的组合,才是我们多分支企业内网长期稳定、可控、可观测的答案。
下面这篇,是我把方案从 0 到 1 落地、踩坑、调优、回归的全过程。全程第一人称,没有说教,只有我在机房里一步步折腾出的细节。
1. 场景与目标
- 企业形态:总部 + 上海/深圳/成都三处分支,均需访问香港中心的数据库与对象存储。
- 带宽/时延目标:单分支 200–500 Mbps,有效 RTT(SH⇄HK)< 45ms,成熟期可上 1Gbps。
- 安全与合规:全链路加密、证书可吊销、精细化网段访问控制、可观测可审计。
- 自治与容错:CN2 专线为主,公网(优化过的 443/TCP/UDP)为备;隧道自动存活与健康探测。
2. 拓扑与地址规划(Hub & Spoke)
架构:香港机房做 Hub(集中转发、统一策略),各分支为 Spoke。
隧道形态:OpenVPN TUN(三层路由),避免二层广播风暴;路由发布用 client-config-dir 做精确 iroute。
2.1 地址规划(样例)
| 角色 | 位置 | 物理/Underlay | 隧道/Overlay |
|---|---|---|---|
| HK-Hub(OpenVPN 服务器) | 香港 | CN2 GIA:203.0.113.10/30;公网备 198.51.100.20 |
10.8.0.1/24 |
| Branch-SH | 上海 | CN2 端:203.0.113.6/30 |
业务网:10.10.10.0/24;隧道:10.8.0.10 |
| Branch-SZ | 深圳 | CN2 端:203.0.113.14/30 |
业务网:10.10.20.0/24;隧道:10.8.0.20 |
| Branch-CD | 成都 | CN2 端:203.0.113.22/30 |
业务网:10.10.30.0/24;隧道:10.8.0.30 |
注:CN2 为运营商交付的 L3VPN/专线侧地址;公网为备份入口。
3. 硬件与系统基线
香港 Hub 服务器(物理机)
- 机型:Supermicro 1U
- CPU:AMD EPYC 7402P(24C/48T)
- 内存:64GB
- 磁盘:NVMe 1TB(OS/日志/监控)
- 网卡:Intel X710 10GbE ×2(bond 做 LACP)
- OS:CentOS 7.9(客户环境要求;Ubuntu 20.04+ 同理)
- OpenVPN:2.5.x(支持 tls-crypt-v2、data-ciphers)
分支侧 CPE
可用:MikroTik、H3C、Cisco ISR,或一台小型 x86 盒子(Intel i5/8GB/双网口)跑 Linux + OpenVPN Client。
4. CN2 专线交付对接(Underlay)
专线验收:让运营商开回环测试(RFC 2544/Y.1564),拿到基线:
- HK⇄SH:RTT 33–38ms,丢包 <0.1%
- HK⇄SZ:RTT 27–32ms
- HK⇄CD:RTT 42–48ms
路由与 QoS:要求对端 不做 NAT,分配静态 /30 或 L3 子接口;承诺 CN2 GIA 回程。
BFD/健康检查(可选):部分交付支持 BFD 提升探测灵敏度;没有也没关系,OpenVPN 的 keepalive 能兜底。
旁路备份:在 Hub 侧保留公网入口(443/UDP 与 443/TCP),做策略路由容灾。
5. Linux 基线与内核调优
5.1 系统参数(CentOS 7)
# 开启转发与队列优化
cat >> /etc/sysctl.d/99-vpn.conf <<'EOF'
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.core.netdev_max_backlog = 250000
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_mtu_probing = 1
EOF
sysctl --system
备注:启用 BBR 有助于长肥管道下的吞吐稳定。
5.2 MTU / MSS 计算
CN2 专线一般以太网 MTU 1500,OpenVPN/UDP + TUN 开销后:
建议 TUN MTU = 1450,mssfix = 1420(按实际抓包微调)。
经验值:HK⇄SH 若报文路径有额外封装,降到 tun-mtu 1400 / mssfix 1360 会更稳。
6. OpenVPN 服务端(Hub)部署
6.1 安装
yum install -y epel-release
yum install -y openvpn easy-rsa iproute iptables-services
mkdir -p /etc/openvpn/pki
6.2 CA 与证书(easy-rsa 3.x)
cd /etc/openvpn
make-cadir easy-rsa
cd easy-rsa
./easyrsa init-pki
./easyrsa build-ca nopass # 生产建议设置密码
./easyrsa gen-dh
./easyrsa build-server-full hk-hub nopass
# 为各分支生成证书
./easyrsa build-client-full branch-sh nopass
./easyrsa build-client-full branch-sz nopass
./easyrsa build-client-full branch-cd nopass
openvpn --genkey secret ta.key # 或使用 tls-crypt-v2
6.3 server.conf(关键项标注)
port 443
proto udp
dev tun
user nobody
group nobody
topology subnet
# 加密与握手
tls-version-min 1.2
cipher AES-256-GCM
data-ciphers AES-256-GCM:AES-128-GCM
auth SHA256
tls-server
ca /etc/openvpn/easy-rsa/pki/ca.crt
cert /etc/openvpn/easy-rsa/pki/issued/hk-hub.crt
key /etc/openvpn/easy-rsa/pki/private/hk-hub.key
dh /etc/openvpn/easy-rsa/pki/dh.pem
tls-crypt /etc/openvpn/easy-rsa/ta.key
# 地址池与路由发布
server 10.8.0.0 255.255.255.0
client-config-dir /etc/openvpn/ccd
push "topology subnet"
push "redirect-gateway def1 bypass-dhcp" # 仅需内网可去掉
# 向客户端推送常用内部网段或服务发现
push "route 10.10.0.0 255.255.0.0"
# 健康与 MTU
keepalive 10 30
ping-timer-rem
sndbuf 0
rcvbuf 0
txqueuelen 4000
tun-mtu 1450
mssfix 1420
# 安全与稳定
persist-key
persist-tun
explicit-exit-notify 1
client-to-client
duplicate-cn
# 日志
log-append /var/log/openvpn/openvpn.log
verb 3
6.4 CCD(精确 iroute)
mkdir -p /etc/openvpn/ccd
# 上海分支(branch-sh)
cat > /etc/openvpn/ccd/branch-sh <<EOF
ifconfig-push 10.8.0.10 255.255.255.0
iroute 10.10.10.0 255.255.255.0
EOF
# 深圳分支
cat > /etc/openvpn/ccd/branch-sz <<EOF
ifconfig-push 10.8.0.20 255.255.255.0
iroute 10.10.20.0 255.255.255.0
EOF
# 成都分支
cat > /etc/openvpn/ccd/branch-cd <<EOF
ifconfig-push 10.8.0.30 255.255.255.0
iroute 10.10.30.0 255.255.255.0
EOF
6.5 防火墙与启动
# iptables(生产我更喜欢直观可控)
systemctl enable iptables
iptables -F
iptables -A INPUT -p udp --dport 443 -j ACCEPT
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -o tun+ -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o bond0 -j MASQUERADE # 如需 SNAT
service iptables save
systemctl enable openvpn@server --now
7. 分支客户端部署与策略路由(以 Linux 盒子为例)
7.1 客户端配置 branch-sh.ovpn
client
dev tun
proto udp
remote hk-hub.example.com 443 # 优先走 CN2:可在 CPE 上策略将此域名解析/路由到专线
resolv-retry infinite
nobind
remote-cert-tls server
cipher AES-256-GCM
data-ciphers AES-256-GCM:AES-128-GCM
auth SHA256
tls-version-min 1.2
tls-crypt ta.key
verb 3
persist-key
persist-tun
sndbuf 0
rcvbuf 0
tun-mtu 1450
mssfix 1420
<ca>
...CA...
</ca>
<cert>
...branch-sh.crt...
</cert>
<key>
...branch-sh.key...
</key>
<tls-crypt>
...ta.key...
</tls-crypt>
7.2 CN2 优先 / 公网备份(策略路由)
思路:CN2 接口权重更低(更优);若 CN2 失联,使用默认公网。
# 例:cn2 接口名 cn2if,公网为 wan
ip route add default via 203.0.113.5 dev cn2if metric 50
ip route add default via 198.51.100.1 dev wan metric 200
# 仅将 OpenVPN 服务器的目标路由固定走 CN2
ip route replace $(getent hosts hk-hub.example.com | awk '{print $1}') via 203.0.113.5 dev cn2if metric 10
在 CPE(MikroTik/Cisco)上做策略路由/ECMP 更优雅,这里演示 Linux 盒子思路。
8. 服务发现与访问控制
分支访问总部数据库:在 Hub 上以 iptables 或 nftables 做 源网段 → 目的端口 的白名单。
按用户/系统下发路由:结合 client-config-dir 与 ccd-exclusive 实现精确最小权限。
DNS:建议在 Hub 侧跑 CoreDNS/Unbound,分支通过 push "dhcp-option DNS 10.8.0.1" 使用统一解析。
9. 性能与稳定性调优清单
| 调优项 | 作用 | 结果(HK⇄SH 实测) |
|---|---|---|
tun-mtu 1450 / mssfix 1420 |
降低分片、减少重传 | 吞吐 +18%,RTT 抖动 -25% |
sndbuf/rcvbuf 0(内核自调) |
让内核自适应队列 | 高峰丢包从 0.3% → 0.05% |
txqueuelen 4000 |
提升队列长度 | 500Mbps 时队列饱和告警消失 |
BBR 拥塞控制 |
提升长距离吞吐与稳定 | iperf3 单流 320→420 Mbps |
tls-crypt |
抗探测、减轻握手开销 | 隧道重连更快、探测失败率下降 |
| CN2 主 / 公网备 | 异常切换 | 故障 90s 内恢复可达 |
iperf3 典型:iperf3 -c <hub-tun-ip> -P 4 -t 30
10. 观测与告警
- 连通性:Hub 对每个分支做 smokeping(CN2 & 公网双路径),保留 RTT/抖动趋势。
- 流量/带宽:vnStat + node_exporter + Prometheus + Grafana 出图。
- 日志:OpenVPN verb 3 日志接入 Loki/ELK,关键字告警(TLS Error、Inactivity timeout)。
- 合规审计:在 Hub 做 conntrack 采样与 iptables -j LOG 样本,留 90 天。
11. 常见坑与我的现场处理
MTU 黑洞
现象:Ping 通,应用卡住。
处理:tracepath 发现 1450 以上丢包,降 tun-mtu 1400/mssfix 1360 立刻恢复。
重复网段
现象:新并入的成都分支也用了 10.10.10.0/24。
处理:临时在 CCD 做基于源的 NAT 过渡;窗口期改网段为 10.10.30.0/24,清理路由缓存。
CN2 运营商侧策略变更
现象:夜间回程非 GIA,RTT 飙升。
处理:与运营商对表路由策略,核对 show route 截图;期间自动切回公网备隧道保障业务。
多核加速
现象:OpenVPN 单核瓶颈在 500–700 Mbps。
处理:开 多实例 + 多隧道(SH 分支起 2 个客户端,分别连 :443/:1194),上层采用 ECMP/会话哈希分摊。
TLS 证书吊销
现象:离职同事设备残留。
处理:./easyrsa revoke <cn> + 生成 crl.pem,server.conf 指定 crl-verify,一分钟内生效。
12. 安全基线
- 仅开放必要端口(443/UDP + 443/TCP 备用);管理面走专用跳板。
- 强制 tls-version-min 1.2 / data-ciphers 明确,禁用旧算法。
- 证书分支一机一证,绝不复用;定期轮换 ta.key/tls-crypt。
- 管控平面分离(Ansible 下发 CCD 与策略,GitOps 记录变更)。
13. 关键文件目录结构(Hub)
/etc/openvpn/
├── server.conf
├── ccd/
│ ├── branch-sh
│ ├── branch-sz
│ └── branch-cd
├── easy-rsa/
│ └── pki/{ca.crt, issued/, private/, dh.pem}
├── ta.key
└── logrotate.d/openvpn
/etc/logrotate.d/openvpn 示例:
/var/log/openvpn/*.log {
weekly
rotate 8
compress
missingok
notifempty
create 0640 root adm
postrotate
/bin/systemctl kill -s HUP openvpn@server.service 2>/dev/null || true
endscript
}
14. 验收清单(交付必检)
- HK⇄各分支隧道稳定 48 小时,无异常重连
- iperf3 多流吞吐 ≥ 400 Mbps(CN2 主路径)
- 业务关键端口(DB/ERP/对象存储)可达与 ACL 生效
- 监控看板:RTT/抖动/吞吐/重连次数一目了然
- 证书与 CRL 流程演练、离职注销流程通过
- 备份公网隧道演练(拉闸专线 3 分钟内业务恢复)
15. 扩展与演进
- WireGuard Sidecar:对移动端与开发者场景,旁挂 WG,OpenVPN 仍做“内部骨干”。
- 多 Hub 容灾:在新加坡/东京加备 Hub,路由基于 Geo/Latency 自动择优。
- 分支零信任:叠加 SSO(SAML/OIDC)到管理面,细化身份到路由策略。
回到那次凌晨应急。等图表曲线重新贴着地平线走的时候,我靠在机柜门上,听着风扇的嗡嗡声,心里踏实了。CN2 专线给了确定性,OpenVPN 给了可编排的秩序。
这套方案不是最“闪亮”的,但它经得住凌晨 3 点的告警电话、经得住换运营商的口径、经得住新分支接入的灰度。
如果你也在为跨城互联的抖动发愁,按这篇一步一步走——把“能跑”变成“敢跑”。
附:完整命令速查(精简版)
# Hub
yum -y install epel-release openvpn easy-rsa iptables-services
sysctl -w net.ipv4.ip_forward=1
# easy-rsa 建 CA/证书(见正文)
# 写入 server.conf / ccd / 防火墙规则
systemctl enable --now openvpn@server iptables
# Branch
# 安装 openvpn,放置 branch-*.ovpn 与证书
openvpn --config /etc/openvpn/branch-sh.ovpn --daemon
# 策略路由:CN2 主,公网备