SiamCafe.net Blog
Technology

Tailscale Mesh Home Lab Setup

tailscale mesh home lab setup
Tailscale Mesh Home Lab Setup | SiamCafe Blog
2025-11-15· อ. บอม — SiamCafe.net· 9,402 คำ

Tailscale Home Lab

Tailscale Mesh VPN WireGuard Home Lab NAT Traversal MagicDNS ACL Subnet Router Exit Node Headscale Self-hosted SSH Remote Access

VPN SolutionProtocolSetupNAT Traversalราคา
TailscaleWireGuardง่ายมากอัตโนมัติFree 100 devices
WireGuardWireGuardManual Configต้อง Port Forwardฟรี
ZeroTierCustomง่ายอัตโนมัติFree 25 devices
OpenVPNOpenVPNซับซ้อนต้อง Port Forwardฟรี
HeadscaleWireGuardปานกลางอัตโนมัติฟรี (Self-hosted)

Tailscale Setup

# === Tailscale Installation ===

# Linux
# curl -fsSL https://tailscale.com/install.sh | sh
# sudo tailscale up

# Ubuntu/Debian
# curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/jammy.noarmor.gpg \
#   | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg
# echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] \
#   https://pkgs.tailscale.com/stable/ubuntu jammy main" \
#   | sudo tee /etc/apt/sources.list.d/tailscale.list
# sudo apt update && sudo apt install tailscale
# sudo tailscale up

# Docker
# docker run -d --name tailscale \
#   --hostname homelab-docker \
#   -v /var/lib/tailscale:/var/lib/tailscale \
#   -v /dev/net/tun:/dev/net/tun \
#   --cap-add=NET_ADMIN \
#   --cap-add=NET_RAW \
#   -e TS_AUTHKEY=tskey-auth-xxxxx \
#   -e TS_STATE_DIR=/var/lib/tailscale \
#   tailscale/tailscale:latest

# Subnet Router — เข้าถึงทั้ง Subnet
# sudo tailscale up --advertise-routes=192.168.1.0/24,10.0.0.0/24
# # Approve ใน Tailscale Admin Console

# Exit Node — ใช้ Internet ผ่าน Home
# sudo tailscale up --advertise-exit-node
# # On client: tailscale up --exit-node=homelab-server

# MagicDNS — ใช้ชื่อแทน IP
# ssh homelab-server  # แทน ssh 100.64.0.1
# curl http://proxmox.tailnet-xxxx.ts.net:8006

from dataclasses import dataclass
from typing import List

@dataclass
class TailscaleNode:
    hostname: str
    os: str
    ip_tailscale: str
    ip_local: str
    role: str
    online: bool
    last_seen: str

nodes = [
    TailscaleNode("proxmox-01", "Debian 12", "100.64.0.1", "192.168.1.10", "Hypervisor + Subnet Router", True, "now"),
    TailscaleNode("nas-synology", "DSM 7", "100.64.0.2", "192.168.1.20", "NAS Storage", True, "now"),
    TailscaleNode("pi-hole", "Raspberry Pi OS", "100.64.0.3", "192.168.1.30", "DNS + Ad Block", True, "now"),
    TailscaleNode("laptop-work", "Windows 11", "100.64.0.4", "DHCP", "Client", True, "now"),
    TailscaleNode("phone-iphone", "iOS 17", "100.64.0.5", "DHCP", "Client + Exit Node User", True, "2min ago"),
    TailscaleNode("vps-cloud", "Ubuntu 22.04", "100.64.0.6", "203.0.113.50", "Exit Node (Cloud)", True, "now"),
]

print("=== Tailscale Network ===")
for n in nodes:
    status = "Online" if n.online else "Offline"
    print(f"  [{status}] {n.hostname} ({n.os})")
    print(f"    Tailscale: {n.ip_tailscale} | Local: {n.ip_local} | Role: {n.role}")

ACL และ Security

# === Tailscale ACL Policy ===

# tailscale ACL — JSON Policy
# {
#   "acls": [
#     // Admin can access everything
#     {"action": "accept", "src": ["group:admin"], "dst": ["*:*"]},
#
#     // Developers can SSH and access web UIs
#     {"action": "accept", "src": ["group:dev"],
#      "dst": ["tag:server:22", "tag:server:80", "tag:server:443",
#              "tag:server:8006", "tag:server:3000"]},
#
#     // Guests can only access specific services
#     {"action": "accept", "src": ["group:guest"],
#      "dst": ["tag:public:80", "tag:public:443"]},
#   ],
#
#   "groups": {
#     "group:admin": ["user@example.com"],
#     "group:dev": ["dev1@example.com", "dev2@example.com"],
#     "group:guest": ["guest@example.com"],
#   },
#
#   "tagOwners": {
#     "tag:server": ["group:admin"],
#     "tag:public": ["group:admin"],
#   },
#
#   "ssh": [
#     {"action": "accept", "src": ["group:admin"], "dst": ["tag:server"],
#      "users": ["root", "admin"]},
#     {"action": "accept", "src": ["group:dev"], "dst": ["tag:server"],
#      "users": ["autogroup:nonroot"]},
#   ],
# }

# Tailscale SSH — ไม่ต้อง SSH Key
# tailscale ssh proxmox-01
# # Uses Tailscale identity, no SSH keys needed

security_features = {
    "WireGuard Encryption": "ChaCha20-Poly1305 ทุก Connection",
    "ACL Policy": "ควบคุม Access ละเอียดต่อ User/Group/Tag",
    "MagicDNS": "DNS อัตโนมัติ ใช้ชื่อแทน IP",
    "Tailscale SSH": "SSH ไม่ต้อง Key ใช้ Identity",
    "HTTPS Certificates": "ออก Cert ให้ทุก Node อัตโนมัติ",
    "Key Expiry": "กำหนดอายุ Key ต้อง Re-authenticate",
    "Audit Log": "บันทึกทุกการเชื่อมต่อ",
    "2FA": "บังคับ 2FA สำหรับ User ทุกู้คืน",
}

print("\nSecurity Features:")
for feature, desc in security_features.items():
    print(f"  [{feature}]: {desc}")

Headscale Self-hosted

# === Headscale Setup ===

# Install Headscale
# wget https://github.com/juanfont/headscale/releases/latest/download/headscale_linux_amd64
# sudo mv headscale_linux_amd64 /usr/local/bin/headscale
# sudo chmod +x /usr/local/bin/headscale

# Configuration /etc/headscale/config.yaml
# server_url: https://headscale.example.com:443
# listen_addr: 0.0.0.0:8080
# private_key_path: /var/lib/headscale/private.key
# noise:
#   private_key_path: /var/lib/headscale/noise_private.key
# ip_prefixes:
#   - 100.64.0.0/10
# dns_config:
#   nameservers:
#     - 1.1.1.1
#   magic_dns: true
#   base_domain: homelab.ts
# db_type: sqlite3
# db_path: /var/lib/headscale/db.sqlite

# Docker Compose
# services:
#   headscale:
#     image: headscale/headscale:latest
#     volumes:
#       - ./config:/etc/headscale
#       - ./data:/var/lib/headscale
#     ports: ["8080:8080"]
#     command: serve
#
#   headscale-ui:
#     image: ghcr.io/gurucomputing/headscale-ui:latest
#     ports: ["8443:443"]

# Register Node
# headscale users create homelab
# headscale preauthkeys create --user homelab --reusable --expiration 24h
# # On client:
# tailscale up --login-server https://headscale.example.com

comparison = {
    "Tailscale Cloud": {
        "control": "Tailscale servers",
        "privacy": "Data on Tailscale",
        "limit": "100 devices free",
        "setup": "1 minute",
        "maintenance": "Zero",
    },
    "Headscale": {
        "control": "Your server",
        "privacy": "Full control",
        "limit": "Unlimited",
        "setup": "30 minutes",
        "maintenance": "Updates + backup",
    },
}

print("Tailscale vs Headscale:")
for name, info in comparison.items():
    print(f"\n  [{name}]")
    for k, v in info.items():
        print(f"    {k}: {v}")

เคล็ดลับ

Tailscale คืออะไร

Mesh VPN WireGuard Backend NAT Traversal ไม่เปิด Port MagicDNS ACL Free 100 Devices ติดตั้งง่าย 1 คำสั่ง

Home Lab ใช้ Tailscale อย่างไร

เชื่อม Server Cloud Laptop มือถือ SSH จากทุกที่ Web UI Proxmox Grafana Subnet Router Exit Node Share Node Lab

Tailscale กับ WireGuard ต่างกันอย่างไร

WireGuard Protocol Manual Config Port Forward Public IP Tailscale จัดการ Key NAT DNS ACL ไม่เปิด Port ง่ายมาก ใช้งานจริง

Headscale คืออะไร

Open Source Self-hosted Control Server แทน Tailscale Cloud Privacy Full Control ไม่ Limit ฟรี Setup เอง Tailscale Client เดิม

สรุป

Tailscale Mesh VPN WireGuard Home Lab NAT Traversal MagicDNS ACL Subnet Router Exit Node Headscale Self-hosted SSH Remote Access Docker Proxmox Security

📖 บทความที่เกี่ยวข้อง

Calico Network Policy Home Lab Setupอ่านบทความ → อ่านบทความ → Tailscale Mesh Architecture Design Patternอ่านบทความ → Shadcn UI Home Lab Setupอ่านบทความ →

📚 ดูบทความทั้งหมด →