Headscale сервер вполне можно использовать в stand-alone варианте без провайдера пользователей (identity provider), по типу Authentik. Однако пользователей придется создавать вручную через cli или панель, если таковая у вас установлена. В данном случае мы рассмотрим настройку headscale с использованием OIDC авторизации через Authentik.
Настройка Authentik
Создаем новое приложение с провайдером. Из опций провайдера выбираем OAuth/OpenID Connect

В настройках провайдера выбираем предпочитаемый вами authorization consent, и добавляем Redirect URI.
Для headscale этим uri будет https://domain.com/oidc/callback, где domain.com - ваш домен.

Сохраняем приложение и провайдер, копируя в конфиг сгенерированные client id и client secret.
Деплой Headscale
В первую очередь необходимо создать в любом удобном месте на диске директорию для compose проекта.
В ней создаем файл docker-compose.yml и записываем в него описанный здесь проект.
Далее создаем директорию headscale-config и файл config.yaml в нем. Туда записываем sample config, который можно взять здесь. В нем есть несколько полей, которые необходимо изменить.
## домен, по которому будет доступен headscale.
# можно указать ip адрес и порт,
# если не планируете использовать домен
server_url: https://headscale.domain
dns:
base_domain: some.domain ## домен для нод внутри tailnet
## здесь необходимо заменить authentik.outpost на домен вашего authentik
# и заполнить поля client_id и client_secret значениями из authentik
oidc:
only_start_if_oidc_is_available: true
issuer: "https://authentik.outpost/application/o/headscale/"
client_id: ""
client_secret: ""После этого можно запустить проект командой docker compose up -d.
При успешном запуске контейнера можно проверить работоспособность headscale,
перейдя по ссылке https://headscale.domain/windows.
WARNING
Важно - для доступа к headscale по https вам необходимо либо выпустить сертификаты домена и передать их headscale в конфиге, либо использовать reverse proxy
Если при установке все сделано правильно, то по выше указанной ссылке вы должны увидеть следующую страницу:

Reverse proxy
В данном случае мы рассматриваем установку headscale с использованием reverse-proxy,
поэтому в docker-compose headscale выходит на порт 8080. Основными вариантами reverse-proxy являются caddy и nginx.
При использовании nginx потребуется наличие сертификатов для домена, получение
которых мы здесь рассматривать не будем.
Caddy
Для caddy потребуется добавить совсем маленький блок конфигурации в /etc/caddy/Caddyfile:
headscale.domain {
reverse_proxy * localhost:8080
}
где headscale.domain - домен, по которому будет доступен ваш headscale сервер.
Внимание
Домен в конфигурации caddy и поле
server_urlв конфиге headscale должны совпадать!
Nginx
В случае с nginx конфиг выглядит уже менее просто и локонично:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name headscale.domain;
ssl_certificate <PATH_TO_CERT>;
ssl_certificate_key <PATH_CERT_KEY>;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $server_name;
proxy_redirect http:// https://;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
}
}где headscale.domain - домен, по которому будет доступен ваш headscale сервер.
Настройка панели headplane
Открываем (или создаем, если еще не существует) файл config.yaml в корне compose проекта. Туда записываем дефолтный конфиг, который можно взять здесь.
В нем редактируем следующие поля:
server:
## здесь должна быть строка случайных символов.
# сгенерировать такую можно командой
# openssl rand --base64 32
cookie_secret: "рандомная строка"
## заполняем этот блок теми же данными, что и аналогичный блок
# в конфигурации headscale
oidc:
issuer: "https://authentik.outpost/application/o/headplane/"
client_id: ""
client_secret: ""
disable_api_key_login: true
token_endpoint_auth_method: "client_secret_post"
# headscale apikeys create --expiration 999d
headscale_api_key: ""
## меняем домен на тот, по которому доступен ваш headscale сервер
redirect_uri: "https://headscale.domain/admin/oidc/callback"и добавляем https://headscale.domain/admin/oidc/callback в redirect uris
в настройках провайдера authentik. После этого добавляем настройку проксирования панели в вашем reverse proxy:
# caddy
headscale.domain {
reverse_proxy * localhost:8080
+ reverse_proxy /admin* http://localhost:3037
}
# nginx
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name headscale.domain;
ssl_certificate <PATH_TO_CERT>;
ssl_certificate_key <PATH_CERT_KEY>;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $server_name;
proxy_redirect http:// https://;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
}
+ location /admin {
+ proxy_pass http://localhost:3037;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ proxy_set_header Host $server_name;
+ proxy_redirect http:// https://;
+ proxy_buffering off;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
+ }
}Теперь по ссылке https://headscale.domain/admin будет открываться панель headplane.