VLESS 經 CDN 架設:以自有域名設定 WebSocket 或 XHTTP

VLESS 經 CDN 架設:以自有域名設定 WebSocket 或 XHTTP

Jason Chen
2026年10月14日· 7 分鐘讀完

VLESS 經 CDN 架設,是在客戶端與你自行管理的 Ubuntu VPS 之間加入 CDN 邊緣節點:客戶端連接邊緣上的自有域名,CDN 只把一條秘密路徑轉發回源站,Xray 則只在本機回環地址接收。本文採用 Xray v26.3.27、源站以 Nginx 作反向代理,並以 Cloudflare 為 CDN 例子,傳輸方式在 WebSocket 與 XHTTP 之間擇一。[1]

關鍵要點

  • 動手前先細閱 CDN 現行條款;隧道能夠運作,不等於這種用法獲准。
  • 回源採用 Cloudflare Full (strict) 一類嚴格 TLS 模式,不用略過證書驗證的模式。
  • Xray 只監聽 127.0.0.1,每種傳輸只由 Nginx 轉發一條秘密路徑。
  • 經 CDN 時 XHTTP packet-up 較穩妥,WebSocket 則較簡單亦較舊。
  • 把「客戶端連上了」與「流量經過 CDN」分開驗證:分別測試直連源站、錯誤路徑及錯誤 UUID 會被拒絕。

本文按文末官方來源整理,未完成完整端到端實測。版本號只表示所依據的文件,並非作者實測環境。開始前,先參考自建規劃及復原清單,釐清擁有權、存取權限及復原方法。

你是否真的需要 VLESS 經 CDN 架設?

只在你擁有或獲授權管理的 VPS 及域名上操作。你需要不依賴代理的控制台存取、以已核實 known_hosts 嚴格驗證主機密鑰的 SSH,以及現有 Nginx、防火牆和 Xray 檔案的備份。不要借用他人域名、免費子域名服務或第三方 Worker 承載自己的入口。

CDN 會改變誰能看到並終結你的流量。邊緣節點先解密客戶端的 TLS,再向源站建立第二條 TLS 連接,因此 CDN 營運商會在中間經手你的代理流量。如果你只需要穩定的日常出口,不想自行維護證書、Nginx 及 Xray,請先評估託管 VPN 是否更省事,再決定是否多加一個環節。邊緣與源站的一般關係,可參考 CDN 如何位處你與網站之間。

設定之前先核對 CDN 條款

Cloudflare 的服務專屬條款保留權利:若未購買相關付費服務而以 CDN 提供影片,或提供比例過高的大型檔案,可停用或限制其 CDN 使用。[2] 承載串流或大量下載的代理,有可能落入這種情況。請細閱現行條款及你所用計劃的限制;如需一條不受 CDN 政策影響的路徑,請保留直連入口,例如 VLESS REALITY 伺服器。

本文任何步驟都不能令線路「不會被封鎖」。CDN 可能重新啟動邊緣伺服器、執行閒置逾時或調整功能;Cloudflare 亦寫明,發佈更新時可能中斷已開啟的 WebSocket 連接。[3]

WebSocket 還是 XHTTP:哪種傳輸適合經 CDN?

兩種傳輸都把 VLESS 包在 HTTP 之內,所以能代理 HTTP 的 CDN 都可以轉發。分別在於資料流的組織方式,以及 CDN 需要放行甚麼。

問題VLESS WebSocket TLS 設定VLESS XHTTP 經 CDN(packet-up)
資料如何傳送一條升級後的 HTTP/1.1 連接上行拆成編號 POST 請求,下行為串流式 GET
對 CDN 的要求該區域已啟用 WebSockets普通 HTTP 代理即可,毋須協議升級
Project X 的建議文件建議改用 XHTTP,因 WebSocket 的 ALPN 為 http/1.1packet-up 被形容為在 CDN 及反向代理後相容性最強的模式
源站反向代理要求傳遞 Upgrade 與 Connection 標頭請求內容及回應內容均不緩衝
主要取捨簡單,客戶端支援廣泛較新,客戶端及伺服器核心都必須支援

Project X 的 WebSocket 頁面建議改用 XHTTP,以避開 WebSocket 明顯的 http/1.1 ALPN 特徵。[4] XHTTP 傳輸條目指向項目的 XHTTP 討論區;討論中建議在 CDN 或反向代理不放行其他模式時選用 packet-up,並指出經 Cloudflare 使用 stream-up 需要啟用 gRPC 支援。[5][6] 本文把 XHTTP 固定為 packet-up,讓源站維持普通的 HTTP/1.1 反向代理。如你已有直連的 XHTTP 入口,請讓它與這個 CDN 入口保持獨立。

步驟 1:準備域名、證書及源站防火牆

建立一條指向 VPS 的 DNS 記錄,例如 proxy.example.com,並設為經 CDN 代理。在 Cloudflare 把該區域的 SSL/TLS 模式設為 Full (strict):邊緣節點會驗證源站證書,證書可由公共 CA 或 Cloudflare Origin CA 簽發。[7] 不要使用 Flexible 或 Full,前者回源不加密,後者接受無效證書。

如選用 WebSocket,請在區域的 Network 設定中啟用 WebSockets。[3] 把源站證書及私鑰放在 /etc/ssl/vless-cdn/fullchain.pem 與 /etc/ssl/vless-cdn/privkey.pem,擁有者為 root,私鑰權限 0600。

把源站 TCP 443 限制為只接受 CDN 公佈的地址範圍,客戶端便無法繞過邊緣直連。[8] 保留 SSH 規則,以及仍需連到伺服器的證書續期途徑。CDN 更新地址範圍時要重新核對,過時的名單可能令入口在毫無提示下失效。

步驟 2:讓 Xray 入站只監聽本機回環

從官方 v26.3.27 發佈頁下載 Linux 64 位元壓縮檔,查閱發佈說明及官方提供的驗證資料,把執行檔安裝到 /opt/xray-cdn/v26.3.27/xray,擁有者 root,權限 0755。以 /opt/xray-cdn/v26.3.27/xray uuid 產生 UUID,並為每種傳輸揀選一個隨機路徑片段。建立不可登入的系統帳戶 xray-cdn,把以下內容儲存為 /etc/xray-cdn/server.json,權限 0640,擁有者 root:xray-cdn。[1]

{
  "log": {"loglevel": "warning"},
  "inbounds": [
    {
      "tag": "vless-ws",
      "listen": "127.0.0.1",
      "port": 10001,
      "protocol": "vless",
      "settings": {"clients": [{"id": "REPLACE_UUID"}], "decryption": "none"},
      "streamSettings": {"network": "ws", "wsSettings": {"path": "/ws-REPLACE_SECRET"}}
    },
    {
      "tag": "vless-xhttp",
      "listen": "127.0.0.1",
      "port": 10002,
      "protocol": "vless",
      "settings": {"clients": [{"id": "REPLACE_UUID"}], "decryption": "none"},
      "streamSettings": {"network": "xhttp", "xhttpSettings": {"path": "/xh-REPLACE_SECRET/", "mode": "packet-up"}}
    }
  ],
  "outbounds": [{"tag": "direct", "protocol": "freedom"}]
}

只保留所選傳輸對應的入站。兩個入站都沒有啟用 TLS,因為 TLS 在同一部主機的 Nginx 終結;只有在兩者都監聽 127.0.0.1 時,這樣做才安全。VLESS 的 decryption: none 表示 VLESS 本身不會額外加密。以 sudo -u xray-cdn /opt/xray-cdn/v26.3.27/xray run -test -config /etc/xray-cdn/server.json 檢查設定,再以 xray-cdn 帳戶作為 systemd 服務執行。

步驟 3:以 Nginx 只轉發秘密路徑

為 proxy.example.com 加入一個 server 區塊。除秘密路徑外,所有路徑都回應 404,掃描源站的人只會看到一個背後空無一物的普通 HTTPS 網站。

server {
    listen 443 ssl;
    server_name proxy.example.com;
    ssl_certificate     /etc/ssl/vless-cdn/fullchain.pem;
    ssl_certificate_key /etc/ssl/vless-cdn/privkey.pem;

    location = /ws-REPLACE_SECRET {
        proxy_pass http://127.0.0.1:10001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 300s;
    }

    location /xh-REPLACE_SECRET/ {
        proxy_pass http://127.0.0.1:10002;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_request_buffering off;
        proxy_set_header Host $host;
        proxy_read_timeout 300s;
    }

    location / { return 404; }
}

WebSocket 區塊傳遞 Upgrade 與 Connection 標頭,否則逐跳代理會把它們丟棄。[9] XHTTP 區塊關閉雙向緩衝;在 proxy_http_version 1.1 下,Nginx 可以一邊接收一邊把請求內容交給 Xray,而毋須先全部收齊。[10] XHTTP 使用前綴比對,因為每個請求都會在路徑後附加自己的後綴。先執行 sudo nginx -t,通過後才重新載入。

步驟 4:讓客戶端連接 CDN 上的域名

在 Ubuntu 客戶端安裝同一版本的 Xray,為 WebSocket 路線儲存一個私人 client.json(權限 0600):

{
  "inbounds": [{"listen": "127.0.0.1", "port": 1083, "protocol": "socks", "settings": {"auth": "noauth", "udp": false}}],
  "outbounds": [{
    "tag": "cdn-ws",
    "protocol": "vless",
    "settings": {"vnext": [{"address": "proxy.example.com", "port": 443, "users": [{"id": "REPLACE_UUID", "encryption": "none"}]}]},
    "streamSettings": {
      "network": "ws",
      "security": "tls",
      "tlsSettings": {"serverName": "proxy.example.com", "allowInsecure": false},
      "wsSettings": {"path": "/ws-REPLACE_SECRET"}
    }
  }]
}

選用 XHTTP 時,保留同一個出站,只替換傳輸欄位:

"network": "xhttp",
"xhttpSettings": {"path": "/xh-REPLACE_SECRET/", "mode": "packet-up"}

地址與 serverName 都填你的域名,不填源站 IP,客戶端的 TLS 工作階段因而在邊緣終結,證書驗證保持開啟。執行 xray run -test -config ./client.json,然後在前台啟動客戶端,只讓一個測試應用程式使用 SOCKS5 127.0.0.1:1083。

如何證明流量確實經過 CDN?

經代理開到一個網頁,只能說明「某條路徑」可用。每次只改一個條件,逐一檢查每道邊界,測試之間恢復可用的設定。

檢查方法預期現象不符時的處理
對自己的端點執行 curl --proxy socks5h://127.0.0.1:1083 https://check.example.net/health經代理取得預期回應先看 Nginx 及 Xray 日誌,再考慮更換傳輸
dig +short proxy.example.com傳回 CDN 邊緣地址,而非 VPS IP記錄未經代理;先修正 DNS,再相信其他結果
在外部主機執行 curl --resolve proxy.example.com:443:ORIGIN_IP https://proxy.example.com/連接逾時或被拒絕源站防火牆仍放行非 CDN 來源
經邊緣請求 https://proxy.example.com/wrong-pathNginx 回應 404location 範圍過闊,轉發了多餘路徑
客戶端副本換成另一個有效 UUID代理請求失敗確認舊客戶端程序已停止、UUID 清單正確
客戶端副本使用邊緣證書上沒有的 serverNameTLS 驗證失敗保持 allowInsecure: false,切勿以關閉驗證來「修正」

接着在已設定本機 SOCKS 埠的瀏覽器開啟 IP 地址查詢工具。它應顯示 VPS 的出口地址:CDN 只承載入站一段,Xray 的 freedom 出站由伺服器發出。這個結果只涵蓋瀏覽器這一個請求,並不代表其他應用程式的 DNS、IPv6 或 UDP。

如果 WebSocket 請求失敗,而同一邊緣上的普通 HTTPS 正常,可參考 WebSocket 失敗但 HTTPS 正常的排查方法,區分 CDN 設定、代理及客戶端問題。至於 XHTTP,若 CDN 會在閒置後切斷下行,表現為長請求中途斷開;XHTTP 討論區指出,Cloudflare 會切斷 100 秒沒有實際資料的 HTTP 回應。[6]

如何回退或停用 CDN 入口?

修改前,私下保存 server.json、Nginx 網站檔案、防火牆規則及客戶端檔案的副本。客戶端回退即恢復之前的設定,並以一次新請求確認。伺服器方面,停用新的 Nginx 網站及 xray-cdn 服務,重新載入 Nginx,再以 sudo ss -lntp 確認 10001 及 10002 埠已無人監聽。

徹底停用時,刪除這條代理 DNS 記錄或關閉它的 CDN 代理,並從其餘設定中刪除該 UUID;如源站證書再無其他用途,便撤銷或刪除它。只為 CDN 而設的防火牆規則最後才刪,先弄清伺服器上還有哪些網站依賴 443 埠。升級亦用同一方式:準備新的版本目錄,對兩個檔案執行 -test,重做上面的驗證表後才切換服務。

總結

  • 設定前先確認 CDN 條款及你自己的復原途徑。
  • 回源使用嚴格 TLS 模式,Xray 只經本機回環上的 Nginx 對外提供服務。
  • 求簡單選 WebSocket,求穩妥經 CDN 選 XHTTP packet-up,同一客戶端不要兩者混用。
  • 以拒絕測試證明 CDN 路徑,而不是只看一次網頁成功開啟。

常見問題

在 VLESS 前面加 CDN,會比直連入口更私密嗎?

不會自動更私密。CDN 會終結客戶端的 TLS,再自行連接你的源站,因此它能看到承載 VLESS 流量的那段代理 HTTP 串流,私隱邊界要按這一點評估。

為求方便,可以用 Cloudflare 的 Flexible 模式嗎?

不建議。Flexible 由邊緣到源站不使用 TLS;Full (strict) 會驗證源站證書,既保護第二段傳輸,亦可防止有人冒充你的源站接收流量。

WebSocket 與 XHTTP 能否放在同一個域名?

可以,像示例那樣分別使用獨立的秘密路徑及獨立的 Nginx location 即可。不過每個客戶端只用一種傳輸,出現故障時才能判斷屬於哪條路徑。

為何這裏的 XHTTP 用 packet-up 而不是 auto?

項目指南把 packet-up 列為在 CDN 及反向代理後相容性最強的模式,它亦讓源站維持普通 HTTP/1.1,毋須額外設定 gRPC。

把源站藏在 CDN 之後,就能擋住所有直連掃描嗎?

只有在源站防火牆僅放行 CDN 地址範圍時才可以。沒有這條規則,任何知道 VPS 地址的人都能直接連接 Nginx,完全繞過邊緣節點。

這樣能保證代理在任何網絡封鎖下都可用嗎?

不能。經 CDN 的入口仍可能被限速、過濾,或被 CDN 本身限制,邊緣節點重新啟動亦會關閉已開啟的連接,因此請另外保留一條復原路徑。

源站防火牆內的 CDN 地址範圍應多久更新一次?

按固定週期核對 CDN 公佈的地址範圍,並在收到服務商通知後立即檢查。過時的放行名單會悄悄拒絕來自邊緣節點的正常回源連接。

免責聲明: 本文僅供一般資訊參考,不構成法律、技術或其他專業建議。我們不保證內容的準確性、完整性或時效性。

來源:

  1. Xray-core release v26.3.27 — https://github.com/XTLS/Xray-core/releases/tag/v26.3.27
  2. Cloudflare Service-Specific Terms — https://www.cloudflare.com/service-specific-terms-application-services/
  3. Cloudflare Docs: WebSockets — https://developers.cloudflare.com/network/websockets/
  4. Project X: WebSocket transport — https://xtls.github.io/en/config/transports/websocket.html
  5. Project X: XHTTP (SplitHTTP) transport entry — https://xtls.github.io/en/config/transports/splithttp.html
  6. Project X: XHTTP: Beyond REALITY — https://github.com/XTLS/Xray-core/discussions/4113
  7. Cloudflare Docs: SSL/TLS encryption modes — https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/
  8. Cloudflare IP ranges — https://www.cloudflare.com/ips/
  9. NGINX: WebSocket proxying — https://nginx.org/en/docs/http/websocket.html
  10. NGINX: ngx_http_proxy_module — https://nginx.org/en/docs/http/ngx_http_proxy_module.html

Sources checked 2026 年 10 月 14 日。

延伸閱讀:

開啟 3 天免費試用

註冊即可免費體驗全部高級功能。

*只限新用戶;每位用戶只可獲得一次試用。

VLESS 經 CDN 架設:以自有域名設定 WebSocket 或 XHTTP | AethoVPN