这个目录是一个脱敏后的自托管 Tailscale 控制面示例,重点保留 headscale、headplane、traefik/caddy 和 authentik 的可复现配置关系。真实域名、IP、OIDC 凭据、Headscale API key、数据库密码、BasicAuth 哈希、上游 API token 和运行态数据都已替换为占位符或移除。
英文版见 README.en.md。
先复制或编辑 .env:
cp .env.example .env必须替换这些值:
| 占位符 | 位置 | 说明 |
|---|---|---|
<AUTHENTIK_POSTGRES_PASSWORD> |
.env 的 PG_PASS |
Authentik PostgreSQL 密码 |
<AUTHENTIK_SECRET_KEY> |
.env 的 AUTHENTIK_SECRET_KEY |
Authentik Django secret key |
<HEADSCALE_DOMAIN> |
headscale/config/config.yaml、headplane/config/config.yaml、traefik/dynamic/hs.yml 或 caddy/Caddyfile |
Headscale/Headplane 公网域名,例如 hs.example.com |
<AUTHENTIK_DOMAIN> |
headscale/config/config.yaml、headplane/config/config.yaml、traefik/dynamic/authentik.yml 或 caddy/Caddyfile |
Authentik 公网域名 |
<ROOT_DOMAIN> |
traefik/dynamic/authentik.yml |
Authentik outpost HostRegexp 使用的根域名 |
<PUBLIC_SERVER_IPV4> |
headscale/config/config.yaml |
嵌入式 DERP/STUN 对外 IP |
<MAGIC_DNS_DOMAIN> |
headscale/config/config.yaml |
Tailnet MagicDNS 后缀,例如 tailnet.example |
<ACME_EMAIL> |
traefik/traefik.yml |
Let's Encrypt 证书邮箱 |
<HEADSCALE_OIDC_CLIENT_ID> / <HEADSCALE_OIDC_CLIENT_SECRET> |
headscale/config/config.yaml |
Authentik 中给 Headscale 创建的 OAuth2/OIDC Provider 凭据 |
<HEADPLANE_OIDC_CLIENT_ID> / <HEADPLANE_OIDC_CLIENT_SECRET> |
headplane/config/config.yaml |
Authentik 中给 Headplane 创建的 OAuth2/OIDC Provider 凭据 |
<AUTHENTIK_HEADSCALE_PROVIDER_SLUG> / <AUTHENTIK_HEADPLANE_PROVIDER_SLUG> |
headscale/config/config.yaml、headplane/config/config.yaml |
Authentik Provider slug,影响 issuer URL |
<HEADPLANE_COOKIE_SECRET> |
headplane/config/config.yaml |
Headplane session cookie secret |
<HEADSCALE_API_KEY> |
headplane/config/config.yaml |
Headplane 调 Headscale API 用的 key |
<ADMIN_USER>@ / <NORMAL_USER>@ |
headscale/config/acl.hujson |
Headscale ACL 中的用户或登录名匹配 |
辅助示例中的 <AUX_SERVICE_DOMAIN>、<UPSTREAM_HOST>、<UPSTREAM_PORT>、<BASIC_AUTH_HASH>、<UPSTREAM_API_TOKEN> 只在你启用对应示例路由时填写。
| 路径 | 对应组件 | 内容 |
|---|---|---|
headscale-compose.yml |
Headscale + Headplane + Traefik | 主体编排文件,启动控制面、管理界面和 Traefik 入口 |
authentik-compose.yml |
Authentik | Authentik server/worker、PostgreSQL、Redis |
.env.example / .env |
Authentik 环境变量 | PostgreSQL 密码、Authentik secret key、错误上报开关 |
headscale/config/config.yaml |
Headscale | server URL、监听地址、DERP/STUN、SQLite、MagicDNS、ACL 路径、OIDC |
headscale/config/acl.hujson |
Headscale ACL | 用户组、tag owner、访问规则示例 |
headscale/data/、headscale/run/ |
Headscale 运行态 | 数据库、密钥、socket;已清空并由容器运行时生成 |
headplane/config/config.yaml |
Headplane | Web 入口、Headscale 地址、OIDC、Headscale API key;Docker integration 默认关闭 |
headplane/data/ |
Headplane 运行态 | 持久化数据库;已清空并由容器运行时生成 |
traefik/traefik.yml |
Traefik 静态配置 | 80/443 入口、文件 provider、Let's Encrypt resolver |
traefik/dynamic/hs.yml |
Traefik 动态配置 | Headscale 和 /admin Headplane 路由 |
traefik/dynamic/authentik.yml |
Traefik 动态配置 | Authentik Web 和 outpost 路由 |
traefik/dynamic/middlewares.yml |
Traefik 动态配置 | 通用压缩和 Authentik forward auth 中间件 |
traefik/examples/*.example.yml |
Traefik 示例 | BasicAuth、forward auth、普通反代、API CORS 等辅助路由模板;默认不会被 Traefik 加载 |
caddy/Caddyfile |
Caddy 示例 | 如果不用 Traefik,可参考的 Headscale、Headplane、Authentik 和辅助路由写法 |
start_end.sh |
运维脚本 | 对 authentik、headscale 或 all 执行 start/stop/restart/status/logs |
rs_ba.sh |
同步脚本示例 | rsync 模板,远程路径、SSH key 均为占位符 |
- 填写
.env。 - 在 Authentik 中规划两个 OAuth2/OIDC Provider:一个给 Headscale,一个给 Headplane。创建完成后,把 client ID、client secret、provider slug 写入对应配置。
- 填写
headscale/config/config.yaml、headplane/config/config.yaml、traefik/traefik.yml、traefik/dynamic/hs.yml、traefik/dynamic/authentik.yml中的域名、IP、邮箱和 OIDC 占位符。 - DNS 指向服务器公网 IP:
<HEADSCALE_DOMAIN>、<AUTHENTIK_DOMAIN>,以及你需要的辅助域名。 - 防火墙或云安全组开放
80/tcp、443/tcp、3478/udp。 - 启动 Authentik:
./start_end.sh start authentik- 完成 Authentik 初始设置和 Provider 配置后,启动 Headscale/Headplane/Traefik:
./start_end.sh start headscale也可以直接使用 Docker Compose:
docker compose -f authentik-compose.yml up -d
docker compose -f headscale-compose.yml up -d创建用户或生成 API key 时进入容器执行:
docker exec -it headscale headscale users create <USER>
docker exec -it headscale headscale apikeys create --expiration 90d把 API key 写入 headplane/config/config.yaml 的 oidc.headscale_api_key。
客户端加入示例:
tailscale up --login-server https://<HEADSCALE_DOMAIN>headplane/config/config.yaml 中的 integration.docker.enabled 默认是 false,headscale-compose.yml 也默认不挂载 /var/run/docker.sock。Docker socket 即使用 :ro 挂载也不是只读 API,公开的 /admin 管理面一旦被攻破可能扩大到主机/容器控制权限。只有在可信环境确实需要 Headplane Docker integration 时,再手动开启并添加 socket 挂载。
默认 compose 启用 Traefik。Traefik 的主体配置是:
traefik/traefik.yml:入口、证书、provider。traefik/dynamic/hs.yml:Headscale 和 Headplane。traefik/dynamic/authentik.yml:Authentik。traefik/dynamic/middlewares.yml:压缩和 Authentik forward auth。
traefik/examples/ 下的文件仅作为辅助服务示例,默认不会被 traefik/traefik.yml 加载。需要启用某个示例时,先复制到 traefik/dynamic/,再替换域名、上游地址、BasicAuth 哈希或 token。
如果要改用 Caddy,参考 caddy/Caddyfile,并把 headscale-compose.yml 中的 Traefik 服务替换成 Caddy 服务或自行添加 Caddy compose 配置。Caddy 示例只保留端口和反代指引,不包含生产凭据。
- 真实域名、真实公网 IP、私有 registry 地址。
- OIDC client ID/client secret、Headscale API key、pre-auth key。
- Authentik PostgreSQL 密码、Authentik secret key。
- BasicAuth 哈希及注释中的明文密码。
- 上游 API bearer token。
headscale/data/、headplane/data/、authentik/*数据目录、traefik/letsencrypt/等运行态数据。