Merge pull request #385 from outis1one/claude/frigate-authelia-openid-0l1htj
Claude/frigate authelia openid 0l1htj
This commit is contained in:
+360
-12
@@ -232,14 +232,20 @@ install_authelia() {
|
||||
echo " promote/demote admin, per-service access, delete)"
|
||||
echo " 5) Register an app to log in VIA Authelia (OIDC/SSO — e.g. ActualBudget,"
|
||||
echo " Vaultwarden, or any other app with its own \"Enable OpenID\" setting)"
|
||||
echo " 6) Reconfigure from scratch (regenerates secrets/users — breaks"
|
||||
echo " 6) Remove a registered OIDC app (undoes option 5 for one app — its own"
|
||||
echo " separate password login, if it has one, is untouched)"
|
||||
echo " 7) Reconfigure from scratch (regenerates secrets/users — breaks"
|
||||
echo " existing sessions for every domain already on this instance)"
|
||||
echo " 7) Show who has universal vs. service-scoped access"
|
||||
echo " 8) Change \"Remember me\" session duration (stay logged in longer)"
|
||||
echo " 9) Leave as-is"
|
||||
echo " 8) Show who has universal vs. service-scoped access"
|
||||
echo " 9) Change \"Remember me\" session duration (stay logged in longer)"
|
||||
echo " 10) Protect an existing site with this instance (pick a local Caddy site,"
|
||||
echo " or type one on a different box — gates it with a login, same as any"
|
||||
echo " other service already protected this way)"
|
||||
echo " 11) Un-protect a site (undoes option 10 for one site)"
|
||||
echo " 12) Leave as-is"
|
||||
echo ""
|
||||
local EXISTING_CHOICE=""
|
||||
prompt_text " Choice [1/2/3/4/5/6/7/8/9]:" "9" EXISTING_CHOICE
|
||||
prompt_text " Choice [1/2/3/4/5/6/7/8/9/10/11/12]:" "12" EXISTING_CHOICE
|
||||
case "$EXISTING_CHOICE" in
|
||||
1)
|
||||
add_authelia_domain
|
||||
@@ -262,16 +268,28 @@ install_authelia() {
|
||||
return 0
|
||||
;;
|
||||
6)
|
||||
: # fall through to the full reinstall flow below
|
||||
_authelia_remove_oidc_client_menu
|
||||
return 0
|
||||
;;
|
||||
7)
|
||||
: # fall through to the full reinstall flow below
|
||||
;;
|
||||
8)
|
||||
_authelia_report_access_scope
|
||||
return 0
|
||||
;;
|
||||
8)
|
||||
9)
|
||||
_authelia_set_remember_me
|
||||
return 0
|
||||
;;
|
||||
10)
|
||||
_authelia_protect_site
|
||||
return 0
|
||||
;;
|
||||
11)
|
||||
_authelia_unprotect_site
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo " Keeping existing Authelia. (Edit config/users.yml then: cd $AUTHELIA_DIR && docker compose restart authelia)"
|
||||
return 0
|
||||
@@ -881,6 +899,274 @@ remove_authelia_domain() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Generalizes the "Protect X with Authelia SSO?" prompt individual services
|
||||
# (magicmirror, wolf-pair, security-dashboard, etc.) each offer on their own
|
||||
# install into one menu action here: pick any existing LOCAL Caddy site by
|
||||
# number, or type a domain that's on a DIFFERENT box's Caddy entirely (this
|
||||
# box only runs Authelia, not that site) — e.g. this repo's own case of a
|
||||
# DigitalOcean droplet's site protected by an Authelia instance on a
|
||||
# separate IONOS box.
|
||||
#
|
||||
# Local site: inserts "import authelia" as the very first line inside its
|
||||
# existing block — must come before reverse_proxy, since Caddy runs
|
||||
# directives in the order they're written and an auth check placed after
|
||||
# reverse_proxy is dead code that never runs (full bypass, not an error;
|
||||
# see lib/common.sh's configure_caddy_for_service for the fuller version of
|
||||
# this warning). Idempotent: an already-protected site is flagged in the
|
||||
# list and skips re-inserting a duplicate import, going straight to access
|
||||
# scoping below.
|
||||
#
|
||||
# Remote site: this box can't edit a file on another machine, so it prints
|
||||
# (and saves to caddy-snippets/, same convention as every other remote-
|
||||
# Authelia caller in this repo) the forward_auth block that box's OWN
|
||||
# Caddyfile needs instead — the remote-hop-safe form with a literal
|
||||
# X-Forwarded-Host, not the {host} placeholder, for the header-rewrite
|
||||
# reasons documented at length in CLAUDE.md and services/asterisk.sh.
|
||||
#
|
||||
# Either way, finishes by offering _authelia_scope_access for the domain —
|
||||
# identical either way, since it only cares about the domain, not which box
|
||||
# is actually enforcing the gate.
|
||||
_authelia_protect_site() {
|
||||
local authelia_dir="$DOCKER_DIR/authelia"
|
||||
local config_file="$authelia_dir/config/configuration.yml"
|
||||
local caddy_file="$DOCKER_DIR/caddy/Caddyfile"
|
||||
|
||||
if [ ! -f "$config_file" ]; then
|
||||
log_warning "No configuration.yml found at $config_file — install Authelia first."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local -a site_domains
|
||||
if [ -f "$caddy_file" ]; then
|
||||
mapfile -t site_domains < <(grep -oE '^[A-Za-z0-9][A-Za-z0-9.-]*\.[A-Za-z]{2,} \{$' "$caddy_file" | sed 's/ {$//')
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo " Protect a site with this Authelia instance."
|
||||
if [ "${#site_domains[@]}" -gt 0 ]; then
|
||||
echo " Local Caddy sites on this box:"
|
||||
local i d marker
|
||||
for i in "${!site_domains[@]}"; do
|
||||
d="${site_domains[$i]}"
|
||||
marker=""
|
||||
sed -n "/^${d} {\$/,/^}/p" "$caddy_file" | grep -qE 'import authelia|forward_auth' && marker=" (already protected)"
|
||||
echo " $((i + 1))) ${d}${marker}"
|
||||
done
|
||||
else
|
||||
echo " No local Caddy sites found."
|
||||
fi
|
||||
echo " Or type a domain directly — including one on a DIFFERENT box's Caddy"
|
||||
echo " entirely (this box only needs to run Authelia itself for that to work)."
|
||||
echo ""
|
||||
local choice=""
|
||||
prompt_text " Number or domain:" "" choice
|
||||
if [ -z "$choice" ]; then
|
||||
log_warning "Nothing entered — nothing to do."
|
||||
return 0
|
||||
fi
|
||||
|
||||
local target_domain="" is_local=false
|
||||
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#site_domains[@]}" ]; then
|
||||
target_domain="${site_domains[$((choice - 1))]}"
|
||||
is_local=true
|
||||
else
|
||||
target_domain="$choice"
|
||||
[ -f "$caddy_file" ] && grep -qx "${target_domain} {" "$caddy_file" 2>/dev/null && is_local=true
|
||||
fi
|
||||
|
||||
if [ "$is_local" = true ]; then
|
||||
if sed -n "/^${target_domain} {\$/,/^}/p" "$caddy_file" | grep -qE 'import authelia|forward_auth'; then
|
||||
log_info "${target_domain} is already protected — moving on to access scoping."
|
||||
else
|
||||
cp "$caddy_file" "$caddy_file.backup.$(date +%Y%m%d-%H%M%S)"
|
||||
sed -i "/^${target_domain} {\$/a\\ import authelia" "$caddy_file"
|
||||
log_success "Inserted 'import authelia' into ${target_domain}'s Caddy block."
|
||||
docker exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile 2>/dev/null || true
|
||||
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^caddy$"; then
|
||||
if docker exec -w /etc/caddy caddy caddy reload 2>/dev/null; then
|
||||
log_success "Caddy reloaded"
|
||||
elif docker restart caddy &>/dev/null; then
|
||||
log_success "Caddy restarted (reload API is disabled by default)"
|
||||
else
|
||||
log_warning "Reload/restart failed — check: docker logs caddy"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# This instance's own portal — read back from the primary apex's
|
||||
# session.cookies entry (the first one; same read-back pattern
|
||||
# every other caller in this file uses). A domain on a different
|
||||
# box isn't "added" to this instance the way add_authelia_domain's
|
||||
# apex domains are — it's just gated by THIS instance's existing
|
||||
# portal, same as any local site above, so there's no per-domain
|
||||
# cookie entry of its own to read from.
|
||||
local portal_domain
|
||||
portal_domain="$(tr -d '\r' < "$config_file" | awk '/^ cookies:$/{f=1; next} f && /authelia_url:/{print $2; exit}' | sed -E 's#^https?://##')"
|
||||
if [ -z "$portal_domain" ]; then
|
||||
log_warning "Couldn't determine this instance's own portal domain from $config_file — aborting."
|
||||
return 1
|
||||
fi
|
||||
echo ""
|
||||
log_info "${target_domain} isn't on this box's own Caddy — add this to the OTHER box's"
|
||||
log_info "Caddyfile instead (the one that actually serves ${target_domain}), BEFORE reverse_proxy:"
|
||||
echo ""
|
||||
echo " forward_auth https://${portal_domain} {"
|
||||
echo " uri /api/authz/forward-auth"
|
||||
echo " copy_headers Remote-User Remote-Groups Remote-Name Remote-Email"
|
||||
echo " header_up X-Forwarded-Method {method}"
|
||||
echo " header_up X-Forwarded-Proto {scheme}"
|
||||
echo " header_up X-Forwarded-Host ${target_domain}"
|
||||
echo " header_up X-Forwarded-Uri {uri}"
|
||||
echo " }"
|
||||
echo ""
|
||||
log_warning "Must come BEFORE reverse_proxy in that block, not after — Caddy runs"
|
||||
log_warning "directives in the order they're written, and an auth check placed after"
|
||||
log_warning "reverse_proxy never runs at all (full bypass, not an error)."
|
||||
local snippet_dir="$DOCKER_DIR/caddy-snippets"
|
||||
mkdir -p "$snippet_dir"
|
||||
cat > "$snippet_dir/${target_domain}-authelia.caddy" << SNIPPET
|
||||
forward_auth https://${portal_domain} {
|
||||
uri /api/authz/forward-auth
|
||||
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
|
||||
header_up X-Forwarded-Method {method}
|
||||
header_up X-Forwarded-Proto {scheme}
|
||||
header_up X-Forwarded-Host ${target_domain}
|
||||
header_up X-Forwarded-Uri {uri}
|
||||
}
|
||||
SNIPPET
|
||||
chown "$ACTUAL_USER:$ACTUAL_USER" "$snippet_dir/${target_domain}-authelia.caddy" 2>/dev/null || true
|
||||
log_success "Also saved: $snippet_dir/${target_domain}-authelia.caddy"
|
||||
fi
|
||||
|
||||
_authelia_scope_access "$(echo "$target_domain" | tr '.' '-')" "$target_domain"
|
||||
}
|
||||
|
||||
# Reverse of _authelia_protect_site — removes a local site's "import
|
||||
# authelia" line from its own Caddy block (reloading Caddy), and the two
|
||||
# access_control.rules entries _authelia_scope_access may have added for
|
||||
# it, if any (found by the same "<domain-with-dots-as-hyphens>-only" group
|
||||
# name _authelia_protect_site used). Each scoped rule is a 3-line
|
||||
# "- domain: ...\n subject: ...\n policy: ..." block — bounded removal by
|
||||
# buffering exactly 3 lines at a time from each " - domain:" line and
|
||||
# only dropping the buffer if the group's subject line is inside it, so an
|
||||
# unrelated rule sharing the same "*.<apex>" domain line for a DIFFERENT
|
||||
# group is untouched.
|
||||
#
|
||||
# Does NOT remove the user group itself from users.yml (a user's ["x-only"]
|
||||
# membership with no matching rule left is inert, not a live grant) or
|
||||
# touch a domain on a different box's Caddy (nothing here can edit that
|
||||
# file) — for a remote site, this only cleans up the access rules on this
|
||||
# side; removing the forward_auth block itself is a manual edit on the box
|
||||
# that actually serves it.
|
||||
_authelia_unprotect_site() {
|
||||
local authelia_dir="$DOCKER_DIR/authelia"
|
||||
local config_file="$authelia_dir/config/configuration.yml"
|
||||
local caddy_file="$DOCKER_DIR/caddy/Caddyfile"
|
||||
|
||||
if [ ! -f "$config_file" ]; then
|
||||
log_warning "No configuration.yml found at $config_file — install Authelia first."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local -a protected_domains
|
||||
if [ -f "$caddy_file" ]; then
|
||||
mapfile -t protected_domains < <(
|
||||
grep -oE '^[A-Za-z0-9][A-Za-z0-9.-]*\.[A-Za-z]{2,} \{$' "$caddy_file" | sed 's/ {$//' |
|
||||
while read -r d; do
|
||||
sed -n "/^${d} {\$/,/^}/p" "$caddy_file" | grep -qE 'import authelia|forward_auth' && echo "$d"
|
||||
done
|
||||
)
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo " Un-protect a site (remove its Authelia gate)."
|
||||
if [ "${#protected_domains[@]}" -gt 0 ]; then
|
||||
echo " Currently-protected local Caddy sites:"
|
||||
local i
|
||||
for i in "${!protected_domains[@]}"; do
|
||||
echo " $((i + 1))) ${protected_domains[$i]}"
|
||||
done
|
||||
else
|
||||
echo " No locally-gated Caddy sites found."
|
||||
fi
|
||||
echo " Or type a domain directly — including one on a different box's Caddy, to"
|
||||
echo " clean up its access-scoping rules here even though the gate itself lives"
|
||||
echo " elsewhere and needs removing there by hand."
|
||||
echo ""
|
||||
local choice=""
|
||||
prompt_text " Number or domain (blank to cancel):" "" choice
|
||||
if [ -z "$choice" ]; then
|
||||
log_info "Cancelled — nothing changed."
|
||||
return 0
|
||||
fi
|
||||
|
||||
local target_domain="" is_local=false
|
||||
if [[ "$choice" =~ ^[0-9]+$ ]] && [ "$choice" -ge 1 ] && [ "$choice" -le "${#protected_domains[@]}" ]; then
|
||||
target_domain="${protected_domains[$((choice - 1))]}"
|
||||
is_local=true
|
||||
else
|
||||
target_domain="$choice"
|
||||
[ -f "$caddy_file" ] && grep -qx "${target_domain} {" "$caddy_file" 2>/dev/null && is_local=true
|
||||
fi
|
||||
|
||||
if [ "$is_local" = true ]; then
|
||||
if sed -n "/^${target_domain} {\$/,/^}/p" "$caddy_file" | grep -qE 'import authelia|forward_auth'; then
|
||||
cp "$caddy_file" "$caddy_file.backup.$(date +%Y%m%d-%H%M%S)"
|
||||
sed -i "/^${target_domain} {\$/,/^}/{/^ *import authelia\$/d; /^ *forward_auth /,/^ *}\$/d}" "$caddy_file"
|
||||
log_success "Removed the Authelia gate from ${target_domain}'s Caddy block."
|
||||
docker exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile 2>/dev/null || true
|
||||
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^caddy$"; then
|
||||
if docker exec -w /etc/caddy caddy caddy reload 2>/dev/null; then
|
||||
log_success "Caddy reloaded"
|
||||
elif docker restart caddy &>/dev/null; then
|
||||
log_success "Caddy restarted (reload API is disabled by default)"
|
||||
else
|
||||
log_warning "Reload/restart failed — check: docker logs caddy"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_info "${target_domain} isn't currently gated — nothing to remove there."
|
||||
fi
|
||||
else
|
||||
log_info "${target_domain} isn't on this box's own Caddy — only cleaning up its access"
|
||||
log_info "rules here. Remove the forward_auth block from the box that actually serves"
|
||||
log_info "it yourself (see $DOCKER_DIR/caddy-snippets/ if it was added via option 9)."
|
||||
fi
|
||||
|
||||
local group="$(echo "$target_domain" | tr '.' '-')-only"
|
||||
if grep -qF "subject: \"group:${group}\"" "$config_file" 2>/dev/null; then
|
||||
awk -v grp="\"group:${group}\"" '
|
||||
BEGIN { buf=""; n=0; hit=0 }
|
||||
/^ - domain:/ {
|
||||
if (n > 0) { if (!hit) printf "%s", buf; buf=""; n=0; hit=0 }
|
||||
buf = $0 "\n"; n=1
|
||||
if ($0 ~ grp) hit=1
|
||||
next
|
||||
}
|
||||
n > 0 && n < 3 {
|
||||
buf = buf $0 "\n"; n++
|
||||
if ($0 ~ grp) hit=1
|
||||
if (n == 3) { if (!hit) printf "%s", buf; buf=""; n=0; hit=0 }
|
||||
next
|
||||
}
|
||||
{ if (n > 0) { if (!hit) printf "%s", buf; buf=""; n=0; hit=0 } print }
|
||||
END { if (n > 0 && !hit) printf "%s", buf }
|
||||
' "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file"
|
||||
chown 1000:1000 "$config_file" 2>/dev/null || true
|
||||
log_success "Removed the '${group}' access-scoping rules — ${target_domain} is open to any"
|
||||
log_success "Authelia user again (users' membership in '${group}' is left as harmless"
|
||||
log_success "unused metadata — remove it by hand in users.yml if you want it fully gone)."
|
||||
fi
|
||||
|
||||
local RESTART_AUTH=""
|
||||
prompt_yn " Restart Authelia to apply? (y/n):" "y" RESTART_AUTH
|
||||
if [ "$RESTART_AUTH" = "y" ] || [ "$RESTART_AUTH" = "Y" ]; then
|
||||
(cd "$authelia_dir" && docker compose restart authelia 2>/dev/null) \
|
||||
&& log_success "Authelia restarted" \
|
||||
|| log_warning "Restart failed — check: docker compose logs authelia"
|
||||
fi
|
||||
}
|
||||
|
||||
# Picks "count" random characters from "charset" using an unbiased-enough
|
||||
# per-byte modulo draw from /dev/urandom. Not part of lib/common.sh's shared
|
||||
# generate_password (that one is deliberately alphanumeric-only — see its
|
||||
@@ -2069,11 +2355,14 @@ _authelia_add_oidc_client() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
if grep -qF "client_id: '${CLIENT_ID}'" "$CONFIG_FILE" 2>/dev/null; then
|
||||
log_warning "A client with ID '$CLIENT_ID' is already registered in $CONFIG_FILE."
|
||||
log_warning "Pick a different app, or edit that entry by hand."
|
||||
return 0
|
||||
fi
|
||||
# No duplicate-ID check here — _authelia_provision_oidc_client below
|
||||
# already handles that safely by replacing the stale registration (its
|
||||
# old secret was shown once and is unrecoverable either way, so there's
|
||||
# nothing to lose). An earlier version of this function dead-ended here
|
||||
# instead ("pick a different app, or edit by hand") before ever
|
||||
# reaching that safe path — confirmed live: this blocked re-registering
|
||||
# ActualBudget after nothing more than a first attempt, with no way
|
||||
# through except hand-editing configuration.yml.
|
||||
|
||||
local APP_DOMAIN_DEFAULT="" APP_DOMAIN=""
|
||||
[ -n "${SITE_DOMAIN:-}" ] && [ "$SITE_DOMAIN" != "example.com" ] && APP_DOMAIN_DEFAULT="${CLIENT_ID}.${SITE_DOMAIN}"
|
||||
@@ -2159,5 +2448,64 @@ _authelia_add_oidc_client() {
|
||||
log_warning "The Client Secret above is shown once — it isn't stored in plaintext anywhere. Save it now."
|
||||
}
|
||||
|
||||
# Interactive wrapper around _authelia_remove_oidc_client (the internal
|
||||
# helper _authelia_provision_oidc_client already uses to replace a stale
|
||||
# registration) — exposes it as its own menu action so removing an app's
|
||||
# OIDC client doesn't require hand-editing configuration.yml either. Lists
|
||||
# every registered client's ID and display name, numbered; removing one
|
||||
# doesn't affect that app's own separate password login (if it has one) or
|
||||
# any other client on this instance.
|
||||
_authelia_remove_oidc_client_menu() {
|
||||
local AUTHELIA_DIR="$DOCKER_DIR/authelia"
|
||||
local CONFIG_FILE="$AUTHELIA_DIR/config/configuration.yml"
|
||||
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
log_warning "No configuration.yml found at $CONFIG_FILE — install Authelia first."
|
||||
return 1
|
||||
fi
|
||||
|
||||
local -a client_ids client_names
|
||||
mapfile -t client_ids < <(grep -oP "(?<=- client_id: ')[^']+" "$CONFIG_FILE")
|
||||
mapfile -t client_names < <(grep -oP "(?<=client_name: ')[^']+" "$CONFIG_FILE")
|
||||
|
||||
if [ "${#client_ids[@]}" -eq 0 ]; then
|
||||
log_info "No OIDC clients registered on this instance."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo " Registered OIDC clients:"
|
||||
local i
|
||||
for i in "${!client_ids[@]}"; do
|
||||
echo " $((i + 1))) ${client_ids[$i]} (${client_names[$i]:-unnamed})"
|
||||
done
|
||||
echo ""
|
||||
local choice=""
|
||||
prompt_text " Number to remove (blank to cancel):" "" choice
|
||||
if [ -z "$choice" ] || ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt "${#client_ids[@]}" ]; then
|
||||
log_info "Cancelled — nothing changed."
|
||||
return 0
|
||||
fi
|
||||
local target_id="${client_ids[$((choice - 1))]}"
|
||||
|
||||
log_warning "This removes the OIDC client '${target_id}' — anyone using it to log into that app"
|
||||
log_warning "via Authelia will no longer be able to until it's re-registered (option 5). It does"
|
||||
log_warning "NOT touch that app's own separate password login, if it has one."
|
||||
local confirm=""
|
||||
prompt_yn " Continue? (y/n):" "n" confirm
|
||||
[[ "$confirm" =~ ^[Yy]$ ]] || { log_info "Cancelled — nothing changed."; return 0; }
|
||||
|
||||
_authelia_remove_oidc_client "$CONFIG_FILE" "$target_id"
|
||||
log_success "Removed OIDC client '${target_id}'."
|
||||
|
||||
local RESTART_AUTH=""
|
||||
prompt_yn " Restart Authelia to apply? (y/n):" "y" RESTART_AUTH
|
||||
if [ "$RESTART_AUTH" = "y" ] || [ "$RESTART_AUTH" = "Y" ]; then
|
||||
(cd "$AUTHELIA_DIR" && docker compose restart authelia 2>/dev/null) \
|
||||
&& log_success "Authelia restarted" \
|
||||
|| log_warning "Restart failed — check: docker compose logs authelia"
|
||||
fi
|
||||
}
|
||||
|
||||
# Run immediately when executed directly (deferred until after function definition)
|
||||
[[ "${_RUN_STANDALONE:-0}" == 1 ]] && install_authelia
|
||||
|
||||
@@ -814,6 +814,20 @@ CADDYBLOCK
|
||||
log_warning "$SD_DOMAIN already in Caddyfile — leaving the existing entry alone."
|
||||
fi
|
||||
|
||||
# Offer per-user access scoping now that this domain is actually
|
||||
# Authelia-protected (local import or remote forward_auth — EXTRA_BLOCK
|
||||
# is only non-empty when one of those was configured above; skip this
|
||||
# entirely for Basic-Auth-only or no-auth setups, where there's no
|
||||
# Authelia gate to scope). This dashboard was never wired into
|
||||
# _authelia_scope_access before now, on either this domain-takeover path
|
||||
# or the plain separate-subdomain path below it — every protected
|
||||
# domain here defaulted to "any Authelia user", with no way to restrict
|
||||
# it to specific people. Guarded by declare -F: this file can run
|
||||
# standalone with authelia.sh never sourced.
|
||||
if [ -n "$EXTRA_BLOCK" ] && declare -F _authelia_scope_access >/dev/null 2>&1; then
|
||||
_authelia_scope_access "security-dashboard" "$SD_DOMAIN"
|
||||
fi
|
||||
|
||||
# This port never needs to be open to the internet — only Caddy (local,
|
||||
# via host.docker.internal) ever needs to reach it.
|
||||
if command -v ufw &>/dev/null; then
|
||||
|
||||
Reference in New Issue
Block a user