Tailscale Multi-tenant Mesh
Tailscale WireGuard Mesh VPN Multi-tenant ACL Tag Group Subnet Router Exit Node MagicDNS Headscale Zero Trust Production
| Isolation Method | Complexity | Isolation Level | Best For |
|---|---|---|---|
| Tag-based ACL | ต่ำ | ปานกลาง (Shared Tailnet) | ทีมภายใน 2-10 กลุ่ม |
| Group-based ACL | ปานกลาง | ปานกลาง-สูง | องค์กร หลายแผนก |
| Separate Tailnet | สูง | สูงสุด | ลูกค้าภายนอก Compliance |
| Headscale (Self-hosted) | สูง | สูงสุด + Data Control | Enterprise Self-hosted |
ACL Configuration
# === Tailscale ACL Policy ===
# tailscale ACL (HuJSON format)
# {
# "groups": {
# "group:tenant-a-admins": ["alice@example.com"],
# "group:tenant-a-users": ["bob@example.com", "carol@example.com"],
# "group:tenant-b-admins": ["dave@example.com"],
# "group:tenant-b-users": ["eve@example.com"],
# "group:platform-admins": ["admin@example.com"]
# },
# "tagOwners": {
# "tag:tenant-a": ["group:tenant-a-admins"],
# "tag:tenant-b": ["group:tenant-b-admins"],
# "tag:shared": ["group:platform-admins"],
# "tag:monitoring": ["group:platform-admins"]
# },
# "acls": [
# // Tenant A can access only their devices
# {"action": "accept", "src": ["group:tenant-a-admins", "group:tenant-a-users"],
# "dst": ["tag:tenant-a:*"]},
# // Tenant B can access only their devices
# {"action": "accept", "src": ["group:tenant-b-admins", "group:tenant-b-users"],
# "dst": ["tag:tenant-b:*"]},
# // Everyone can access shared services on port 443
# {"action": "accept", "src": ["*"], "dst": ["tag:shared:443"]},
# // Platform admins can access monitoring
# {"action": "accept", "src": ["group:platform-admins"], "dst": ["tag:monitoring:*"]},
# // Platform admins can access everything
# {"action": "accept", "src": ["group:platform-admins"], "dst": ["*:*"]}
# ],
# "tests": [
# {"src": "alice@example.com", "accept": ["tag:tenant-a:22"]},
# {"src": "alice@example.com", "deny": ["tag:tenant-b:22"]},
# {"src": "dave@example.com", "accept": ["tag:tenant-b:80"]},
# {"src": "dave@example.com", "deny": ["tag:tenant-a:80"]}
# ]
# }
from dataclasses import dataclass
@dataclass
class ACLRule:
tenant: str
src: str
dst: str
ports: str
purpose: str
rules = [
ACLRule("Tenant A",
"group:tenant-a-admins + users",
"tag:tenant-a:*",
"All Ports",
"Tenant A เข้าถึงเฉพาะ Device ของตัวเอง"),
ACLRule("Tenant B",
"group:tenant-b-admins + users",
"tag:tenant-b:*",
"All Ports",
"Tenant B เข้าถึงเฉพาะ Device ของตัวเอง"),
ACLRule("Shared Services",
"* (Everyone)",
"tag:shared:443",
"443 (HTTPS)",
"ทุก Tenant เข้าถึง Shared API Gateway"),
ACLRule("Monitoring",
"group:platform-admins",
"tag:monitoring:*",
"All Ports",
"Platform Admin ดู Monitoring ทุก Tenant"),
ACLRule("Platform Admin",
"group:platform-admins",
"*:*",
"All Ports",
"Super Admin เข้าถึงทุก Device (Emergency)"),
]
print("=== ACL Rules ===")
for r in rules:
print(f" [{r.tenant}] {r.src} → {r.dst}:{r.ports}")
print(f" Purpose: {r.purpose}")
Network Architecture
# === Multi-tenant Network Design ===
@dataclass
class NetworkComponent:
component: str
config: str
per_tenant: bool
shared: bool
note: str
components = [
NetworkComponent("Subnet Router",
"tailscale up --advertise-routes=10.1.0.0/24",
True,
False,
"แต่ละ Tenant มี Subnet Router แยก เชื่อม On-prem"),
NetworkComponent("Exit Node",
"tailscale up --advertise-exit-node",
True,
False,
"แยก Exit Node ต่อ Tenant สำหรับ IP Isolation"),
NetworkComponent("MagicDNS",
"device.tailnet-name.ts.net",
False,
True,
"ทุก Device มี DNS Name อัตโนมัติ"),
NetworkComponent("Split DNS",
"Resolve *.tenant-a.internal → Subnet Router A",
True,
False,
"แต่ละ Tenant มี Internal DNS แยก"),
NetworkComponent("Auth Key",
"tailscale up --auth-key=tskey-xxx",
True,
False,
"สร้าง Auth Key ต่อ Tenant สำหรับ Auto-join"),
NetworkComponent("Funnel",
"tailscale funnel 443",
False,
True,
"เปิด Shared Services สู่ Internet (ถ้าต้องการ)"),
]
print("=== Network Components ===")
for c in components:
tenant = "Per-tenant" if c.per_tenant else "Shared"
print(f" [{c.component}] {tenant}")
print(f" Config: {c.config}")
print(f" Note: {c.note}")
Automation & Monitoring
# === Tailscale API Automation ===
# Tailscale API
# curl -s https://api.tailscale.com/api/v2/tailnet/example.com/devices \
# -H "Authorization: Bearer tskey-api-xxx" | jq '.devices[] | {name, online}'
# Terraform Provider
# terraform {
# required_providers {
# tailscale = { source = "tailscale/tailscale" }
# }
# }
# resource "tailscale_acl" "main" {
# acl = file("acl.json")
# }
# resource "tailscale_tailnet_key" "tenant_a" {
# reusable = true
# ephemeral = false
# preauthorized = true
# tags = ["tag:tenant-a"]
# }
@dataclass
class AutomationTask:
task: str
tool: str
trigger: str
action: str
tasks = [
AutomationTask("Device Provisioning",
"Terraform + Tailscale Provider",
"New Tenant Onboarding",
"สร้าง Auth Key + ACL Rule + Subnet Router"),
AutomationTask("ACL Update",
"Terraform + Git PR Review",
"Tenant Change Request",
"Update ACL JSON → PR → Review → Apply"),
AutomationTask("Device Monitoring",
"Tailscale API + Prometheus",
"Continuous (every 60s)",
"ตรวจ Device Online/Offline Last Seen"),
AutomationTask("Key Rotation",
"Tailscale API + Cron Job",
"Every 90 days",
"Rotate Auth Keys สร้าง Key ใหม่ ลบ Key เก่า"),
AutomationTask("Audit Log Review",
"Tailscale Admin Console",
"Weekly",
"ตรวจ Login Attempts ACL Changes Device Joins"),
]
print("=== Automation Tasks ===")
for t in tasks:
print(f" [{t.task}] Tool: {t.tool}")
print(f" Trigger: {t.trigger}")
print(f" Action: {t.action}")
เคล็ดลับ
- ACL Tests: เขียน Tests ใน ACL ตรวจ Rule ก่อน Deploy
- Tag: ใช้ Tag แบ่ง Tenant ง่ายสุด ไม่ต้องแยก Tailnet
- Subnet Router: ตั้ง Subnet Router แยกต่อ Tenant
- Key Expiry: เปิด Key Expiry 90 วัน บังคับ Re-auth
- Terraform: ใช้ Terraform จัดการ ACL เป็น IaC
Tailscale คืออะไร
Zero-config VPN WireGuard Mesh Peer-to-peer NAT Traversal MagicDNS ACL Subnet Router Exit Node Taildrop SSH Funnel Free 3 Users
Multi-tenant Design ทำอย่างไร
Tag-based ACL Group-based Separate Tailnet Headscale Self-hosted Tailnet Sharing Namespace Isolation Compliance
ACL กำหนดอย่างไร
HuJSON groups tagOwners acls tests src dst accept deny Tag กำหนด Device Group กำหนด User Tests ตรวจ Rule ก่อน Deploy
Production ตั้งอย่างไร
Subnet Router Exit Node Split DNS Auth Key Terraform API Monitoring Prometheus Key Rotation 90d Audit Log MFA Security
สรุป
Tailscale Multi-tenant WireGuard Mesh ACL Tag Group Subnet Router Exit Node MagicDNS Terraform Headscale Monitoring Production
