找回密碼
 立即註冊
    查看: 15|回覆: 0

    WireGuard 連不上:照這七步查,每一步都給你一個確定的答案

    [複製鏈接]

    !lvup!   100%

    384

    主題

    27

    回帖

    2200萬

    積分

    管理員

    積分
    22005859
    發表於 前天 01:22 | 顯示全部樓層 |閱讀模式
    WireGuard 幾乎不給錯誤訊息。連不上的時候它不會說「密碼錯誤」也不會說「連線逾時」,就是安靜地什麼都沒發生。

    所以只能靠排除。這篇的每一步都設計成一個二選一的判定:下一個指令,看一個輸出,得到「往左走」或「往右走」,不是「可能是這個也可能是那個」。

    一個二選一的判定

    這篇假設的環境


    • 家裡的內網 `192.168.88.0/24`,伺服器在 `192.168.88.20`(Linux / Docker)或是路由器自己(RouterOS)
    • 隧道網段 `10.20.30.0/24`
    • 對外位址 `114.32.80.149`,WireGuard 聽在 UDP `51820`


    你的數字不一樣的話,下面每個指令裡的對應位置都要換掉。

    ⚠ 開始之前:測試一定要在家門外

    人在家裡、連著自家 Wi-Fi 的時候測 VPN,測到的東西沒有意義:流量根本沒出過家門,而且多數路由器不支援「從內部連自己的對外 IP」(叫做 NAT 回流)。

    把手機的 Wi-Fi 關掉、用行動網路。 這一句解決掉的案例比底下七步加起來還多。

    ---

    步驟 1:先看有沒有交握,決定要往哪半邊查

    在伺服器上:
    1. # Linux / Docker 容器裡
    2. sudo wg show
    3. # RouterOS
    4. /interface/wireguard/peers/print detail
    複製代碼

    你會看到(Linux 版):
    1. interface: wg0
    2.   public key: xTIBA8dJ+YbXQ9r2vKcN0mFe7sLpQwZ3hYuGaVcRtE4=
    3.   listening port: 51820
    4. peer: 9kLm2XpQwErTyUiOp3AsDfGhJkL5ZxCvBnM8QwE=
    5.   endpoint: 203.0.113.88:41235
    6.   allowed ips: 10.20.30.2/32
    7.   latest handshake: 43 seconds ago
    8.   transfer: 380.21 KiB received, 1.24 MiB sent
    複製代碼

    照這三種結果分岔:


    • 完全沒有 `latest handshake` 這一行(RouterOS 是 `last-handshake` 空白) → 從來沒連上過,往步驟 2
    • 有時間,但是好幾個小時或好幾天前 → 曾經通過,現在斷了。往步驟 2,同時先檢查用戶端設定檔有沒有 `PersistentKeepalive = 25`,沒有的話補上再測
    • 有時間,而且是幾秒到兩分鐘前 → 隧道本身是好的,問題在路由或 DNS,直接跳步驟 5


    ⚠ 交握時間在兩分鐘上下跳動是正常的。WireGuard 在有流量的時候大約每兩分鐘重新交握一次,沒流量就不動。看到「1 分 50 秒前」不要以為快斷了。

    ---

    步驟 2:封包到底有沒有抵達伺服器(整篇最重要的一刀)

    「沒有交握」這個狀態底下藏著兩個完全不同的世界:封包根本沒到(問題在網路路徑上),或是封包到了但談不攏(問題在金鑰設定上)。

    不先切開的話,你會一直在改金鑰,而封包連門都沒進來。

    在伺服器上開著這個指令:
    1. # Linux / Docker 主機
    2. sudo tcpdump -ni any udp port 51820
    3. # RouterOS:改用防火牆規則的計數器
    4. /ip/firewall/filter/print stats where comment="WireGuard"
    複製代碼

    然後用手機(行動網路)把 WireGuard 打開。

    你會看到(Linux 版,有封包進來的話):
    1. 09:41:02.183045 IP 203.0.113.88.41235 > 192.168.88.20.51820: UDP, length 148
    2. 09:41:07.245113 IP 203.0.113.88.41235 > 192.168.88.20.51820: UDP, length 148
    3. 09:41:12.301882 IP 203.0.113.88.41235 > 192.168.88.20.51820: UDP, length 148
    複製代碼

    RouterOS 版的話是 `PACKETS` 那一欄的數字在增加。

    兩種結果:


    • 有封包進來(每隔約 5 秒一筆,`length 148` 是交握的第一個封包)→ 網路路徑是通的,往步驟 4
    • 一片空白,手機按了十幾秒也沒有任何一行 → 封包沒到,往步驟 3


    ⚠ 只有「送出去」沒有「回來」也算有到。上面的輸出如果只有 `> 192.168.88.20.51820` 的方向、沒有反方向,代表伺服器收到了但沒回應 —— 那是步驟 4 的金鑰問題,不是路徑問題。

    ⚠ 不要用線上的「埠掃描」工具來判斷。那些工具全部測 TCP,而 WireGuard 走 UDP。它們一定會告訴你「51820 是關閉的」,而那個結論是錯的。上面的 `tcpdump` 是唯一可信的判準。

    ---

    步驟 3:封包沒到,四個原因依序排除

    3-1 你是不是在 CGNAT 後面

    在路由器的管理頁上找到 WAN IP(廣域網路 IP),跟外面看到的 IP 比對:
    1. curl -4 ifconfig.me; echo
    複製代碼

    兩個不一樣,或是 WAN IP 落在下面任何一段:
    1. 10.0.0.0    ~ 10.255.255.255
    2. 172.16.0.0  ~ 172.31.255.255
    3. 192.168.0.0 ~ 192.168.255.255
    4. 100.64.0.0  ~ 100.127.255.255   <- 這段是 CGNAT 專用
    複製代碼

    → 你根本沒有一個外面連得進來的門牌,埠轉發做了也是白做。這不是設定錯,是你沒有那個東西。三條路:


    • 中華電信 HiNet:申請「非固定制固定 IP」(免費),申請完一定要把 PPPoE 帳號從 `xxxx@hinet.net` 改成 `xxxx@ip.hinet.net`,帳號沒改的話申請了不會生效
    • 向電信業者申請固定 IP(通常要加錢)
    • 租一台有公網 IP 的小 VPS 當中繼,由家裡主動連出去


    3-2 埠號對不對


    • RouterOS 的 WireGuard 預設埠是 13231,不是 51820。建立介面時沒寫 `listen-port=51820` 的話它就聽在 13231,而你轉發的是 51820 —— 封包送到一個沒人在聽的埠,安靜地被丟掉。用 `/interface/wireguard/print` 看實際的 `listen-port`
    • Docker 的話看 compose 裡的 ports 有沒有 `/udp`:要寫 `"51820:51820/udp"`。少了那四個字元會變成轉發 TCP,永遠不會通


    3-3 路由器的埠轉發

    到路由器管理頁確認那一筆:
    1. 通訊協定:  UDP            <- 不是 TCP,也不是 Both
    2. 外部連接埠: 51820
    3. 內部 IP:   192.168.88.20   <- 伺服器主機的內網 IP
    4. 內部連接埠: 51820
    複製代碼

    ⚠ 最常見的隱形失敗:伺服器主機是用 DHCP 拿 IP 的,重開機之後拿到新位址,轉發就轉到空氣去了。症狀是「以前能連,現在連不上」,而且什麼設定都沒改過。

    到路由器的 DHCP 設定裡把那台主機設成固定 IP(DHCP 保留)。

    3-4 伺服器自己的防火牆有沒有擋
    1. # Linux(ufw)
    2. sudo ufw status
    3. # Linux(firewalld)
    4. sudo firewall-cmd --list-all
    5. # RouterOS
    6. /ip/firewall/filter/print where chain=input
    複製代碼

    你會看到一份規則清單。要找的是:有沒有一條允許 UDP 51820,而且排在「丟棄其他全部」之前。

    RouterOS 特別容易踩到順序:防火牆是由上往下、第一個命中就結束,你的放行規則排在 `drop all not coming from LAN` 後面的話,等於完全沒加。用 `place-before` 把它插到那條 drop 之前。

    ---

    步驟 4:封包到了但沒有交握,那一定是金鑰

    到這一步表示路徑完全正常。WireGuard 收到一個它驗不過簽章的封包時,會一聲不響地丟掉 —— 不回應、不記錄、什麼都沒有。這是設計上刻意的(避免被掃描探測),也是它最難除錯的地方。

    4-1 不要用看的,用算的

    公鑰是由私鑰算出來的,所以可以驗證:
    1. # 在任何一台有 wg 指令的機器上
    2. echo "貼上用戶端設定檔裡的 PrivateKey" | wg pubkey
    複製代碼

    你會看到一串 44 個字元、結尾是 `=` 的公鑰:
    1. 9kLm2XpQwErTyUiOp3AsDfGhJkL5ZxCvBnM8QwE=
    複製代碼

    以下還有約 60% 的內容
    登入後即可閱讀完整教學

    登入繼續閱讀使用 Google 登入
    您需要登入後纔可以回帖 登入 | 立即註冊

    本版積分規則

    延伸閱讀

    加入惟家 LINE 群 QR Code加入惟家 LINE 群

    Archiver|手機版|惟家的智能論壇

    GMT+8, 2026-9-27 02:14 , Processed in 0.162386 second(s), 25 queries .

    快速回覆 返回頂部 返回列表