防火墙该放行哪些 VPN 端口:逐协议说明
PPTP 需要 TCP 1723 加 GRE,L2TP/IPsec 需要 UDP 500 和 4500 加 ESP,SSTP、OpenVPN 和 WireGuard 各需一个端口。以下是要放行的内容。
防火墙能否放行一条 VPN 隧道,取决于两条彼此独立的规则:客户端拨号所用的端口,以及承载载荷的协议。只开前者,隧道能完成认证,却不再传输任何数据。最低配置是:PPTP 需要一个 TCP 端口加 GRE,L2TP/IPsec 与 IKEv2 需要两个 UDP 端口加 ESP,SSTP、OpenVPN 和 WireGuard 各需一个端口。方向、状态跟踪和 NAT 决定其余部分。
从客户端拨号的端口开始
每一类协议都有一个客户端最先联系的入口,放行规则必须点名这个入口。PPTP 客户端连接 TCP 1723。L2TP/IPsec 在 UDP 500 上启动 IKE,启用 NAT 穿越后转到 UDP 4500,L2TP 帧本身位于隧道内的 UDP 1701。SSTP 用 TCP 443 上的 TLS 封装会话,IKEv2 在 UDP 500 和 4500 上协商,OpenVPN 默认用 UDP 1194,但常被改到 TCP 443,WireGuard 则在 UDP 51820 上监听。
| Family | Rule to add on the gateway | Typical mistake |
|---|---|---|
| WireGuard | UDP port from ListenPort, for the peer address | Assuming 51820 when the config says otherwise |
| OpenVPN | The configured UDP or TCP port, often 443 | Opening 1194 after the server moved |
| SSTP | TCP 443 limited to the gateway IP | Allowing 443 to any destination |
| IKEv2 | UDP 500 and UDP 4500, plus ESP | Allowing only 500 and losing NAT-T |
| L2TP/IPsec | UDP 500, 4500, ESP, and 1701 inside the tunnel | Exposing 1701 to the internet |
| PPTP | TCP 1723 and IP protocol 47 | Writing a rule for TCP 47 |
这些数字应视为默认值,而非固定属性。WireGuard 接口使用其配置声明的任意监听端口,OpenVPN 服务器也可以停在管理员选定的任意端口上。写规则前先读服务器配置,因为为 1194 打开的防火墙对已迁到 443 的服务器毫无用处。
第三列正是大多数变更工单出错的地方。规则存在,却指向错误的目地、方向或传输方式。
GRE 与 ESP 是协议号,不是端口
GRE 与 ESP 根本没有端口,所以只接受端口号的防火墙表单无法表达它们。GRE 是 IP 协议 47,ESP 是 IP 协议 50,两者都通过 IP 头中的协议字段匹配。把规则写成 TCP 端口 47 什么也匹配不到,PPTP 策略看起来正确,却在握手之后丢弃每一个数据包。
家用路由器把这件事藏在“穿透”勾选框后面,勾选后会安装协议规则,对 GRE 还会装上映射流量所需的 NAT 辅助模块。在真正的防火墙上要自己加协议:允许 IP 协议 47 到 PPTP 服务器,允许 IP 协议 50 到 IPsec 网关。平台没有协议字段时,封装就是出路,这也是 IKEv2 能回落到 UDP 4500、OpenVPN 和 WireGuard 从不遇到该问题的原因。
责怪客户端之前,先确认规则实际匹配的是什么。网关上始终为零的包计数器说明规则从未触发,客户端怎么重装都改变不了这一点。
方向、状态与 NAT 会改变答案
客户端向外拨号与网关向内监听是两种不同需求,同一份端口清单可能在一个方向上正确、在另一个方向上错误。有状态防火墙会跟踪 500 和 4500 上的 UDP 流,无需第二条规则就能让回包通过。ESP 与 GRE 不带端口,NAT 设备没有可依据的字段,需要辅助模块或封装才能跟随会话。
NAT 穿越是最容易被漏掉的部分。IKEv2 从 UDP 500 开始,检测到 NAT 设备后继续用 UDP 4500,因此只放行 500 的策略会得到一条建立后随即沉默的隧道。L2TP/IPsec 也做同样动作。如果抓包只看到第一次交换而没有持续流量,就去找停在 500 的规则。
每条规则都要记下方向。“允许 UDP 4500”在没说清从哪到哪之前毫无意义,而对漫游客户端正确的规则,对站点到站点的对端通常是错的。
用抓包检查每条路径
抓包要在网关上做,而不是在客户端上:客户端只记录到达的东西。以下过滤器覆盖上述各类协议,并指出缺失的是哪一步:
sudo tcpdump -ni any tcp port 1723
sudo tcpdump -ni any udp port 500 or udp port 4500
sudo tcpdump -ni any proto gre
sudo tcpdump -ni any proto 50
把输出当作序列来读。协商出现而载荷协议不出现时,丢包发生在客户端与网关之间的某处。两者都出现而页面仍然失败时,防火墙已不再是嫌疑对象,去看路由、DNS 或分配给客户端的地址池。
没有 tcpdump 的机器上,同样的证据来自接口计数和规则计数。隧道接口上字节只进不出,指向的是回程路径,而不是最初的放行规则。
留下一套站得住脚的规则
TCP 443 上的 SSTP 对任何基于端口的过滤器来说都与普通 HTTPS 无法区分,网络只允许 Web 流量时这正是关键。443 规则因此应把网关而非整个互联网写成目的地。隧道一通就删掉临时的任意到任意规则。写清哪条规则命中、协议号(如有)以及方向,让下一个人从证据出发。
云上的点到站点网关让选择变得可见:下载的配置文件要么用 443 上的 SSTP,要么用 500 与 4500 上的 IKEv2,只应放行配置实际选中的那一个。在现代网络里 PPTP 不值得为它开 GRE 例外,因为移动运营商常常无视你的防火墙丢弃协议 47。关单前确认规则与服务器配置中的端口一致、协议字段在需要的地方已设置、目的地是网关而不是任意地址。