Post

看懂 GFW 之前,先搞懂 VPN

看懂 GFW 之前,先搞懂 VPN

這篇筆記主要會專注在 VPN 本身的運作機制,以及常見的 WireGuard / OpenVPN 架設方法。如果是單純為了網路安全或隱藏 IP 非常實用;但如果是要專門對抗 GFW 翻牆,文末也會簡單提一下目前主流的 Xray 方案。

先說結論

VPN 說白了就是在你跟某台伺服器之間打一條加密的隧道,讓外面的人(ISP、咖啡廳 Wi-Fi 上的其他人)看不到你在傳什麼,同時目標網站也只看得到 VPN 伺服器的 IP,不是你的。

沒有 VPN:

你的電腦 (IP 暴露) →明文→ ISP (可監控) → 中間節點 →明文→ 目標網站 (知道你是誰)

使用 VPN:

你的電腦 (加密) ═══加密隧道═══ VPN 伺服器 → 目標網站 (只看到 VPN IP)

ISP 和中間節點只看到加密流量,看不到你在幹嘛


怎麼運作的

可以想像成「信封裡面還有信封」:

內容
外層封包目的地: VPN 伺服器 IP(任何人只看到這層)
VPN 加密層AES-256-GCM / ChaCha20-Poly1305 加密
原始資料你的請求(例如: GET google.com
  1. 建立安全通道 — VPN 客戶端和伺服器透過 ECDHE 之類的演算法協商出只有彼此知道的會話金鑰。因為用的是臨時金鑰(Ephemeral),每次連線都不一樣,有前向保密(PFS),就算以後伺服器私鑰洩漏也解不開之前錄下的流量。
  2. 加密你的資料 — 你的請求(DNS 查詢、HTTP 請求)先被 VPN 客戶端用會話金鑰加密,變成亂碼。用的是 AEAD 加密(下一節會講)。
  3. 封裝成新封包 — 加密後的資料被塞進一個新的 IP 封包,目的地是 VPN 伺服器的 IP。中途的 ISP 只看得到你在跟 VPN 伺服器通訊,看不到裡面裝什麼。
  4. VPN 伺服器解密 & 代轉 — VPN 伺服器解密取出原始請求,代替你向目標網站發送。網站只看到 VPN 伺服器的 IP。
  5. 回程也一樣 — 網站的回應 → VPN 伺服器加密 → 傳回你的設備 → 你的 VPN 客戶端解密 → 你看到內容。

加密用什麼

上面步驟 2 提到的 AEAD,實際傳輸用的是對稱加密(速度快):

  • AES-256-GCM — 有硬體加速(AES-NI),大部分設備都跑得很快
  • ChaCha20-Poly1305 — 沒硬體加速的設備(手機舊型號)用這個反而更快

這兩個都屬於 AEAD(Authenticated Encryption with Associated Data),跟舊的 AES-CBC + HMAC 不一樣的地方是:加密和驗證是同一個操作,一次搞定。舊的做法要分開處理加密跟 MAC,順序搞錯(像 MAC-then-encrypt)還會有 padding oracle 之類的攻擊面,AEAD 在設計上就避掉了這些問題。

加密的兩個階段

 ① 金鑰交換② 資料傳輸 (AEAD)
做什麼雙方協商出只有彼此知道的會話金鑰用會話金鑰加密資料,同時產生驗證碼
算法ECDHE / X25519AES-256-GCM / ChaCha20-Poly1305
保障前向保密 (PFS) — 竊聽也推不出金鑰機密性 + 完整性 + 防篡改,一次完成

各種協議

協議速度安全性備註
WireGuard極快程式碼大概 4000 行,簡潔好審計,自架首選。只支援 UDP
OpenVPN中等可以走 TCP 443 假裝 HTTPS,設定比較麻煩但彈性大。
IPSec/IKEv2原生支援多平台(iOS/macOS 內建),但協議指紋較明顯。
PPTPMS-CHAPv2 已被破解,別用。

如果是要對抗 GFW 翻牆,傳統 VPN 協議的流量特徵容易被 DPI(深度封包檢測)識別,可以看文末的 Xray 方案。


自己架

需要一台海外 VPS,日本、美國、新加坡都行。Vultr、DigitalOcean、Akamai(原 Linode)都有,大概每月 $3~$5 美元。

整體架構

你的設備(筆電、手機、桌機、路由器)→加密隧道ISP(只看到加密流量)→ 你的 VPS(WireGuard / OpenVPN → 解密 → NAT → 轉發)→ 目標網站

WireGuard(最簡單)

1
2
3
4
5
6
# 安裝
sudo apt update && sudo apt install wireguard -y

# 產生金鑰
wg genkey | tee server_private.key | wg pubkey > server_public.key
wg genkey | tee client_private.key | wg pubkey > client_public.key

伺服器設定 /etc/wireguard/wg0.conf

1
2
3
4
5
6
7
8
9
10
11
12
[Interface]
Address    = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server_private_key>
# 對外網卡名稱,用 ip a 確認(可能是 eth0、ens3、enp3s0)
PostUp     = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown   = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# 較新的 Debian/Ubuntu 可能預設用 nftables,iptables 指令失敗的話改用 nft 語法

[Peer]
PublicKey  = <client_public_key>
AllowedIPs = 10.0.0.2/32
1
2
3
4
5
6
7
# 開啟 IP 轉發
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# 啟動
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

客戶端設定:

1
2
3
4
5
6
7
8
9
10
11
[Interface]
Address    = 10.0.0.2/32
PrivateKey = <client_private_key>
# 一定要設 DNS!不設的話 DNS 查詢會走本地 ISP,等於 IP 藏了但你查了什麼網站還是暴露的
DNS        = 1.1.1.1

[Peer]
PublicKey           = <server_public_key>
Endpoint            = <VPS_IP>:51820
AllowedIPs          = 0.0.0.0/0
PersistentKeepalive = 25

OpenVPN(一鍵腳本)

1
2
3
4
curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh
chmod +x openvpn-install.sh
sudo bash openvpn-install.sh
# 跑完會吐出 .ovpn 檔,丟進 OpenVPN 客戶端就好

要注意的事

自架代表你要自己顧安全:

  • 定期 apt upgrade
  • 防火牆只開必要的 port(WireGuard 預設 51820/UDP)
  • SSH 用金鑰登入,關掉密碼登入
  • 換掉預設的 22 port 也可以少一些 brute force
  • 小心 DNS 洩漏 — 客戶端沒設 DNS 的話,DNS 查詢會走本地 ISP,你的瀏覽紀錄還是暴露的

架起來之後可以用 ipleak.net 確認 IP 和 DNS 都換成 VPN 伺服器的了。如果 DNS 那欄還是顯示你 ISP 的 DNS,就是 DNS 洩漏,回去檢查客戶端設定。


補充:對抗 GFW 的方案

如果你的需求不只是 VPN,而是要翻牆,傳統 VPN 協議(WireGuard、OpenVPN)的流量特徵容易被 GFW 的 DPI 識別然後封掉。目前主流的做法是用 Xray + REALITY

REALITY 的原理很聰明:流量偽裝成在存取某個正常網站的 TLS,GFW 主動探測的時候也只看到真實網站的回應(因為會反代過去),沒辦法判斷這是代理。

1
2
3
# x-ui 面板(帶 Web 管理界面,最快上手)
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
# 裝完進去管理界面,設定 Xray inbound,選 VLESS + REALITY

其他常見的翻牆方案還有:

方案特色
Shadowsocks加密代理,專為 GFW 設計,但部分特徵已被識別。
V2Ray/Xray + REALITY流量偽裝成正常 HTTPS,目前最難被偵測。
Hysteria2基於 QUIC,速度快,抗封鎖能力強。
This post is licensed under CC BY 4.0 by the author.