Communitygithub.com

homelab-wireguard-vpn

WireGuard VPN 伺服器設定、對等節點配置、金鑰產生、分流隧道與全隧道路由,以及從手機和筆電客戶端遠端存取家庭網路。適用於設定 WireGuard 以遠端存取家庭網路,或決定使用分流隧道與全隧道路由時。

homelab-wireguard-vpn 是什麼?

此技能提供一個全面的指南,用於在家庭實驗室環境中設定 WireGuard VPN,涵蓋從伺服器安裝、用戶端設定到進階路由決策的所有內容。它詳細說明了在 Linux 主機上設定 WireGuard 伺服器,包括金鑰產生、使用 scoped iptables 規則的防火牆設定,以及啟用 IP 轉發。技能的另一個重點是客戶端設定,並清楚解釋了分流隧道(僅將家庭網路流量導向 VPN)和全隧道(透過 VPN 路由所有流量)之間的差異,協助使用者根據其需求選擇最佳方案。為了實現穩定的遠端存取,該指南也涵蓋了使用 Cloudflare DDNS 或 DuckDNS 的動態 DNS (DDNS) 設定,並提供排錯步驟和常見反模式,以確保設定安全高效。此技能在任何支援 WireGuard 的平台上都非常實用,例如 Linux、pfSense 及 OPNsense,並包含可自動化金鑰與客戶端設定檔管理的 Python 程式碼片段。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/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 = <貼上伺服器私鑰>

# 限定範圍的轉發規則:允許 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 = <手機公鑰>
AllowedIPs = 10.8.0.2/32

[Peer]
# 筆電 — 替換為實際的筆電公鑰
PublicKey = <筆電公鑰>
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 = <手機私鑰>
Address = 10.8.0.2/32
DNS = 192.168.1.2                  # 可選:使用 Pi-hole 在隧道中進行 DNS

[Peer]
PublicKey = <伺服器公鑰>
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 廣告阻擋。
  缺點:家庭的上傳速度會成為任何地方的瓶頸。

# 多子網路分流隧道(最常見的家庭實驗室使用案例):
  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 = 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 錯誤
sudo 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/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

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.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

相關技能