Communitygithub.com

家庭实验室-WireGuard-VPN

WireGuard VPN服务器搭建、对等点配置、密钥生成、分流隧道与全隧道路由选择,以及通过手机和笔记本电脑客户端远程访问家庭网络。用于设置WireGuard以远程访问家庭网络,或在分流隧道与全隧道路由之间做出选择。

家庭实验室-WireGuard-VPN 是什么?

该技能详细指导如何搭建WireGuard VPN服务器,实现从移动设备和笔记本电脑安全远程访问家庭网络。它涵盖服务器安装、密钥生成、对等点配置、防火墙规则、IP转发,以及通过DDNS处理动态IP。技能明确解释了分流隧道(仅路由家庭网络流量)与全隧道(路由所有流量)的区别,并给出了基于pfSense/OPNsense的替代方案。此外,还包含一个Python脚本,用于自动化密钥生成和对等点配置,以及常见问题排查章节和反模式列表,帮助用户避开典型陷阱。该技能适用于Raspberry Pi、Linux主机、pfSense和路由器等环境,强调安全最佳实践,如每台设备使用独立密钥对、避免将私钥放入版本控制,以及在移动客户端上使用PersistentKeepalive。

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

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

家庭实验室 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:端口)。
流量端到端加密,无需中央服务器或证书颁发机构。

服务器设置(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。
  Internet 流量(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 以便在 IP 更改后 VPN 端点仍可访问。

# 选项 1:Cloudflare DDNS — 将凭据存储在秘密文件中,而非内联
# docker-compose 条目,使用 env 文件:
  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 转发
# 隧道连接成功但没有流量路由 — 排查困难

# 错误:在多个客户端设备之间共享一个密钥对
# 每个设备必须拥有自己唯一的密钥对 — 共享密钥破坏安全模型

# 错误:使用宽泛的 iptables 规则 "FORWARD ACCEPT"
# 将转发规则限定到 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.

相关技能