|
|
家裡的路由器是 MikroTik 的話,WireGuard 直接跑在路由器上是最乾淨的做法:不用多開一台機器、不用 Docker,連進來就直接站在家裡的網段上。
這篇從「還沒打開 WinBox」開始,做到手機在外面用行動網路掃一次 QR code 就連回家。每一步都寫了你會看到什麼,做完第三步能自己確認第三步成功了,才走第四步。
做完這篇你會有什麼
- 路由器上一個叫 wg0 的 WireGuard 介面,聽在 UDP 51820
- 一份可以用手機掃的 QR code,掃完就能連
- 一個明確的判定方法:連不上的時候知道是卡在哪一層
- 加第二個、第三個人的指令(照著複製就好)

這篇用到的兩個網段,先講清楚
- 家裡的內網:`192.168.88.0/24`,路由器自己是 `192.168.88.1`(MikroTik 的出廠預設就是這個)
- 隧道網段:`10.20.30.0/24`,路由器在隧道裡是 `10.20.30.1`
這兩個一定要不一樣。 你家如果不是 192.168.88.x,下面所有指令裡的 `192.168.88` 都換成你家的。隧道網段挑一個你確定沒在用的,`10.20.30.0/24` 通常很安全。
為什麼不能一樣:手機連上 VPN 之後,作業系統要決定「192.168.88.5 這個位址要往哪送」。兩邊網段相同時,手機同時有兩條一模一樣的路由,它會挑錯,而且不會告訴你它挑錯了。
---
步驟 1:確認你的 RouterOS 版本
用 WinBox 或 SSH 連進路由器,開 New Terminal,下:
你會看到像這樣(數字會不一樣):
- uptime: 3d4h12m36s
- version: 7.24.3 (stable)
- build-time: 2026-09-14 10:22:31
- free-memory: 180.5MiB
- total-memory: 256.0MiB
- cpu: ARM
- platform: MikroTik
複製代碼
- version 是 7.x → 可以往下走
- version 是 6.x → v6 完全沒有 WireGuard,沒有例外。這篇做不了,要先升到 7
- version 在 7.0 到 7.20 之間 → WireGuard 有(7.1 起),但產生用戶端設定的功能會少一塊,步驟 8 要看那裡的說明
順手確認有沒有更新:
- /system/package/update/check-for-updates
複製代碼
你會看到:
- channel: stable
- current-version: 7.24.3
- latest-version: 7.24.3
- status: System is already up to date
複製代碼
`status` 不是 `already up to date` 的話,建議先更新再做這篇(`/system/package/update/install`,路由器會重開機,大約兩分鐘)。本篇的寫法以 7.24.3 為準,那是 2026 年 9 月 14 日釋出的 stable。
---
步驟 2:確認你家有一個「外面連得進來」的位址
這一步決定整件事做不做得成,做完再往下。 很多人一路設到底才發現這關沒過。
2-1 看路由器自己拿到的對外位址
你會看到每個介面上的位址:
- # ADDRESS NETWORK INTERFACE
- 0 192.168.88.1/24 192.168.88.0 bridge
- 1 D 114.32.80.149/32 168.95.98.254 pppoe-out1
複製代碼
那個不是 192.168 開頭的就是你的對外位址。 用 PPPoE 撥號的話它會出現在 `pppoe-out1` 上,帶一個 `D`(動態取得)。
2-2 讓路由器自己去外面問一次「我的 IP 是什麼」
- :put [/tool/fetch url="https://ifconfig.me/ip" output=user as-value]->"data"
複製代碼
你會看到一行純粹的 IP:
這兩個數字一樣 → 你有真實的對外 IP,往下走。
兩個不一樣 → 你在電信業者的 CGNAT 後面,埠轉發不可能成功。判斷方法是看 2-1 的位址落在哪:
- 10.0.0.0 ~ 10.255.255.255
- 172.16.0.0 ~ 172.31.255.255
- 192.168.0.0 ~ 192.168.255.255
- 100.64.0.0 ~ 100.127.255.255 <- 這段是 CGNAT 專用
複製代碼
落在上面任何一段,就代表你家根本沒有一個外面找得到的門牌。這時候有三條路:
- 中華電信 HiNet 使用者:到 HiNet 客服後台申請「非固定制固定 IP」,免費。申請完一定要把 PPPoE 帳號從 `xxxx@hinet.net` 改成 `xxxx@ip.hinet.net`(多了 `ip.`),帳號沒改的話申請了也不會生效。這個帳號要設在路由器上(`/interface/pppoe-client/set [find] user="xxxx@ip.hinet.net"`)
- 打電話給電信業者申請固定 IP(通常要加錢)
- 租一台有公網 IP 的小 VPS 當中繼,由家裡主動連出去
2-3 對外 IP 會變的話,開 MikroTik 自己的 DDNS
MikroTik 有內建的免費動態網域,不用去申請別家:
- /ip/cloud/set ddns-enabled=yes
- /ip/cloud/print
複製代碼
你會看到:
- ddns-enabled: yes
- ddns-update-interval: none
- update-time: yes
- public-address: 114.32.80.149
- dns-name: 1234567890ab.sn.mynetname.net
- status: updated
複製代碼
- `dns-name` 那串就是你家的固定名字,等一下填給手機用。它永遠指到你家目前的 IP
- `status` 是 `updated` → 成功
- `public-address` 跟 2-1 看到的位址不一樣 → 再一次證明你在 CGNAT 後面。這個欄位是 MikroTik 的雲端伺服器「從外面看到你」的位址,跟路由器自己以為的位址不同,就代表中間還有一層
- `status` 是 `error` 或一直停在 `updating` → 路由器連不到 MikroTik 的雲端。先確認 `/ip/dns/print` 裡有設 servers
下面的指令一律用 `114.32.80.149` 代表你家的對外位址。你有 DDNS 的話就換成 `1234567890ab.sn.mynetname.net`,用名字比用 IP 好,IP 變了不用重發設定給所有人。
---
步驟 3:建立 WireGuard 介面
- /interface/wireguard/add name=wg0 listen-port=51820
- /interface/wireguard/print
複製代碼
不用指定金鑰,建立的時候它會自己產生一組。
你會看到:
- 0 R name="wg0" mtu=1420 listen-port=51820
- private-key="***" public-key="xTIBA8dJ+YbXQ9r2vKcN0mFe7sLpQwZ3hYuGaVcRtE4="
複製代碼
- 開頭有 `R` → running,介面起來了
- 記下 `public-key` 那一串。這是伺服器的公鑰,等一下手機的設定檔裡要填它。它不是機密,可以貼在記事本裡
- 沒有出現任何東西 → 你的 RouterOS 是 6.x,回步驟 1
⚠ 第一個會卡住的地方:MikroTik 的預設埠不是 51820
RouterOS 的 WireGuard 預設 `listen-port` 是 13231,不是全世界教學都在用的 51820。
不寫 `listen-port=51820` 的話它會聽在 13231,然後你在路由器上轉發 51820,永遠連不上,而且兩邊都不會有任何錯誤訊息 —— 封包送到一個沒有人在聽的埠,就是被默默丟掉。
上面那行有明確指定 51820,照抄就不會踩到。想用 13231 也可以,只要後面每一處都跟著改。
順手確認 MTU:上面印出來的 `mtu=1420` 是預設值,先不要動。真的遇到「連得上但大檔傳一半卡死」再調,那是另一個題目。
---
步驟 4:給隧道一個位址
介面本身沒有 IP,要自己給:
- /ip/address/add address=10.20.30.1/24 interface=wg0
- /ip/address/print where interface=wg0
複製代碼
你會看到:
- # ADDRESS NETWORK INTERFACE
- 0 10.20.30.1/24 10.20.30.0 wg0
複製代碼
看不到這一行,代表 `interface=wg0` 打錯了(介面名稱大小寫要完全一致)。
---
步驟 5:讓 WireGuard 的封包進得了路由器
這一步是最多人卡住的地方,而且卡住的原因通常不是規則寫錯,是規則排錯位置。
5-1 先看現在的 input 規則長什麼樣
- /ip/firewall/filter/print where chain=input
複製代碼
你會看到出廠設定的五條(數字前面的編號很重要):
- 0 ;;; defconf: accept established,related,untracked
- chain=input action=accept connection-state=established,related,untracked
- 1 ;;; defconf: drop invalid
- chain=input action=drop connection-state=invalid
- 2 ;;; defconf: accept ICMP
- chain=input action=accept protocol=icmp
- 3 ;;; defconf: accept to local loopback (for CAPsMAN)
- chain=input action=accept dst-address=127.0.0.1
- 4 ;;; defconf: drop all not coming from LAN
- chain=input action=drop in-interface-list=!LAN
複製代碼
記下最後那條 `drop all not coming from LAN` 的編號,上面是 `4`。你的路由器可能是別的數字,以你實際看到的為準。
為什麼要記它:RouterOS 的防火牆是由上往下、第一個命中就結束。你的放行規則如果排在那條 drop 後面,封包早就被丟掉了,等於你什麼都沒加。
5-2 插在那條 drop 前面
- /ip/firewall/filter/add chain=input action=accept protocol=udp dst-port=51820 comment="WireGuard" place-before=4
複製代碼
(`place-before=4` 的 4 就是 5-1 記下來的編號。不確定的話寫 `place-before=0`,插到最前面也一定有效,只是會多比對幾個封包,對家用完全無感。)
5-3 確認它真的排在前面
- /ip/firewall/filter/print where chain=input
複製代碼
你會看到你的規則變成 4,原本的 drop 被推到 5:
- 4 ;;; WireGuard
- chain=input action=accept protocol=udp dst-port=51820
- 5 ;;; defconf: drop all not coming from LAN
- chain=input action=drop in-interface-list=!LAN
複製代碼
你的規則編號比 drop 大 → 排錯了。用 `/ip/firewall/filter/move 5 destination=4` 把它搬上去(第一個數字是「要搬的那條」,destination 是「要搬到第幾個位置」)。
5-4 這條規則等一下要當成「封包到底有沒有進來」的儀表
- /ip/firewall/filter/print stats where comment="WireGuard"
複製代碼
你會看到:
- # CHAIN ACTION BYTES PACKETS
- 4 input accept 0 0
複製代碼
現在是 0 很正常,還沒有人連。步驟 9 會再回來看這個數字 —— 它是整篇唯一能證明「封包真的從外面進到路由器了」的東西。
---
|
|