Authelia 配置通用语法与数据结构完全指南:Duration、Address、TLS 与 Server Buffers 深度解析
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 编写或排查配置时,先识别某个键属于哪一类通用语法/结构,再对照本文的格式与默认值进行书写,即可显著降低配置出错率。