Add headscale

This commit is contained in:
uumas
2026-06-08 19:36:46 +03:00
parent e28a4097a0
commit df302cf6f5
7 changed files with 191 additions and 0 deletions

View File

@@ -0,0 +1 @@
Sets up a headscale container

View File

@@ -0,0 +1,4 @@
---
headscale_oidc_issuer_url: ""
headscale_oidc_client_id: ""
headscale_oidc_client_secret: ""

View File

@@ -0,0 +1,85 @@
---
argument_specs:
main:
description: "Sets up a headscale container"
options:
headscale_domain:
description: Domain headscale should be available at
type: str
required: true
headscale_magicdns_base_domain:
description: Base domain for magic dns hostnames
type: str
required: true
headscale_policy:
description:
- Headscale policy configuration.
- See https://headscale.net/stable/ref/acls/
- This role's support for acls is currently quite limited. Waiting for headscale to release grants support.
type: dict
required: true
options:
groups:
description: >-
Groups of users. Formatted as dict where dict key is group name and
value is a list of users in the group.
type: dict
required: false
hosts:
description: Mapping of host names to ip addresses
type: dict
required: false
tagOwners:
description: Mapping of tags to lists of their owners
type: dict
required: false
acls:
description: List of acls
type: list
required: true
elements: dict
options:
action:
description: ACL action
type: str
required: true
choices:
- accept
- check
src:
description: >-
A list of sources, formatted as prefix:name:ports,
where prefix is the type of object, like tag: or group:,
name is the object name and ports is a comma separated list of ports or *
type: list
required: true
elements: str
dst:
description: A list of destinations. Same format as sources.
type: list
required: true
elements: str
proto:
description: Protocol
type: str
required: false
choices:
- tcp
- udp
- icmp
headscale_oidc_issuer_url:
description: OIDC issuer url. Leave unset to not use OIDC.
type: str
required: false
default: ""
headscale_oidc_client_id:
description: OIDC client id. Required if OIDC issuer is set.
type: str
required: false
default: ""
headscale_oidc_client_secret:
description: OIDC client secret. Required if OIDC issuer is set.
type: str
required: false
default: ""

View File

@@ -0,0 +1,36 @@
---
- name: Headscale service
ansible.builtin.import_role:
name: service
vars:
service_name: headscale
service_container_image: docker.io/headscale/headscale:stable
service_container_command: serve
service_container_mounts:
- type: volume
source: data
destination: /var/lib/headscale
- type: template
source: config.yaml.j2
destination: /etc/headscale/config.yaml
- type: template
source: policy.hujson.j2
destination: /etc/headscale/policy.hujson
template_validate_command: headscale policy check --file /etc/headscale/policy.hujson
service_container_http_port: 8080
service_domains:
- "{{ headscale_domain }}"
service_container_publish_ports:
- name: stun
container_port: 3478
protocol: udp
host_port: 3478
service_container_secrets: "{{ _headscale_secrets }}"
service_container_reload_method: kill
- name: Open port for stun
ansible.posix.firewalld:
service: stun
state: enabled
permanent: true
immediate: true

View File

@@ -0,0 +1,56 @@
---
# vim:ft=yaml
# {{ ansible_managed }}
listen_addr: 0.0.0.0:8080
server_url: https://{{ headscale_domain }}
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:
server:
enabled: true
region_id: 999
region_code: "headscale"
region_name: "Headscale embedded DERP"
verify_clients: true
stun_listen_addr: "0.0.0.0:3478"
private_key_path: /var/lib/headscale/derp_server_private.key
urls: []
database:
type: sqlite
sqlite:
path: /var/lib/headscale/db.sqlite
policy:
mode: file
path: /etc/headscale/policy.hujson
dns:
magic_dns: true
base_domain: {{ headscale_magicdns_base_domain }}
nameservers:
global:
- https://dns.quad9.net/dns-query
logtail:
enabled: false
{% if headscale_oidc_issuer_url | length > 0 %}
oidc:
only_start_if_oidc_is_available: false
issuer: {{ headscale_oidc_issuer_url }}
client_id: "{{ headscale_oidc_client_id }}"
client_secret_path: /run/secrets/oidc-client-secret
pkce:
enabled: true
{% endif %}

View File

@@ -0,0 +1,3 @@
// {{ ansible_managed }}
{{ headscale_policy | to_nice_json }}

View File

@@ -0,0 +1,6 @@
---
_headscale_oidc_secret:
name: oidc-client-secret
value: "{{ headscale_oidc_client_secret }}"
_headscale_secrets: "{{ [_headscale_oidc_secret] if headscale_oidc_issuer_url | length > 0 else [] }}"