Add tailscale!
All checks were successful
Test and Publish Templates / test-and-publish (push) Successful in 35s

This commit is contained in:
Your Name
2025-09-07 22:52:10 +12:00
parent 8e6b00bfee
commit 9aa6168f76
12 changed files with 487 additions and 0 deletions

104
tailscale/README.txt Normal file
View File

@@ -0,0 +1,104 @@
Tailscale VPN Service Template
==============================
This template deploys Tailscale as a Docker container, providing secure network access
to your server through Tailscale's zero-config VPN.
REQUIREMENTS
------------
* A Tailscale account (free at https://tailscale.com)
* An auth key from https://login.tailscale.com/admin/settings/keys
* Docker installed on the host system
CONFIGURATION
-------------
Before installation, you MUST set the following in your service configuration:
1. TAILSCALE_AUTH_KEY (required)
- Generate at: https://login.tailscale.com/admin/settings/keys
- Can be reusable or one-time use
- Required for automatic connection
2. TAILSCALE_HOSTNAME (optional)
- Custom hostname for this node in your Tailscale network
- If not set, uses the system hostname
3. TAILSCALE_EXTRA_ARGS (optional)
- Additional Tailscale arguments
- Examples:
--advertise-exit-node (make this an exit node)
--accept-routes (accept advertised routes)
--advertise-routes=10.0.0.0/24 (advertise local routes)
4. TAILSCALE_USERSPACE (optional)
- Set to "true" for environments without TUN device support
- Useful for some container platforms or restricted environments
DEFAULT SETTINGS
----------------
* Container name: tailscale
* Image: tailscale/tailscale:stable
* State volume: tailscale_state (persistent across restarts)
* Network mode: Host networking with NET_ADMIN capability
USAGE
-----
After installation, your server will be accessible through your Tailscale network:
1. Access by Tailscale IP:
- Find IP with: ./status.sh
- Connect via: ssh user@100.x.x.x
2. Access by MagicDNS name:
- Enable MagicDNS in Tailscale admin console
- Connect via: ssh user@hostname
3. Use as exit node (if configured):
- Configure with: --advertise-exit-node in TAILSCALE_EXTRA_ARGS
- Approve in Tailscale admin console
- Route traffic through this server
COMMANDS
--------
* ./install.sh - Install and start Tailscale
* ./start.sh - Start the Tailscale container
* ./stop.sh - Stop the Tailscale container
* ./status.sh - Check Tailscale connection status
* ./logs.sh - View Tailscale logs
* ./ssh.sh - Access container shell
* ./uninstall.sh - Remove container (preserves state)
* ./destroy.sh - Complete removal including state
TROUBLESHOOTING
---------------
1. Container won't start:
- Check TAILSCALE_AUTH_KEY is set correctly
- Verify Docker has necessary permissions
- Review logs with ./logs.sh
2. Not connecting to network:
- Ensure auth key is valid and not expired
- Check if key is reusable if using multiple times
- Verify no firewall blocking outbound connections
3. Can't create TUN device:
- Set TAILSCALE_USERSPACE=true for userspace mode
- This is slower but works in restricted environments
4. Need to re-authenticate:
- Generate new auth key
- Update configuration
- Restart with ./start.sh
SECURITY NOTES
--------------
* Auth keys should be kept secret
* Use ephemeral keys for temporary access
* Regularly review connected devices in admin console
* Consider using ACLs to restrict access
RESOURCES
---------
* Tailscale Documentation: https://tailscale.com/kb/
* Admin Console: https://login.tailscale.com/admin/
* ACL Guide: https://tailscale.com/kb/1018/acls/

View File

@@ -0,0 +1,27 @@
# DO NOT EDIT THIS FILE FOR YOUR SERVICE!
# This file is replaced from the template whenever there is an update.
# Edit the service.env file to make changes.
# Template to use - always required!
TEMPLATE=tailscale
REQUIRES_HOST_ROOT=false
REQUIRES_DOCKER=true
REQUIRES_DOCKER_ROOT=false
# Service settings
CONTAINER_NAME=tailscale
# Image settings
IMAGE_REGISTRY="docker.io"
IMAGE_REPO="tailscale/tailscale"
IMAGE_TAG="stable"
# Volumes for persistent state
STATE_VOLUME="${CONTAINER_NAME}_state"
# Tailscale settings (to be overridden in service.env)
TAILSCALE_AUTH_KEY=""
TAILSCALE_HOSTNAME=""
TAILSCALE_EXTRA_ARGS=""
TAILSCALE_USERSPACE="false"

View File

@@ -0,0 +1,25 @@
# Service settings for Tailscale
# (can also override anything in the .template_info.env file in the template to make it specific to this server)
# REQUIRED: Your Tailscale authentication key
# Get this from: https://login.tailscale.com/admin/settings/keys
# Can be reusable or one-time use
TAILSCALE_AUTH_KEY=
# Optional: Custom hostname for this node
# If not set, will use the system hostname
TAILSCALE_HOSTNAME=
# Optional: Additional Tailscale arguments
# Examples:
# TAILSCALE_EXTRA_ARGS="--advertise-exit-node"
# TAILSCALE_EXTRA_ARGS="--accept-routes"
# TAILSCALE_EXTRA_ARGS="--advertise-routes=10.0.0.0/24"
TAILSCALE_EXTRA_ARGS=
# Optional: Enable userspace networking (for environments without TUN support)
# Set to "true" if running in restricted environments
TAILSCALE_USERSPACE=false
# Server Settings
SSH_USER="dropshell"

35
tailscale/destroy.sh Executable file
View File

@@ -0,0 +1,35 @@
#!/bin/bash
# shellcheck disable=SC1091
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME" "STATE_VOLUME"
# Tailscale Destroy Script - Complete removal including data
echo "WARNING: This will completely remove Tailscale and all its data!"
echo "This includes the Tailscale state and authentication."
echo ""
read -p "Are you sure you want to continue? (yes/no): " confirmation
if [ "$confirmation" != "yes" ]; then
echo "Destruction cancelled."
exit 0
fi
echo ""
echo "Destroying Tailscale service and data..."
# First run uninstall
${SERVICE_PATH}/uninstall.sh
# Remove the state volume
echo "Removing Tailscale state volume..."
if docker volume ls | grep -q ${STATE_VOLUME}; then
docker volume rm ${STATE_VOLUME} || echo "Warning: Could not remove volume ${STATE_VOLUME}"
else
echo "Volume ${STATE_VOLUME} does not exist."
fi
echo ""
echo "Tailscale has been completely destroyed."
echo "Note: You should also remove this node from your Tailscale admin console at:"
echo " https://login.tailscale.com/admin/machines"

45
tailscale/install.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/bash
# shellcheck disable=SC1091
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME" "IMAGE_REGISTRY" "IMAGE_REPO" "IMAGE_TAG" "TAILSCALE_AUTH_KEY"
# Check if auth key is set
if [ -z "$TAILSCALE_AUTH_KEY" ] || [ "$TAILSCALE_AUTH_KEY" = "" ]; then
_die "TAILSCALE_AUTH_KEY is not set in config/service.env! Please add your Tailscale auth key."
fi
_check_docker_installed || _die "Docker test failed, aborting installation..."
echo "Installing Tailscale service..."
echo "Pulling Tailscale image..."
docker pull "$IMAGE_REGISTRY/$IMAGE_REPO:$IMAGE_TAG" || _die "Failed to pull image $IMAGE_REGISTRY/$IMAGE_REPO:$IMAGE_TAG"
# Create volume for persistent state
echo "Creating volume for Tailscale state..."
if ! docker volume create ${STATE_VOLUME}; then
echo "Volume ${STATE_VOLUME} may already exist, continuing..."
fi
# Stop and remove existing container if it exists
if _is_container_exists "$CONTAINER_NAME"; then
echo "Removing existing container..."
bash ./stop.sh 2>/dev/null || true
_remove_container "$CONTAINER_NAME" || true
fi
# Start the tunnel
bash ./start.sh || _die "Failed to start Tailscale"
echo ""
echo "=========================================="
echo "Tailscale installation complete!"
echo "=========================================="
echo ""
echo "Next steps:"
echo "1. Check connection status: ds status [server] tailscale"
echo "2. View logs: ds logs [server] tailscale"
echo "3. Manage device in Tailscale admin console:"
echo " https://login.tailscale.com/admin/machines"
echo ""
echo "Your device should appear as connected in the admin console."

26
tailscale/logs.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/bash
# shellcheck disable=SC1091
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME"
# Tailscale Logs Script
# Optional: follow logs with -f flag
FOLLOW=""
if [ "$1" = "-f" ] || [ "$1" = "--follow" ]; then
FOLLOW="-f"
fi
if ! _is_container_exists "$CONTAINER_NAME"; then
echo "Error: Tailscale container does not exist."
exit 1
fi
echo "Fetching logs from Tailscale container..."
echo "========================================="
docker logs ${FOLLOW} ${CONTAINER_NAME} 2>&1
if [ -z "$FOLLOW" ]; then
echo ""
echo "Tip: Use '${SERVICE_PATH}/logs.sh -f' to follow logs in real-time."
fi

17
tailscale/ssh.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
# shellcheck disable=SC1091
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME"
# Tailscale SSH Script - Access container shell
if ! _is_container_running "$CONTAINER_NAME"; then
echo "Error: Tailscale container is not running."
echo "Start it with: ${SERVICE_PATH}/start.sh"
exit 1
fi
echo "Entering Tailscale container shell..."
echo "Type 'exit' to leave the container."
echo ""
docker exec -it ${CONTAINER_NAME} /bin/sh

90
tailscale/start.sh Executable file
View File

@@ -0,0 +1,90 @@
#!/bin/bash
# shellcheck disable=SC1091
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME" "IMAGE_REGISTRY" "IMAGE_REPO" "IMAGE_TAG" "TAILSCALE_AUTH_KEY"
# Check if auth key is set
if [ -z "$TAILSCALE_AUTH_KEY" ] || [ "$TAILSCALE_AUTH_KEY" = "" ]; then
_die "TAILSCALE_AUTH_KEY is not set in config/service.env! Please add your Tailscale auth key."
fi
echo "Starting Tailscale container..."
# Determine if we should use userspace networking
NETWORK_MODE=""
CAP_ADD=""
DEVICE_MOUNT=""
if [ "$TAILSCALE_USERSPACE" = "true" ]; then
echo "Using userspace networking mode..."
TAILSCALE_EXTRA_ARGS="--tun=userspace-networking ${TAILSCALE_EXTRA_ARGS}"
else
# Standard mode with TUN device
CAP_ADD="--cap-add=NET_ADMIN --cap-add=SYS_MODULE"
DEVICE_MOUNT="--device=/dev/net/tun:/dev/net/tun"
fi
# Build hostname argument if provided
HOSTNAME_ARG=""
if [ -n "$TAILSCALE_HOSTNAME" ]; then
HOSTNAME_ARG="--hostname=${TAILSCALE_HOSTNAME}"
fi
# Build the Docker run command
DOCKER_RUN_CMD="docker run -d \
--restart unless-stopped \
--name ${CONTAINER_NAME} \
--network=host \
-v ${STATE_VOLUME}:/var/lib/tailscale \
-v /dev/net/tun:/dev/net/tun \
${CAP_ADD} \
${DEVICE_MOUNT} \
-e TS_AUTHKEY=${TAILSCALE_AUTH_KEY} \
-e TS_STATE_DIR=/var/lib/tailscale \
-e TS_USERSPACE=${TAILSCALE_USERSPACE} \
${HOSTNAME_ARG} \
${IMAGE_REGISTRY}/${IMAGE_REPO}:${IMAGE_TAG} \
tailscaled"
# Create and start the container
if ! _create_and_start_container "$DOCKER_RUN_CMD" "$CONTAINER_NAME"; then
_die "Failed to start Tailscale container"
fi
# Give it a moment to initialize
sleep 2
# Check if the container is still running (didn't crash immediately)
if ! _is_container_running "$CONTAINER_NAME"; then
echo "Container failed to start. Checking logs..."
docker logs "$CONTAINER_NAME" 2>&1 | tail -20
_die "Tailscale container exited unexpectedly. Check the TAILSCALE_AUTH_KEY and logs above."
fi
# Connect to Tailscale network
echo "Connecting to Tailscale network..."
# Build tailscale up command
TAILSCALE_UP_CMD="tailscale up --authkey=${TAILSCALE_AUTH_KEY}"
if [ -n "$TAILSCALE_HOSTNAME" ]; then
TAILSCALE_UP_CMD="${TAILSCALE_UP_CMD} --hostname=${TAILSCALE_HOSTNAME}"
fi
if [ -n "$TAILSCALE_EXTRA_ARGS" ]; then
TAILSCALE_UP_CMD="${TAILSCALE_UP_CMD} ${TAILSCALE_EXTRA_ARGS}"
fi
# Execute tailscale up command
if ! docker exec ${CONTAINER_NAME} ${TAILSCALE_UP_CMD}; then
echo "Warning: Failed to connect to Tailscale network automatically."
echo "You may need to connect manually using:"
echo " docker exec ${CONTAINER_NAME} tailscale up"
fi
echo ""
echo "Tailscale started successfully!"
echo "Container: ${CONTAINER_NAME}"
echo ""
echo "The device should appear as connected in your Tailscale admin console."
echo "Manage at: https://login.tailscale.com/admin/machines"

62
tailscale/status.sh Executable file
View File

@@ -0,0 +1,62 @@
#!/bin/bash
# shellcheck disable=SC1091
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME"
# Tailscale Status Script
echo "Tailscale Service Status"
echo "========================"
# Check if container exists
if ! _is_container_exists "$CONTAINER_NAME"; then
echo "Status: Not Installed"
echo "The Tailscale container does not exist."
exit 1
fi
# Check if container is running
if ! _is_container_running "$CONTAINER_NAME"; then
echo "Status: Stopped"
echo "The Tailscale container exists but is not running."
echo ""
echo "To start the service, run:"
echo " ${SERVICE_PATH}/start.sh"
exit 1
fi
echo "Status: Running"
echo ""
# Get Tailscale connection status
echo "Tailscale Connection Status:"
echo "----------------------------"
if docker exec ${CONTAINER_NAME} tailscale status --json >/dev/null 2>&1; then
# Get basic status
docker exec ${CONTAINER_NAME} tailscale status 2>/dev/null || {
echo "Unable to get Tailscale status. The daemon may still be starting."
}
echo ""
echo "Tailscale IP Address:"
docker exec ${CONTAINER_NAME} tailscale ip -4 2>/dev/null || echo "Not connected"
echo ""
echo "Device Name:"
docker exec ${CONTAINER_NAME} tailscale status --json 2>/dev/null | \
docker exec -i ${CONTAINER_NAME} sh -c 'cat | grep -o "\"Self\":{[^}]*}" | grep -o "\"HostName\":\"[^\"]*\"" | cut -d":" -f2 | tr -d "\""' 2>/dev/null || echo "Unknown"
else
echo "Tailscale is running but not yet connected to the network."
echo "This might be normal if the container was just started."
fi
echo ""
echo "Container Information:"
echo "----------------------"
docker ps --filter "name=${CONTAINER_NAME}" --format "table {{.Status}}\t{{.Ports}}"
echo ""
echo "To view detailed logs, run:"
echo " ${SERVICE_PATH}/logs.sh"
exit 0

26
tailscale/stop.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/bash
# shellcheck disable=SC1091
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME"
# Tailscale Stop Script
echo "Stopping Tailscale container..."
if _is_container_running "$CONTAINER_NAME"; then
# Gracefully disconnect from Tailscale network before stopping
echo "Disconnecting from Tailscale network..."
docker exec ${CONTAINER_NAME} tailscale down 2>/dev/null || true
# Give it a moment to cleanly disconnect
sleep 2
# Stop the container
if _stop_container "$CONTAINER_NAME"; then
echo "Tailscale container stopped successfully."
else
_die "Failed to stop Tailscale container"
fi
else
echo "Tailscale container is not running."
fi

29
tailscale/uninstall.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
# shellcheck disable=SC1091
source "${AGENT_PATH}/common.sh"
_check_required_env_vars "CONTAINER_NAME" "STATE_VOLUME"
# Tailscale Uninstallation Script
echo "Uninstalling Tailscale service..."
# Stop the container if it's running
if _is_container_running "$CONTAINER_NAME"; then
echo "Stopping Tailscale container..."
_stop_container "$CONTAINER_NAME"
fi
# Remove the container
if _is_container_exists "$CONTAINER_NAME"; then
echo "Removing Tailscale container..."
_remove_container "$CONTAINER_NAME"
fi
echo "Tailscale service has been uninstalled."
echo ""
echo "Note: The Tailscale state volume (${STATE_VOLUME}) has been preserved."
echo "This maintains your Tailscale node configuration and keys."
echo "To completely remove all data, run:"
echo " docker volume rm ${STATE_VOLUME}"
echo ""
echo "You may also want to remove this node from your Tailscale admin console."