caddy的Authelia认证
Authelia 统一认证与 Lychee 荔枝相册联调部署笔记
部署方案概述
为了防止 Authelia 在进行前置认证(forward_auth)时因无差别拦截其自身的静态资源或 API 而导致重定向死循环,必须将 认证中心 与 应用服务 分离到不同的子域名下:
zpic.zhaopeng.site:受保护的荔枝相册应用。zauth.zhaopeng.site:Authelia 认证控制台,专用于用户登录和两步验证。
通过根域名 zhaopeng.site 共享 Session Cookie,用户在 zauth 登录成功后即可无缝访问 zpic。
1. 容器部署与启动步骤
1.1 创建持久化目录
在服务器上创建用于存放 Authelia 配置和用户数据的目录:
mkdir -p /data/auth
1.2 准备核心随机密钥
在配置 configuration.yml 之前,需要为 Authelia 生成三个安全的随机密钥。请在终端运行以下命令并记录输出:
# 生成 JWT Secret、Session Secret 和 Storage Encryption Key
podman run --rm authelia/authelia:latest authelia crypto rand alphanumeric --length 64
请运行此命令三次,分别获取三个不同的随机字符串,用于后续填写到主配置文件中。
1.3 初始化配置文件
在 /data/auth 目录下创建以下两个核心配置文件。
**创建主配置文件
configuration.yml**:touch /data/auth/configuration.yml
(注:具体内容见下文“2.1 主配置文件模板”)
**创建用户数据库文件
users_database.yml**:touch /data/auth/users_database.yml
(注:具体内容见下文“2.2 用户数据库模板”)
1.4 使用 Podman 启动容器
运行以下命令启动 Authelia 容器。该命令会将宿主机的 /data/auth 目录挂载到容器内,并将其时区设置为北京时间:
podman run -d \
--name authelia \
--restart always \
-p 9091:9091 \
-v /data/auth:/config \
-e TZ=Asia/Shanghai \
authelia/authelia:latest
2. 核心配置文件
2.1 主配置文件 configuration.yml
这是精简且优化后的主配置文件。请根据其中注释的指引,替换你在 1.2 节中生成的密钥。
theme: light
server:
address: 'tcp://0.0.0.0:9091'
buffers:
read: 4096
write: 4096
log:
level: info
format: text
# 1. 核心加密密钥(请替换为你自己生成的随机字符串)
jwt_secret: '这里替换为1.2步骤中生成的第一个64位随机字符串'
# 2. 身份验证提供者(使用本地 YAML 文件)
authentication_backend:
file:
path: /config/users_database.yml
watch: true # 监控文件变化,修改密码或用户后无需重启容器即可生效
password:
algorithm: argon2
argon2:
variant: id
iterations: 3
memory: 65536
parallelism: 4
# 3. Session 会话控制与 Cookie 作用域
session:
name: authelia_session
same_site: lax
expiration: 2592000 # 绝对过期时间:30天(30 * 24 * 3600 秒)
inactivity: 604800 # 未活动超时时间:7天(7 * 24 * 3600 秒)
remember_me: 30d # 允许用户在登录页勾选“记住我”,保持最长30天免登录
secret: '这里替换为1.2步骤中生成的第二个64位随机字符串'
# 注意:在多子域名共享 Session 架构中,顶级层绝不能配置 domain 参数(即不能出现 session.domain)
# 必须统一写在下面的 cookies 列表块内,否则会触发启动冲突
cookies:
- domain: "zhaopeng.site" # 扩大作用域至根域名,实现多子域名共享登录态
authelia_url: "https://zauth.zhaopeng.site" # 认证控制台的实际访问地址
default_redirection_url: "https://zpic.zhaopeng.site" # 登录成功后的默认跳转目标
# 4. 存储配置(保存2FA绑定关系和认证状态)
storage:
local:
path: /config/db.sqlite3
encryption_key: '这里替换为1.2步骤中生成的第三个64位随机字符串'
# 5. 2FA 一次性密码生成器配置
totp:
issuer: authelia.com
period: 30
skew: 1
# 6. 邮件配置(使用本地文件存储,不占用 SMTP 发信通道,免于复杂的发信配置)
notifier:
filesystem:
filename: /config/notification.txt
# 7. 访问控制策略
access_control:
default_policy: deny # 默认拒绝所有没有明确匹配到规则的访问
rules:
# 保护 zhaopeng.site 旗下所有子域名(包括 zpic.zhaopeng.site)
- domain: "*.zhaopeng.site"
policy: two_factor # two_factor 表示需要“密码 + Google验证器”双重验证。若只需密码,请改为 one_factor
2.2 用户数据库配置文件 users_database.yml
该文件用于定义能够登录系统的用户账号、密码及邮箱。
# 本地用户数据库
users:
zhaopeng: # 👈 登录时需要输入的“用户名”
displayname: "Zhaopeng"
password: "$argon2id$v=19$m=65536,t=3,p=4$qOKNq+u5lZHOTnsJY..." # 👈 必须填入加密后的 Argon2 哈希值,不可填明文密码
email: zhaopeng@example.com # 👈 即使是假邮箱也不影响普通登录;若未配置真实的 SMTP 发信,可保持默认
groups:
- admins
- users
2.3 Authelia配置文件 podman-compose.yml
services:
authelia:
image: docker.1ms.run/authelia/authelia:latest
container_name: authelia
restart: on-failure
logging:
driver: none
volumes:
- /data/auth:/config
# 限制 1核1G 环境下的资源占用上限,防止意外爆内存
deploy:
resources:
limits:
memory: 100M
environment:
- AUTHELIA_STORAGE_ENCRYPTION_KEY=97ce8ed54290c8b82e6cbfcf7dcdaaaa
- AUTHELIA_SESSION_SECRET=f36b50f3a620486fac0c7072e5cdaaaa
- AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET=659cb0405fb777ebae013026c0a7aaaa
- TZ=Asia/Shanghai
networks:
- znet
networks:
znet:
external: true
1. AUTHELIA_STORAGE_ENCRYPTION_KEY
- 中文名称:存储加密密钥
- 作用对象:你的本地数据库文件
db.sqlite3 - 具体用途:
Authelia 需要在数据库中保存一些敏感信息,例如你为 Google 验证器绑定的 2FA 密钥(TOTP Secret)、WebAuthn 设备数据等。 - 如果没有它:如果黑客拿到了你的
db.sqlite3文件,就能直接读出你的两步验证密钥,从而克隆出你的 Google 验证器动态码。 - 有了它:Authelia 会使用这个密钥对数据库中的所有敏感字段进行高强度加密。即使
db.sqlite3文件泄漏,没有这个密钥,里面的数据也只是一堆无法破译的乱码。
2. AUTHELIA_SESSION_SECRET
- 中文名称:会话加密密钥
- 作用对象:用户浏览器中的 Cookie
- 具体用途:
用来给发放给浏览器的 Session Cookie(会话凭证) 进行签名和加密。 - 工作原理:当你登录成功后,Authelia 会在你的浏览器里存入一个代表“已登录”的 Cookie。为了防止你或黑客在浏览器中恶意修改这个 Cookie(比如把用户名从
zhaopeng伪造成管理员admin),Authelia 会用这个SESSION_SECRET对 Cookie 进行数学签名。 - 安全保障:每次你访问
zpic或zblog时,Authelia 都会用这个密钥去验算 Cookie 的签名。一旦发现 Cookie 被篡改,或者密钥不匹配,就会立即强制你重新登录。
3. AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET
- 中文名称:重置密码/身份验证 JWT 密钥
- 作用对象:一次性临时验证链接(JWT 令牌)
- 具体用途:
用于生成和验证重置密码或注册 2FA 设备时发送给你的临时安全链接。 - 工作原理:当你在网页上申请“重置密码”或“绑定新验证器”时,Authelia 会生成一个短时间内有效的、包含你身份信息的 JWT(JSON Web Token)链接,写入到
notification.txt(或发到邮箱)。 - 安全保障:这个链接必须使用此
JWT_SECRET进行签名。当你在浏览器中点击该链接时,Authelia 会用该密钥验证这个链接是否由它本人颁发、是否在有效期内、以及是否被篡改。这能彻底防止黑客伪造重置密码的请求。
3. Caddyfile 配置
修改 Caddy 的配置文件,正确定义这两个子域名的行为:
# (zbb) 全局安全响应头及日志配置片段
(zbb) {
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY
X-XSS-Protection "1; mode=block"
}
encode gzip zstd
log {
format console
level ERROR
}
}
# 1. 专门用于 Authelia 认证中心的子域名(绝对不能配置 forward_auth)
zauth.zhaopeng.site {
import zbb
reverse_proxy authelia:9091
}
# 2. 荔枝相册服务域名(受 Authelia 保护)
zpic.zhaopeng.site {
import zbb
# 启用前置认证
forward_auth authelia:9091 {
# 重定向参数 rd 必须直接拼接到 uri 后面,Caddyfile 不支持单独的 query 子指令
uri /api/authz/forward-auth?rd=https://zauth.zhaopeng.site/
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
}
# 认证通过后,反向代理到相册容器
reverse_proxy lychee:80 {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
4. 用户密码生成与管理
Authelia 使用文件存储管理本地用户凭据。当你需要初始化密码、或者忘记密码时,请使用以下步骤安全生成哈希。
步骤一:生成新密码哈希
在宿主机运行以下命令,使用一次性容器生成基于 Argon2 算法的密码哈希值(以新密码 abcd12345 为例):
podman run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'abcd12345'
系统会输出一串加密哈希,请将其完整复制:
$argon2id$v=19$m=65536,t=3,p=4$qOKNq+u5lZHOTnsJY...
步骤二:修改配置文件
- 编辑
users_database.yml文件。 - 将对应用户下的
password字段替换为刚才复制的新哈希字符串并保存。 - 由于在
configuration.yml中开启了watch: true,Authelia 会在几秒钟内自动热加载,无需手动重启容器。
5. 双因子认证(2FA)优化方案
在 Authelia 中,验证器(Google Authenticator / Microsoft Authenticator 等生成的 6 位一次性动态验证码 TOTP)不能独立用于免密登录。因为 TOTP 动态码本身不包含用户名等身份信息,登录时必须先输入用户名和密码。
你可以根据使用习惯对双因子认证进行以下优化:
方案 A:配置单因子登录(仅密码登录)
如果你想关闭两步验证,直接输入账号密码便进入相册:
- 编辑 Authelia 的主配置文件
configuration.yml。 将安全规则中的
policy修改为one_factor:access_control: default_policy: deny rules: - domain: "*.zhaopeng.site" policy: one_factor # one_factor 表示仅密码验证即可放行保存并重启容器:
podman restart authelia
方案 B:保持安全且免去频繁输入(延长会话时间)
如果你想保留两步验证,但延长 Session 保持时间(最长保持 30 天免登录),可以直接沿用 2.1 节中已经调整完毕的 session 参数(inactivity: 604800,expiration: 2592000 以及开启 remember_me: 30d)。并在登录页面勾选 “记住我 (Remember Me)” 选项。