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