Authelia 配置通用语法与数据结构完全指南:Duration、Address、TLS 与 Server Buffers 深度解析

原创2026-09-11 22:05:06128 阅读
文章标签:后端认证鉴权单点登录身份认证应用安全

Authelia 配置通用语法与数据结构完全指南:Duration、Address、TLS 与 Server Buffers 深度解析

导读

Authelia 作为面向 Web 应用的单点登录与多因素认证门户,其配置系统横跨认证、授权、会话、存储、通知、OIDC 等多个模块。为了让这些模块共享一致的配置体验,Authelia 定义了一套贯穿全配置体系的通用语法(Common Syntax)与通用数据结构(Common Structures)。本篇指南以 docs/content/configuration/prologue/common.md 为骨架,系统讲解 Duration 时长语法、Address 监听/连接地址语法、正则表达式书写规范、Network 网段表示、TLS 配置结构、Server Buffers 与 Server Timeouts 结构,并结合仓库源码(如 internal/utils/time.go、internal/configuration/schema/types_address.go)揭示底层解析原理。读完本文,你将能够准确读懂 Authelia 任意配置文件中出现的时长、地址、TLS 段落,并避免因 YAML 转义、IPv6 括号、单位缩写等细节而踩坑。

说明:本文所描述的通用语法与结构是"跨模块复用"的公共约定,而非针对某个具体实例的配置指南;各模块的专属参数请查阅对应模块文档(如 server 等)。文中引用的链接均已转换为以仓库根目录为起点的相对路径。

语法(Syntax)

以下通用语法在多个配置区域中被反复使用,且对书写格式有明确要求。理解这些语法是正确配置 Authelia 的前提。

字典引用语法(Dictionary Reference)

字典引用语法适用于"键名可由管理员任意指定,且该键名可在其他位置被引用"的场景。

例如,如果文档中标注 policies 是一个字典(Dictionary),那么其中的 arbitrary_name 键就是管理员自定义的任意名称,它可以被其他地方引用——如下面示例中 usage_example 列表里的 policy 字段,就通过 'arbitrary_name' 引用了上面定义的策略:

policies:
  arbitrary_name:
    enable: true

usage_example:
  - name: 'example'
    policy: 'arbitrary_name'

这种"先定义、后引用"的模式在 Authelia 的访问控制规则、OIDC 客户端、2FA 方法策略等场景中大量出现,理解它能帮助你读懂"名称从哪里来、被谁消费"的配置关系。

时长语法(Duration)

Duration 是 Authelia 配置中最常见的通用语法之一,其基础类型是字符串,同时也接受整数(但不推荐使用整数)。

  • 整数:被视为秒数。例如 5400 表示 5400 秒。
  • 字符串:按"数量 + 单位字母"的块(block)解析,例如 5h 表示 5 个 h 单位(5 小时)。

解析时以下内容会被忽略或剔除:

  • 所有空格;
  • 前导零;
  • 单词 and。

虽然支持将多个"数量+单位"块组合使用(如 1h30m),但官方建议保持简单、尽量使用单一值。同时需要提醒:该格式虽具一定可读性,仍需严格遵循预期的格式规范。

单位对照表(Unit Legend)

下表为时长语法支持的单位。长格式单位(Long Unit,如 hours)自 v4.38.0 起才可用:

单位 短格式 人类可读长格式
年 y year, years
月 M month, months
周 w week, weeks
天 d day, days
小时 h hour, hours
分钟 m minute, minutes
秒 s second, seconds
毫秒 ms millisecond, milliseconds

注意:月(M)使用大写字母,以避免与分钟(m)混淆。

配置示例(Examples)

期望值 短格式配置示例 长格式配置示例
1 小时 30 分钟 90m 或 1h30m 或 5400 或 5400s 1 hour and 30 minutes
1 天 1d 或 24h 或 86400 或 86400s 1 day
10 小时 10h 或 600m 或 9h60m 或 36000 10 hours

源码级解析原理

从源码结构看,时长的标准化与解析位于 internal/utils/time.go:

  • StandardizeDurationString 先将输入中的空格与 and 剔除,再用正则 reDurationStandard = (?P<Duration><a href="https://link.gitcode.com/i/06fc9051d3d15b23f37e43245790ba4a" target="_blank">1-9]\d*?)(?P<Unit>[^\d\s]+)(定义于 [internal/utils/const.go)将输入切分为"数量+单位"块,逐块调用 standardizeQuantityAndUnits 转换。该正则以 [1-9] 开头、不允许前导零,恰好印证了文档中"忽略前导零"的行为。
  • 对于 Go 标准库 time.ParseDuration 不认识的单位(如天、周、月、年),standardizeQuantityAndUnits(internal/utils/time.go)会将其换算为小时:1 天 = 24h、1 周 = 168h、1 月 = 730h、1 年 = 8760h。
  • ParseDurationString 会先判断输入是否为纯数字(^\d+$):若是则按秒处理(time.Second * duration),否则走标准化流程后交给 time.ParseDuration。

在配置反序列化阶段,internal/configuration/decode_hooks.go 中的 DecodeTimeDuration 负责将配置值转换为 time.Duration,其中字符串分支调用 utils.ParseDurationString,整数分支同样按秒计算,并通过 durationMax = time.Duration(math.MaxInt64)(见 internal/configuration/const.go)做最大值校验。因此,你在配置里写 6s、30s、1h30m 或纯整数 5400,最终都会被统一归一化到纳秒级的 time.Duration。

地址语法(Address)

地址类型的基础类型也是字符串。它用于描述两类对象:

  • 监听器(Listener):即服务监听连接的一端,例如 HTTP 服务器监听的地址;
  • 连接器(Connector):即发起远程连接的一端,例如 LDAP、SMTP 客户端连接的远端地址。

查询参数(Query Parameters)

部分 scheme 支持查询参数,参数以 ? 附加在地址之后,多个参数用 & 连接:

参数 监听器 连接器 用途
umask 是 否 在创建 socket 前设置 umask,创建完成后恢复原值。取值必须是 3 或 4 位八进制数字。
path 是 否 设置子路径变量,主要用于 unix socket,但对 TCP 也技术性生效。注意只需填写字母数字部分,不要以正斜杠 / 前缀。

格式(Format)

地址格式使用传统的 POSIX 记法表示可选与必填部分:方括号 [] 包裹可选部分,尖括号 <> 包裹必填部分。必填部分也可能出现在可选部分之内,此时通常伴随其他格式说明文字,指示"若该文字存在则该部分实际必填,否则整体可选"。

另外需要说明:某部分"可选"仅指解析层面,配置校验层面可能仍要求必须提供其中一项。

Hostname 格式

同时适用于监听器与连接器(大多数场景)。scheme 与 port 可选,未提供时的默认值因选项而异:

[<scheme>://]<hostname>[:<port>][/<path>]
Port 格式

大多数场景下仅适用于监听器。scheme 与 hostname 可选:scheme 未提供时默认值因选项而异,hostname 未提供时默认为所有可用地址:

[<scheme>://][hostname]:<port>[/<path>]
文件描述符格式(File Descriptors)

仅适用于监听器,且无可选部分。该格式接受查询字符串,由上文查询参数控制其行为:

fd://<file descriptor number>
fd://<file descriptor number>?umask=0022
fd://<file descriptor number>?path=auth
fd://<file descriptor number>?umask=0022&path=auth
Unix 域套接字格式(Unix Domain Socket)

适用于监听器与连接器(大多数场景),无可选部分。同样接受查询字符串:

unix://<path>
unix://<path>?umask=0022
unix://<path>?path=auth
unix://<path>?umask=0022&path=auth
示例(Examples)
0.0.0.0
tcp://0.0.0.0
tcp://0.0.0.0/subpath
tcp://0.0.0.0:9091
tcp://0.0.0.0:9091/subpath
tcp://:9091
tcp://:9091/subpath
0.0.0.0:9091

udp://0.0.0.0:123
udp://:123

unix:///var/lib/authelia.sock

(示例中的端口 9091 为 Authelia 默认 HTTP 端口,文档站点使用 sitevar 变量按版本注入,实际值以当前版本为准。)

scheme

整个 scheme 是可选的,但一旦字符串中出现 scheme 与 host 的分隔符 ://,则 scheme 必须存在。scheme 必须是下列之一("监听器/连接器"列表示该 scheme 在对应地址类型上的支持情况):

scheme 监听器 连接器 默认端口 说明
tcp 是 是 N/A 标准 TCP socket,允许 IPv4 和/或 IPv6 地址
tcp4 是 是 N/A 标准 TCP socket,仅允许 IPv4 地址
tcp6 是 是 N/A 标准 TCP socket,仅允许 IPv6 地址
udp 是 是 N/A 标准 UDP socket,允许 IPv4 和/或 IPv6 地址
udp4 是 是 N/A 标准 UDP socket,仅允许 IPv4 地址
udp6 是 是 N/A 标准 UDP socket,仅允许 IPv6 地址
unix 是 是 N/A 标准 Unix 域套接字,仅允许绝对路径
ldap 否 是 389 通过 TCP socket 的远端 LDAP 连接,可用时使用 StartTLS
ldaps 否 是 636 通过 TLS socket 的远端 LDAP 连接
ldapi 否 是 N/A 通过 Unix 域套接字的 LDAP 连接
smtp 否 是 25 通过 TCP socket 的远端 SMTP 连接,可用时使用 StartTLS
submission 否 是 587 通过 TCP socket 的远端 SMTP Submission 连接,可用时使用 StartTLS
submissions 否 是 465 通过 TLS socket 的远端 SMTP Submission 连接

scheme 缺失时的默认推断规则:

  • 若地址以 / 前缀开头,则推断为 unix;
  • 否则推断为 tcp;
  • 若 scheme 为 unix,则必须以绝对路径作为后缀,例如 /var/run/authelia.sock 应写作 unix:///var/run/authelia.sock(注意 unix:// 之后是三斜杠,因为路径本身以 / 开头)。

hostname

当 scheme 为 tcp 或 udp 且未指定 port 时,hostname 为必填。它可以是任意本机可寻址的 IP,或解析到本机可寻址 IP 的主机名。

指定 IPv6 时必须用方括号包裹。例如 IPv6 地址 ::1 搭配 tcp scheme 与端口 80 的正确写法是:

tcp://[::1]:80

port

当 scheme 为 tcp 或 udp 且未指定 hostname 时,port 为必填。

源码级解析原理

地址解析的核心实现在 internal/configuration/schema/types_address.go:

  • NewAddressDefault 是解析入口:先用正则判断字符串是否携带 scheme(regexpHasScheme),有则直接交给 url.Parse;否则若以 / 开头就自动补 unix:// 前缀,其余情况补 tcp:// 前缀——这正是文档中"以 / 前缀推断为 unix、否则推断为 tcp"规则的代码实现。
  • NewAddressFromURL 等函数负责将 url.URL 校验并转换为内部 Address 结构(定义于同文件 L190)。
  • 空字符串会被解析为 tcp://:0 形式(见 NewAddressDefault 的边界处理)。
  • 对于 SMTP 类地址,NewSMTPAddress 演示了默认端口的回退逻辑:port 为 0 时按 scheme 回退到 465/587/25,scheme 为空时按端口反推 scheme。

在反序列化链路中,StringToAddressHookFunc 注册于 internal/configuration/decode_hooks.go 的 decode hooks 列表,负责把字符串自动转换为地址类型。也就是说,你在配置文件中写下的每一个地址字符串,最终都会经过上述解析流程变成结构化的网络地址对象。

正则表达式(Regular Expressions)

Authelia 多处配置使用正则表达式,采用 Google RE2 正则引擎(即 Go 标准库正则语法引擎)。它与 PCRE、Perl、Python 等引擎非常相似,主要区别是不支持回溯(backtracking)。

官方建议手动验证正则:可使用 Regex 101 之类的工具,并务必选择 Golang 选项,或用其他手段验证。

反斜杠转义陷阱

使用反斜杠时必须格外小心:YAML 解析器很可能把反斜杠当作 YAML 转义语法而非正则转义语法。为了避免这一问题,请使用单引号而不是无引号或双引号。

正确示例:

domain_regex: '^(admin|secure)\.example\.com$'

错误示例:

domain_regex: "^(admin|secure)\.example\.com$"

上面的错误示例中,双引号内的 \. 会被 YAML 当作转义序列处理,导致最终传给 RE2 的模式与预期不符。

网络(Network)

Authelia 支持将字符串反序列化为网段(network range)的网络语法。字符串使用标准 CIDR 记法;若省略 CIDR 后缀,则默认视为单个主机(IPv4 适配为 /32,IPv6 适配为 /128)。

示例 CIDR 范围
192.168.0.1 192.168.0.1/32 192.168.0.1
192.168.1.0/24 192.168.1.0/24 192.168.1.0 - 192.168.1.255
192.168.2.1/24 192.168.2.0/24 192.168.2.0 - 192.168.2.255
2001:db8:3333:4444:5555:6666:7777:8888 2001:db8:3333:4444:5555:6666:7777:8888/128 2001:db8:3333:4444:5555:6666:7777:8888
2001:db8:3333:4400::/56 2001:db8:3333:4400::/56 2001:0db8:3333:4400:0000:0000:0000:0000 - 2001:0db8:3333:44ff:ffff:ffff:ffff:ffff
2001:db8:3333:4444:5555:6666:7777:8888/56 2001:db8:3333:4400::/56 2001:0db8:3333:4400:0000:0000:0000:0000 - 2001:0db8:3333:44ff:ffff:ffff:ffff:ffff

注意上表中两个值得留意的归一化行为:

  • 192.168.2.1/24 会被归一化为网络地址 192.168.2.0/24,覆盖 192.168.2.0 - 192.168.2.255 整个子网;
  • 带前缀长度的 IPv6 地址同样会被归一化到该前缀的网络边界,如 2001:db8:3333:4444:5555:6666:7777:8888/56 等价于 2001:db8:3333:4400::/56。

数据结构(Structures)

以下通用数据结构在多个配置区域被复用,各自具有明确的字段要求。

TLS

配置中多个区域使用统一的 tls 配置结构,用于配置 TLS socket 与 TLS 校验参数。默认情况下,Authelia 使用系统证书信任库进行 TLS 证书校验,你可以通过全局的 certificates_directory 选项扩充信任库,也可以通过下面的 skip_verify 完全关闭 TLS 证书校验。

tls:
  server_name: 'example.com'
  skip_verify: false
  minimum_version: 'TLS1.2'
  maximum_version: 'TLS1.3'
  certificate_chain: |
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    ...
    -----END CERTIFICATE-----
  private_key: |
    -----BEGIN PRIVATE KEY-----
    ...
    -----END PRIVATE KEY-----

server_name

  • 类型:string,非必填。

server_name 会覆盖证书校验过程中用于比对证书的名称。当后端服务的主机地址需要使用 IP 时,这一选项尤为有用——你可以连接 IP,但校验特定的证书服务器名称。

skip_verify

  • 类型:boolean,默认 false,非必填。

skip_verify 会完全跳过对后端服务证书的校验。不推荐使用。更合理的做法是调整 server_name 选项,以及全局的 certificates directory。

minimum_version

  • 类型:string,默认 TLS1.2,非必填。

控制 Authelia 执行 TLS 握手时使用的最低 TLS 版本。可选值为 TLS1.3、TLS1.2、TLS1.1、TLS1.0、SSL3.0。除 TLS1.3 与 TLS1.2 之外的值都非常古老且已废弃,应避免使用——正确做法是升级后端服务,而不是降低此值。截至撰写本文时,SSL3.0 在任何情况下都会产生错误。

从源码看,schema 层的默认值被定义为 MinimumVersion: TLSVersion{tls.VersionTLS12}(见 internal/configuration/schema/authentication.go 等多处),与文档默认值一致。

maximum_version

  • 类型:string,默认 TLS1.3,非必填。

控制 Authelia 执行 TLS 握手时使用的最高 TLS 版本。可选值同上(TLS1.3、TLS1.2、TLS1.1、TLS1.0、SSL3.0),同样不建议使用除 TLS1.3 与 TLS1.2 以外的值。

certificate_chain

  • 类型:string,非必填(secret 类型参见下文 private_key 说明)。

与 private_key 配合使用,用于与服务器进行双向 TLS(mTLS)认证的证书链/证书包。

取值必须是一个或多个以 DER base64(RFC4648)编码的 PEM 格式证书。若提供多个证书,按自上而下的顺序,每个证书必须由下一个证书(若提供)签名。

private_key

  • 类型:string,非必填,secret(敏感值)。

与 certificate_chain 配合用于双向 TLS 认证的私钥。该私钥的公钥材料必须与 certificate_chain 中第一个证书的私钥匹配。

取值必须是一份以 DER base64(RFC4648)编码的 PEM 格式私钥,并必须符合 PKCS#8、PKCS#1 或 SECG1 规范之一。

引用规范:PKCS#8 见 RFC 5208,PKCS#1 见 RFC 8017,SECG1 见 RFC 5915,RFC4648 见 RFC 4648(此处仅给出规范名称,不展开外部链接)。

Server Buffers

配置中多个区域使用统一的 buffers 结构来配置 HTTP 服务器缓冲区,典型使用者包括 server 与 metrics telemetry 两个配置段。

buffers:
  read: 4096
  write: 4096

read

  • 类型:integer,默认 4096,非必填。

配置最大请求大小(单位为字节)。默认值 4096 对大多数场景已足够。

write

  • 类型:integer,默认 4096,非必填。

配置最大响应大小(单位为字节)。默认值 4096 对大多数场景已足够。

Server Timeouts

配置中多个区域使用统一的 timeouts 结构来配置 HTTP 服务器超时,典型使用者包括 server 与 metrics telemetry 两个配置段。

timeouts:
  read: '6s'
  write: '6s'
  idle: '30s'

read

  • 类型:string,integer,语法:duration,默认 6 秒,非必填。

配置服务器读取超时。注意其值必须遵循上文时长语法书写。

write

  • 类型:string,integer,语法:duration,默认 6 秒,非必填。

配置服务器写入超时。

idle

  • 类型:string,integer,语法:duration,默认 30 秒,非必填。

配置服务器空闲超时。

这三个字段的默认值 6s、6s、30s 是时长语法在真实配置中的典型应用——它们会被 DecodeTimeDuration 反序列化为 Go 的 time.Duration 并作用于底层 HTTP 服务器。

历史锚点(Historical References)

原文档末尾保留了对历史锚点的引用,其中 "Duration Notation Format" 一节即指向本文的时长语法小节,用于维持旧版文档链接的兼容性。

结语:把这些通用要素串起来

掌握 Authelia 的通用语法与数据结构后,你会发现整个配置体系的"公共词汇表"已经打通:

  • 任何"时长"类参数(超时、刷新间隔、会话有效期)都遵循 Duration 语法,底层由 internal/utils/time.go 与 internal/configuration/decode_hooks.go 负责归一化;
  • 任何"地址"类参数(监听端口、LDAP/SMTP 连接、unix socket)都遵循 Address 语法,底层由 internal/configuration/schema/types_address.go 负责解析,其中 tcp4/tcp6、ldap/ldaps/ldapi、smtp/submission/submissions 等 scheme 直接决定了连接的协议与默认端口;
  • 正则类参数必须使用 RE2 语法并以单引号书写,避免 YAML 转义破坏模式;
  • TLS、buffers、timeouts 三个结构作为"公共零件"被 server、metrics、LDAP、SMTP、存储等模块反复装配,配置一次即可理解多处。

当你需要为 Authelia 编写或排查配置时,先识别某个键属于哪一类通用语法/结构,再对照本文的格式与默认值进行书写,即可显著降低配置出错率。

登录后查看全文
authelia