[WireGuard] 架設穿透防火牆的家用伺服器網路環境(Homelab)

本篇文章更新時間:2025/04/22
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣新台幣 贊助支持。


不得不說,WireGuard 真的是很強大的發明!能讓使用這套應用的電腦像畫圈圈一樣的圈在一起,就算網路提供者不同也不影響。

也因為 WireGuard 的設計,讓我這免費仔能用最低成本方式來蹭時下最夯的 Home Lab!XD(最近大家為了跑 AI 都去各種串聯顯卡或主機)

除了需要對應長時間開機的省電主機外,網路部分不要求有對外公開的 IP 也沒問題。

對外的 IP 我選擇使用雲端服務 VPS,便宜的 2.5 USD ~ 5 USD,當作就是租用 IP 的費用,如果正好有自己的網站在營運,就是順便而已。

架構如下:

Public IP Server (外網IP + 10.10.10.1 內網IP)<-> WireGuard <-> Private Home Lab (10.10.10.2 內網IP)

對外 IP 的 VPS 主機當 WireGuard Server,然後內網的家用伺服器當 Client 去連結 Server,透過預設配置的內網固定 IP,即可做對應處理。

好處也是不論今天家用伺服器移至哪裡,只要它能連上網,就能用外網那台主機找到它。也算是順便完成 DDNS 這架構。

講起來好像很難,但其實真的只需要兩邊都安裝 WireGuard 即可啊~~

以下為安裝流程:

安裝 WireGuard 應用服務

兩台都要安裝。

apt update && apt install wireguard -y

使用 wg --version 指令確認版本,本文當前為 wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/

WireGuard 的設定檔預設放在 /etc/wireguard

設定外網的 Public IP VPS (WireGuard Server)

編輯 /etc/wireguard/wg0.conf 檔案,內容如下:

[Interface]
PrivateKey = PrivateKey_貼這
Address = 10.10.10.1/24
ListenPort = 51820
# 啟用 NAT
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = PublicKey_貼這
AllowedIPs = 10.10.10.2/32
PresharedKey = PresharedKey_貼這

產生設定檔案對應的金鑰 Key 值:

cd /etc/wireguard
umask 077
wg genkey | tee server_private.key | wg pubkey > server_public.key
wg genkey | tee client_private.key | wg pubkey > client_public.key
wg genpsk > preshared.key

經過上述指令,在 /etc/wireguard 目錄內會出現五個 .key 檔案,將 server_ 開頭的 Key 值內容貼到上方的 wg0.conf 對應位置中。

PresharedKey 是 WireGuard 中的一個 額外的加密層,讓連線更安全。雖然不是強制要用,但加上它可以增加私鑰洩漏的保護力。

PresharedKey 是 WireGuard Server 與 Client 都需要設定一樣的值,故使用同一份檔案。

到這邊,已經完成 WireGuard Server 必要的設定,接下來是主機的 IP Forwarding 轉發部分:

echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

再來就是啟用服務:

systemctl start wg-quick@wg0
systemctl enable wg-quick@wg0

確認服務指令: wg show

有看到 interface: wg0 等資訊就代表啟用成功,接下來是 Client 連線的部分。

記得確保外網雲端的防火牆有開放預設的 51820 Port

設定內網的家用伺服器 (WireGuard Client)

前一段落設定完 Server 後,Client 要注意的是:

  1. 只需要連通預設內網的網段 10.10.10.1/24,不然全部主機內的對外連線預設會被劫走,包含當下 SSH 服務也會斷,延伸其他問題,這部分透過 AllowedIPs 來處理。
  2. 由 Client 主動去保持連線,透過 PersistentKeepalive 參數來處理。

以上,同樣在 /etc/wireguard 目錄下建立一個 wg0.conf 檔案,內容如下:

[Interface]
PrivateKey = Client_PrivateKey_貼這
Address = 10.10.10.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = Client_PublicKey_貼這
PresharedKey = PresharedKey_貼這
AllowedIPs = 10.10.10.0/24
PersistentKeepalive = 25
Endpoint = :51820

Key 檔案是剛剛在 Server 上產生的 client_ 開頭檔案與共用的preshared.key

把對應的 Key 填入後,這份 conf 檔案就可以當作連線用的設定黨,可以先把這份使用桌面端軟體來匯入測試,確認是否會拿到 10.10.10.2 這組 IP,以及 ping 10.10.10.1 會通。(反過來也是在 Server 那台去 ping 10.10.10.2 也是)

如果確認沒問題,就可以用此份設定在內網的 Client 主機啟用。

sudo systemctl start wg-quick@wg0
sudo systemctl enable wg-quick@wg0

特別注意,同一時間只允許一個裝置使用同一個 conf 檔案連線,記得先停用桌面端的連線。

連線是否正確可以使用 wg show 指令或是直接互相 ping 主機試試~

常用指令

指令 說明
sudo wg 查看目前 WireGuard 連線狀態
sudo wg show 顯示詳細連線與傳輸資訊
sudo wg-quick up/down wg0 啟動或關閉指定介面
sudo systemctl enable/disable wg-quick@wg0 啟用/停用開機啟動
sudo ufw allow 51820/udp 如果有用防火牆,放行 UDP 連接埠

後記

前述希望配置的 IP 與介面等名稱都是可以調整的,不過內網的運作不影響太多,照著做也沒問題。

對於如何將服務轉發對外只需要使用 Nginx, HAProxy, Caddy 或是 Traefik 這類提供反向代理的服務處理就可以。

不需要對外網,純內網的話,也只需要產生過新的一組 Client 的連線 conf 給桌面版作業系統使用,當連進內網後,都可以找到這些服務,透過指定的內網 IP 來連線使用。

如果不想這麼手工,參考 TailscaleCloudflare Tunnel 這樣的服務也可以辦到。(Tailscale 底層也是走 WireGuard 協議,開源版是 Headscale)。

至於家用伺服器的 Home Lab 怎不用 Proxmox VE 這套虛擬主機服務呢? 其實我也還沒想到要架設什麼服務,管理成本落在同一台上我也方便,這樣本篇也簡單得多了(真的)。

補充使用 Nginx 當反向代理服務下的服務設定

在 WireGuard Server 那台外網主機只需要額外安裝 Nginx 就可以直接帶入下方設定玩轉服務。至於 SSL 憑證要使用 Cloudflare 或是參考 [SSL] 一次弄懂 Let’s Encrypt 以及建議使用的工具 – DNSroboCert 都行,這邊不贅述了。

n8n 流程工具

Client 端使用 Docker 工具開服務:

docker run -d --restart unless-stopped \
 --name n8n \
 -p 5678:5678 \
 -e GENERIC_TIMEZONE="Asia/Taipei" \
 -e TZ="Asia/Taipei" \
 -e N8N_SECURE_COOKIE=false \
 -e N8N_HOST="n8n.mxp.tw" \
 -e N8N_RUNNERS_ENABLED=true \
 -e N8N_EXPRESS_TRUST_PROXY=true \
 -e N8N_PROXY_HOPS=1 \
 -e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
 -e WEBHOOK_URL="https://n8n.mxp.tw" \
 -v n8n_data:/home/node/.n8n \
 docker.n8n.io/n8nio/n8n

Server 端 Nginx 的重點設定

location / {
        proxy_pass http://10.10.10.2:5678;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
}

WordPress 建站工具

Client 一樣是使用 LNMP 工具開一個站,但是要注意 wp-config.php 中,要補上:

$_SERVER['HTTPS'] = 'on';
define('WP_HOME', 'https://www.mxp.tw');
define('WP_SITEURL', 'https://www.mxp.tw');

一來是強迫輸出 HTTPS 協議的連結,二來是把網址要指定成對外那組。

Server 端的設定基本上都可以一樣,使用上面那組 localtion / {.... 即可。如下範例:

location / {
        proxy_pass http://10.10.10.2:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
}

關鍵是指定的 port 有變,對到 HTTP 協議。延伸使用問題就如同前篇筆記: [WordPress] 實體主機 Server 版本系統的 IPv6 網路問題


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[///////////____36%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


文章
Filter
Apply Filters
Mastodon