deploying-tailscale-for-zero-trust-vpn について
Tailscale をゼロトラストのメッシュ VPN として導入・設定するためのセキュリティスキルです。デバイス接続とアクセス制御を計画する管理者向けに、ACL、ルーティング、Tailscale SSH、MagicDNS、Headscale によるセルフホストを扱います。
主な機能
- 01ID ベースの ACL 設定
- 02出口ノードとサブルートの構成
- 03Tailscale SSH によるアクセス管理
- 04MagicDNS とスプリット DNS の設定
- 05Headscale によるコントロールサーバーのセルフホスト
- 06デバイスキーとネットワークロックの管理
活用シーン
- 01ゼロトラストのデバイスネットワーク導入
- 02チームやデバイスごとのアクセス制限
- 03ルーティングによる内部サブネット接続
- 04CI/CD ジョブへの一時的な内部アクセス提供
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill deploying-tailscale-for-zero-trust-vpnインストール後、Claude Code で/deploying-tailscale-for-zero-trust-vpnを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py詳細
ゼロトラスト VPN のための Tailscale のデプロイ
概要
Tailscale は WireGuard を基盤とするゼロトラストのメッシュ VPN です。従来の VPN サーバーや複雑なネットワーク設定を必要とせず、デバイス間に暗号化されたピアツーピア接続を作成します。Tailscale ネットワーク(tailnet)内のすべての接続は、Curve25519 鍵交換を備えた WireGuard の Noise プロトコルフレームワークを使用して、エンドツーエンドで暗号化されます。Tailscale は、ID プロバイダーを通じてすべての接続要求を認証し、きめ細かなアクセス制御リスト(ACL)を適用し、出口ノード、サブネットルーター、MagicDNS、Tailscale SSH などの機能をサポートすることで、ゼロトラストネットワークを実現します。セルフホスト可能なインフラストラクチャを希望する組織向けに、Headscale は Tailscale コントロールサーバーのオープンソース実装を提供します。
使用する場面
- 環境でゼロトラスト VPN 機能を実現するために、Tailscale をデプロイまたは設定する場合
- コンプライアンス要件に沿ったセキュリティ制御を確立する場合
- この分野のセキュリティアーキテクチャを構築または改善する場合
- この実装を必要とするセキュリティ評価を実施する場合
前提条件
- ID プロバイダー(Okta、Azure AD、Google Workspace、GitHub、または OIDC 互換のもの)
- サポート対象 OS(Linux、Windows、macOS、iOS、Android、FreeBSD)を実行するデバイス
- DNS とファイアウォールルールを設定するための管理者アクセス権
- WireGuard プロトコルの基本的な理解
- サブネットルーティング要件に関するネットワーク計画ドキュメント
アーキテクチャ
Tailscale Coordination Server
(or self-hosted Headscale)
|
Key Distribution
& NAT Traversal
|
+-----------------+-----------------+
| | |
+----+----+ +----+----+ +----+----+
| Node A |<---->| Node B |<---->| Node C |
| (Linux) | | (macOS) | |(Windows)|
+---------+ +---------+ +---------+
WireGuard WireGuard WireGuard
Encrypted Encrypted Encrypted
P2P Tunnel P2P Tunnel P2P Tunnel
Each node connects directly to every other node.
DERP relay servers used only when direct P2P fails.
インストールとセットアップ
Linux へのインストール
# Add Tailscale repository and install
curl -fsSL https://tailscale.com/install.sh | sh
# Start Tailscale and authenticate
sudo tailscale up
# Check connection status
tailscale status
# View assigned IP address
tailscale ip -4
tailscale ip -6
Windows/macOS へのインストール
# Windows: Download from https://tailscale.com/download/windows
# macOS: Install via Homebrew
brew install --cask tailscale
# Or download from https://tailscale.com/download/mac
Docker でのデプロイ
# docker-compose.yml for Tailscale sidecar
version: '3.8'
services:
tailscale:
image: tailscale/tailscale:latest
container_name: tailscale
hostname: my-service
environment:
- TS_AUTHKEY=tskey-auth-xxxxx # Pre-auth key
- TS_STATE_DIR=/var/lib/tailscale
- TS_EXTRA_ARGS=--advertise-tags=tag:container
volumes:
- tailscale-state:/var/lib/tailscale
- /dev/net/tun:/dev/net/tun
cap_add:
- net_admin
- sys_module
restart: unless-stopped
volumes:
tailscale-state:
Kubernetes でのデプロイ
# Tailscale operator for Kubernetes
apiVersion: v1
kind: Secret
metadata:
name: tailscale-auth
namespace: tailscale
type: Opaque
stringData:
TS_AUTHKEY: "tskey-auth-xxxxx"
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: tailscale
namespace: tailscale
spec:
selector:
matchLabels:
app: tailscale
template:
metadata:
labels:
app: tailscale
spec:
containers:
- name: tailscale
image: tailscale/tailscale:latest
env:
- name: TS_AUTHKEY
valueFrom:
secretKeyRef:
name: tailscale-auth
key: TS_AUTHKEY
- name: TS_KUBE_SECRET
value: tailscale-state
- name: TS_USERSPACE
value: "true"
securityContext:
capabilities:
add: ["NET_ADMIN"]
アクセス制御リスト(ACL)
Tailscale ACL は、宣言型 JSON 形式を使用して、tailnet 内のリソースにアクセスできるユーザーを定義します。デフォルトのポリシーはすべて拒否であり、設計上、ゼロトラストになっています。
{
"acls": [
// Engineering team can access development servers
{
"action": "accept",
"src": ["group:engineering"],
"dst": ["tag:dev-server:*"]
},
// SRE team can access production infrastructure
{
"action": "accept",
"src": ["group:sre"],
"dst": ["tag:production:22,443,8080"]
},
// Database access restricted to backend services
{
"action": "accept",
"src": ["tag:backend"],
"dst": ["tag:database:5432,3306,27017"]
},
// All employees can access internal tools
{
"action": "accept",
"src": ["group:employees"],
"dst": ["tag:internal-tools:443"]
}
],
"groups": {
"group:engineering": ["[email protected]", "[email protected]"],
"group:sre": ["[email protected]", "[email protected]"],
"group:employees": ["autogroup:members"]
},
"tagOwners": {
"tag:dev-server": ["group:engineering"],
"tag:production": ["group:sre"],
"tag:backend": ["group:sre"],
"tag:database": ["group:sre"],
"tag:internal-tools": ["group:sre"],
"tag:container": ["group:sre"]
},
"ssh": [
{
"action": "check",
"src": ["group:sre"],
"dst": ["tag:production"],
"users": ["root", "admin"]
},
{
"action": "accept",
"src": ["group:engineering"],
"dst": ["tag:dev-server"],
"users": ["autogroup:nonroot"]
}
],
"nodeAttrs": [
{
"target": ["autogroup:members"],
"attr": ["funnel:deny"]
}
]
}
出口ノードとサブネットルーティング
出口ノードの設定
# On the exit node machine
sudo tailscale up --advertise-exit-node
# On the client machine, use the exit node
sudo tailscale up --exit-node=<exit-node-ip>
# Verify exit node routing
curl ifconfig.me # Should show exit node's public IP
サブネットルーターの設定
# Advertise local subnets through Tailscale
sudo tailscale up --advertise-routes=10.0.0.0/24,192.168.1.0/24
# Enable IP forwarding on Linux
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# Accept routes on client
sudo tailscale up --accept-routes
Tailscale SSH(ゼロトラスト SSH)
Tailscale SSH は、従来の SSH 鍵管理を ID ベースのアクセスに置き換えます。
# Enable Tailscale SSH on a server
sudo tailscale up --ssh
# Connect using Tailscale SSH (no SSH keys needed)
ssh user@hostname # Authenticates via Tailscale identity
# Session recording (audit logging)
# Configure in ACL policy:
# "ssh": [{"action": "check", "src": [...], "dst": [...], "users": [...]}]
# "check" action requires re-authentication and records sessions
MagicDNS の設定
# MagicDNS is enabled by default in new tailnets
# Access devices by hostname instead of IP
ping my-server # Resolves via MagicDNS
# Custom DNS configuration via admin console
# Split DNS: route specific domains to internal DNS servers
# Global nameservers: override default DNS resolution
Headscale を使ったセルフホスト
# Install Headscale (open-source Tailscale control server)
wget https://github.com/juanfont/headscale/releases/latest/download/headscale_linux_amd64
chmod +x headscale_linux_amd64
sudo mv headscale_linux_amd64 /usr/local/bin/headscale
# Create configuration
sudo mkdir -p /etc/headscale
sudo headscale generate config > /etc/headscale/config.yaml
# Edit config for your environment
# Key settings:
# server_url: https://headscale.example.com
# listen_addr: 0.0.0.0:8080
# private_key_path: /etc/headscale/private.key
# db_type: sqlite3
# db_path: /var/lib/headscale/db.sqlite
# Start Headscale
sudo headscale serve
# Create user and pre-auth key
headscale users create myorg
headscale preauthkeys create --user myorg --reusable --expiration 24h
# Connect Tailscale client to Headscale
tailscale up --login-server https://headscale.example.com
セキュリティ強化
鍵の有効期限とローテーション
# Set key expiry in admin console (default: 180 days)
# Force re-authentication periodically
# Disable key expiry for servers (use auth keys instead)
sudo tailscale up --authkey=tskey-auth-xxxxx
# Pre-auth keys for automated deployment
# Create ephemeral, single-use keys for CI/CD
デバイスの認証
{
"nodeAttrs": [
{
"target": ["autogroup:members"],
"attr": [
"mullvad:deny",
"funnel:deny"
]
}
],
"autoApprovers": {
"routes": {
"10.0.0.0/24": ["group:sre"],
"192.168.0.0/16": ["group:sre"]
},
"exitNode": ["group:sre"]
}
}
ネットワークロック(Tailnet Lock)
# Initialize network lock with signing keys
tailscale lock init
# Add trusted signing keys
tailscale lock add nodekey:xxxxx
# All new nodes require signing before joining
# Prevents unauthorized nodes from joining the tailnet
モニタリングと可観測性
# View network status
tailscale status --json | jq '.Peer | to_entries[] | {name: .value.HostName, online: .value.Online, os: .value.OS}'
# Check connection quality
tailscale ping <peer-ip>
# View network map
tailscale netcheck
# Audit logs available in Tailscale admin console
# Integration with SIEM via webhook or API
統合パターン
サービスメッシュとの統合
# Tailscale as sidecar for service-to-service communication
# Each service gets a Tailscale identity
# ACLs enforce service-to-service access policies
# Example: API service can only reach database service
# ACL: tag:api -> tag:database:5432
CI/CD パイプラインとの統合
# Use ephemeral auth keys in CI/CD
export TS_AUTHKEY=tskey-auth-xxxxx-ephemeral
tailscale up --authkey=$TS_AUTHKEY --hostname=ci-runner-$CI_JOB_ID
# Access internal resources during build/deploy
# Node automatically removed when container stops