Proxmox LXC Tailscale Fix
Status: ✅ RESOLVED (November 25, 2025) Phase 2 Story 3 Completion: Tailscale mesh network operational
Problem Identified
The Tailscale implementation failed on Proxmox LXC containers because they were missing the /dev/net/tun device required for Tailscale's WireGuard VPN.
Root Cause
- Tailscale requires
/dev/net/tunto create VPN tunnels - Proxmox LXC containers don't have this device by default
- The Ansible role didn't account for this Proxmox-specific requirement
Error Symptoms
tailscaled: /dev/net/tun does not exist
tailscaled: tun module not loaded nor found on disk
tailscaled: CreateTUN("tailscale0") failed
Fix Applied
1. LXC Container Configuration (✅ COMPLETED)
Added TUN device support to all containers by modifying their Proxmox configuration files:
# Added to /etc/pve/lxc/104.conf, 105.conf, 106.conf
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net dev/net none bind,create=dir 0 0
Containers affected: - 104 (github-runner) - 105 (smart-smoker-dev-cloud) - 106 (smart-smoker-cloud-prod)
2. SSH Keys Re-applied (✅ COMPLETED)
SSH keys were re-added to all containers after the restarts.
Resolution Steps Taken
Step 1: Re-run Ansible Playbooks with Tailscale Auth Key
The TUN devices were configured, and playbooks were executed:
cd /home/benjr70/Dev/Smart-Smoker-V2/infra/proxmox/ansible
# Get your Tailscale auth key from: https://login.tailscale.com/admin/settings/keys
# Option 1: Configure all infrastructure at once
ansible-playbook playbooks/site.yml \
--extra-vars "tailscale_auth_key=YOUR_TAILSCALE_KEY_HERE"
# Option 2: Configure each server individually
ansible-playbook playbooks/setup-github-runner.yml \
--extra-vars "tailscale_auth_key=YOUR_KEY"
ansible-playbook playbooks/setup-dev-cloud.yml \
--extra-vars "tailscale_auth_key=YOUR_KEY"
ansible-playbook playbooks/setup-prod-cloud.yml \
--extra-vars "tailscale_auth_key=YOUR_KEY"
Step 2: Verify Tailscale is Running
# Check all containers
ssh root@192.168.1.151 'for ct in 104 105 106; do echo "=== Container $ct ==="; pct exec $ct -- tailscale status; echo ""; done'
# Or use the verification playbook
ansible-playbook playbooks/verify-tailscale.yml
Step 3: Check Your Tailscale Admin Console
Visit https://login.tailscale.com/admin/machines
You should now see these machines:
- ✅ smoker-runner (github-runner)
- ✅ smoker-dev-cloud (dev environment)
- ✅ smokecloud (production environment)
Important Notes
Hostname Clarification
smokecloudis configured as the hostname for the NEW production container (smart-smoker-cloud-prod)- If you have an OLD machine also called
smokecloud, you should: - Rename the old machine in Tailscale admin, OR
- Change the new hostname in the Ansible configuration
To change the new production hostname:
# Edit this file
vim infra/proxmox/ansible/inventory/host_vars/smart-smoker-cloud-prod.yml
# Change this line:
tailscale_hostname: "smokecloud"
# To something like:
tailscale_hostname: "smokecloud-new"
Virtual Smoker Device (10.30.0.40)
The virtual smoker device at 10.30.0.40 is currently unreachable via SSH. You'll need to: 1. Check if the VM is running 2. Verify network configuration 3. Configure it separately once it's accessible
Terraform Integration (Future Enhancement)
To prevent this issue in future deployments, the Terraform configuration should be updated to automatically configure TUN devices when creating LXC containers.
Recommended addition to Terraform LXC module:
# In infra/proxmox/terraform/modules/lxc-container/main.tf
resource "proxmox_lxc" "container" {
# ... existing configuration ...
# Enable TUN device for Tailscale support
features {
nesting = true
}
# Note: TUN device config must be added manually via Proxmox API
# or post-provisioning script as Terraform provider doesn't support
# lxc.cgroup2.devices.allow and lxc.mount.entry parameters
}
Post-provisioning script approach (recommended):
Create infra/proxmox/scripts/configure-lxc-for-tailscale.sh:
#!/bin/bash
# Configure Proxmox LXC container for Tailscale support
# Usage: ./configure-lxc-for-tailscale.sh <container_id>
CT_ID=$1
if [ -z "$CT_ID" ]; then
echo "Usage: $0 <container_id>"
exit 1
fi
echo "Configuring container $CT_ID for Tailscale..."
# Add TUN device configuration
if ! grep -q "lxc.cgroup2.devices.allow.*10:200" /etc/pve/lxc/$CT_ID.conf 2>/dev/null; then
echo "lxc.cgroup2.devices.allow: c 10:200 rwm" >> /etc/pve/lxc/$CT_ID.conf
echo "lxc.mount.entry: /dev/net dev/net none bind,create=dir 0 0" >> /etc/pve/lxc/$CT_ID.conf
echo "✅ TUN device configured for container $CT_ID"
else
echo "ℹ️ Container $CT_ID already configured for TUN"
fi
Then call this from Terraform using a local-exec provisioner or Ansible.
Testing
After re-running the Ansible playbooks, test connectivity:
# Run comprehensive test suite
bash infra/proxmox/scripts/test-tailscale-mesh.sh
# Or manually test
ssh root@10.20.0.10 # github-runner
tailscale status
ping -c 3 smoker-dev-cloud
ping -c 3 smokecloud
# Test public access (production funnel)
curl https://smokecloud.tail74646.ts.net
Status
- [x] Identified root cause (missing /dev/net/tun)
- [x] Fixed LXC container configurations
- [x] Re-applied SSH keys
- [x] Re-ran Ansible playbooks with Tailscale auth key
- [x] Verified all machines appear in Tailscale admin (3 containers connected)
- [x] Tested mesh network connectivity
- [ ] Test production funnel (public HTTPS access) - Future work
References
- Proxmox LXC TUN devices: https://pve.proxmox.com/wiki/Linux_Container#pct_options
- Tailscale on LXC: https://tailscale.com/kb/1130/lxc-unprivileged
- Terraform Proxmox provider: https://registry.terraform.io/providers/Telmate/proxmox/latest/docs