# 以 Windows PC 作為節點伺服器之科學上網筆記 本文將以 Windows PC 作為伺服器,使用 V2Ray 工具搭配 vmess+ws+tls+web 完成翻牆用的節點搭建,過程中也會實作較為簡單的 vmess+tcp 及 vmess+ws+tls。只要你有能上網的電腦,並且對外有可訪問的公網 IP,就能不花一分錢,實現自建節點。 :::warning 請務必先確認你的網路運營商有配發給你家電腦一個外網可訪問的 IPv4 地址,我的情況是:若直接讓電腦使用 PPPoE 撥號,運營商會分配一個公網 IPv4 地址給我,但使用 DHCP 時,拿到的只有內網地址。 在終端機輸入以下命令,可以檢查設備分配的地址 ```shell ipconfig ``` 下面這張圖就是有拿到公網地址的結果。 ![螢幕擷取畫面 2024-06-18 113428](https://hackmd.io/_uploads/SJx3gt0SA.png) 如果你的 IPv4 地址是像這樣 192.168 開頭的話,就代表不是公網地址。 ![image](https://hackmd.io/_uploads/BkiZVT8I0.png) ::: ## 序 由於某些原因,下個月要去一趟中國。為了確保在中國的上網安全,在下做了一系列的功課,學習了從網路架構到 GFW 的運作方式,以及目前流行的各類翻牆軟體、協議,並且成功在家中的 Windows 主機上架設好了節點伺服器用以翻牆。 由於網路上主要的翻牆教學都是以 VPS + linux 為主,但我相信一定會有像我這樣的情況:前往中國而有科學上網需求,但又不想使用不穩定的免費 VPN,或者是花錢買機場、VPS,在有限資源的情況下又只有自家的 Windows PC 有機會可以作為節點伺服器。故本篇將詳細說明我的設置流程,需要的可以參考。 本文著重在技術的實現,而非原理講解,故本文將不會著墨於細節原理。若有想深入探究原理的人,推薦[不良林](https://www.youtube.com/@bulianglin)的 youtube 頻道給你們。 ## 流程簡介 #### 第一階段 搭建 V2Ray 的 vmess+tcp 節點。實現最簡單的 vmess+tcp 代理。 #### 第二階段 註冊域名,建立 https 連結,包含申請證書(由可信任機構頒發)。 #### 第三階段 套用域名與證書,實現 vmess+ws+tls 流量偽裝。 #### 第四階段 使用 nginx 搭建偽裝站點,達到迴避 GFW 主動探測的目的,即 vmess+ws+tls+web 伺服器端設置。 ## 實作流程 ### 第一階段 搭建 V2Ray 的 vmess+tcp 節點。實現最簡單的 vmess+tcp 代理。 #### Step 1 在 Windows 伺服器下載 Windows 端的 [V2Ray Core](https://github.com/v2fly/v2ray-core/releases) (我這邊使用的是 v5.14.1,可下載當前最新的就好) ![螢幕擷取畫面 2024-06-18 104039](https://hackmd.io/_uploads/HyOgNd0SA.png) 以及 [Nginx for windows](https://nginx.org/en/download.html) (我這邊使用 1.27.0)(nginx 在 vmess+tcp 不會用到,vmess+ws+tls+web 跟證書申請時才需要) ![image](https://hackmd.io/_uploads/HkTjNT8UC.png) 接著解壓縮,放在你喜歡的目錄下,推薦直接丟 D 槽下 ( D:/v2ray/v2ray.exe 跟 D:/nginx/nginx.exe ) 就好,下面也會以這個 D 槽路徑為範例。 #### Step 2 設置 v2ray 的 config.json 文件,如下 ```json { "inbounds": [ { "port": 8388, "protocol": "vmess", "settings": { "clients": [ { "id": "e5a3ef20-a939-47d0-9e23-4c97836e0fa6", "alterId": 0 } ] } } ], "outbounds": [ { "protocol": "freedom", "settings": {} } ] } ``` port 端口可以跟我的不一樣,65535 以下的正整數都行,但之後用戶端設定的時候要記得跟這邊的一樣。 clients 的 id 也可以跟我不一樣,使用的 UUID 可讓[這個網站](https://www.uuidgenerator.net/)隨機生成,之後的設置也記得跟這邊的一致。 嘗試運行一下 v2ray.exe:在終端機開啟同個根目錄,執行 ```shell v2ray.exe run ``` 或者 ```shell v2ray.exe run -c "config.json" ``` 若 v2ray 版本是 4.x.x,你可能要運行 ```shell v2ray.exe -c "config.json" ``` 它如果跳出防火牆通知,按確認就行了。 接著如果你看到 ![image](https://hackmd.io/_uploads/Hyoxu_CHA.png) 就表示執行成功。而這就是伺服器端的 vmess+tcp 實踐。 (若要結束運行,輸入 Ctrl+C 就行了。) #### Step 3 vmess+tcp 客戶端配置。 ###### Windows 裝置 可以選擇不同客戶端軟體,只要能支持 vmess 協議的都行(像是 v2rayN、Clash 等)。這邊以 v2RayN 為例。 首先要下載 v2rayN 客戶端。前往 [github 頁面](https://github.com/2dust/v2rayN/releases),找最新版本即可,我這邊用的是 6.43。 下載這個 v2rayN-With-Core.zip 的壓縮檔 ![螢幕擷取畫面 2024-06-18 112114](https://hackmd.io/_uploads/BkGLT_CSA.png) 解壓縮後直接運行 v2rayN.exe 即可。 接下來要加入我們剛剛創建好的節點。 在左上角選擇「伺服器」,選擇「新增[VMess]伺服器」。 ![螢幕擷取畫面 2024-06-18 114159](https://hackmd.io/_uploads/HJoYGF0rR.png) 別名:隨便填 位址:填入你的伺服器 IP 地址 埠:填入之前 config.json 設置的 port,我這邊就是 8388。 ![螢幕擷取畫面 2024-06-18 114542](https://hackmd.io/_uploads/Bko77YArA.png) 最後點選確定,右鍵選擇「測試伺服器真連結延遲」,如果延遲不是-1,則表示成功搭建 vmess+tcp 節點。 ###### Android 裝置 學會 Windows 客戶端的使用,其實其他軟體乃至不同的裝置的設置都是非常雷同。 在 Android 操作系統中,可以使用 [v2rayNG](https://play.google.com/store/apps/details?id=com.v2ray.ang) 進行類似操作。故在此就不多贅述。 :::warning 現有情報表明,vmess+tcp 已經能夠被 GFW 精準探測,所以極不建議只使用 vmess+tcp 進行科學上網。若被 GFW 主動探測到,你搭的節點 IP 很大機率會被牆。所以建議繼續往下看,下面的 vmess+ws+tls+web 能夠達到較為安全的科學上網環境。 ::: :::warning 為防止 DNS 洩漏,在 v2rayN 建議啟用 TUN模式,在 v2rayNG 建議前往「設定」->「轉送設定」將轉送模式設置為「全域 Proxy」。 ![螢幕擷取畫面 2024-06-18 120327](https://hackmd.io/_uploads/SypEPtAHA.png) ::: --- ### 第二階段 註冊域名,建立 https 連結,包含申請證書(由可信任機構頒發)。 #### Step 1 首先要註冊一個域名。 前往 [no-ip](https://www.noip.com/),註冊一個帳號,並創建一個域名。 進入 Dashboard,在側欄進入「Dynamic DNS」->「No-IP Hostnames」,點選「Create Hostname」。 ![螢幕擷取畫面 2024-06-18 131700](https://hackmd.io/_uploads/Bkc8p5ArA.png) 填寫必要資料。Hostname 跟 Domain 可隨便選,而 IPv4 Address 要填伺服器的 IPv4 位址。 ![螢幕擷取畫面 (38)](https://hackmd.io/_uploads/SkVopcCrA.png) :::warning 由於是免費域名,之後記得要測試該域名是否有被牆。方法在第四階段會說。 ::: #### Step 2 再來要為域名申請 SSL 證書。(你可以選擇使用自簽證書,不過為了完美模擬正常網站的請求,這邊還是推薦使用可信任的機構頒發的證書) 前往 [ZeroSSL](https://zerossl.com/),註冊一個帳號。 點選「New Certificate」。 在「Domains」輸入剛剛註冊的域名,然後在「Validity」選擇「90-Day Certificate」(免費方案,到期後可以再用相同步驟申請一次)。接著一直下一步,跳轉到 Varify Domain 的頁面。 這個頁面是要驗證你是否是該域名的持有者。 我們選第三個,以 HTTP File Upload 進行驗證。 ![image](https://hackmd.io/_uploads/B1GPeiAHA.png) 點選「Download Auth File」獲得一份 txt 檔案。 前往伺服器的 nginx 資料夾,在裡面創建一個兩層資料夾「.well-known/pki-validation」,並且將下載的 txt 檔案放到 pki-validation 之下。 在「config」資料夾中,編輯「nginx.conf」如下。 ``` worker_processes 1; events { worker_connections 1024; } http { default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name [your ip]; # 你的 IP location /.well-known/pki-validation/ { # 符合你的 nginx 路徑 alias D:/nginx/.well-known/pki-validation/; } location / { root html; index index.html index.htm; } } } ``` `[your ip]` 的部分要輸入你的伺服器 IPv4 位址。 接著在根目錄開啟終端機,輸入以下內容,來啟動伺服器。 ```shell start nginx ``` 先在自己的瀏覽器測試一下以下網址是否能正常顯示下載的 txt 內容(`[your domain]` 是你註冊的域名,`[your txt].txt`是你下載下來的 txt 檔案) ```shell http://[your domain]/.well-known/pki-validation/[your txt].txt ``` 若能正常顯示,就可以到 ZeroSSL 在 Finalize 中點選 Verify Domain 進行驗證。 驗證完畢後,在下拉選單中選擇 NGINX,下載一份壓縮檔。可以先將裡面的 certificate.crt 以及 private.key 解壓縮複製到 v2ray 的資料夾下。 到此,域名跟證書就已經申請完成了。 :::info 可以在 nginx 根目錄下的終端機輸入 `nginx.exe -s stop` 或 `./nginx.exe -s stop` 停止 nginx 的執行。再者,也可以直接 Ctrl+Shift+Esc 打開工作管理員,搜尋到 nginx.exe,直接停止工作。 ::: --- ### 第三階段 套用域名與證書,實現 vmess+ws+tls 流量偽裝。 #### Step 1 到伺服器的 v2ray 資料夾 (D:/v2ray),找到之前修改過的 config.json 文件。修改成以下內容。 ```json { "inbounds": [ { "port": 8288, "protocol": "vmess", "settings": { "clients": [ { "id": "e5a3ef20-a939-47d0-9e23-4c97836e0fa6", "alterId": 0 } ] }, "streamSettings": { "network": "ws", "security": "tls", "tlsSettings": { "certificates": [ { "certificateFile": "D:/v2ray/certificate.crt", "keyFile": "D:/v2ray/private.key" } ] } } } ], "outbounds": [ { "protocol": "freedom", "settings": {} } ] } ``` id 跟前面 vmess+tcp 一樣可以填你自己的。而 port 的部分為了區分前面的 vmess+tcp,這裡我選用 8288。在`"certificates"` 下填入剛剛申請到的證書路徑。 接下來就是啟動 v2ray.exe 以及客戶端連線,就跟第一階段的時候差不多。 在客戶端,我們將「位址」改為剛剛註冊的域名,port 就填寫這次的 8288。 底層傳輸方式中,我們將「傳輸協定」改為 ws,「傳輸層安全」選擇 tls。使用自簽證書的話,可以將「跳過憑證驗證」設為 True。 同樣地,在 v2rayN 右鍵選擇「測試伺服器真連結延遲」,若有出現非 -1 的延遲,就代表 vmess+ws+tls 搭建成功。 :::warning vmess+ws+tls 同樣無法到達完美的流量偽裝。如果 GFW 進行主動探測(向你註冊的域名發出網站請求),回傳的頁面會是一個 Bad Request ,而不是正常的網站,所以依舊有很高的機率被 GFW 封鎖。為此,我們就有了最終階段: vmess+ws+tls+web。 ::: --- ### 第四階段 使用 nginx 將主頁面轉發到偽裝站點,達到迴避 GFW 主動探測的目的,即 vmess+ws+tls+web 伺服器端設置。 第三階段最大的毛病就是:網站如果被正常訪問就會漏餡,所以第四階段的目的就是解決這個問題。 在第二階段我們使用 nginx 是為了要域名驗證,而在這邊,我們就要用它來作為轉發的工具,也就是:當 GFW 對你的網站發起請求時,我們讓伺服器透過 nginx 返回一個在中國可以正常訪問的網站,來欺騙 GFW。 #### Step 1 配置伺服器 v2ray & nginx 設置。 將 v2ray 資料夾下的 config.json 修改為 ```json { "inbounds": [ { "port": 8488, "listen":"127.0.0.1", "protocol": "vmess", "settings": { "clients": [ { "id": "e5a3ef20-a939-47d0-9e23-4c97836e0fa6", "alterId": 0 } ] }, "streamSettings": { "network": "ws", "wsSettings": { "path": "/myray" } } } ], "outbounds": [ { "protocol": "freedom", "settings": {} } ] } ``` 將 D:/nginx/conf 下的 nginx.conf 修改為 ``` worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 443 ssl; listen [::]:443 ssl; server_name [your domain]; # 你的域名 ssl_certificate D:/v2ray/certificate.crt; # 之前複製到 v2ray 資料夾下的證書檔案 ssl_certificate_key D:/v2ray/private.key; # 同上 ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; location / { proxy_pass https://www.bing.com; # 偽裝網址 proxy_ssl_server_name on; proxy_redirect off; sub_filter_once off; sub_filter "www.bing.com" $server_name; proxy_set_header Host "www.bing.com"; proxy_set_header Referer $http_referer; proxy_set_header X-Real-IP $remote_addr; proxy_set_header User-Agent $http_user_agent; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header Accept-Encoding ""; proxy_set_header Accept-Language "zh-CN"; } location /myray { proxy_redirect off; proxy_pass http://127.0.0.1:8488; # 填寫轉發的內網 IP 與端口 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } server { listen 80; server_name [your domain]; # 你的域名 rewrite ^(.*)$ https://${server_name}$1 permanent; } } ``` 首先,port 為了跟之前做區別,我設為 8488。而這裡,v2ray 只監聽來自於 nginx 轉發的位址 127.0.0.1。所以現在,當 GFW 直接訪問你的域名網站(https://[yourdomain])(預設接入 443 端口),nginx 會回傳偽裝網站(bing.com)的內容,只有當 GFW 訪問 https://[your domain]/myray 時,才會漏餡。而這個 myray 的目錄我們可以隨便換,更改 `"path": "/myray"` 參數以及 `location /myray` 的名稱就行了。 #### Step 2 啟動伺服器。 在 v2ray 根目錄啟動 v2ray ```shell v2ray.exe run -c "config.json" ``` 接著在 nginx 根目錄啟動 nginx ```shell start nginx ``` (結束服務就在 v2ray 終端機按 ctrl+C,在 nginx 終端機輸入 `nginx.exe -s stop` ) 最後,客戶端設定時,在「底層傳輸方式」中將「路徑」設為剛剛的目錄 myray,測試延遲沒問題的話,vmess+ws+tls+web 就大功告成了~ 順帶一提,這裡 Android 手機端的 V2rayNG 似乎一定要把「跳過憑證驗證(allowInsecure)」設置為 true 才能順利連線。 ### 測試 最後,你可以透過 [boce.com](https://www.boce.com/) 或 [greatfire.org](https://zh.greatfire.org/analyzer) 來測試你架設的 vmess+ws+tls+web 的域名,以及伺服器 IP 有沒有被牆。 ## 結語 雖然線上測試都能過關,但實際情況誰都說不準。只有真正實地到中國測試連線才能知道成功與否。祝所有翻牆人都能找到自己的出路。 最後我想為這幾天做的一系列功課,寫下一些感言。 我覺得,建牆與翻牆的對抗可謂「道高一尺,魔高一丈」。沒有 100% 絕對可行的翻牆方式。當初 ShodowSocks 出來的時候,所有人無不是高喊「牆已形同虛設~」「牆要倒啦~」;而到了現在,它終究也因為牆的升級而逐漸成為了歷史的產物。而其他新世代的翻牆協議 shodowsocksR、vmess、vless、trojan ...,也可能某一天變得不再靠普。 唯有牆倒下的那天,這段抗爭才能夠平息。 ## 參考資料 不良林 [https://www.youtube.com/@bulianglin](https://www.youtube.com/@bulianglin) ChatGPT [https://chat.openai.com](https://chat.openai.com)