1. 簡介
傳統的遠端瀏覽器方案將畫面轉為影片串流,在受限的辦公室網路中極易產生延遲。本方案採用 Xray (VLESS) + WebSocket + TLS 架構。其核心邏輯是將代理流量偽裝成標準的 HTTPS (Port 443) 流量,透過家中的 Traefik 進行 SSL 終止,並以雙路由設計分別處理 X-ui 管理面板與 VLESS 代理節點,確保兩者的安全政策互不干擾。
方案優勢
- 低延遲:本地瀏覽器負責渲染,反應速度極快。
- 高隱蔽性:流量特徵與標準 WebSocket (如 Slack、Teams) 一致,能有效穿透防火牆。
- 免安裝驅動:用戶端僅需執行綠色免安裝軟體,無需系統管理員權限。
2. 先決條件
在開始部署前,請確保具備以下環境:
- 已安裝 Docker 與 Docker Compose 的 Linux 主機 (位於家中)。
- 已部署完成並可正常運作的 Traefik,且設定好
websecure入口點、憑證解析器 (myresolver) 以及sec-strict@file、sec-normal@file兩組 middleware。 - 一個可用的網域,並已將子網域 (如
proxy.example.com) 指向家中 IP。 - 公司電腦具備執行自定義
.exe檔案與修改瀏覽器代理設定的權限。
3. 全量參數提取清單
以下為本架構中涉及的核心參數,請根據實際需求進行調整。部署時統一以環境變數注入,避免將敏感資訊直接寫入設定檔。
| 參數名稱 | 建議值 / 範例 | 說明 |
|---|---|---|
APP_DOMAIN | proxy.yourdomain.com | 對外公開的子網域 |
ROUTER_NAME | x-ui | Traefik 路由與服務的命名前綴 |
PANEL_PORT | 2053 | X-ui 管理面板的容器內部埠口 |
NODE_PORT | 2054 | VLESS 代理節點的容器內部埠口 |
NODE_PATH | / (或自訂如 /chat) | WebSocket 路徑,須與 X-ui 入站設定一致 |
| 用戶端 SOCKS 埠口 | 10808 | v2rayN 在本地端開啟的代理埠口 |
路由分離設計說明:面板 (Route A) 使用嚴格安全標頭 (
sec-strict@file);代理節點 (Route B) 使用一般安全標頭 (sec-normal@file),避免嚴格的 HSTS 與 CSP 標頭干擾 WebSocket 握手與 VLESS 連線。
4. 逐步教學
第一階段:服務端 (Server) 部署
步驟 1:配置 Docker Compose
建立新的 Stack 並填入以下設定。本設定採雙路由架構,管理面板與代理節點分別對應不同的內部埠口與安全政策。
version: '3.8'
networks:
traefik_network:
external: true
default:
driver: bridge
services:
x-ui:
image: ghcr.io/mhsanaei/3x-ui:latest
container_name: x-ui
restart: unless-stopped
environment:
XRAY_VMESS_AEAD_FORCED: "false"
volumes:
- /mnt/cloud1/dockerData/x-ui/db:/etc/x-ui/
- /mnt/cloud1/dockerData/x-ui/cert:/root/cert
tty: true
networks:
- default
- traefik_network
labels:
- "traefik.enable=true"
# ==========================================
# 路由 A:X-ui 管理面板 (PANEL_PORT)
# ==========================================
- "traefik.http.routers.${ROUTER_NAME}-panel.rule=Host(`${APP_DOMAIN}`)"
- "traefik.http.routers.${ROUTER_NAME}-panel.entrypoints=websecure"
- "traefik.http.routers.${ROUTER_NAME}-panel.tls.certresolver=myresolver"
- "traefik.http.routers.${ROUTER_NAME}-panel.service=${ROUTER_NAME}-panel-svc"
- "traefik.http.services.${ROUTER_NAME}-panel-svc.loadbalancer.server.port=${PANEL_PORT}"
# 嚴格安全防護,適合管理介面
- "traefik.http.routers.${ROUTER_NAME}-panel.middlewares=sec-strict@file"
# ==========================================
# 路由 B:VLESS 代理節點 (NODE_PORT + NODE_PATH)
# ==========================================
# PathPrefix 規則優先級較高,Traefik 會自動處理路由匹配順序
- "traefik.http.routers.${ROUTER_NAME}-node.rule=Host(`${APP_DOMAIN}`) && PathPrefix(`${NODE_PATH}`)"
- "traefik.http.routers.${ROUTER_NAME}-node.entrypoints=websecure"
- "traefik.http.routers.${ROUTER_NAME}-node.tls.certresolver=myresolver"
- "traefik.http.routers.${ROUTER_NAME}-node.service=${ROUTER_NAME}-node-svc"
- "traefik.http.services.${ROUTER_NAME}-node-svc.loadbalancer.server.port=${NODE_PORT}"
# 一般安全防護:避免嚴格標頭干擾 WebSocket 握手
- "traefik.http.routers.${ROUTER_NAME}-node.middlewares=sec-normal@file"
- "traefik.docker.network=traefik_network"
在 Portainer Stack 的 Environment variables 區塊填入對應變數:APP_DOMAIN、ROUTER_NAME、PANEL_PORT、NODE_PORT、NODE_PATH。
步驟 2:Traefik WebSocket 支援說明
Traefik 預設即支援 WebSocket 連線升級,無需額外設定。本方案的關鍵在於路由 B 套用 sec-normal@file 而非 sec-strict@file,確保 Traefik 不會移除 Upgrade 與 Connection 標頭,讓 VLESS over WebSocket 的握手得以正常完成。
步驟 3:配置 X-ui 面板入站規則
X-ui 需要設定兩個入站:管理面板使用預設埠口,代理節點需額外新增一個獨立入站。
訪問
http://家裡內網IP:2053並登入。進入「入站列表」 -> 「添加入站」,設定代理節點:
- 協議:vless
- 埠口:
${NODE_PORT}(與 Docker Compose 中一致,例如2054) - 傳輸:ws (WebSocket)
- 路徑:
${NODE_PATH}(與 Docker Compose 中一致,例如/) - TLS:關閉 (SSL 終止由外部 Traefik 負責)
儲存後點擊「查看」並「複製連結」。
[圖片說明:X-ui 面板中入站設定的截圖,重點標注 vless、ws 傳輸、埠口與路徑,以及關閉 TLS 的位置]
第二階段:用戶端 (Client) 配置
步驟 1:匯入代理設定
- 在公司電腦啟動 v2rayN。
- 點選「伺服器」 -> 「從剪貼簿匯入批次網址」。
- 雙擊該伺服器進行細節修正:
- 地址 (Address):填入網域
proxy.yourdomain.com。 - 埠口 (Port):修改為
443。 - 傳輸層安全 (TLS):選擇
tls。
- 地址 (Address):填入網域
步驟 2:Firefox 代理設定
- 開啟 Firefox 設定,搜尋「代理」。
- 選擇「手動設定代理」:
- SOCKS 主機:
127.0.0.1 - 埠口:
10808 - 類型:SOCKS v5
- 勾選:使用 SOCKS v5 時代理 DNS。
- SOCKS 主機:
5. 故障排除紀錄 (Troubleshooting Log)
問題 A:連線成功但無法解析網頁
- 現象:v2rayN 顯示已連線,但瀏覽器出現 DNS 解析錯誤。
- 原因:公司網路環境可能攔截了非授權的 DNS 查詢。
- 解決方法:務必在瀏覽器設定中勾選「使用 SOCKS v5 時代理 DNS」,強制讓遠端的家網主機代為解析網域。
問題 B:Traefik 轉發失敗 (Error 502)
- 現象:Traefik 回傳 502 Bad Gateway。
- 嘗試過的無效方法:在 X-ui 面板開啟 TLS。
- 最終解決邏輯:X-ui 內部必須維持明文 (TLS off),SSL 終止由 Traefik 負責。同時確認容器已正確加入
traefik_network,且 Label 中的traefik.docker.network與實際網路名稱一致,避免 Traefik 取錯容器 IP。
問題 C:WebSocket 連線握手失敗
- 現象:連線建立後立即斷開,日誌顯示 WebSocket handshake 失敗。
- 原因:路由套用了
sec-strict@file,其中的嚴格安全標頭 (如 CSP、HSTS) 干擾了 WebSocket 的Upgrade握手流程。 - 解決方法:代理節點路由 (Route B) 必須改用
sec-normal@file,確保握手標頭不被覆蓋或移除。
問題 D:面板與節點路由衝突
- 現象:訪問管理面板被導向代理節點,或兩者路由不如預期。
- 原因:Traefik 依路由規則的「精確度」決定優先順序,包含
PathPrefix的規則 (Route B) 優先級自動高於純Host規則 (Route A)。 - 解決方法:確認節點的
NODE_PATH與面板路徑不衝突;若仍有問題,可透過priority標籤手動指定路由優先順序。
6. 進階優化:自動化切換 (SwitchyOmega)
為了避免手動開關 Firefox 代理設定,建議安裝 Proxy SwitchyOmega 擴充功能。
- 建立一個專屬情境模式 (如「Home-Proxy」),協定選 SOCKS5,地址
127.0.0.1:10808。 - 利用「自動切換」功能,設定特定內部網址直接連線,其餘網址走「Home-Proxy」。
7. 結論
本架構成功將複雜的 VPN 驅動安裝需求轉化為單純的 HTTPS 流量轉發,以 Traefik 作為統一的反向代理閘道,透過 Docker Labels 與環境變數即可完成雙路由設定。面板與代理節點分離的設計確保了管理安全性與連線穩定性不互相妥協,是一套針對「流量代理」而非「畫面傳送」的高效優化方案。
