573785f2cc
Ship policy.hujson (mounted + installed on first deploy, edits preserved) and wire policy.mode=file / policy.path in config.yaml. Translate the Tailscale "grants" default into headscale's legacy "acls" format (self-access, tag:shared, Tailscale SSH), since headscale 0.28 doesn't support grants. Embed in deploy.sh and document `headscale policy check`.
98 lines
2.7 KiB
YAML
98 lines
2.7 KiB
YAML
# headscale config.yaml -- 0.28.0
|
|
#
|
|
# Placeholder tokens (UPPER_SNAKE wrapped in double underscores) are
|
|
# substituted at deploy time by deploy.sh from the values in .env. Don't set
|
|
# them here directly unless you're running headscale outside the deploy script.
|
|
|
|
server_url: https://__HEADSCALE_DOMAIN__
|
|
listen_addr: 0.0.0.0:8080
|
|
metrics_listen_addr: 0.0.0.0:9090
|
|
|
|
# gRPC remote-control API. Disabled by default; clients use the standard
|
|
# `headscale` CLI inside the container instead. Uncomment + expose if you
|
|
# want remote admin.
|
|
# grpc_listen_addr: 0.0.0.0:50443
|
|
# grpc_allow_insecure: false
|
|
|
|
noise:
|
|
private_key_path: /var/lib/headscale/noise_private.key
|
|
|
|
prefixes:
|
|
v4: 100.64.0.0/10
|
|
v6: fd7a:115c:a1e0::/48
|
|
allocation: sequential
|
|
|
|
# DERP: use Tailscale's public DERP map. Embedded DERP server stays off so
|
|
# we don't need to open UDP/3478 publicly.
|
|
derp:
|
|
server:
|
|
enabled: false
|
|
urls:
|
|
- https://controlplane.tailscale.com/derpmap/default
|
|
paths: []
|
|
auto_update_enabled: true
|
|
update_frequency: 24h
|
|
|
|
database:
|
|
type: sqlite
|
|
sqlite:
|
|
path: /var/lib/headscale/db.sqlite
|
|
write_ahead_log: true
|
|
wal_autocheckpoint: 1000
|
|
|
|
log:
|
|
level: info
|
|
format: text
|
|
|
|
# ACL policy, loaded from a HuJSON file (see policy.hujson, mounted into the
|
|
# container). headscale uses Tailscale's legacy "acls" format, not "grants".
|
|
policy:
|
|
mode: file
|
|
path: /etc/headscale/policy.hujson
|
|
|
|
# Magic DNS for the tailnet. base_domain becomes the suffix for node
|
|
# DNS names (e.g. laptop.__TAILNET_DOMAIN__).
|
|
dns:
|
|
magic_dns: true
|
|
base_domain: __TAILNET_DOMAIN__
|
|
override_local_dns: false
|
|
nameservers:
|
|
global:
|
|
- 1.1.1.1
|
|
- 1.0.0.1
|
|
- 2606:4700:4700::1111
|
|
- 2606:4700:4700::1001
|
|
split: {}
|
|
search_domains: []
|
|
extra_records: []
|
|
|
|
# OIDC: delegate authentication to the pocket-id deployment. Register a
|
|
# new OIDC client in pocket-id with redirect URI:
|
|
# https://__HEADSCALE_DOMAIN__/oidc/callback
|
|
oidc:
|
|
only_start_if_oidc_is_available: true
|
|
issuer: https://__POCKETID_DOMAIN__
|
|
client_id: __OIDC_CLIENT_ID__
|
|
client_secret: __OIDC_CLIENT_SECRET__
|
|
scope:
|
|
- openid
|
|
- profile
|
|
- email
|
|
# PKCE protects the authorization-code exchange. Enabled with the S256
|
|
# challenge method -- make sure the pocket-id OIDC client also has PKCE on.
|
|
pkce:
|
|
enabled: true
|
|
method: S256
|
|
# Restrict who can register a node. Uncomment one or more.
|
|
# allowed_users:
|
|
# - alice@example.com
|
|
# allowed_groups:
|
|
# - tailscale-admins
|
|
# allowed_domains:
|
|
# - example.com
|
|
# How long a node stays authenticated before re-auth is required. This is a
|
|
# duration scalar (not a map). use_expiry_from_token overrides it with the
|
|
# OIDC token's own expiry when true.
|
|
expiry: 180d
|
|
use_expiry_from_token: false
|