Communitygithub.com

homelab-wireguard-vpn

WireGuard VPN 伺服器設定、對端配置、金鑰生成、分流隧道與完整隧道路由,以及從手機和筆電用戶端遠端存取家庭網路。在設定用於遠端存取家庭網路的 WireGuard,或決定使用分流隧道與完整隧道路由時使用。

homelab-wireguard-vpn 是什麼?

這項技能提供了一個完整的指南,用於建立自託管的 WireGuard VPN,以安全地遠端存取家庭網路。它涵蓋了從伺服器安裝與設定的基礎知識,到進階主題,例如使用 Python 腳本進行金鑰生成與對端管理,以及在 pfSense 和 OPNsense 等平台上的設定。該技能對於解釋分流隧道與完整隧道路由之間的差異特別有幫助,並提供了關於何時使用每種方法的明確指導。通過自動化對端配置生成並提供詳細的疑難排解步驟,它簡化了管理多個用戶端(手機、筆電)的過程,同時強調了不應將私密金鑰儲存在版本控制中以及在防火牆中使用範圍限定的轉送規則等反模式。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/homelab-wireguard-vpn

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Homelab WireGuard VPN

WireGuard 是一個快速、現代的 VPN 協定。它是遠端存取家庭網路的正確選擇——設定比 OpenVPN 更簡單,且比大多數替代方案更快。

所有配置範例都顯示了常見的設定。在應用到您的系統之前,請仔細審查每個命令——特別是 iptables 轉送規則和金鑰檔案權限——並在維護時段內進行更改。

使用時機

  • 在 Raspberry Pi、Linux 主機、pfSense 或路由器上設定 WireGuard 伺服器
  • 生成 WireGuard 金鑰對並編寫對端配置檔案
  • 設定從手機或筆電到家庭網路的遠端存取
  • 解釋分流隧道(僅路由家庭流量)與完整隧道(路由所有流量)
  • 疑難排解無法建立的 WireGuard 連線
  • 自動化為多個用戶端生成對端配置

WireGuard 如何運作

您的手機 (WireGuard 用戶端)
    │
    │  加密的 UDP 隧道 (連接埠 51820)
    │
您的家庭路由器 (WireGuard 伺服器 — 需要公有 IP 或 DDNS)
    │
您的家庭網路 (192.168.1.0/24, NAS, Pi 等)


每個設備都有一組金鑰對(公鑰 + 私鑰)。
伺服器知道每個用戶端的公鑰。
用戶端知道伺服器的公鑰 + 端點 (IP:port)。
流量是端到端加密的,沒有中央伺服器或憑證授權單位。

伺服器設定 (Linux)

# 安裝 WireGuard
sudo apt update && sudo apt install wireguard -y

# 生成伺服器金鑰對 — 從一開始就以私有權限建立檔案
sudo mkdir -p /etc/wireguard
sudo sh -c 'umask 077; wg genkey > /etc/wireguard/server_private.key'
sudo sh -c 'wg pubkey < /etc/wireguard/server_private.key > /etc/wireguard/server_public.key'

# 編寫伺服器配置 — 替換實際的私鑰值
# 不要將私鑰儲存在版本控制中或共用它們
sudo tee /etc/wireguard/wg0.conf << 'EOF'
[Interface]
Address = 10.8.0.1/24              # VPN 子網路 — 伺服器取得 .1
ListenPort = 51820
PrivateKey = <paste_server_private_key_here>

# 範圍限定的轉送規則:允許 VPN 流量進/出,非全面的 FORWARD ACCEPT
PostUp   = iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT
PostUp   = iptables -A FORWARD -i eth0 -o wg0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
PostUp   = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -o eth0 -j ACCEPT
PostDown = iptables -D FORWARD -i eth0 -o wg0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# 手機 — 替換為實際的手機公鑰
PublicKey = <phone_public_key>
AllowedIPs = 10.8.0.2/32

[Peer]
# 筆電 — 替換為實際的筆電公鑰
PublicKey = <laptop_public_key>
AllowedIPs = 10.8.0.3/32
EOF
sudo chmod 600 /etc/wireguard/wg0.conf

# 將 eth0 替換為您實際的對外介面名稱
# 使用以下指令檢查:ip route show default

# 啟用 IP 轉送(伺服器路由流量所需)
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system

# 啟動 WireGuard 並設定開機啟動
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

用戶端配置

# 為每個用戶端設備生成唯一的金鑰對
# 在用戶端上執行,或在伺服器上執行並安全地傳輸私鑰 — 絕不能以純文字形式
umask 077
wg genkey | tee phone_private.key | wg pubkey > phone_public.key

# 用戶端配置檔案 (phone_wg0.conf):
[Interface]
PrivateKey = <phone_private_key>
Address = 10.8.0.2/32
DNS = 192.168.1.2                  # 可選:使用 Pi-hole 作為隧道的 DNS

[Peer]
PublicKey = <server_public_key>
Endpoint = your-home-ip.ddns.net:51820  # 您的公有 IP 或 DDNS 主機名稱
AllowedIPs = 192.168.1.0/24            # 分流隧道:僅家庭網路流量
# AllowedIPs = 0.0.0.0/0, ::/0        # 完整隧道:所有流量通過 VPN

PersistentKeepalive = 25              # 保持 NAT 洞開(手機用戶端需要)

分流隧道 vs 完整隧道

# 分流隧道:AllowedIPs = 192.168.1.0/24
  只有目的地為家庭網路的流量會通過 VPN。
  網路流量(YouTube, Spotify)直接連線 — 手機上效能更好。
  最適合:「我只想從任何地方存取我的 NAS 和 Pi。」

# 完整隧道:AllowedIPs = 0.0.0.0/0, ::/0
  所有流量都通過您的家庭網路連線。
  適用於:利用家庭 DNS/Pi-hole 廣告封鎖。
  缺點:家庭上傳速度成為所有地方的瓶頸。

# 多子網路分流隧道(最常見的 Homelab 使用案例):
  AllowedIPs = 192.168.10.0/24, 192.168.20.0/24, 192.168.30.0/24, 10.8.0.0/24
  透過隧道路由所有 VLAN;網路保持直接連線。

金鑰生成和對端管理

import subprocess

def generate_keypair() -> tuple[str, str]:
    """生成一個 WireGuard 金鑰對。返回 (private_key, public_key)。"""
    private = subprocess.check_output(["wg", "genkey"]).decode().strip()
    public = subprocess.run(
        ["wg", "pubkey"], input=private.encode(), capture_output=True
    ).stdout.decode().strip()
    return private, public

def generate_preshared_key() -> str:
    return subprocess.check_output(["wg", "genpsk"]).decode().strip()

def build_client_config(
    client_private_key: str,
    client_vpn_ip: str,       # 例如 "10.8.0.3"
    server_public_key: str,
    server_endpoint: str,     # 例如 "home.example.com:51820"
    allowed_ips: str = "192.168.1.0/24",
    dns: str = "",
) -> str:
    dns_line = f"DNS = {dns}\n" if dns else ""
    return f"""[Interface]
PrivateKey = {client_private_key}
Address = {client_vpn_ip}/32
{dns_line}
[Peer]
PublicKey = {server_public_key}
Endpoint = {server_endpoint}
AllowedIPs = {allowed_ips}
PersistentKeepalive = 25
"""

def build_server_peer_block(
    client_public_key: str,
    client_vpn_ip: str,
    comment: str = "",
) -> str:
    comment_line = f"# {comment}\n" if comment else ""
    return f"""
{comment_line}[Peer]
PublicKey = {client_public_key}
AllowedIPs = {client_vpn_ip}/32
"""

將私鑰排除在版本控制之外。如果您使用此腳本,請將金鑰材料寫入權限為 600 的檔案,並且絕不記錄或列印它。

pfSense / OPNsense WireGuard

# pfSense:VPN → WireGuard → 新增隧道
  介面金鑰:生成(自動建立金鑰對)
  監聽連接埠:51820
  介面位址:10.8.0.1/24

# 新增對端(每個用戶端一個):
  公鑰:<用戶端公鑰>
  允許 IP:10.8.0.2/32

# 指派 WireGuard 介面:
  介面 → 指派 → 新增(選擇 wg0)
  啟用介面,無需 IP(已在隧道配置中設定)

# 防火牆規則:
  WAN → 允許 UDP 連接埠 51820 傳入(以便用戶端連接到伺服器)
  WireGuard 介面 → 允許流量到您希望可存取的 LAN 網路

家庭伺服器的 DDNS(動態 DNS)

大多數家庭網路連線都有動態 IP。使用 DDNS 以便您的 VPN 端點在 IP 變更後仍可連線。

# 選項 1:Cloudflare DDNS — 將憑證儲存在 secrets 檔案中,而非內嵌
# 使用 env 檔案的 docker-compose 條目:
  ddns-updater:
    image: qmcgaw/ddns-updater
    env_file: ./ddns.env   # 將 zone_id 和 token 儲存在此,而非 compose 中
    restart: unless-stopped

# ddns.env (chmod 600, 不提交到 git):
# SETTINGS_CLOUDFLARE_ZONE_ID=your_zone_id
# SETTINGS_CLOUDFLARE_TOKEN=your_api_token

# 選項 2:DuckDNS(免費、簡單)
  在 duckdns.org 註冊 → 取得 token 和子網域 (myhome.duckdns.org)
  將 token 儲存在 /etc/ddns.env(模式 600),然後使用一個由 root 擁有的小型腳本:

  # /usr/local/bin/update-duckdns
  #!/bin/sh
  set -eu
  . /etc/ddns.env
  curl --fail --silent --show-error --max-time 10 \
    --get "https://www.duckdns.org/update" \
    --data-urlencode "domains=myhome" \
    --data-urlencode "token=${DUCKDNS_TOKEN}" \
    --data-urlencode "ip="

  # Cron 工作:
  */5 * * * * /usr/local/bin/update-duckdns >/dev/null 2>&1

疑難排解

# 檢查 WireGuard 狀態和上次握手
sudo wg show

# 如果 "latest handshake" 從未出現或非常舊,則隧道未連線。
# 檢查:
# 1. 路由器/防火牆上的 UDP 連接埠 51820 是否開放?
sudo ufw status  # 或檢查 pfSense/UniFi 防火牆規則

# 2. 用戶端配置中的伺服器公鑰是否正確?
sudo wg show wg0 public-key   # 與用戶端配置中的進行比較

# 3. 伺服器上是否啟用了 IP 轉送?
cat /proc/sys/net/ipv4/ip_forward  # 應為 1

# 4. 用戶端 AllowedIPs 是否涵蓋您嘗試存取的 IP?
# 如果 AllowedIPs = 192.168.1.0/24 而您嘗試存取 192.168.3.5,則不會路由。

# 檢查核心日誌中的 WireGuard 錯誤
dmesg | grep wireguard

# 重新啟動 WireGuard
sudo wg-quick down wg0 && sudo wg-quick up wg0

反模式

# 錯誤:將私鑰儲存在版本控制中或共用它們
# 私鑰等同於密碼 — 絕不提交到 git

# 錯誤:在手機上使用 AllowedIPs = 0.0.0.0/0 而未考慮影響
# 完整隧道會將所有手機流量路由通過您的家庭上傳 — 通常很慢

# 錯誤:在手機用戶端上未設定 PersistentKeepalive
# 位於 NAT 後方的手機用戶端會在無空閒隧道時斷開連線

# 錯誤:在防火牆中開啟連接埠 51820,但忘記在伺服器上啟用 IP 轉送
# 隧道連線了,但沒有流量路由 — 難以除錯

# 錯誤:跨多個用戶端設備共用一個金鑰對
# 每個設備必須有自己的唯一金鑰對 — 共用金鑰會破壞安全模型

# 錯誤:使用寬鬆的 "FORWARD ACCEPT" iptables 規則
# 將轉送規則的範圍限定在 wg0 介面和方向上

最佳實踐

  • 為每個用戶端設備生成唯一的金鑰對 — 絕不重複使用金鑰
  • 對手機使用分流隧道(AllowedIPs = <家庭子網路>)
  • 在所有手機用戶端上設定 PersistentKeepalive = 25
  • 如果您的 ISP 分配動態 IP,請使用 DDNS;將憑證儲存在 env 檔案中,而非內嵌
  • 使用範圍限定的 iptables 轉送規則(僅在 wg0 上傳入),而非全面的 FORWARD ACCEPT
  • 在用戶端配置中新增 Pi-hole 的 IP 作為 DNS =,以透過 VPN 取得廣告封鎖功能
  • 定期輪換伺服器金鑰對並更新所有用戶端配置

相關技能

  • homelab-network-setup
  • homelab-vlan-segmentation
  • homelab-pihole-dns

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

相關技能