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