Authelia 4.39 配置参数详解

以 configuration.yml 为核心逐段详解 Authelia v4.39.28:server/session/storage/access_control/regulation/identity_validation/ntp/telemetry 全参数与生产模板,行为均实测验证

AutheliaAuthelia身份认证2026/10/18

Authelia 4.39 配置参数详解

目标:以 Authelia v4.39.28 的 configuration.yml 为核心,逐段讲清每个配置段的作用、默认值与改动影响,覆盖 server/session/storage/access_control/regulation/identity_validation/ntp/telemetry 等全部核心段,并给出生产场景配置模板。已在 Ubuntu 22.04 实测通过(部署载体为《Authelia Docker Compose 部署指南》所述环境,本篇所有行为实测均在其中完成)。

一、环境信息

本篇是配置详解专题篇,实验环境与部署篇一致,配置修改后即时重载验证:

  • 操作系统:Ubuntu 22.04
  • Authelia:v4.39.28(官方发布镜像,authelia --version 实测输出 authelia version v4.39.28)
  • 基准配置:部署篇 4.4 节的 configuration.yml(含 server TLS、文件用户后端、SQLite 存储、one_factor 访问规则、filesystem 通知)
  • 验证工具:curl(认证行为)、sqlite3(存储内容核对)、官方 authelia validate-config(配置校验)
  • 演示账号:admin / q1w2e3r4(用户文件方式,见 5.4)
  • 会话域名家族:example.com(authelia.example.com:9091 登录门户、app.example.com:8098 受保护应用)

二、前置条件

  • 已按《Authelia Docker Compose 部署指南》完成部署并能通过 4.10 的健康检查(/api/health 返回 {"status":"OK"});
  • 有权限修改 /opt/authelia/authelia/data/configuration.yml 并执行 docker compose restart authelia;
  • 本篇部分实测需要修改配置(如临时开启 two_factor),改完记得恢复并重启。

三、参数查看与修改方式

配置的「读、改、校验、生效」四步是调参的基本功。Authelia 的配置来源有四层,优先级从高到低:命令行参数 > 环境变量 > 配置文件 > 内置默认值。日常调参主要在配置文件层,敏感值走环境变量层。

3.1 校验配置:validate-config

改完配置先校验再重启,避免服务起不来:

docker run --rm -v /opt/authelia/authelia/data/configuration.yml:/tmp/cfg.yml:ro \
  authelia/authelia:4.39.28 authelia validate-config --config /tmp/cfg.yml

配置正确时的实测回显(无 error 输出、退出码 0):

(无输出,命令正常返回)

配置有错时的实测回显(故意删掉 jwt_secret 环境变量后校验):

Configuration parsed and loaded with errors:

         - identity_validation: reset_password: option 'jwt_secret' is required when the reset password functionality isn't disabled
         - server: tls: option 'key' with path '/config/certs/key.pem' refers to a file that doesn't exist

Error: configuration validation failed

回显解读:validate-config 会把「必填项缺失」「文件路径不存在」这类问题全部列出,且给出的路径是容器内视角(如 /config/...)。注意:校验命令不加载 .env 密钥(环境变量层),所以密钥类报错只在这一步出现,运行时由环境变量补上则不影响实际启动。

3.2 修改与生效

vim /opt/authelia/authelia/data/configuration.yml
cd /opt/authelia && docker compose restart authelia

生效验证(重启后健康值回到 healthy、日志无 error):

docker compose ps --format '{{.Name}} {{.Status}}'

实测回显:

authelia-v4-app Up 9 seconds (healthy)

⚠️ 注意:users.yml 用户文件修改后同样需要重启 authelia 服务生效。access_control、session 等所有配置段均无热加载。

3.3 环境变量覆盖规则

任何「以 key/secret/password/token/certificate_chain 结尾」的配置项都可以用环境变量覆盖,命名规则是 AUTHELIA_ 前缀 + 配置点路径大写化:

配置点路径环境变量名
session.secretAUTHELIA_SESSION_SECRET
storage.encryption_keyAUTHELIA_STORAGE_ENCRYPTION_KEY
identity_validation.reset_password.jwt_secretAUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET
authentication_backend.ldap.passwordAUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD
notifier.smtp.passwordAUTHELIA_NOTIFIER_SMTP_PASSWORD

表格解读:这个映射规律可以「见名知变量」,但变量名拼错时 Authelia 不会报错失败,而是打出 not expected 警告后忽略该变量——这是 4.39 最容易踩的坑(部署篇 Q1 有完整复现)。非敏感的普通配置项同样支持环境变量覆盖(规则相同),但为保持配置文件的可审计性,建议只有密钥类走环境变量。

四、参数总览

配置段必填作用域默认行为
server否监听与 TLS监听 tcp://:9091/,明文 HTTP
log否日志级别 info,输出 stdout
identity_validation部分敏感操作身份验证reset_password 需 jwt_secret;elevated_session 有内置默认时长
authentication_backend是用户来源无默认,必须显式配置 file 或 ldap 二选一
session是会话cookies 段必填(domain/authelia_url)
storage是持久化必须显式配置 local/mysql/postgres 之一
access_control否授权未配置时对 2FA 用户默认 two_factor
regulation否防爆破官方默认 3 次 / 2 分钟 / 封禁 5 分钟
notifier是*通知配置了密码重置/2FA 功能时实际必需
ntp否时钟校验默认校验 time.cloudflare.com:123,偏移超 3s 报警
telemetry否指标metrics 关闭

表格解读:真正「不配起不来」的只有 authentication_backend、session.cookies、storage 三处;notifier 在启用密码重置时必配(验证码/重置链接要通过它送达用户)。以下逐段详解。

五、核心参数分类详解

5.1 server:监听地址与 TLS

server:
  address: tcp://0.0.0.0:9091/
  tls:
    certificate: /config/certs/cert.pem
    key: /config/certs/key.pem
  • address:4.38+ 新格式 [tcp[(4|6)]://][host]:<port>[/<path>]。实测旧写法 host: 0.0.0.0 + port: 9091 仍可用但打 deprecation 警告(部署篇 Q3 原文),新写法警告消失;/ 结尾的 path 部分是 Web 入口子路径,根路径部署写 /;
  • tls.certificate / tls.key:配了这对键,Authelia 自身就是 HTTPS 服务(本方案如此);不配则明文 HTTP,仅适合反代与 Authelia 同机且走内部网络的场景;
  • server.headers、server.endpoints:4.39 还有更细的响应头与端点配置(如 authz 端点策略、限速 server.endpoints.rate_limits),常规部署用默认值即可。

启动成功的验证回显(日志):

time="2026-10-18T07:15:24Z" level=info msg="Listening for TLS connections on '[::]:9091' path '/'" server=main service=server

5.2 log:日志级别

log:
  level: info

可选值 trace/debug/info/warn/error。排查认证失败时把级别临时调到 debug 能看到每条请求的校验细节;生产长期运行建议 info 或 warn。级别是纯运行时开关,改完重启即可。部署篇各步骤的日志回显均为 info 级别采集。

5.3 identity_validation:密码重置与会话提权

identity_validation:
  reset_password:
    jwt_lifespan: 5m
    jwt_algorithm: HS256
  elevated_session:
    code_lifespan: 5m
    elevation_lifespan: 10m
    characters: 8
  • reset_password:用户点「忘记密码」后,重置链接里的 JWT 由 jwt_secret(经环境变量注入)签名;jwt_lifespan 限制链接有效期(默认 5 分钟);jwt_algorithm 默认 HS256,配 RS256 等非对称算法时需另配密钥对;
  • elevated_session(4.38+ 新机制):修改安全设置(注册 2FA 设备、改密码等)前必须「提权」——Authelia 向用户邮箱发一个一次性验证码(characters 位、code_lifespan 有效),验证通过后提权状态保持 elevation_lifespan。

提权机制实测:在仅完成一因子登录的会话上直接注册 TOTP,返回 403 并触发发码:

HTTP/1.1 403 Forbidden

{"status":"KO","data":{"elevation":true,"first_factor":false,"second_factor":false}}

随后查询提权状态、请求发起提权:

curl -sk --resolve authelia.example.com:9091:127.0.0.1 https://authelia.example.com:9091/api/user/session/elevation -H "Cookie: $CK"

实测回显:

{"status":"OK","data":{"require_second_factor":false,"skip_second_factor":false,"can_skip_second_factor":false,"factor_knowledge":true,"elevated":false,"expires":0}}

发起提权后,验证码经 notifier 送达(本方案是 filesystem,生产是 SMTP 邮件)。实测收到的通知文件内容(节选):

Subject: Confirm your identity
A ONE-TIME CODE HAS BEEN GENERATED TO COMPLETE A REQUESTED ACTION
The following one-time code should only be used in the prompt displayed in your browser.
DPC3QK8N

⚠️ 注意:4.39 的 elevated_session 与旧文档的 expiration/elevation_secret 键不兼容——实测 identity_validation.elevated_session.expiration 会直接报 configuration key not expected 并拒绝启动(部署篇亦有记录)。升级到 4.39 时务必改用 code_lifespan/elevation_lifespan 新键。

5.4 authentication_backend:用户后端与密码哈希

authentication_backend:
  file:
    path: /config/users.yml
    password:
      algorithm: argon2
      argon2:
        variant: argon2id
        iterations: 3
        memory: 65536
        parallelism: 4
  • file.path:用户数据库 YAML;已有 LDAP 的组织换 authentication_backend.ldap 段(address: ldap://...、base_dn、users_filter、groups_filter 等),两者互斥;
  • password 段约定新哈希的生成参数,与哈希工具默认值一致(argon2id, m=65536, t=3, p=4)。密码校验按哈希串自身携带的参数执行,因此修改本段不影响存量用户登录;
  • 用户文件结构与 admin 账号示例见部署篇 4.5(哈希用 authelia crypto hash generate argon2 --password '...' 生成,实测回显 $argon2id$v=19$m=65536,t=3,p=4$...)。

💡 技术拓展:文件后端的定位是「小规模/演示」,它没有修改密码的自助入口(改密码=改 YAML 重启),也没有登录失败锁定以外的账号状态管理。用户量上百或有自助需求时应切换 LDAP(如 OpenLDAP、FreeIPA):

后端密码管理组适用规模
file (YAML)手工改文件文件内 groups 列表≤ 几十人
LDAP目录服务自助改密目录组中大型、已有目录设施

本方案采用 file 后端,理由是最小化部署依赖、聚焦认证链路本身。

5.5 session:域名、cookie 与时长体系

session:
  name: authelia_session
  expiration: 1h
  inactivity: 5m
  remember_me: 1M
  cookies:
    - name: authelia_session
      domain: example.com
      authelia_url: https://authelia.example.com:9091
      default_redirection_url: https://app.example.com:8098/
  • session.secret:会话签名与加密密钥(本方案经 AUTHELIA_SESSION_SECRET 注入)。⚠️ 4.39 已移除独立的 session.encryption_key——实测环境变量 AUTHELIA_SESSION_ENCRYPTION_KEY 报 not expected,签名与加密统一由 secret 承担;
  • cookies[]:4.38+ 的多域名结构,每个条目覆盖一个「会话域」。domain 是 cookie 的作用域(子域共享,登录一次全家族生效);authelia_url 是本域对应的登录门户地址,必须 https(实测 http 直接 fatal,部署篇 Q2);default_redirection_url 是无明确回跳目标时的默认去向;每个条目还可单独覆盖 name/inactivity/expiration/remember_me;
  • expiration:绝对有效期,到点强制重登(实测 Set-Cookie 的 expires 与之一致,部署篇 4.11 回显 +1h);
  • inactivity:不活跃超时,会话 refreshed 时窗口重置;remember_me:登录勾选后的延长有效期(1M = 一个月);
  • session.redis:默认内存会话;多实例或重启保持登录态时配置 session.redis(host/port/database_index,集群用 high_availability 子段)。

实测确认 cookie 属性(部署篇 4.11 回显):

Set-Cookie: authelia_session=N#FleNgyVQj47ElmTNQS6FLvwGHfaly!; expires=Sun, 18 Oct 2026 08:17:01 GMT; domain=example.com; path=/; HttpOnly; secure; SameSite=Lax

5.6 storage:local 存储与加密键

storage:
  local:
    path: /config/db.sqlite3
  • local.path:SQLite 数据库文件路径。首次启动自动完成 schema 迁移(实测日志 Storage schema migration from 0 to 29 is complete);文件落盘验证:
ls -l /opt/authelia/authelia/data/db.sqlite3

实测回显:

-rw-r--r-- 1 root root 311296 Oct 18 15:22 db.sqlite3
  • storage.encryption_key:加密库内敏感列(2FA 设备密钥等),≥20 字符,经 AUTHELIA_STORAGE_ENCRYPTION_KEY 注入。更换密钥会导致既有加密数据不可解密——备份必须「数据库文件 + 密钥」成对;
  • 库表清单实测(sqlite3 .tables):
authentication_logs                oauth2_device_code_session
banned_ip                          oauth2_openid_connect_session
banned_user                        oauth2_par_context
cached_data                        oauth2_pkce_request_session
duo_devices                        oauth2_refresh_token_session

(完整 20+ 张表,节选首屏;authentication_logs 认证流水、banned_user/banned_ip 封禁记录见 5.8 实测。)

  • 迁移到 MySQL/PostgreSQL:改用 storage.mysql / storage.postgres 段(address/database/username/password),启动时 schema 自动迁移到新库;SQLite → 外部库的数据搬迁需按官方迁移文档导出导入,不做自动转换。

5.7 access_control:策略与规则语法

access_control:
  default_policy: deny
  rules:
    - domain: app.example.com
      policy: bypass
      resources:
        - ^/public
    - domain: app.example.com
      policy: one_factor

策略四值:bypass(免认证放行)、one_factor(密码登录即可)、two_factor(须再完成 TOTP/WebAuthn/Duo 之一)、deny(拒绝)。未命中规则时落 default_policy。

规则匹配维度(可组合):domain(支持通配 *.example.com)、resources(路径正则)、methods(HTTP 方法)、subject(user:xxx / group:xxx / ip:1.2.3.0/24 列表)、networks(来源网段,注意 4.38+ 已从 subject: network: 改为顶层 networks 键)。规则自上而下,首条命中即生效。

实测一:bypass 公开路径。上面的规则让 /public 前缀免登录,其余路径仍需 one_factor:

curl -sk --resolve app.example.com:8098:127.0.0.1 -o /dev/null -w '%{http_code}\n' https://app.example.com:8098/public/

实测回显:

200

同域其余路径未登录依旧被拦截:

302

实测二:two_factor 策略下的一因子会话。临时把规则改为 policy: two_factor 并重启,用仅完成密码登录的会话访问:

# 1FA 成功后查询会话级别
curl -sk --resolve authelia.example.com:9091:127.0.0.1 https://authelia.example.com:9091/api/state -H "Cookie: authelia_session=$CK"

实测回显:

{"status":"OK","data":{"username":"admin","authentication_level":1,"factor_knowledge":true,"default_redirection_url":"https://app.example.com:8098/"}}

authentication_level: 1 即一因子级别。此时访问 two_factor 保护的应用:

HTTP 302(跳转补充二因子)

直接校验 verify:

401

回显解读:one_factor 会话在 two_factor 规则下不满足要求,Authelia 拒绝并引导补二因子——这验证了策略引擎按「会话级别 ≥ 规则要求」放行的语义。改回 one_factor 后恢复 200。

💡 说明:two_factor 策略要求用户先注册 2FA 设备(TOTP/WebAuthn/Duo),注册动作在登录门户的设置页完成,且受 5.3 会话提权机制保护;生产启用 two_factor 前务必先配好可用的 notifier(否则用户收不到提权验证码)。

5.8 regulation:防暴力破解

regulation:
  max_retries: 3
  find_time: 2m
  ban_time: 5m
  • 语义:find_time 窗口内同一来源对同一用户的失败登录达到 max_retries 次,即封禁 ban_time;三个值均支持时长后缀;
  • 封禁的判定与存储在后端数据库(banned_user/banned_ip 表),重启服务不解封。

实测(对 admin 连续输错 3 次密码):

第 1~3 次:HTTP 401  {"status":"KO","message":"Authentication failed. Check your credentials."}
第 4 次起:HTTP 401(响应外观相同)

日志中出现封禁记录:

time="2026-10-18T07:17:41Z" level=error msg="Unsuccessful 1FA authentication attempt by user 'admin' and they are banned until 7:22:40AM on October 18 2026 (+00:00)" method=POST path=/api/firstfactor remote_ip=10.89.23.1

封禁期内即使输入正确密码也返回 401(实测确认),对外不区分「密码错」与「被封禁」,防账号枚举。查库确认封禁落盘:

sqlite3 /opt/data/authelia/db.sqlite3 'SELECT * FROM banned_user;'

实测回显:

1|2026-10-18 07:17:40|2026-10-18 07:22:40.353693774+00:00||0|admin|regulation|Exceeding Maximum Retries

字段依次为:id、封禁时刻、解封时刻、来源 IP(用户级封禁为空)、尝试次数、用户名、原因类别、原因描述。

💡 说明:解封有三种途径——等 ban_time 自然到期、直接删除 banned_user 表记录(实测删除后立即恢复登录,再次登录返回 200)、以及把 ban_time 调小后重启(仅影响后续判定)。日常运维不建议频繁手删记录,应先弄清失败来源是否为攻击。

5.9 notifier:通知渠道

notifier:
  disable_startup_check: true
  filesystem:
    filename: /config/notification.txt
  • filesystem:通知写入指定文件,是 SMTP 不可用时的最小方案(本方案采用);每次通知追加写入,含收件人、主题、正文与一次性码;
  • smtp:生产配置形态——address: smtp.example.com:587、username、password(走 AUTHELIA_NOTIFIER_SMTP_PASSWORD 注入)、sender、disable_require_tls/tls 子段按服务商要求调整;
  • disable_startup_check:只对 smtp 模式有意义(默认 false,启动时试连 SMTP);filesystem 模式设 true 消除无意义的检查。

5.10 ntp:时钟校验

4.39 默认在启动时向 NTP 源校验本机时钟,防 TOTP 因时间漂移失效:

ntp:
  address: udp://time.cloudflare.com:123
  version: 4
  max_desync: 3s
  disable_startup_check: false
  disable_failure: false
  • max_desync:允许偏移;disable_startup_check: true 关闭启动校验;disable_failure: true 把超差从阻断降级为警告;
  • 本环境(外网 UDP 123 受限)的实测启动日志:
time="2026-10-18T07:15:18Z" level=warning msg="Could not determine the clock offset due to an error" error="error occurred reading ntp packet response to the connection: read udp 10.89.23.4:44577->162.159.200.1:123: i/o timeout"

处理:无法出网 UDP 123 的环境,把 address 指向内网 NTP 服务器(如 udp://ntp.internal:123);确实无 NTP 源时可 disable_startup_check: true,但应改由系统层保证时间同步(chrony/ntp 服务对齐上游)。TOTP 依赖时钟准确,这条链路不能长期裸奔。

5.11 telemetry:指标暴露

telemetry:
  metrics:
    enabled: true
    address: tcp://0.0.0.0:9959/metrics
  • enabled:默认 false;开启后 metrics 在独立地址监听(4.39 形态;4.38 旧键 telemetry.metrics.service.monitoring_path 已移除——实测保留旧键会 fatal,报 configuration key not expected);
  • address:与 server.address 同格式,路径段即抓取端点;建议绑定内网/监控网段地址,不要暴露公网;
  • 实测指标(同网络内抓取 http://authelia:9959/metrics,输出节选):
# HELP authelia_authz The number of authz requests processed.
# TYPE authelia_authz counter
authelia_authz{code="200"} 3
authelia_authz{code="401"} 1
# HELP authelia_request The number of HTTP requests processed.
# TYPE authelia_request counter
authelia_request{code="200",method="GET"} 3
authelia_request_duration_bucket{code="200",le="0.005"} 5

实测该端点共输出 45 个 authelia_ 前缀指标序列,覆盖认证成败(authz)、请求计数与时延直方图(request_duration_bucket)等,可直接被 Prometheus 抓取。

六、生产配置模板

适用场景:16GB 内存、NVMe SSD、50–200 用户、Nginx 反代、已有 PostgreSQL/Redis/SMTP 设施的中小团队生产环境。模板只列关键段(域名、密码、地址按实际替换,密钥经环境变量注入):

server:
  address: tcp://0.0.0.0:9091/
  tls:
    certificate: /config/certs/fullchain.pem
    key: /config/certs/privkey.pem

log:
  level: info

identity_validation:
  reset_password:
    jwt_lifespan: 5m
    jwt_algorithm: HS256
  elevated_session:
    code_lifespan: 5m
    elevation_lifespan: 10m
    characters: 8

authentication_backend:
  ldap:
    address: ldap://ldap.internal:389
    base_dn: dc=example,dc=com
    users_filter: (&({username_attribute}={input})(objectClass=person))
    groups_filter: (&(member={dn})(objectClass=groupOfNames))
    attributes:
      display_name: displayName
      mail: mail
      member_of: memberOf

session:
  name: authelia_session
  expiration: 8h
  inactivity: 30m
  remember_me: 1M
  cookies:
    - domain: example.com
      authelia_url: https://auth.example.com
      default_redirection_url: https://portal.example.com/
  redis:
    host: redis.internal
    port: 6379

storage:
  postgres:
    address: tcp://postgres.internal:5432
    database: authelia
    username: authelia

access_control:
  default_policy: deny
  rules:
    - domain: portal.example.com
      policy: bypass
    - domain: grafana.example.com
      policy: two_factor
    - domain: internal.example.com
      policy: one_factor
      subject:
        - group:employees

regulation:
  max_retries: 5
  find_time: 2m
  ban_time: 15m

notifier:
  smtp:
    address: smtp.example.com:587
    username: no-reply@example.com
    sender: Authelia <no-reply@example.com>

ntp:
  address: udp://ntp.internal:123

telemetry:
  metrics:
    enabled: true
    address: tcp://0.0.0.0:9959/metrics

模板要点:LDAP 承接用户目录后不再维护 YAML 用户库;会话迁 Redis 使 Authelia 可重启/多实例而登录态不丢;expiration: 8h + inactivity: 30m 是办公场景平衡值;核心系统 two_factor、普通内网 one_factor、门户页 bypass 分层放行;regulation 放宽到 5 次/15 分钟封禁以适配办公室出口 IP 汇聚;NTP 指向内网源规避公网 UDP 限制。四项密钥(session.secret、storage.encryption_key、reset_password.jwt_secret、smtp.password)一律经 AUTHELIA_* 环境变量注入。

七、常见问题

Q1:配置明明写了,为什么没生效? 按优先级排查:① 环境变量层是否同名覆盖(AUTHELIA_* 变量优先于配置文件,且拼错的变量只报 not expected 警告);② 是否忘了 docker compose restart authelia(无热加载);③ 是否被同段其他键的旧键名拖累 fatal(如 4.39 不认 session.encryption_key、elevated_session.expiration)。用 3.1 的 validate-config 先过滤语法层错误。

Q2:4.38/4.39 的破坏性键变化有哪些? 实测确认的三处:server.host/port → server.address(旧键弃用映射,警告不阻断);session.remember_me_duration → session.remember_me(同上);session.encryption_key → 删除(其变量报 not expected,功能并入 session.secret);telemetry.metrics.service.monitoring_path → telemetry.metrics.address(旧键 fatal);elevated_session.expiration → code_lifespan/elevation_lifespan(旧键 fatal)。从 4.37 直接升 4.39 的用户重点核对后三处。

Q3:regulation 误封了自己怎么办? 封禁响应与密码错误无法区分(都是 401),先查日志 banned until 确认;解封见 5.8(删 banned_user 记录立即生效)。办公环境多人共享出口 IP 时,适当调大 max_retries 或把 find_time 拉长,避免整办公室连环误伤。

Q4:two_factor 规则加了,用户登录后一直跳「需要二因子」。 这是预期行为:用户尚未注册 2FA 设备。引导其进门户设置页注册 TOTP/WebAuthn;注册动作本身需要提权验证码,所以 notifier 必须先可用。若全体用户都无需 2FA,把规则降回 one_factor 即可。

Q5:metrics 端点宿主机 curl 不通。 4.39 的 metrics 是独立监听地址,需要在 compose.yml 给 authelia 服务补一条 ports: - "9959:9959" 映射(或像本篇实测那样从同网络的监控侧抓取)。确认 telemetry.metrics.enabled: true 且 address 端口未被占用。

八、参考链接