Natter 端口映射实验:验证 STUN 可达性并安全清理

Natter 端口映射实验:验证 STUN 可达性并安全清理

Marcus Reid
2026年10月11日· 7 分钟阅读

Natter 端口映射尝试维持 NAT 映射并把连接转发给本地服务。STUN 报出的公网地址,不证明获准外部客户端能访问认证服务。本文限定 Ubuntu 24.04 LTS x64、Python 3.12、Natter 2.2.1 和一个 TCP 端点,未在作者网络完成端到端自测。

关键要点

  • 仅测试自有或获授权网络、服务及外部客户端。
  • 使用双向 TLS 保护固定非敏感响应,不暴露管理界面。
  • 始终保留单来源防火墙和证书校验。
  • 停止服务、撤销访问;停止保活不会立即抹除 NAT 状态。

Natter 端口映射能证明什么?

STUN 让客户端知道服务器看到的地址信息,不是通用入站服务。映射与过滤是不同条件,结果会随目标和网络变化。RFC 8489 说明协议角色,不保证任意 CGNAT 都能完成实验。[3]

按自建责任清单确定访问与清理所有者。共享公网地址的解释和家庭 NAT 排障有助理解前提,不能把 NAT 标签当成功连接。

若只需要普通出站隐私,先比较 VPN 出口与入站端口转发。发布本地服务是另一项责任;本实验不保证穿透、不统计运营商成功率,也不扫描第三方。

VPN 基础导览解释出站访问模型,不证明本实验托管端点可达。

Natter NAT 条件和恢复前提有哪些?

使用专用 Ubuntu 局域网主机和另一网络中的自有外部客户端。示例 LAN 地址 192.168.50.10,Natter 本地 TCP 58961,loopback TLS 8443;实际 LAN 地址须全文替换。记录路由、IPv4/IPv6、监听、防火墙及外部客户端公网来源。

保留不依赖此映射且已验证的管理路径。示例要求已启用、由操作者管理的 UFW,默认拒绝未请求入站,且无竞争防火墙管理器。不在 SSH 中盲目启用 UFW、不清空规则、不关防火墙、不改生产 NGINX;不具备基线就停止,准备专用主机。

需要允许的 TCP STUN、保活通信和兼容 NAT 行为。多层 NAT、按目标变化的映射或过滤可能阻断外部访问。路由器 WAN 私有地址只是线索,不能证明整个供应商拓扑。失败不以 DMZ、UPnP 或公开 NAS 管理、RDP、数据库补救。

步骤 1:准备短期认证 TLS 服务

使用尚未安装 NGINX、没有其既有配置、服务或 mask 的全新专用主机,否则停止。Ubuntu 软件包通常会启动默认站点;先屏蔽新服务启动,再从可信仓库安装。记录本次新增软件包及版本。[8][9]

sudo systemctl mask nginx.service
sudo apt update
sudo apt install nginx openssl curl python3
systemctl is-enabled nginx.service
systemctl is-active nginx.service
ss -ltnp 'sport = :80 or sport = :8443 or sport = :58961'
readlink /etc/nginx/sites-enabled/default

预期状态为 masked、inactive(这些状态命令返回非零码),所列端口均不得被占用。安装失败或 NGINX 已启动就停止并清理。只有 readlink 显示本次安装创建的链接指向 /etc/nginx/sites-available/default,才用 sudo unlink /etc/nginx/sites-enabled/default 删除该链接,否则停止;不删其他站点文件。

用 ip route get 127.0.0.2 确认本地回环路由。TLS 使用 127.0.0.2,因为 Natter 2.2.1 会把精确目标 127.0.0.1 改为自身 LAN 地址;目标与监听必须一致。[7] 以下建立私有两天有效 CA 和临时证书。[5][6]

mkdir -m 700 "$HOME/natter-lab"
cd "$HOME/natter-lab"
umask 077
openssl req -x509 -newkey rsa:3072 -nodes -days 2 -keyout ca.key -out ca.crt -subj '/CN=Natter Lab CA'
openssl req -new -newkey rsa:3072 -nodes -keyout server.key -out server.csr -subj '/CN=natter-lab.example'
printf 'subjectAltName=DNS:natter-lab.example\nextendedKeyUsage=serverAuth\n' > server.ext
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 2 -extfile server.ext -out server.crt
openssl req -new -newkey rsa:3072 -nodes -keyout client.key -out client.csr -subj '/CN=Owned external client'
printf 'extendedKeyUsage=clientAuth\n' > client.ext
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAserial ca.srl -days 2 -extfile client.ext -out client.crt
sudo install -d -m 700 /etc/nginx/natter-lab
sudo install -m 600 server.key /etc/nginx/natter-lab/server.key
sudo install -m 644 server.crt ca.crt /etc/nginx/natter-lab/

ca.key 留在操作者私有主机,不传给客户端。仅经既有认证传输方式把 ca.crt、client.crt、client.key 复制给自有外部客户端。客户端私钥权限继续收紧,不放公开文章或共享盘。

用 sudoedit 把下列保存为 /etc/nginx/conf.d/natter-lab.conf。只增加 loopback 监听,要求本实验 CA 签发的客户端证书,/check 返回固定文本。不复用信任其他用户客户端证书的 CA。[4]

server {
    listen 127.0.0.2:8443 ssl;
    server_name natter-lab.example;
    ssl_certificate /etc/nginx/natter-lab/server.crt;
    ssl_certificate_key /etc/nginx/natter-lab/server.key;
    ssl_client_certificate /etc/nginx/natter-lab/ca.crt;
    ssl_verify_client on;
    ssl_protocols TLSv1.2 TLSv1.3;
    access_log off;
    location = /check { return 200 "natter-lab-ok\n"; }
    location / { return 404; }
}

解除屏蔽前完整检查 nginx -T 输出:只能有 127.0.0.2:8443 ssl 监听,不得有默认站点或 IPv6 监听;不符就停止。检查配置、解除屏蔽、禁用开机启动后手动启动,用 ss 确认监听。第一条本地请求应返回固定响应,无客户端证书的请求不得返回;这是预期检查,不是作者观测。

sudo nginx -T
sudo nginx -t
sudo systemctl unmask nginx.service
sudo systemctl disable nginx.service
sudo systemctl start nginx.service
ss -ltnp 'sport = :80 or sport = :8443 or sport = :58961'
curl --noproxy '*' --cacert ca.crt --cert client.crt --key client.key --resolve natter-lab.example:8443:127.0.0.2 https://natter-lab.example:8443/check
curl --noproxy '*' --cacert ca.crt --resolve natter-lab.example:8443:127.0.0.2 https://natter-lab.example:8443/check

检查失败,按步骤 4 清理已创建资源;若仍处于 masked 状态,用 sudo systemctl unmask nginx.service 只撤销本实验新增的屏蔽。保留证书有效期及服务器名验证,不用 curl -k。

步骤 2:以最小权限运行 Natter STUN 测试

下载官方 2.2.1 脚本到私有实验目录,阅读后用普通账户运行;管理配置及防火墙需要提权。[1][2]

此版本的 -i 选择 STUN/保活地址,但 socket 转发器实际监听所有 IPv4 地址,不能把它当作入站绑定保证。启动前检查 sudo ufw status verbose、sudo ufw show raw:所有接口须默认拒绝入站,且没有向 58961 放行的宽规则,否则停止。将 OWNED_CLIENT_PUBLIC_IP 替换成本主机所见自有外部来源,仅允许该来源到保留的 LAN 目标地址。[7]

curl --fail --location --proto '=https' --proto-redir '=https' -o natter.py https://github.com/MikeWang000000/Natter/releases/download/2.2.1/natter.py
python3 natter.py --version
sudo ufw allow in proto tcp from OWNED_CLIENT_PUBLIC_IP to 192.168.50.10 port 58961 comment 'natter-lab'
python3 natter.py -i 192.168.50.10 -b 58961 -m socket -t 127.0.0.2 -p 8443 -q

在第二个终端检查 ss -ltnp 'sport = :8443 or sport = :58961':预期 NGINX 位于 127.0.0.2:8443,Natter 位于 0.0.0.0:58961;后者必须由防火墙限制为单一获准来源及目标地址。不增加 IPv6 或手动路由器转发。

-m socket 转发 loopback TLS,不安装 NAT 表规则;-q 在映射地址变化时结束本次会话。不加 -U、守护进程、重试循环、通知脚本或开机服务。Natter 仍会访问其 STUN/保活目标,只用获准网络服务,策略不允许就停止。

私下记录报出的公网 IP、端口,公网端口不必等于 58961。本实验只允许自有外部来源,Natter 内置可达性检查可能因此失败;决定性检查是下一步该来源的认证服务请求,不为让自动测试成功而扩大防火墙。

步骤 3:从自有外部客户端验证

把外部客户端放到独立目标网络,核实来源仍匹配规则。同局域网请求可能只验证 hairpin,不代替真实外部检查。客户端证书和私钥私下保存。

按当前映射替换 PUBLIC_IP 和两处 PUBLIC_PORT。--resolve 指定连接地址,同时保留 TLS 名称 natter-lab.example,不需公网 DNS 或 hosts 修改。--noproxy '*' 仅影响本次请求,不修改已有代理或 VPN。

curl --noproxy '*' --connect-timeout 10 --max-time 20 --cacert ca.crt --cert client.crt --key client.key --resolve natter-lab.example:PUBLIC_PORT:PUBLIC_IP https://natter-lab.example:PUBLIC_PORT/check
curl --noproxy '*' --connect-timeout 10 --max-time 20 --cacert ca.crt --resolve natter-lab.example:PUBLIC_PORT:PUBLIC_IP https://natter-lab.example:PUBLIC_PORT/check

带证书请求应返回固定文本,无证书请求不得返回它。检查 HTTP 状态和内容,不只看 curl 退出码,因为 HTTP 拒绝也可能使进程成功退出。错误 CA 或证书不含的服务器名也应验证失败,不能靠关闭 TLS 校验修复。

怎样解释失败与映射变化?

读者现象可支持结论下一项动作
STUN 未报可用地址此 STUN 路径不可用查获准出站;未解决就停止
已报映射但外部 TCP 超时尚未证明可达查来源规则、映射/过滤与 NAT 层数
TCP 已连接但 TLS 身份失败未确认预期服务身份查 SAN、CA、端点和期限,保留校验
带证书成功,无证书也成功访问控制错误停 Natter,修客户端证书强制要求
映射变动,Natter 退出原端点已过时核对网络,审查后才手动再启

失败仍按失败记录;服务请求未成功,不发布“已穿透”的 NAT 标签。浏览器 STUN 地址暴露与认证入站服务是不同证据,不能互相证明。

示例只有 IPv4 监听。其他服务独立的 IPv6 暴露需另查,不宣称保护整台主机网络。保留已有保护,只检查本次自有资源。

步骤 4:停止、撤销并验证清理

在本次 Natter 前台按 Ctrl+C。只删除新增来源规则,停止本次新装 NGINX 并禁用其开机启动,再删除实验配置和复制的凭据。所列监听均不得保留:

sudo ufw delete allow in proto tcp from OWNED_CLIENT_PUBLIC_IP to 192.168.50.10 port 58961
sudo systemctl disable --now nginx.service
sudo rm /etc/nginx/conf.d/natter-lab.conf
sudo rm /etc/nginx/natter-lab/server.key /etc/nginx/natter-lab/server.crt /etc/nginx/natter-lab/ca.crt
sudo rmdir /etc/nginx/natter-lab
ss -ltnp 'sport = :80 or sport = :8443 or sport = :58961'

停止保活后 NAT 映射可能暂留。因此移除监听和服务后,用最后已知映射重复认证外部请求,必须不再返回实验文本。超时或拒绝可以证明该端点不可访问,不证明路由器所有状态即时删除。

证据不再需要时删除两端临时凭据,只恢复实验改动并验证独立管理路径。保持默认站点禁用。对照安装记录审查卸载方案,只移除本次新增且没有其他使用者的软件包,不做宽泛 autoremove。若准备阶段停在 masked 状态,停止新服务后只撤销实验新增的屏蔽。移除隔离 CA 信任及服务只撤销本实验访问,不撤销其他证书。

以后升级先保留旧脚本、无秘密调用参数、私有配置备份和基线,再替换版本。重复正向、拒绝、地址变化及清理检查;不把失败映射变成无人看管的无限重试服务。

总结

  • STUN 地址发现和认证外部可达性分开验证。
  • 测试端点无敏感内容,同时限制证书与来源。
  • NAT 不兼容及身份失败都是合法停止结果。
  • 删除监听、服务、规则和凭据,再验证外部拒绝。

常见问题

报出 STUN 地址就说明端口可达吗?

报出的地址描述 STUN 服务器看见的信息,映射与过滤条件仍可能阻止目标外部客户端访问。

Natter 一定能穿过 CGNAT 吗?

CGNAT 标签不能推出通用结果,仍需兼容映射、过滤、获准通信,以及真正外部服务检查。

无敏感响应为什么还用双向 TLS?

固定响应限制数据暴露,客户端证书限制接收者;测试互联网可达监听时,两项边界都有价值。

本地检查能代替外部客户端吗?

本地请求只核服务和认证前提;独立网络中的客户端才可证明所声称的真实外部可达性。

为什么 Natter 自带检查可能失败?

本实验只允许一个自有外部来源,范围外的自动检查者可能被阻断,即使自有客户端认证成功。

停止 Natter 会立刻删除映射吗?

路由器可能保留状态。应停目标服务、撤销规则和凭据,再发外部请求,不假定映射立即到期。

能改为暴露 NAS 管理页吗?

这里仅用短期固定响应 TLS 端点;管理界面具有不同风险与权限,不属于本实验允许范围。

免责声明:仅在获授权基础设施和允许的网络操作。上文均为预期检查,不声称运营商成功率或已完成作者网络测量。

来源:

  1. Natter 2.2.1
  2. Natter usage
  3. RFC 8489 Session Traversal Utilities for NAT
  4. NGINX ngx_http_ssl_module
  5. OpenSSL req
  6. OpenSSL x509
  7. Natter 2.2.1 implementation
  8. Ubuntu Install nginx
  9. Ubuntu 24.04 systemctl manual

Sources checked 2026 年 10 月 11 日。


延伸阅读:

开启 3 天免费试用

注册即可免费体验全部高级功能。

*仅限新用户;每位用户只能获得一次试用。

Natter 端口映射实验:验证 STUN 可达性并安全清理 | AethoVPN