Communitygithub.com

홈랩 WireGuard VPN

WireGuard VPN 서버 설정, 피어 구성, 키 생성, 분할 터널링 vs 전체 터널 라우팅, 모바일 및 노트북 클라이언트에서 홈 네트워크로의 원격 액세스를 지원합니다. 홈 네트워크에 원격으로 접속하기 위해 WireGuard를 설정하거나 분할 터널과 전체 터널 라우팅 중에서 결정할 때 사용하세요.

홈랩 WireGuard VPN란 무엇인가요?

이 스킬은 홈랩 환경에서 WireGuard VPN을 설정하고 관리하는 방법을 상세히 설명합니다. WireGuard는 OpenVPN보다 간단하고 대부분의 대안보다 빠른 최신 VPN 프로토콜로, Raspberry Pi, Linux 호스트, pfSense 또는 라우터에서 서버를 설정하는 방법을 다룹니다. 서버 및 클라이언트 키 쌍 생성, 피어 구성 파일 작성, 분할 터널링(홈 트래픽만 라우팅)과 전체 터널(모든 트래픽 라우팅)의 차이점, 그리고 동적 DNS(DDNS) 설정을 포함합니다. 또한 iptables 포워딩 규칙, IP 포워딩 활성화, 방화벽 규칙 구성 등 네트워크 설정에 대한 모범 사례를 제공하며, Python 스크립트를 사용한 키 생성 및 피어 관리를 자동화하는 방법도 보여줍니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/homelab-wireguard-vpn

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

홈랩 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을 통해 전송됩니다.
  인터넷 트래픽(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 — 자격 증명을 인라인이 아닌 시크릿 파일에 저장
# 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에 가입 → 토큰과 서브도메인(myhome.duckdns.org) 획득
  토큰을 /etc/ddns.env (모드 600)에 저장한 후, 루트 소유의 작은 스크립트 사용:

  # /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 파일에 저장
  • 포괄적인 FORWARD ACCEPT 대신 범위가 지정된 iptables 포워딩 규칙 사용(wg0에서 인바운드만)
  • 클라이언트 구성에서 DNS =로 Pi-hole의 IP를 추가하여 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.

관련 스킬