---
# System prepended metadata

title: 以 Windows PC 作為節點伺服器之科學上網筆記
tags: [科學上網]

---

# 以 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)
