external/anthropic-cybersecurity-skills/skills/deploying-tailscale-for-zero-trust-vpn/SKILL.md
Deploys and configures Tailscale (or self-hosted Headscale) as a WireGuard-based zero trust mesh VPN, setting up identity-aware ACLs, exit nodes, subnet routers, and MagicDNS for encrypted peer-to-peer connectivity. Use when replacing traditional VPN servers with an identity-authenticated mesh network or enforcing granular per-device access control lists.
npx skillsauth add seikaikyo/dash-skills deploying-tailscale-for-zero-trust-vpnInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Tailscale is a zero trust mesh VPN built on WireGuard that creates encrypted peer-to-peer connections between devices without requiring traditional VPN servers or complex network configuration. Every connection in a Tailscale network (tailnet) is end-to-end encrypted using WireGuard's Noise protocol framework with Curve25519 key exchange. Tailscale implements zero trust networking by authenticating every connection request through identity providers, enforcing granular Access Control Lists (ACLs), and supporting features like exit nodes, subnet routers, MagicDNS, and Tailscale SSH. For organizations preferring self-hosted infrastructure, Headscale provides an open-source implementation of the Tailscale control server.
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.
# 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: Download from https://tailscale.com/download/windows
# macOS: Install via Homebrew
brew install --cask tailscale
# Or download from https://tailscale.com/download/mac
# 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:
# 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"]
Tailscale ACLs define who can access what within your tailnet using a declarative JSON format. The default policy is deny-all, making it zero trust by design.
{
"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 replaces traditional SSH key management with identity-based access.
# 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 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
# 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"]
}
}
# 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
# 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
tools
Conduct comprehensive GDPR compliance assessments by evaluating data processing activities against EU Regulation 2016/679, including Article 30 records of processing, lawful basis validation, data subject rights implementation, Data Protection Impact Assessments (DPIAs) under Article 35, breach notification procedures, international transfer safeguards (SCCs, adequacy decisions), and technical/organizational measures under Article 32. Use when processing personal data of EU residents, preparing for supervisory authority audits, implementing privacy-by-design for new systems, scoping compliance gaps for M&A due diligence, assessing third-party processors, or responding to data subject access requests at scale. Incorporates 2026 guidance from ICO, EDPB, and post-Data (Use and Access) Act 2025 UK-GDPR considerations. Do not use for implementing specific Article 32 controls — use implementing-gdpr-data-protection-controls; or for DSAR automation — use implementing-gdpr-data-subject-access-request.
tools
Parse Windows forensic artifacts—$MFT/$J (MFTECmd), Prefetch (PECmd), registry hives (RECmd), shellbags, and Amcache—into normalized CSV/JSON with Eric Zimmerman's EZ Tools, then load results into Timeline Explorer for analysis. Use during DFIR/incident-response investigations, after triage collection (e.g. with KAPE), to establish program execution, file/folder access, and persistence evidence from acquired forensic images.
development
Build automated multi-turn adversarial attacks against conversational LLM targets using Microsoft PyRIT's RedTeamingOrchestrator, CrescendoOrchestrator (gradual escalation), and TreeOfAttacksWithPruningOrchestrator (adaptive branching), with scorer feedback loops and persisted conversation memory. Use when single-shot LLM scanning is insufficient and you need multi-turn, scorer-driven AI red-team campaigns against a chatbot or agent.
testing
Stand up MISP, enable and cache curated threat feeds (CIRCL, abuse.ch, Feodo Tracker), apply warninglists to suppress false positives, query indicators with PyMISP, and export attributes as auto-generated Suricata/Sigma/Wazuh detection rules. Use when maturing a MISP instance to actively drive detection, curating threat feeds with quality controls, or automating IOC-to-detection pipelines for the SIEM/IDS.