Skip to content

Tailscale Cheatsheet

Tailscale is a modern VPN solution built on WireGuard that creates secure, encrypted networks between devices without the complexity of traditional VPN setups. It provides zero-configuration networking with automatic key management, NAT traversal, and seamless connectivity across different networks and platforms.

Platform Overview

Architecture and Design Philosophy

Tailscale operates on a mesh networking model where each device connects directly to others when possible, falling back to relay servers (DERP) when direct connections aren't feasible. The service handles all the complex networking automatically, including NAT traversal, firewall configuration, and key rotation.

The Tailscale coordination server manages device authentication, key distribution, and network topology, while the actual data traffic flows directly between devices using WireGuard encryption. This approach provides both security and performance while maintaining ease of use.

Key Features

bash
# Core Tailscale Capabilities
- WireGuard-based encryption and performance
- Zero-configuration mesh networking
- Automatic NAT traversal and firewall handling
- Cross-platform support (Windows, macOS, Linux, iOS, Android)
- Magic DNS for easy device discovery
- Subnet routing and exit nodes
- Access control lists (ACLs) for fine-grained permissions
- SSO integration with major identity providers
- Audit logging and network monitoring

Installation and Setup

Linux Installation

bash
# Install on Ubuntu/Debian
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt update
sudo apt install tailscale

# Install on CentOS/RHEL/Fedora
sudo dnf config-manager --add-repo https://pkgs.tailscale.com/stable/centos/8/tailscale.repo
sudo dnf install tailscale

# Install on Arch Linux
sudo pacman -S tailscale

# Start and enable Tailscale service
sudo systemctl enable --now tailscaled

# Authenticate and connect to your network
sudo tailscale up

# Check status
tailscale status

# Get your device's Tailscale IP
tailscale ip -4
tailscale ip -6

# View network map
tailscale netmap

# Check connection quality
tailscale ping <device-name-or-ip>

# Enable SSH access through Tailscale
sudo tailscale up --ssh

# Set up as exit node
sudo tailscale up --advertise-exit-node

# Accept routes from other devices
sudo tailscale up --accept-routes

# Set custom hostname
sudo tailscale up --hostname=my-server

Windows Installation

powershell
# Download and install Tailscale for Windows
$TailscaleUrl = "https://pkgs.tailscale.com/stable/tailscale-setup-latest.exe"
$TailscaleInstaller = "$env:TEMP\tailscale-setup.exe"

Invoke-WebRequest -Uri $TailscaleUrl -OutFile $TailscaleInstaller
Start-Process -FilePath $TailscaleInstaller -Wait

# Connect to network (run as administrator)
tailscale up

# Check status
tailscale status

# Enable as exit node
tailscale up --advertise-exit-node

# Configure Windows firewall for Tailscale
New-NetFirewallRule -DisplayName "Tailscale" -Direction Inbound -Protocol UDP -LocalPort 41641 -Action Allow
New-NetFirewallRule -DisplayName "Tailscale" -Direction Outbound -Protocol UDP -LocalPort 41641 -Action Allow

# Set up automatic startup
$TailscaleService = Get-Service -Name "Tailscale"
Set-Service -Name "Tailscale" -StartupType Automatic

# PowerShell script for automated deployment
$TailscaleConfig = @"
{
  "AuthKey": "$env:TAILSCALE_AUTHKEY",
  "Hostname": "$env:COMPUTERNAME-tailscale",
  "AdvertiseExitNode": false,
  "AcceptRoutes": true
}
"@

$TailscaleConfig | Out-File -FilePath "$env:ProgramData\Tailscale\config.json"

macOS Installation

bash
# Install via Homebrew
brew install tailscale

# Or download from Mac App Store
# https://apps.apple.com/us/app/tailscale/id1475387142

# Start Tailscale
sudo tailscale up

# Check status
tailscale status

# Configure as exit node
sudo tailscale up --advertise-exit-node

# Enable SSH access
sudo tailscale up --ssh

# macOS-specific network configuration
# Allow Tailscale through macOS firewall
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add /Applications/Tailscale.app/Contents/MacOS/Tailscale
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --unblockapp /Applications/Tailscale.app/Contents/MacOS/Tailscale

# Configure launch daemon for automatic startup
sudo launchctl load /Library/LaunchDaemons/com.tailscale.tailscaled.plist

Mobile Device Setup

bash
# iOS Setup
# 1. Download Tailscale from App Store
# 2. Sign in with your account
# 3. Device automatically appears in admin console

# Android Setup
# 1. Download from Google Play Store
# 2. Sign in with your account
# 3. Grant VPN permissions when prompted

# Generate auth keys for automated mobile deployment
tailscale up --authkey=tskey-auth-xxxxxx-xxxxxx

# Create reusable auth key (admin console or API)
curl -X POST \
  -H "Authorization: Bearer $TAILSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"capabilities": {"devices": {"create": {"reusable": true, "ephemeral": false}}}}' \
  https://api.tailscale.com/api/v2/tailnet/$TAILNET/keys

# Mobile device management via MDM
# Example configuration for iOS/Android MDM systems
{
  "authKey": "tskey-auth-xxxxxx-xxxxxx",
  "hostname": "mobile-device-001",
  "acceptRoutes": true,
  "exitNode": "exit-node-hostname"
}

Network Configuration

Subnet Routing

bash
# Advertise subnet routes
sudo tailscale up --advertise-routes=192.168.1.0/24,10.0.0.0/8

# Accept subnet routes from other devices
sudo tailscale up --accept-routes

# View available routes
tailscale status --peers

# Enable IP forwarding (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

# Configure iptables for subnet routing
sudo iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i tailscale0 -j ACCEPT
sudo iptables -A FORWARD -o tailscale0 -j ACCEPT

# Persistent iptables rules (Ubuntu/Debian)
sudo iptables-save | sudo tee /etc/iptables/rules.v4

# Advanced routing configuration
# Route specific traffic through Tailscale
sudo ip route add 192.168.100.0/24 dev tailscale0

# Set up policy-based routing
sudo ip rule add from 100.64.0.0/10 table 100
sudo ip route add default dev tailscale0 table 100

# Configure multiple subnet advertisements
cat > /etc/tailscale/subnet-config.sh << 'EOF'
#!/bin/bash
SUBNETS="192.168.1.0/24,10.0.0.0/16,172.16.0.0/12"
tailscale up --advertise-routes=$SUBNETS --accept-routes
EOF

chmod +x /etc/tailscale/subnet-config.sh

Exit Nodes

bash
# Set up device as exit node
sudo tailscale up --advertise-exit-node

# Use another device as exit node
tailscale up --exit-node=exit-node-hostname

# Use exit node with specific IP
tailscale up --exit-node=100.64.0.1

# Disable exit node usage
tailscale up --exit-node=""

# List available exit nodes
tailscale status --peers | grep "exit node"

# Configure exit node with specific routes
sudo tailscale up --advertise-exit-node --advertise-routes=0.0.0.0/0,::/0

# Exit node health monitoring
cat > /usr/local/bin/tailscale-exit-node-monitor.sh << 'EOF'
#!/bin/bash
LOG_FILE="/var/log/tailscale-exit-node.log"

check_exit_node() {
    if tailscale status | grep -q "exit node"; then
        echo "$(date): Exit node is active" >> $LOG_FILE
        return 0
    else
        echo "$(date): Exit node is not active, restarting..." >> $LOG_FILE
        sudo tailscale up --advertise-exit-node
        return 1
    fi
}

check_connectivity() {
    if ping -c 1 8.8.8.8 >/dev/null 2>&1; then
        echo "$(date): Internet connectivity OK" >> $LOG_FILE
        return 0
    else
        echo "$(date): Internet connectivity failed" >> $LOG_FILE
        return 1
    fi
}

main() {
    check_exit_node
    check_connectivity
}

main
EOF

chmod +x /usr/local/bin/tailscale-exit-node-monitor.sh

# Add to crontab for monitoring
echo "*/5 * * * * /usr/local/bin/tailscale-exit-node-monitor.sh" | crontab -

Magic DNS Configuration

bash
# Enable Magic DNS (usually enabled by default)
tailscale up --accept-dns

# Disable Magic DNS
tailscale up --accept-dns=false

# Configure custom DNS servers
tailscale up --accept-dns --dns=1.1.1.1,8.8.8.8

# View DNS configuration
tailscale status --json | jq '.DNSConfig'

# Test Magic DNS resolution
nslookup device-name.tailnet-name.ts.net
dig device-name.tailnet-name.ts.net

# Configure split DNS
# Add to /etc/systemd/resolved.conf (Linux)
[Resolve]
DNS=100.100.100.100
Domains=~tailnet-name.ts.net

# Restart systemd-resolved
sudo systemctl restart systemd-resolved

# Custom DNS configuration for specific domains
cat > /etc/tailscale/dns-config.json << 'EOF'
{
  "nameservers": ["1.1.1.1", "8.8.8.8"],
  "domains": ["company.local"],
  "routes": {
    "company.local": ["192.168.1.1"],
    "internal.corp": ["10.0.0.1"]
  }
}
EOF

Access Control and Security

Access Control Lists (ACLs)

json
// Example ACL configuration (tailnet policy file)
{
  "tagOwners": {
    "tag:server": ["user@company.com"],
    "tag:client": ["group:employees"],
    "tag:admin": ["user@company.com"]
  },
  
  "groups": {
    "group:employees": ["user1@company.com", "user2@company.com"],
    "group:admins": ["admin@company.com"],
    "group:servers": ["tag:server"]
  },
  
  "acls": [
    {
      "action": "accept",
      "src": ["group:employees"],
      "dst": ["tag:server:22", "tag:server:80", "tag:server:443"]
    },
    {
      "action": "accept",
      "src": ["group:admins"],
      "dst": ["*:*"]
    },
    {
      "action": "accept",
      "src": ["tag:server"],
      "dst": ["tag:server:*"]
    }
  ],
  
  "hosts": {
    "database-server": "100.64.0.10",
    "web-server": "100.64.0.20",
    "admin-workstation": "100.64.0.30"
  },
  
  "autoApprovers": {
    "routes": {
      "192.168.1.0/24": ["tag:server"],
      "10.0.0.0/8": ["group:admins"]
    },
    "exitNode": ["tag:server"]
  }
}

Authentication and SSO

bash
# Configure SSO with Google Workspace
# (Done through Tailscale admin console)
# Settings > SSO > Add Identity Provider

# Configure SAML SSO
# Upload SAML metadata or configure manually:
# - Entity ID: https://login.tailscale.com/saml/acs
# - ACS URL: https://login.tailscale.com/saml/acs
# - Attribute mapping: email, displayName

# Configure OIDC/OAuth
# Provider: Custom OIDC
# Client ID: your-client-id
# Client Secret: your-client-secret
# Issuer URL: https://your-provider.com

# Force re-authentication
tailscale logout
tailscale up

# Configure device authorization
# Require approval for new devices
# Settings > Device Approval > Require approval

# Set up device tags for automated approval
tailscale up --authkey=tskey-auth-xxxxxx --advertise-tags=tag:server

# Configure session recording (enterprise feature)
# Settings > Session Recording > Enable
# Specify recording targets and retention policies

# Multi-factor authentication
# Configured at identity provider level
# Tailscale inherits MFA requirements from SSO provider

Key Management

bash
# View device keys
tailscale status --json | jq '.Peer[].Key'

# Rotate machine key
sudo tailscale up --force-reauth

# Generate auth keys via API
curl -X POST \
  -H "Authorization: Bearer $TAILSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "capabilities": {
      "devices": {
        "create": {
          "reusable": false,
          "ephemeral": true,
          "preauthorized": true,
          "tags": ["tag:server"]
        }
      }
    },
    "expirySeconds": 3600
  }' \
  https://api.tailscale.com/api/v2/tailnet/$TAILNET/keys

# Revoke auth key
curl -X DELETE \
  -H "Authorization: Bearer $TAILSCALE_API_KEY" \
  https://api.tailscale.com/api/v2/tailnet/$TAILNET/keys/$KEY_ID

# Configure key expiry
tailscale up --authkey=tskey-auth-xxxxxx --timeout=24h

# Backup and restore device configuration
# Export device configuration
tailscale status --json > tailscale-backup.json

# Key rotation automation script
cat > /usr/local/bin/tailscale-key-rotation.sh << 'EOF'
#!/bin/bash
LOG_FILE="/var/log/tailscale-key-rotation.log"
ROTATION_INTERVAL_DAYS=30

check_key_age() {
    LAST_ROTATION=$(tailscale status --json | jq -r '.Self.LastSeen')
    CURRENT_TIME=$(date +%s)
    LAST_ROTATION_TIME=$(date -d "$LAST_ROTATION" +%s)
    AGE_DAYS=$(( (CURRENT_TIME - LAST_ROTATION_TIME) / 86400 ))
    
    if [ $AGE_DAYS -gt $ROTATION_INTERVAL_DAYS ]; then
        echo "$(date): Key is $AGE_DAYS days old, rotating..." >> $LOG_FILE
        return 0
    else
        echo "$(date): Key is $AGE_DAYS days old, no rotation needed" >> $LOG_FILE
        return 1
    fi
}

rotate_key() {
    echo "$(date): Starting key rotation" >> $LOG_FILE
    sudo tailscale up --force-reauth --authkey=$TAILSCALE_AUTHKEY
    if [ $? -eq 0 ]; then
        echo "$(date): Key rotation successful" >> $LOG_FILE
    else
        echo "$(date): Key rotation failed" >> $LOG_FILE
    fi
}

if check_key_age; then
    rotate_key
fi
EOF

chmod +x /usr/local/bin/tailscale-key-rotation.sh

Monitoring and Troubleshooting

Network Diagnostics

bash
# Check Tailscale status
tailscale status

# Detailed status with JSON output
tailscale status --json

# Check connectivity to specific peer
tailscale ping device-name

# Network map and topology
tailscale netmap

# Debug connection issues
tailscale debug --help

# Check DERP (relay) server connectivity
tailscale netcheck

# View logs
sudo journalctl -u tailscaled -f

# Debug specific peer connection
tailscale debug peer-status <peer-id>

# Check NAT traversal
tailscale debug derp-map

# Network performance testing
tailscale debug ping <device-name>
tailscale debug speedtest <device-name>

# Capture network traffic for debugging
sudo tcpdump -i tailscale0 -w tailscale-debug.pcap

# Check firewall rules affecting Tailscale
sudo iptables -L | grep tailscale
sudo ufw status | grep tailscale

# DNS troubleshooting
tailscale debug dns-config
nslookup device-name.tailnet.ts.net 100.100.100.100

Performance Monitoring

bash
# Monitor Tailscale interface statistics
watch -n 1 'cat /proc/net/dev | grep tailscale'

# Bandwidth monitoring
iftop -i tailscale0
nethogs tailscale0

# Connection quality monitoring
cat > /usr/local/bin/tailscale-monitor.sh << 'EOF'
#!/bin/bash
LOG_FILE="/var/log/tailscale-monitor.log"
PEERS_FILE="/tmp/tailscale-peers.txt"

# Get list of peers
tailscale status --peers > $PEERS_FILE

# Monitor each peer
while read -r line; do
    if [[ $line =~ ^([0-9.]+)[[:space:]]+([^[:space:]]+) ]]; then
        PEER_IP="${BASH_REMATCH[1]}"
        PEER_NAME="${BASH_REMATCH[2]}"
        
        # Ping test
        PING_RESULT=$(tailscale ping $PEER_NAME 2>/dev/null | head -1)
        
        # Log result
        echo "$(date): $PEER_NAME ($PEER_IP) - $PING_RESULT" >> $LOG_FILE
    fi
done < $PEERS_FILE

# Check overall network health
NETCHECK_RESULT=$(tailscale netcheck 2>/dev/null)
echo "$(date): Network check - $NETCHECK_RESULT" >> $LOG_FILE
EOF

chmod +x /usr/local/bin/tailscale-monitor.sh

# Add to crontab for regular monitoring
echo "*/5 * * * * /usr/local/bin/tailscale-monitor.sh" | crontab -

# Performance metrics collection
cat > /usr/local/bin/tailscale-metrics.sh << 'EOF'
#!/bin/bash
METRICS_FILE="/var/log/tailscale-metrics.log"

# Get interface statistics
RX_BYTES=$(cat /sys/class/net/tailscale0/statistics/rx_bytes)
TX_BYTES=$(cat /sys/class/net/tailscale0/statistics/tx_bytes)
RX_PACKETS=$(cat /sys/class/net/tailscale0/statistics/rx_packets)
TX_PACKETS=$(cat /sys/class/net/tailscale0/statistics/tx_packets)

# Get peer count
PEER_COUNT=$(tailscale status --peers | wc -l)

# Log metrics
echo "$(date),$RX_BYTES,$TX_BYTES,$RX_PACKETS,$TX_PACKETS,$PEER_COUNT" >> $METRICS_FILE
EOF

chmod +x /usr/local/bin/tailscale-metrics.sh

Troubleshooting Common Issues

bash
# Connection issues troubleshooting
# 1. Check if tailscaled is running
sudo systemctl status tailscaled

# 2. Restart Tailscale service
sudo systemctl restart tailscaled

# 3. Re-authenticate
tailscale logout
tailscale up

# 4. Check firewall rules
sudo ufw status
sudo iptables -L

# 5. Verify network connectivity
ping 8.8.8.8
tailscale netcheck

# DNS resolution issues
# 1. Check DNS configuration
tailscale status --json | jq '.DNSConfig'

# 2. Test Magic DNS
nslookup device-name.tailnet.ts.net

# 3. Reset DNS configuration
sudo tailscale up --accept-dns=false
sudo tailscale up --accept-dns

# 4. Check system DNS settings
cat /etc/resolv.conf
systemd-resolve --status

# Performance issues
# 1. Check for direct connections vs DERP relay
tailscale status | grep "relay"

# 2. Test different DERP regions
tailscale netcheck

# 3. Check for packet loss
tailscale ping device-name

# 4. Monitor bandwidth usage
iftop -i tailscale0

# Authentication issues
# 1. Check auth key validity
tailscale up --authkey=tskey-auth-xxxxxx

# 2. Verify SSO configuration
# Check admin console for SSO errors

# 3. Clear cached credentials
rm -rf ~/.config/tailscale/
sudo rm -rf /var/lib/tailscale/

# 4. Force re-authentication
tailscale up --force-reauth

# Subnet routing issues
# 1. Verify IP forwarding is enabled
cat /proc/sys/net/ipv4/ip_forward

# 2. Check iptables rules
sudo iptables -t nat -L

# 3. Verify route advertisement
tailscale status | grep "subnets"

# 4. Test connectivity to subnet
ping 192.168.1.1  # Replace with actual subnet IP

# Complete reset procedure
sudo systemctl stop tailscaled
sudo rm -rf /var/lib/tailscale/
sudo systemctl start tailscaled
tailscale up

API and Automation

Tailscale API Usage

bash
# Set up API access
export TAILSCALE_API_KEY="tskey-api-xxxxxx"
export TAILNET="your-tailnet.ts.net"

# List devices
curl -H "Authorization: Bearer $TAILSCALE_API_KEY" \
  https://api.tailscale.com/api/v2/tailnet/$TAILNET/devices

# Get device details
curl -H "Authorization: Bearer $TAILSCALE_API_KEY" \
  https://api.tailscale.com/api/v2/device/$DEVICE_ID

# Update device settings
curl -X POST \
  -H "Authorization: Bearer $TAILSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "new-device-name"}' \
  https://api.tailscale.com/api/v2/device/$DEVICE_ID

# Delete device
curl -X DELETE \
  -H "Authorization: Bearer $TAILSCALE_API_KEY" \
  https://api.tailscale.com/api/v2/device/$DEVICE_ID

# Create auth key
curl -X POST \
  -H "Authorization: Bearer $TAILSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "capabilities": {
      "devices": {
        "create": {
          "reusable": true,
          "ephemeral": false,
          "preauthorized": true,
          "tags": ["tag:server"]
        }
      }
    },
    "expirySeconds": 86400
  }' \
  https://api.tailscale.com/api/v2/tailnet/$TAILNET/keys

# Get ACL policy
curl -H "Authorization: Bearer $TAILSCALE_API_KEY" \
  https://api.tailscale.com/api/v2/tailnet/$TAILNET/acl

# Update ACL policy
curl -X POST \
  -H "Authorization: Bearer $TAILSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d @acl-policy.json \
  https://api.tailscale.com/api/v2/tailnet/$TAILNET/acl

Infrastructure as Code

yaml
# Terraform configuration for Tailscale
terraform {
  required_providers {
    tailscale = {
      source = "tailscale/tailscale"
      version = "~> 0.13"
    }
  }
}

provider "tailscale" {
  api_key = var.tailscale_api_key
  tailnet = var.tailnet
}

# Create auth key
resource "tailscale_tailnet_key" "server_key" {
  reusable      = true
  ephemeral     = false
  preauthorized = true
  expiry        = 86400
  description   = "Server deployment key"
  
  tags = [
    "tag:server",
    "tag:production"
  ]
}

# ACL policy
resource "tailscale_acl" "main" {
  acl = jsonencode({
    tagOwners = {
      "tag:server" = ["user@company.com"]
      "tag:client" = ["group:employees"]
    }
    
    groups = {
      "group:employees" = ["user1@company.com", "user2@company.com"]
      "group:admins"    = ["admin@company.com"]
    }
    
    acls = [
      {
        action = "accept"
        src    = ["group:employees"]
        dst    = ["tag:server:22", "tag:server:80", "tag:server:443"]
      },
      {
        action = "accept"
        src    = ["group:admins"]
        dst    = ["*:*"]
      }
    ]
  })
}

# DNS configuration
resource "tailscale_dns_nameservers" "main" {
  nameservers = ["1.1.1.1", "8.8.8.8"]
}

resource "tailscale_dns_search_paths" "main" {
  search_paths = ["company.local", "internal.corp"]
}

Ansible Playbook

yaml
# Ansible playbook for Tailscale deployment
---
- name: Deploy Tailscale
  hosts: all
  become: yes
  vars:
    tailscale_authkey: "{{ vault_tailscale_authkey }}"
    tailscale_hostname: "{{ inventory_hostname }}-tailscale"
    
  tasks:
    - name: Add Tailscale repository (Ubuntu/Debian)
      block:
        - name: Add Tailscale GPG key
          apt_key:
            url: https://pkgs.tailscale.com/stable/ubuntu/focal.noarmor.gpg
            state: present
            
        - name: Add Tailscale repository
          apt_repository:
            repo: "deb https://pkgs.tailscale.com/stable/ubuntu focal main"
            state: present
            
        - name: Update package cache
          apt:
            update_cache: yes
      when: ansible_os_family == "Debian"
      
    - name: Add Tailscale repository (CentOS/RHEL)
      yum_repository:
        name: tailscale
        description: Tailscale repository
        baseurl: https://pkgs.tailscale.com/stable/centos/8/
        gpgcheck: yes
        gpgkey: https://pkgs.tailscale.com/stable/centos/8/repo.gpg
      when: ansible_os_family == "RedHat"
      
    - name: Install Tailscale
      package:
        name: tailscale
        state: present
        
    - name: Enable and start tailscaled service
      systemd:
        name: tailscaled
        enabled: yes
        state: started
        
    - name: Connect to Tailscale network
      command: >
        tailscale up
        --authkey={{ tailscale_authkey }}
        --hostname={{ tailscale_hostname }}
        --accept-routes
        {% if tailscale_advertise_routes is defined %}
        --advertise-routes={{ tailscale_advertise_routes }}
        {% endif %}
        {% if tailscale_exit_node is defined %}
        --advertise-exit-node
        {% endif %}
      register: tailscale_up_result
      changed_when: "'Success' in tailscale_up_result.stdout"
      
    - name: Enable IP forwarding (if advertising routes)
      sysctl:
        name: "{{ item }}"
        value: "1"
        state: present
        reload: yes
      loop:
        - net.ipv4.ip_forward
        - net.ipv6.conf.all.forwarding
      when: tailscale_advertise_routes is defined or tailscale_exit_node is defined
      
    - name: Configure iptables for subnet routing
      iptables:
        table: nat
        chain: POSTROUTING
        source: 100.64.0.0/10
        out_interface: "{{ ansible_default_ipv4.interface }}"
        jump: MASQUERADE
      when: tailscale_advertise_routes is defined or tailscale_exit_node is defined
      
    - name: Save iptables rules
      shell: iptables-save > /etc/iptables/rules.v4
      when: tailscale_advertise_routes is defined or tailscale_exit_node is defined

Docker Integration

dockerfile
# Dockerfile with Tailscale
FROM ubuntu:20.04

# Install Tailscale
RUN apt-get update && apt-get install -y curl gnupg && \
    curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.noarmor.gpg | apt-key add - && \
    echo "deb https://pkgs.tailscale.com/stable/ubuntu focal main" > /etc/apt/sources.list.d/tailscale.list && \
    apt-get update && apt-get install -y tailscale && \
    rm -rf /var/lib/apt/lists/*

# Copy startup script
COPY start-tailscale.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/start-tailscale.sh

# Expose Tailscale port
EXPOSE 41641/udp

CMD ["/usr/local/bin/start-tailscale.sh"]
bash
# Docker startup script
#!/bin/bash
# start-tailscale.sh

# Start tailscaled in background
tailscaled --state=/var/lib/tailscale/tailscaled.state &

# Wait for tailscaled to start
sleep 5

# Connect to Tailscale network
tailscale up --authkey=$TAILSCALE_AUTHKEY --hostname=$HOSTNAME

# Keep container running
tail -f /dev/null
yaml
# Docker Compose with Tailscale
version: '3.8'

services:
  app-with-tailscale:
    build: .
    environment:
      - TAILSCALE_AUTHKEY=${TAILSCALE_AUTHKEY}
      - HOSTNAME=docker-app
    volumes:
      - tailscale-data:/var/lib/tailscale
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    sysctls:
      - net.ipv4.ip_forward=1
      - net.ipv6.conf.all.forwarding=1

volumes:
  tailscale-data:

Resources