first commit
This commit is contained in:
commit
a7f5c4b3e7
41
config/config.yaml
Normal file
41
config/config.yaml
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
server_url: https://headscale.rozic-dev.com
|
||||||
|
listen_addr: 0.0.0.0:8080
|
||||||
|
metrics_listen_addr: 0.0.0.0:9090
|
||||||
|
|
||||||
|
noise:
|
||||||
|
private_key_path: /var/lib/headscale/noise_private.key
|
||||||
|
|
||||||
|
prefixes:
|
||||||
|
v4: 100.64.0.0/10
|
||||||
|
v6: fd7a:115c:a1e0::/48
|
||||||
|
|
||||||
|
derp:
|
||||||
|
server:
|
||||||
|
enabled: false
|
||||||
|
urls:
|
||||||
|
- https://controlplane.tailscale.com/derpmap/default
|
||||||
|
auto_update_enabled: true
|
||||||
|
update_frequency: 3h
|
||||||
|
|
||||||
|
dns:
|
||||||
|
magic_dns: true
|
||||||
|
base_domain: tailnet.rozic-dev.com
|
||||||
|
override_local_dns: true
|
||||||
|
nameservers:
|
||||||
|
global:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
log:
|
||||||
|
level: info
|
||||||
|
format: text
|
||||||
|
|
||||||
|
database:
|
||||||
|
type: sqlite
|
||||||
|
sqlite:
|
||||||
|
path: /var/lib/headscale/db.sqlite
|
||||||
|
write_ahead_log: true
|
||||||
|
wal_autocheckpoint: 1000
|
||||||
|
|
||||||
|
unix_socket: /var/run/headscale/headscale.sock
|
||||||
|
unix_socket_permission: "0770"
|
||||||
31
config/config.yaml.bak
Normal file
31
config/config.yaml.bak
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
server_url: https://headscale.rozic-dev.com
|
||||||
|
listen_addr: 0.0.0.0:8080
|
||||||
|
|
||||||
|
# REQUIRED by newer Headscale (TS2021/Noise)
|
||||||
|
noise:
|
||||||
|
private_key_path: /var/lib/headscale/noise_private.key
|
||||||
|
|
||||||
|
# Tailnet address pools
|
||||||
|
prefixes:
|
||||||
|
v4: 100.64.0.0/10
|
||||||
|
v6: fd7a:115c:a1e0::/48
|
||||||
|
|
||||||
|
# Use Tailscale public DERP (built-in disabled so you don't need extra ports)
|
||||||
|
derp:
|
||||||
|
server:
|
||||||
|
enabled: false
|
||||||
|
urls:
|
||||||
|
- https://controlplane.tailscale.com/derpmap/default
|
||||||
|
|
||||||
|
# NEW DNS schema (dns_config is deprecated). Since override_local_dns is true,
|
||||||
|
# nameservers.global MUST be set.
|
||||||
|
dns:
|
||||||
|
override_local_dns: true
|
||||||
|
nameservers:
|
||||||
|
global:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.8.8
|
||||||
|
|
||||||
|
log:
|
||||||
|
level: info
|
||||||
|
format: text
|
||||||
BIN
data/db.sqlite
Normal file
BIN
data/db.sqlite
Normal file
Binary file not shown.
1
data/noise_private.key
Normal file
1
data/noise_private.key
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
privkey:70c34ac681bd47a23e573560825f98c9cef03b6b02e6656b57b9d98f75fe1a58
|
||||||
60
docker-compose.yml
Normal file
60
docker-compose.yml
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
# Compose v2 (no "version" key needed)
|
||||||
|
x-default: &default
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: 50m
|
||||||
|
max-file: "2"
|
||||||
|
|
||||||
|
services:
|
||||||
|
headscale:
|
||||||
|
<<: *default
|
||||||
|
image: docker.io/headscale/headscale:latest
|
||||||
|
container_name: headscale
|
||||||
|
command: serve
|
||||||
|
# Optional: expose metrics to host only
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:9090:9090"
|
||||||
|
volumes:
|
||||||
|
- ./config:/etc/headscale
|
||||||
|
- ./lib:/var/lib/headscale
|
||||||
|
- ./run:/var/run/headscale
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "headscale", "health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
# Headscale API at /
|
||||||
|
- "traefik.http.routers.headscale.rule=Host(`headscale.rozic-dev.com`)"
|
||||||
|
- "traefik.http.routers.headscale.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.headscale.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.headscale.loadbalancer.server.port=8080"
|
||||||
|
|
||||||
|
headscale-ui:
|
||||||
|
<<: *default
|
||||||
|
image: ghcr.io/gurucomputing/headscale-ui:latest
|
||||||
|
container_name: headscale-ui
|
||||||
|
# UI listens on 8080 (and 8443) in the container by default
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
# Serve UI at /web on the *same* host to avoid CORS
|
||||||
|
- "traefik.http.routers.headscale-ui.rule=Host(`headscale.rozic-dev.com`) && PathPrefix(`/web`)"
|
||||||
|
- "traefik.http.routers.headscale-ui.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.headscale-ui.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.headscale-ui.loadbalancer.server.port=8080"
|
||||||
|
|
||||||
|
# 🔐 BASIC AUTH MIDDLEWARE
|
||||||
|
- "traefik.http.middlewares.headscale-ui-basicauth.basicauth.users=Dejan:$$2y$$05$$EAuwBj8Ac5YTRn90WSeQuezJxFZF0ghIC/mBlf6S.x8Bb/5jI49WC"
|
||||||
|
|
||||||
|
# Attach middleware to router
|
||||||
|
- "traefik.http.routers.headscale-ui.middlewares=headscale-ui-basicauth"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
name: traefik_default
|
||||||
65
head-scale-connect.sh
Executable file
65
head-scale-connect.sh
Executable file
|
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# ============================
|
||||||
|
# CONFIG
|
||||||
|
# ============================
|
||||||
|
HEADSCALE_URL="https://headscale.rozic-dev.com"
|
||||||
|
TAILSCALE_BIN="tailscale"
|
||||||
|
DEFAULT_HOSTNAME="$(hostname)"
|
||||||
|
|
||||||
|
require_cmd() {
|
||||||
|
if ! command -v "$1" >/dev/null 2>&1; then
|
||||||
|
echo "ERROR: Command '$1' not found. Please install it first." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
require_cmd "$TAILSCALE_BIN"
|
||||||
|
|
||||||
|
if ! command -v sudo >/dev/null 2>&1 && [[ $EUID -ne 0 ]]; then
|
||||||
|
echo "WARNING: 'sudo' not found and you are not root."
|
||||||
|
echo "You must run this script as root for 'tailscale up' to work."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
AUTHKEY="${1:-}"
|
||||||
|
|
||||||
|
if [[ -z "$AUTHKEY" ]]; then
|
||||||
|
echo -n "Enter Headscale pre-auth key: "
|
||||||
|
read -r AUTHKEY
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$AUTHKEY" ]]; then
|
||||||
|
echo "ERROR: No auth key provided." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "Hostname to register on Headscale [${DEFAULT_HOSTNAME}]: "
|
||||||
|
read -r CUSTOM_HOSTNAME
|
||||||
|
HOSTNAME_TO_USE="${CUSTOM_HOSTNAME:-$DEFAULT_HOSTNAME}"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Connecting this device to Headscale:"
|
||||||
|
echo " Server : ${HEADSCALE_URL}"
|
||||||
|
echo " Host : ${HOSTNAME_TO_USE}"
|
||||||
|
echo
|
||||||
|
|
||||||
|
TS_CMD=(
|
||||||
|
"$TAILSCALE_BIN" up
|
||||||
|
--reset
|
||||||
|
--login-server="${HEADSCALE_URL}"
|
||||||
|
--auth-key="${AUTHKEY}"
|
||||||
|
--hostname="${HOSTNAME_TO_USE}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo "Running: sudo ${TS_CMD[*]}"
|
||||||
|
sudo "${TS_CMD[@]}"
|
||||||
|
else
|
||||||
|
echo "Running: ${TS_CMD[*]}"
|
||||||
|
"${TS_CMD[@]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "✅ Done! This device should now be visible in Headscale."
|
||||||
119
install.sh
Executable file
119
install.sh
Executable file
|
|
@ -0,0 +1,119 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# ===============================================================
|
||||||
|
# Headscale Self-Hosted Installation Script
|
||||||
|
# Compatible with Traefik (network: traefik_default)
|
||||||
|
# ===============================================================
|
||||||
|
|
||||||
|
# --- Configuration ---
|
||||||
|
DOMAIN="headscale.rozic-dev.com"
|
||||||
|
EMAIL="your@email.com" # For Let's Encrypt via Traefik
|
||||||
|
NETWORK="traefik_default"
|
||||||
|
INSTALL_DIR="/home/Dejan/Docker/Headscale"
|
||||||
|
|
||||||
|
# --- Create folders ---
|
||||||
|
echo "📁 Creating folder structure..."
|
||||||
|
mkdir -p "${INSTALL_DIR}/config" "${INSTALL_DIR}/data"
|
||||||
|
cd "${INSTALL_DIR}"
|
||||||
|
|
||||||
|
# --- Create config.yaml ---
|
||||||
|
echo "📝 Creating Headscale config file..."
|
||||||
|
cat > "${INSTALL_DIR}/config/config.yaml" <<EOF
|
||||||
|
server_url: https://${DOMAIN}
|
||||||
|
listen_addr: 0.0.0.0:8080
|
||||||
|
prefixes:
|
||||||
|
v4: 100.64.0.0/10
|
||||||
|
v6: fd7a:115c:a1e0::/48
|
||||||
|
derp:
|
||||||
|
server:
|
||||||
|
enabled: true
|
||||||
|
region_id: 999
|
||||||
|
region_code: slovenia
|
||||||
|
region_name: "Headscale Slovenia"
|
||||||
|
urls:
|
||||||
|
- https://controlplane.tailscale.com/derpmap/default
|
||||||
|
dns_config:
|
||||||
|
nameservers:
|
||||||
|
- 1.1.1.1
|
||||||
|
- 8.8.8.8
|
||||||
|
log_level: info
|
||||||
|
ip_prefixes:
|
||||||
|
v4: 100.64.0.0/10
|
||||||
|
v6: fd7a:115c:a1e0::/48
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# --- Create docker-compose.yml ---
|
||||||
|
echo "🐳 Creating docker-compose.yml..."
|
||||||
|
cat > "${INSTALL_DIR}/docker-compose.yml" <<'EOF'
|
||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
x-default: &default
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- traefik
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: 50m
|
||||||
|
max-file: "2"
|
||||||
|
|
||||||
|
services:
|
||||||
|
headscale:
|
||||||
|
<<: *default
|
||||||
|
image: headscale/headscale:latest
|
||||||
|
container_name: headscale
|
||||||
|
command: serve
|
||||||
|
environment:
|
||||||
|
- HEADSCALE_LOG_LEVEL=info
|
||||||
|
- HEADSCALE_SERVER_URL=https://headscale.rozic-dev.com
|
||||||
|
- HEADSCALE_LISTEN_ADDR=0.0.0.0:8080
|
||||||
|
- HEADSCALE_DB_TYPE=sqlite3
|
||||||
|
- HEADSCALE_DB_PATH=/var/lib/headscale/db.sqlite
|
||||||
|
- HEADSCALE_EPHEMERAL_NODE_INACTIVITY_TIMEOUT=30m
|
||||||
|
volumes:
|
||||||
|
- ./data:/var/lib/headscale
|
||||||
|
- ./config:/etc/headscale
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.headscale.rule=Host(`headscale.rozic-dev.com`)"
|
||||||
|
- "traefik.http.routers.headscale.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.headscale.tls.certresolver=letsencrypt"
|
||||||
|
- "traefik.http.services.headscale.loadbalancer.server.port=8080"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
traefik:
|
||||||
|
external: true
|
||||||
|
name: traefik_default
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# --- Start container ---
|
||||||
|
echo "🚀 Starting Headscale container..."
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# --- Wait for container startup ---
|
||||||
|
sleep 5
|
||||||
|
|
||||||
|
# --- Create user and auth key ---
|
||||||
|
echo "👤 Creating default Headscale user..."
|
||||||
|
docker exec -it headscale headscale users create dejan || true
|
||||||
|
|
||||||
|
echo "🔑 Creating reusable pre-auth key..."
|
||||||
|
docker exec -it headscale headscale preauthkeys create --user dejan --reusable --ephemeral=false
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "✅ Headscale is now running!"
|
||||||
|
echo "🌍 URL: https://${DOMAIN}"
|
||||||
|
echo "💡 To connect a client:"
|
||||||
|
echo " tailscale up --login-server https://${DOMAIN} --authkey <KEY>"
|
||||||
|
echo
|
||||||
|
EOF
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧠 Usage
|
||||||
|
|
||||||
|
1. Copy this file to your server, e.g.:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano install.sh
|
||||||
BIN
lib/db.sqlite
Normal file
BIN
lib/db.sqlite
Normal file
Binary file not shown.
BIN
lib/db.sqlite-shm
Normal file
BIN
lib/db.sqlite-shm
Normal file
Binary file not shown.
BIN
lib/db.sqlite-wal
Normal file
BIN
lib/db.sqlite-wal
Normal file
Binary file not shown.
1
lib/noise_private.key
Normal file
1
lib/noise_private.key
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
privkey:78376c92546f9fecdffd10e45dd95e2d56e88c3a8a890843c1439a13b3d16a47
|
||||||
Loading…
Reference in a new issue