為什麼在 Ubuntu 會選 TUN,以及和系統代理的差異

在 Ubuntu 上,常見的 Clash 使用方式分成兩條路:一條是只開 系統代理或應用程式內的 HTTP/SOCKS 設定,讓「支援代理」的程式主動把流量交給本機埠;另一條是啟用 TUN 模式,由 Clash.Meta/Mihomo 類核心建立虛擬網路介面,並透過策略路由把符合條件的 IP 封包導入代理堆疊。對需要透明代理的情境(例如某些不走系統代理的程式、或你希望規則在 IP 層就生效),TUN 往往更一致。若你想先建立概念圖,可先閱讀 TUN 模式深度解析,再回到本文處理 Linux 上「真的把它跑起來」時會遇到的權限與服務化細節。

選擇 TUN 的代價也很明確:它比單純監聽本機埠更需要與系統互動。除了核心本身要支援對應的 stack(例如 gVisor 或 system 等實作會隨版本演進),Linux 還要能建立 tun 裝置、必要時調整路由與規則表。這些操作在權限模型上通常落在 CAP_NET_ADMIN 附近,也是新手最容易在日誌裡看到 operation not permitted 的原因。相對地,一旦你把它服務化,後續維護會比「手動開終端機執行」可預期得多。

環境前置:核心模組、轉發與命名空間

在乾淨的 Ubuntu Server 或桌面版上,第一步不是先貼一大段 YAML,而是確認系統具備建立 TUN 的基礎。多數情況下核心已內建 tun 模組,但仍建議用 lsmod | grep tun 或檢視 /dev/net/tun 是否存在;若你使用容器或極度精簡的環境,可能還要確認宿主是否把 /dev/net/tun 傳進去。對一般實體機或 VM,這一步通常沒問題,真正常卡的是「路由與權限」而不是模組缺失。

接著要理解:透明代理並不等於自動讓所有東西變快。若你的規則把大量流量導向本機再轉送,CPU 與檔案描述符壓力會上升;若 DNS 與 fake-ip 策略不一致,則會出現「能 ping、不能瀏覽」這類表面矛盾。這時候與 規則分流最佳實踐搭配閱讀會更省力:先把目的地分流想清楚,再讓 TUN 負責把流量送進正確的策略組。

若你同時啟用防火牆(ufwnftables 或雲主機安全群組),請預留一段對照時間:TUN 啟動後會新增介面與路由,某些預設規則可能會攔截轉送。建議先以最小規則集驗證連通,再逐步收緊;否則你會在代理核心看起來正常的情況下,於邊界防火牆默默丟封包。

實務建議:第一次啟用 TUN 時,先在同一台機器用 curl 測試「直連/走代理」兩種出口 IP,確認路由真的按預期切換,再回頭微調規則。這比直接開瀏覽器更能隔離 DNS 與快取造成的假陽性。

執行檔與設定目錄:常見路徑怎麼選

Linux 上常見的 Clash.Meta/Mihomo 發行方式,是單一二進位加上外部設定檔。實務上你會看到兩種擺放哲學:使用者目錄系統目錄。前者適合桌面使用者自行維護,典型路徑會落在 ~/.config/mihomo/ 或社群文件常寫的 ~/.config/clash/(實際目錄名稱依你使用的套件與上游慣例而定);後者適合伺服器,可能會放到 /etc/mihomo//opt/clash/,並搭配專用帳號與較嚴格的檔案權限。

無論選哪一種,請把三件事對齊:設定檔檔名(常見為 config.yaml)、工作目錄(影響相對路徑的 Rule Provider 與 GeoIP 資料庫位置)、以及執行身分(同一個路徑若以 root 與一般使用者各跑一次,會產生兩套互不相同的快取與鎖檔)。若你打算長期用 systemd 管理,建議固定一個使用者與固定目錄,避免更新訂閱時檔案寫入一半造成核心讀到半套設定。

另外,桌面使用者若偏好圖形客戶端,也可以先從 客戶端選型開始:有些介面會幫你管理路徑與更新,但伺服器上通常仍以「單一二進位+設定檔」最透明、最好除錯。兩種路線沒有高下,只有維護成本不同。

目錄權限的小細節

當你把 GeoIP、規則集或訂閱快取放在工作目錄下時,請確保執行身分對該目錄具備讀寫權限。常見錯誤是用 root 手動下載檔案後,一般使用者服務反而無法覆寫;或反過來,使用者目錄下的檔案權限過寬,導致同機多帳號環境出現意外讀取。對單人桌面機影響不大,但對多人伺服器值得多花兩分鐘整理 chmod 與擁有者。

設定檔:啟用 TUN 與自動路由的關鍵欄位

具體 YAML 會隨核心版本演進,但結構上通常會有 tun 區段,並搭配 dnsrules 一起工作。以下是一段「概念示意」,請以你實際使用的核心文件為準,並在升級後重新核對欄位名稱是否仍有效。

config.yaml 片段(示意,請依版本調整)
tun:
  enable: true
  stack: system
  auto-route: true
  auto-detect-interface: true
  strict-route: false

這裡幾個關鍵字對 Ubuntu 特別敏感:auto-route 會觸發系統路由表的調整;auto-detect-interface 則與預設出口網卡判斷有關,筆電在 Wi‑Fi/有線切換時尤為重要。strict-route 則牽涉是否更強硬地避免流量繞過隧道,錯誤理解時常造成「區網印表機突然連不到」這類副作用。建議第一次先採較保守的組合,確認能穩定上網後再逐步收緊。

DNS 方面,若你啟用 fake-ip 或混合解析策略,請同步檢查本機是否還有 systemd-resolved、NetworkManager 或其他 DNS 快取在競爭。此類問題不一定會在 TUN 介面建立時立刻爆炸,反而會以「只有瀏覽器異常、命令列卻正常」呈現。若你遇到跨平台差異,也可對照 常見問題 裡與 DNS、連線相關的條目,先把解析路徑對齊,再懷疑節點品質。

權限實測:CAP_NET_ADMIN、使用者與 root 的取捨

在 Linux 上,建立 TUN 與調整路由通常需要足夠的網路管理權限。實務上有三種常見做法:以 root 執行(最直覺但攻擊面最大)、以一般使用者執行並授予能力集(較符合最小權限原則)、以及透過套件提供的 setuid/政策模組(依發行版而異)。對多數自建部署,社群最常討論的是替二進位加上 cap_net_bind_servicecap_net_admin 這類能力,讓服務不必全程 root。

你可以用 getcap 檢視能力是否生效;若日誌仍出現權限拒絕,請回頭檢查是否被 AppArmor/SELinux 額外限制(Ubuntu 預設多為 AppArmor)。另一個常見誤區是:以為「能啟動核心」等於「TUN 也沒問題」。實際上有些環境允許監聽本機埠,但在建立 tun 或寫入路由表時被拒絕,兩者要分開驗證。

安全提醒:授予能力集等於提高該二進位的敏感操作範圍;請只對可信來源、可驗證簽章或你自行編譯的檔案這樣做,並避免把整個目錄設成 world-writable。

systemd:工作目錄、重啟策略與開機啟用

當你確認手動執行可以穩定建立 TUN 後,下一步就是把命令搬到 systemd。重點是:WorkingDirectory 必須指向放設定與資料檔的那個目錄;ExecStart 建議寫完整路徑;並加上合理的 Restart=on-failure 與節流,避免節點集體失效時進入瘋狂重啟。以下是一個常見骨架,實際欄位請依你的二進位名稱與參數調整。

/etc/systemd/system/mihomo.service 範例(示意)
[Unit]
Description=Mihomo (Clash.Meta) Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=clash
Group=clash
WorkingDirectory=/etc/mihomo
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
Restart=on-failure
RestartSec=3
LimitNOFILE=1048576

[Install]
WantedBy=multi-user.target

建立完單元檔後,依序執行 systemctl daemon-reloadsystemctl enable --now 服務名。若你使用非 root 使用者,請確保該使用者能讀取設定與資料檔,並且能力集已套用在對應的二進位上。若你把服務放在使用者 session(user systemd),行為會與系統層級略有不同:登入與圖形環境會影響啟動時機,較不適合無頭伺服器,但對桌面使用者有時更直覺。

另外,請為日誌預留出口:除了應用程式自身日誌級別,systemd 的標準輸出/錯誤也會進 journal。當你需要把問題濃縮成「可貼給別人看的十行」時,journalctl -u 服務名 -b 往往比翻整包設定檔更快定位。

驗證與排查:ip、journalctl 與核心日誌

啟動後,建議用三層證據交叉確認:介面是否存在ip tuntapip link)、路由是否符合預期ip ruleip route)、以及應用程式日誌是否出現重複錯誤。若介面起來了但路由怪異,優先回到 auto-route 與介面偵測相關設定;若介面根本起不來,優先檢查權限與能力集。這套順序能避免你一開始就誤判成「節點壞了」。

當你懷疑是策略路由與本機服務互動造成問題,可以暫時降低複雜度:先以最小規則集驗證 TUN 可用,再逐步加回 Provider 與規則集。若你同時遇到連線層錯誤(timeout、TLS),請改走連線日誌專題文章的排查樹,不要把路由問題與遠端握手問題混在同一個鍋裡。

最後補一段「工程師會忽略但很重要」的:更新核心或 Ubuntu 版本後,請重新驗證能力集與單元檔是否仍指向正確路徑。套件管理器或手動覆蓋二進位時,最常見的故障就是 systemd 仍指向舊位置,導致你以為更新成功,實際上跑的是另一份檔案。

結語

在 Ubuntu 上把 Clash/Mihomo 跑起來並不難,難的是把它跑得「可預期」:TUN 帶來的透明代理能力,本質上是與系統路由與權限共舞;systemd 則把這段共舞固定成可重啟、可追蹤、可開機自啟的流程。把執行檔位置、設定目錄、執行身分與能力集四件事對齊,你會發現多數故障都能收斂到少數幾類證據上,而不是無止境改 YAML。

相比只能本機監聽埠、卻缺乏一致路由行為的工具,能把 Meta 系核心能力與清楚日誌放在一起的客戶端,通常更適合長期維護;而在 Linux 伺服器場景,直接用上游核心搭配 systemd,往往比層層包裝的「一鍵腳本」更容易還原問題真相。若你也在意跨平台一致性,選擇與桌面/手機同一套規則思維的工具鏈,長期成本會明顯更低。

立即免費下載 Clash,開啟流暢上網新體驗,在 Ubuntu 上把 TUN、權限與自啟都理順之後,把時間花在真正想連的服務與內容上。