docs(reference-ansible): add docs/ tree and document repo, playbooks, Makefile
Addresses the WKS PoC review (Notion 2026-05-26). All docs in English. - README: purpose, docs table of contents, annotated repo tree - docs/getting_started.md: prerequisites (WKS account, OIDC, SSH, VPN) + first deploy - docs/ansible.md: playbook table, "Running Ansible", service parameters, cheatsheet - docs/secrets.md: canonical Bao login (moved out of README) + demo defaults - docs/operations.md: full Makefile reference - docs/inventories.md: repo layout, topology, standard folder structure, walkthrough - docs/testing.md: static checks, inventory resolution, smoke test / dry run - remove ARCHITECTURE.md (architecture docs live externally) Also includes the gymburgdorf inventory build-out (bookstack, homarr, opnform, send) and scripts/bao-seed.sh. site.yml keeps a third traefik play (traefik_servers minus the vagrant _dmz/_backend split) so the demo inventories still configure their reverse proxy after the rebase onto main.
This commit is contained in:
parent
c67e9aac43
commit
2ba0c07cd3
24 changed files with 1541 additions and 525 deletions
|
|
@ -2,15 +2,21 @@
|
|||
# Bao secret expected at <mount>/data/authentik with keys:
|
||||
# secret_key, postgres_password, admin_password,
|
||||
# ldap_outpost_token,
|
||||
# nextcloud_oidc_secret
|
||||
# nextcloud_oidc_secret,
|
||||
# opnform_oidc_secret, homarr_oidc_secret, bookstack_oidc_secret
|
||||
_authentik: "{{ lookup('community.hashi_vault.hashi_vault', vault_mount + '/data/authentik', url=vault_addr) }}"
|
||||
|
||||
# First entry is the canonical public FQDN. Additional entries cover
|
||||
# internal *.int.* names so server-to-server traffic (e.g. the LDAP
|
||||
# outpost) hits authentik on a name with a valid internal cert and
|
||||
# skips the DMZ hop.
|
||||
# Canonical public FQDN browsers and OIDC iss-claim use.
|
||||
authentik_domains:
|
||||
- "auth.gymb.souveredu.ch"
|
||||
|
||||
# Internal FQDN for server-to-server calls (Nextcloud OIDC discovery,
|
||||
# token, userinfo; LDAP outpost configuration pull). Traefik rewrites
|
||||
# the Host header to `authentik_domains[0]` on these routers so authentik
|
||||
# still emits issuer URLs against the public hostname — that keeps the
|
||||
# iss claim matching what the browser sees while the traffic itself
|
||||
# stays inside the LAN (the DMZ has no hairpin-NAT for the public IP).
|
||||
authentik_host_rewrite_domains:
|
||||
- "auth.int.gymb.souveredu.ch"
|
||||
authentik_secret_key: "{{ _authentik.secret_key }}"
|
||||
authentik_postgres_password: "{{ _authentik.postgres_password }}"
|
||||
|
|
@ -31,6 +37,44 @@ authentik_ldap_outpost:
|
|||
authentik_host: "https://auth.int.gymb.souveredu.ch/"
|
||||
log_level: "info"
|
||||
|
||||
# Proxy providers (ForwardAuth) — gate downstream services behind
|
||||
# authentik. The embedded outpost (which authentik ships out of the box)
|
||||
# hosts these providers under /outpost.goauthentik.io/auth/traefik on the
|
||||
# canonical FQDN; the service-side traefik attaches a ForwardAuth
|
||||
# middleware that talks to that endpoint.
|
||||
authentik_proxy_apps:
|
||||
- slug: drawio
|
||||
name: Drawio
|
||||
external_host: "https://draw.gymb.souveredu.ch"
|
||||
internal_host: "http://drawio:8080"
|
||||
allowed_groups:
|
||||
- admins
|
||||
flows:
|
||||
authentication_slug: default-authentication-flow
|
||||
authorization_slug: default-provider-authorization-implicit-consent
|
||||
invalidation_slug: default-provider-invalidation-flow
|
||||
- slug: garage-webui
|
||||
name: "Garage S3 Console"
|
||||
external_host: "https://console.s3.gymb.souveredu.ch"
|
||||
internal_host: "http://garage-webui:3909"
|
||||
allowed_groups:
|
||||
- admins
|
||||
flows:
|
||||
authentication_slug: default-authentication-flow
|
||||
authorization_slug: default-provider-authorization-implicit-consent
|
||||
invalidation_slug: default-provider-invalidation-flow
|
||||
|
||||
# Bind both proxy providers to authentik's built-in embedded outpost so
|
||||
# we don't have to deploy a separate proxy outpost container. The
|
||||
# embedded outpost listens on the same host:9000 as the authentik server
|
||||
# and exposes /outpost.goauthentik.io/auth/traefik for ForwardAuth.
|
||||
authentik_proxy_outposts:
|
||||
- name: "authentik Embedded Outpost"
|
||||
type: proxy
|
||||
providers:
|
||||
- drawio
|
||||
- garage-webui
|
||||
|
||||
# OIDC clients
|
||||
authentik_oidc_apps:
|
||||
- slug: nextcloud
|
||||
|
|
@ -45,10 +89,52 @@ authentik_oidc_apps:
|
|||
authorization_slug: default-provider-authorization-implicit-consent
|
||||
invalidation_slug: default-provider-invalidation-flow
|
||||
scopes: [openid, email, profile, offline_access]
|
||||
- slug: opnform
|
||||
name: OpnForm
|
||||
client_id: opnform
|
||||
client_secret: "{{ _authentik.opnform_oidc_secret }}"
|
||||
redirect_uris:
|
||||
- url: "https://forms.gymb.souveredu.ch/auth/authentik/callback"
|
||||
matching_mode: strict
|
||||
signing_key_name: "authentik Self-signed Certificate"
|
||||
flows:
|
||||
authorization_slug: default-provider-authorization-implicit-consent
|
||||
invalidation_slug: default-provider-invalidation-flow
|
||||
# No separate `groups` scope — authentik's default `profile` mapping
|
||||
# already emits a `groups` claim built from request.user.groups, so
|
||||
# OpnForm's admin-group mapping works without an extra scope.
|
||||
scopes: [openid, email, profile]
|
||||
- slug: homarr
|
||||
name: Homarr
|
||||
client_id: homarr
|
||||
client_secret: "{{ _authentik.homarr_oidc_secret }}"
|
||||
redirect_uris:
|
||||
- url: "https://home.gymb.souveredu.ch/api/auth/callback/oidc"
|
||||
matching_mode: strict
|
||||
signing_key_name: "authentik Self-signed Certificate"
|
||||
flows:
|
||||
authorization_slug: default-provider-authorization-implicit-consent
|
||||
invalidation_slug: default-provider-invalidation-flow
|
||||
scopes: [openid, email, profile]
|
||||
- slug: bookstack
|
||||
name: BookStack
|
||||
client_id: bookstack
|
||||
client_secret: "{{ _authentik.bookstack_oidc_secret }}"
|
||||
redirect_uris:
|
||||
- url: "https://wiki.gymb.souveredu.ch/oidc/callback"
|
||||
matching_mode: strict
|
||||
signing_key_name: "authentik Self-signed Certificate"
|
||||
flows:
|
||||
authorization_slug: default-provider-authorization-implicit-consent
|
||||
invalidation_slug: default-provider-invalidation-flow
|
||||
scopes: [openid, email, profile]
|
||||
|
||||
authentik_groups:
|
||||
- name: admins
|
||||
- name: users
|
||||
- name: opnform-admins
|
||||
- name: homarr-admins
|
||||
- name: bookstack-admins
|
||||
|
||||
authentik_local_users:
|
||||
- username: akadmin
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
# Bao secret <mount>/data/bookstack expected to contain:
|
||||
# db_root_password, db_password, admin_password, oidc_client_secret,
|
||||
# app_key (optional — only set when restoring)
|
||||
_bookstack: "{{ lookup('community.hashi_vault.hashi_vault', vault_mount + '/data/bookstack', url=vault_addr) }}"
|
||||
|
||||
bookstack_domain: "wiki.gymb.souveredu.ch"
|
||||
bookstack_extra_domains:
|
||||
- "wiki.int.gymb.souveredu.ch"
|
||||
bookstack_base_url: "https://wiki.gymb.souveredu.ch"
|
||||
|
||||
# Override the role-default certresolver ("le") with the value used
|
||||
# across this demo (matches traefik_ssl_cert_resolver in group_vars).
|
||||
bookstack_traefik_certresolver: "dns"
|
||||
|
||||
bookstack_db_root_password: "{{ _bookstack.db_root_password }}"
|
||||
bookstack_db_password: "{{ _bookstack.db_password }}"
|
||||
bookstack_admin_password: "{{ _bookstack.admin_password }}"
|
||||
bookstack_admin_email: "admin@gymb.souveredu.ch"
|
||||
bookstack_admin_name: "BookStack Admin"
|
||||
|
||||
# OIDC against Authentik. BookStack compares OIDC_ISSUER strictly against
|
||||
# the `iss` claim in the discovery response. Authentik emits the public
|
||||
# auth.gymb.* hostname there (host-rewrite middleware ensures the claim
|
||||
# matches what browsers see during login), so the issuer URL must use the
|
||||
# public FQDN. Pinning auth.gymb.* in /etc/hosts below keeps the actual
|
||||
# server-to-server traffic on the LAN.
|
||||
bookstack_oidc_enabled: true
|
||||
bookstack_oidc_name: "Authentik"
|
||||
bookstack_oidc_issuer: "https://auth.gymb.souveredu.ch/application/o/bookstack/"
|
||||
bookstack_oidc_client_id: "bookstack"
|
||||
bookstack_oidc_client_secret: "{{ _bookstack.oidc_client_secret }}"
|
||||
bookstack_oidc_additional_scopes: "openid profile email"
|
||||
bookstack_oidc_user_to_groups: true
|
||||
bookstack_oidc_groups_claim: "groups"
|
||||
bookstack_oidc_auto_initiate: false
|
||||
|
||||
# Pin auth.gymb.* to the application host so server-to-server OIDC calls
|
||||
# (discovery, token, userinfo, jwks) stay in the LAN and reach authentik
|
||||
# directly without hairpinning through the DMZ (which has no NAT loop
|
||||
# back to its own public IP).
|
||||
bookstack_extra_hosts:
|
||||
- "auth.gymb.souveredu.ch:172.16.19.101"
|
||||
|
|
@ -1,2 +1,19 @@
|
|||
---
|
||||
drawio_domain: "draw.gymb.souveredu.ch"
|
||||
|
||||
# Internal FQDN the DMZ reverseproxy uses as backend host so its TLS
|
||||
# verify matches a cert SAN (the canonical IP-only route has no SAN
|
||||
# and breaks with "cannot validate certificate ... no IP SANs"). Same
|
||||
# split-horizon pattern as cloud.int.* / auth.int.* / office.int.*.
|
||||
drawio_extra_domains:
|
||||
- "draw.int.gymb.souveredu.ch"
|
||||
|
||||
# Gate drawio behind the authentik embedded outpost (admins-only —
|
||||
# enforced by the policy-binding on the authentik proxy application).
|
||||
# ForwardAuth talks to the embedded outpost on the authentik server's
|
||||
# in-network address. Going via the public FQDN routes through a second
|
||||
# traefik hop that strips/rewrites X-Forwarded-Host, which breaks
|
||||
# authentik's provider matching (it returns 404). Plain HTTP to the
|
||||
# container is the path docs recommend for the embedded outpost.
|
||||
drawio_authentik_forward_auth: true
|
||||
drawio_authentik_forward_auth_url: "http://authentik-server-1:9000/outpost.goauthentik.io/auth/traefik"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
# Bao secret <mount>/data/homarr expected to contain:
|
||||
# secret_encryption_key (64 hex chars), admin_password, oidc_client_secret
|
||||
_homarr: "{{ lookup('community.hashi_vault.hashi_vault', vault_mount + '/data/homarr', url=vault_addr) }}"
|
||||
|
||||
homarr_domain: "home.gymb.souveredu.ch"
|
||||
homarr_extra_domains:
|
||||
- "home.int.gymb.souveredu.ch"
|
||||
homarr_base_url: "https://home.gymb.souveredu.ch"
|
||||
|
||||
homarr_secret_encryption_key: "{{ _homarr.secret_encryption_key }}"
|
||||
homarr_admin_username: "admin"
|
||||
homarr_admin_email: "admin@gymb.souveredu.ch"
|
||||
homarr_admin_password: "{{ _homarr.admin_password }}"
|
||||
|
||||
# OIDC against Authentik. credentials provider stays enabled as a
|
||||
# break-glass account.
|
||||
homarr_auth_providers: "credentials,oidc"
|
||||
homarr_oidc_issuer: "https://auth.int.gymb.souveredu.ch/application/o/homarr/"
|
||||
homarr_oidc_client_id: "homarr"
|
||||
homarr_oidc_client_secret: "{{ _homarr.oidc_client_secret }}"
|
||||
homarr_oidc_client_name: "Authentik"
|
||||
homarr_oidc_scopes: "openid profile email groups"
|
||||
homarr_oidc_groups_attribute: "groups"
|
||||
homarr_oidc_admin_group: "homarr-admins"
|
||||
homarr_oidc_auto_login: "false"
|
||||
|
||||
# Default board with shortcuts to the other gymburgdorf services. Width
|
||||
# values describe horizontal grid cells (1-10 desktop / 6 tablet / 2
|
||||
# mobile, packed left-to-right).
|
||||
homarr_apps:
|
||||
- id: nextcloud
|
||||
name: Nextcloud
|
||||
description: "Cloud Storage & Collaboration"
|
||||
icon: https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/nextcloud.png
|
||||
href: https://cloud.gymb.souveredu.ch
|
||||
width: 2
|
||||
- id: collabora
|
||||
name: Collabora Office
|
||||
icon: https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/collaboraonline.png
|
||||
href: https://office.gymb.souveredu.ch
|
||||
width: 2
|
||||
- id: drawio
|
||||
name: Draw.io
|
||||
icon: https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/drawio.png
|
||||
href: https://draw.gymb.souveredu.ch
|
||||
width: 2
|
||||
- id: send
|
||||
name: Send
|
||||
description: "Encrypted file-share"
|
||||
icon: https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/firefox-send.png
|
||||
href: https://send.gymb.souveredu.ch
|
||||
width: 2
|
||||
- id: opnform
|
||||
name: OpnForm
|
||||
description: "Self-hosted forms"
|
||||
icon: https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/opnform.png
|
||||
href: https://forms.gymb.souveredu.ch
|
||||
width: 2
|
||||
- id: bookstack
|
||||
name: BookStack
|
||||
description: "Wiki & documentation"
|
||||
icon: https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/bookstack.png
|
||||
href: https://wiki.gymb.souveredu.ch
|
||||
width: 2
|
||||
- id: authentik
|
||||
name: Authentik
|
||||
description: "Identity provider"
|
||||
icon: https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/authentik.png
|
||||
href: https://auth.gymb.souveredu.ch
|
||||
width: 2
|
||||
|
|
@ -4,6 +4,11 @@
|
|||
_nextcloud: "{{ lookup('community.hashi_vault.hashi_vault', vault_mount + '/data/nextcloud', url=vault_addr) }}"
|
||||
_authentik: "{{ lookup('community.hashi_vault.hashi_vault', vault_mount + '/data/authentik', url=vault_addr) }}"
|
||||
|
||||
# 33.0.2 hits the PHP 8.4 TypeError in UserConfig::getValueBool() that
|
||||
# user_ldap triggers on every authenticated request (nextcloud/server
|
||||
# #59629; fix in 33.0.3). Pin to the patched tag.
|
||||
nextcloud_image: "nextcloud:33.0.3-fpm"
|
||||
|
||||
# First entry is the canonical public FQDN (used for OVERWRITEHOST and
|
||||
# OIDC redirects). Additional entries cover internal *.int.* names so
|
||||
# collabora's WOPI callbacks hit nextcloud on a name with a valid
|
||||
|
|
@ -57,10 +62,25 @@ nextcloud_s3_port: 443
|
|||
nextcloud_s3_ssl: true
|
||||
nextcloud_s3_usepath_style: true
|
||||
|
||||
# OIDC server-to-server discovery / token / userinfo goes to
|
||||
# auth.int.gymb.souveredu.ch (LAN, RFC1918). Nextcloud's DnsPinMiddleware
|
||||
# would otherwise block that as "local server access".
|
||||
nextcloud_allow_local_remote_servers: true
|
||||
|
||||
# Share the LDAP docker network with the authentik LDAP outpost
|
||||
nextcloud_extra_networks:
|
||||
- ldap
|
||||
|
||||
# Pin the public authentik FQDN to the application host so server-to-server
|
||||
# OIDC traffic (token, userinfo, jwks — endpoints the discovery doc lists
|
||||
# under auth.gymb.* even when discovery itself is fetched via auth.int.*)
|
||||
# stays in the LAN. Without this, curl in the PHP container would hit the
|
||||
# public IP and time out in the DMZ (no hairpin-NAT). The DnsPin middleware
|
||||
# only honours /etc/hosts when allow_local_remote_servers is enabled, so
|
||||
# that flag (set above) is what makes this entry effective.
|
||||
nextcloud_extra_hosts:
|
||||
- "auth.gymb.souveredu.ch:172.16.19.101"
|
||||
|
||||
# LDAP backend (Authentik LDAP outpost)
|
||||
nextcloud_ldap_enabled: true
|
||||
nextcloud_ldap_config:
|
||||
|
|
@ -98,12 +118,13 @@ nextcloud_oidc_providers:
|
|||
display_name: "Login with Authentik"
|
||||
client_id: nextcloud
|
||||
client_secret: "{{ _authentik.nextcloud_oidc_secret }}"
|
||||
# Stays on the public FQDN: user_oidc validates the iss claim against
|
||||
# the discovery host, and authentik returns iss based on the request
|
||||
# host — using auth.int.* would break the iss match with what the
|
||||
# browser sees (auth.gymb.*). Routed via the DMZ for now; revisit if
|
||||
# this becomes a bottleneck.
|
||||
discovery_url: "https://auth.gymb.souveredu.ch/application/o/nextcloud/.well-known/openid-configuration"
|
||||
# Discovery via the internal FQDN (LAN-only) — the DMZ has no
|
||||
# hairpin-NAT for the public IP, so server-to-server calls to
|
||||
# auth.gymb.* would time out. The traefik router for auth.int.*
|
||||
# rewrites the Host header to auth.gymb.souveredu.ch before the
|
||||
# request reaches authentik, so the iss claim authentik emits still
|
||||
# matches the public hostname the browser sees during login.
|
||||
discovery_url: "https://auth.int.gymb.souveredu.ch/application/o/nextcloud/.well-known/openid-configuration"
|
||||
scope: "openid email profile"
|
||||
unique_uid: true
|
||||
mapping:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
# Bao secret <mount>/data/opnform expected to contain:
|
||||
# app_key (must start with "base64:"), jwt_secret, front_api_secret,
|
||||
# db_password, admin_password, oidc_client_secret
|
||||
_opnform: "{{ lookup('community.hashi_vault.hashi_vault', vault_mount + '/data/opnform', url=vault_addr) }}"
|
||||
_authentik: "{{ lookup('community.hashi_vault.hashi_vault', vault_mount + '/data/authentik', url=vault_addr) }}"
|
||||
|
||||
opnform_domain: "forms.gymb.souveredu.ch"
|
||||
opnform_extra_domains:
|
||||
- "forms.int.gymb.souveredu.ch"
|
||||
opnform_base_url: "https://forms.gymb.souveredu.ch"
|
||||
|
||||
opnform_app_key: "{{ _opnform.app_key }}"
|
||||
opnform_jwt_secret: "{{ _opnform.jwt_secret }}"
|
||||
opnform_front_api_secret: "{{ _opnform.front_api_secret }}"
|
||||
opnform_db_password: "{{ _opnform.db_password }}"
|
||||
|
||||
# Bootstrap admin via API on first run so the manual setup page is
|
||||
# skipped. The admin credentials are also required to seed the OIDC
|
||||
# IdentityConnection through OpnForm's API (only an authenticated admin
|
||||
# can create connections).
|
||||
opnform_admin_name: "OpnForm Admin"
|
||||
opnform_admin_email: "admin@gymb.souveredu.ch"
|
||||
opnform_admin_password: "{{ _opnform.admin_password }}"
|
||||
|
||||
# OIDC against Authentik. Discovery via the internal FQDN keeps
|
||||
# server-to-server traffic in the LAN; Authentik's host-rewrite router
|
||||
# rewrites the Host header to auth.gymb.* before the request reaches
|
||||
# authentik so the iss claim still matches the public hostname browsers
|
||||
# see during login.
|
||||
opnform_oidc_enabled: true
|
||||
# Issuer must use the public auth.gymb.* FQDN: OpnForm does OIDC
|
||||
# discovery and then validates the token's `iss` claim against this
|
||||
# value. Authentik emits the public hostname in `iss` (its host-rewrite
|
||||
# middleware keeps the claim aligned with what browsers see), so an
|
||||
# internal-FQDN issuer here would fail iss validation. The extra_hosts
|
||||
# pin below keeps the actual discovery/token/userinfo traffic on the LAN.
|
||||
opnform_oidc_issuer: "https://auth.gymb.souveredu.ch/application/o/opnform/"
|
||||
opnform_oidc_client_id: "opnform"
|
||||
opnform_oidc_client_secret: "{{ _opnform.oidc_client_secret }}"
|
||||
opnform_oidc_client_name: "Authentik"
|
||||
opnform_oidc_slug: "authentik"
|
||||
opnform_oidc_domain: "gymb.souveredu.ch"
|
||||
opnform_oidc_admin_group: "opnform-admins"
|
||||
|
||||
# Disable password login entirely — every user goes through Authentik.
|
||||
# All real users have @gymb.souveredu.ch addresses (matching
|
||||
# opnform_oidc_domain above), so no password fallback is needed.
|
||||
opnform_oidc_force_login: true
|
||||
|
||||
# Serve a /sso page that jumps straight to Authentik without the email
|
||||
# login form. Link users to https://forms.gymb.souveredu.ch/sso.
|
||||
opnform_oidc_sso_entrypoint: true
|
||||
|
||||
# Pin auth.gymb.* to the application host so server-to-server OIDC
|
||||
# calls (token, userinfo, jwks — endpoints discovery returns under the
|
||||
# public hostname even when discovery itself is fetched via auth.int.*)
|
||||
# stay in the LAN.
|
||||
opnform_extra_hosts:
|
||||
- "auth.gymb.souveredu.ch:172.16.19.101"
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Send: anonymized self-hosted file-share (no login). First entry is the
|
||||
# canonical public FQDN (used as BASE_URL); the *.int.* entry covers the
|
||||
# server-to-server hop from the DMZ reverseproxy with a cert SAN that
|
||||
# matches the backend hostname (same split-horizon pattern as cloud/draw).
|
||||
send_domains:
|
||||
- "send.gymb.souveredu.ch"
|
||||
- "send.int.gymb.souveredu.ch"
|
||||
|
|
@ -21,9 +21,26 @@ traefik_dmz_exposed_services:
|
|||
protocol: https
|
||||
- name: drawio
|
||||
domain: draw.gymb.souveredu.ch
|
||||
# No internal FQDN/cert for drawio yet — proxy by IP. Combined
|
||||
# with serversTransport `insecureSkipVerify` (handled by the
|
||||
# selfsigned-mode branch in the template), or accept the route's
|
||||
# 500 until the cert is wired up.
|
||||
backend_host: draw.int.gymb.souveredu.ch
|
||||
port: 443
|
||||
protocol: https
|
||||
- name: send
|
||||
domain: send.gymb.souveredu.ch
|
||||
backend_host: send.int.gymb.souveredu.ch
|
||||
port: 443
|
||||
protocol: https
|
||||
- name: opnform
|
||||
domain: forms.gymb.souveredu.ch
|
||||
backend_host: forms.int.gymb.souveredu.ch
|
||||
port: 443
|
||||
protocol: https
|
||||
- name: homarr
|
||||
domain: home.gymb.souveredu.ch
|
||||
backend_host: home.int.gymb.souveredu.ch
|
||||
port: 443
|
||||
protocol: https
|
||||
- name: bookstack
|
||||
domain: wiki.gymb.souveredu.ch
|
||||
backend_host: wiki.int.gymb.souveredu.ch
|
||||
port: 443
|
||||
protocol: https
|
||||
|
|
|
|||
|
|
@ -12,8 +12,18 @@ garage_s3_domains:
|
|||
garage_webui_domain: "console.s3.gymb.souveredu.ch"
|
||||
garage_use_ssl: true
|
||||
garage_webui_enabled: true
|
||||
# Gate the WebUI behind authentik (admins-only, via policy-binding on the
|
||||
# authentik proxy app). Replaces the htpasswd Basic-Auth — AUTH_USER_PASS
|
||||
# is dropped from the compose env when this is true. The forwardauth URL
|
||||
# resolves to the application-host traefik (network alias
|
||||
# `auth.gymb.souveredu.ch` -> authentik-server-1 in the proxy network on
|
||||
# the application host), but THIS host (storage) is in a different LAN,
|
||||
# so traefik here reaches it via the public name through the DMZ proxy.
|
||||
garage_webui_authentik_forward_auth: true
|
||||
garage_webui_authentik_forward_auth_url: "https://auth.gymb.souveredu.ch/outpost.goauthentik.io/auth/traefik"
|
||||
# Kept for completeness — only used when authentik ForwardAuth is off.
|
||||
garage_webui_username: "admin"
|
||||
garage_webui_password: "{{ _garage.webui_password }}"
|
||||
garage_webui_password: "{{ _garage.webui_password | default('disabled') }}"
|
||||
|
||||
garage_rpc_secret: "{{ _garage.rpc_secret }}"
|
||||
garage_admin_token: "{{ _garage.admin_token }}"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,12 @@
|
|||
---
|
||||
# Local traefik needs to reach authentik for the ForwardAuth subrequest
|
||||
# the garage-webui router fires. The public IP is unreachable from this
|
||||
# subnet (no DMZ hairpin), so point auth.gymb.* directly at the
|
||||
# application host where authentik runs. Without this the forwardauth
|
||||
# middleware would time out and every garage-console request would 502.
|
||||
traefik_extra_hosts:
|
||||
- "auth.gymb.souveredu.ch:172.16.19.101"
|
||||
|
||||
# Services hosted on `storage` that the DMZ reverseproxy should forward
|
||||
# public traffic to. See application/traefik.yml for the mechanism.
|
||||
traefik_dmz_exposed_services:
|
||||
|
|
|
|||
|
|
@ -45,5 +45,21 @@ all:
|
|||
application:
|
||||
|
||||
authentik_outpost_ldap_servers:
|
||||
hosts:
|
||||
application:
|
||||
|
||||
send_servers:
|
||||
hosts:
|
||||
application:
|
||||
|
||||
opnform_servers:
|
||||
hosts:
|
||||
application:
|
||||
|
||||
homarr_servers:
|
||||
hosts:
|
||||
application:
|
||||
|
||||
bookstack_servers:
|
||||
hosts:
|
||||
application:
|
||||
Loading…
Add table
Add a link
Reference in a new issue