caddy的Authelia认证-多用户多域名
Authelia 与 Caddy 联合部署运维笔记
一、 腾讯云 EdgeOne / 阿里云 ESA 回源 IP 穿透配置
1. 核心原理
为了防止 Authelia 的防暴力破解机制(Brute Force Protection)误将 CDN 边缘节点当成恶意攻击者进行封锁,同时为了确保安全审计日志能记录访问者的真实公网 IP,必须在 CDN 端开启真实 IP 携带,并在 Caddy 端配置信任代理。
2. CDN 端配置
- 腾讯云 EdgeOne:在“自定义回源 HTTP 请求头”中,添加规则。头部名称填写
X-Forwarded-For,头部取值选择“客户端真实 IP”。 - 阿里云 ESA:默认亦通过
X-Forwarded-For携带客户端真实 IP。
3. Caddyfile 安全信任配置
由于大厂 CDN 回源 IP 频繁变动且不完全公开,为保证高可用性并在 1核1G 服务器上保持轻量,在 Caddyfile 中推荐采用“全局块盲信 0.0.0.0/0 + 特定域名精准关闭”的隔离策略。
注意: 信任代理配置(trusted_proxies)控制网络底层解析,必须声明在最顶部的全局块中,不能直接写在单个站点块内。
{
# 1. 全局系统日志:仅记录 ERROR 及以上级别错误,降低 IO 与性能开销
log {
level ERROR
}
# 2. 全局信任代理:兼容并接收来自 CDN 节点的 X-Forwarded-For 头部
servers {
trusted_proxies static 0.0.0.0/0 ::/0
}
}
# 场景 A:走 CDN 加速并需要获取真实 IP 的站点(继承全局配置)
zaut.zhaopeng.site {
reverse_proxy authelia:9091
}
# 场景 B:走 CDN 加速且受到 Authelia 守卫保护的站点
ztools.zhaopeng.site {
forward_auth authelia:9091 {
uri /api/verify?rd=https://zaut.zhaopeng.site/
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
}
reverse_proxy 127.0.0.1:8080
}
direct.zhaopeng.site {
reverse_proxy 127.0.0.1:8000
}
二、 Caddyfile 安全运维与无缝重载
为了防止配置错误导致容器崩溃和全站瘫痪,严禁直接使用 podman restart caddy。必须采用“语法预检 + 内存热重载”的流线型操作。
1. 自动化判定与重载命令
podman exec -it caddy caddy validate --config /etc/caddy/Caddyfile && podman exec -it caddy caddy reload --config /etc/caddy/Caddyfile
- 机制说明:
&&逻辑与操作符确保只有当前面的validate成功通过语法核对(输出Valid configuration)时,才会触发后面的reload。 - 安全保证:
reload命令属于原子操作。即使新配置存在隐藏的逻辑冲突(如后端容器挂掉导致的连接失败),Caddy 也会中止加载并自动回滚,继续用内存中旧的、完好的配置运行,实现零停机时间(Zero Downtime)。
2. 终端快捷别名(Alias)设置
将该组合命令写入服务器环境,后续仅需输入 caddy-swap 即可安全重载:
echo "alias caddy-swap='podman exec -it caddy caddy validate --config /etc/caddy/Caddyfile && podman exec -it caddy caddy reload --config /etc/caddy/Caddyfile'" >> ~/.bashrc && source ~/.bashrc
三、 Authelia 用户管理(本地文件模式)
1. 生成加密密码
Authelia 禁止明文存储密码,必须使用内置的 Argon2id 算法生成哈希值:
podman exec -it authelia authelia crypto hash generate argon2 --password "你的明文密码"
执行后会输出一段以 $argon2id$ 开头的长字符串。
2. 写入 users_database.yml
打开挂载的用户配置文件,按如下格式规范追加:
users:
zhaopeng:
displayname: "Zhaopeng"
password: "$argon2id$v=19$m=65536,t=3,p=4$此处替换为生成的加密哈希值"
email: "your-email@example.com" # 必须是真实邮箱,用于接收二次验证(TOTP)的激活确认信
groups:
- admins
guest01:
displayname: "Guest"
password: "$argon2id$v=19$m=65536,t=3,p=4$此处替换为生成的加密哈希值"
email: "guest01@example.com"
groups:
- users
修改完成后,重启容器使配置生效:
podman restart authelia
四、 Authelia 权限控制(Access Control)核心逻辑
Authelia 中的 groups 标签(如 admins、users)本身没有内置特权,其对应的访问限制由 configuration.yml 中的 access_control 规则严格定义。
1. 精准匹配与“或(OR)”逻辑
在配置 subject 权限时,条件判断属于严格匹配。如果希望多个组同时拥有访问权限,必须使用多行并列的“或”逻辑书写。
2. 泛域名规则的声明顺序陷阱
Authelia 的规则链条是自上而下执行的,一旦匹配成功便就地熔断,不再向下审计。因此,精准域名的限制规则必须写在泛域名规则之上。
access_control:
default_policy: deny # 默认拒绝所有人
rules:
# 1. 敏感后台:必须最靠前。仅限管理员,且必须双因子(密码+二级验证码)
- domain: "ztools.zhaopeng.site"
policy: two_factor
subject:
- ["group:admins"]
# 2. 普通应用:仅限特定组。单因子(输入密码即可)
- domain: "dh.zhaopeng.site"
policy: one_factor
subject:
- ["group:users"] # 警告:若不在此处并列写入 group:admins,则管理员也将无法访问此页面
# 3. 泛域名兜底:必须放在最底部。作为垃圾回收网,拦截所有未声明的子域名
- domain: "*.zhaopeng.site"
policy: one_factor
subject:
- ["group:admins"]
- ["group:users"] # 并列写法,代表 admins 组或 users 组的成员都可以登录
自己写的,测试,用户组的用户控制访问哪个网站,不在组里的话打开会403,同一个用户一次google验证就能登录users组的其他网站
access_control:
default_policy: 'deny'
rules:
- domain: "noco.zhaopeng.site"
policy: 'one_factor'
subject:
- ["group:users"]
- domain: "ztools.zhaopeng.site"
policy: 'one_factor'
subject:
- ["group:users"]
- domain: 'zaut.zhaopeng.site' # 换成你自己的域名
policy: 'two_factor'
subject:
- ["group:admins"]
- domain: 'zaut.baidaoya.site' # 换成你自己的域名
policy: 'two_factor'
subject:
- ["group:admins"]如果你在 Authelia 的 access_control 规则中**只配置了 domain 和 policy,而完全不配置 subject**,那么这条规则的含义会发生根本性的改变。
不写 subject 意味着解除用户组限制,只要能通过身份验证,任何人都可以访问。
具体表现取决于你为该规则配置的 policy(认证策略):
🧭 两种典型配置下的实际效果
1. 当 policy: one_factor(单因子认证)且不写 subject
- domain: "dh.zhaopeng.site"
policy: one_factor
- 实际效果:只要是你的 Authelia 数据库(
users_database.yml)里存在的用户,无论他属于哪个组(无论是admins、users还是你随便创建的其他组),只要输入正确的账号密码,就全部能够成功登录并访问该网站。
2. 当 policy: two_factor(双因子认证)且不写 subject
- domain: "ztools.zhaopeng.site"
policy: two_factor
- 实际效果:任何在数据库中的合法用户,只要完成了【第一步:输入密码】以及【第二步:通过谷歌验证码(TOTP)/ 邮件确认】,都可以进入该网站。同样不再审查用户所属的组。
🎯 总结与安全建议
不配置 subject 相当于开启了“只要是合法账号一律放行”的广播模式。
- 什么时候可以不写?
如果你搭建的是一个纯私人的服务器,整个 Authelia 里面只有你自己的这一个账号,没有其他亲友或协同开发人员。此时不写subject是完全可以的,因为能通过密码和验证码的只有你一个人,不写可以精简配置文件。 - 什么时候必须写?
只要你的 Authelia 里面存在第二个人的账号(比如你给朋友或者合作者开了一个受限账号),你就必须在敏感域名的规则下精准写上subject: - ["group:admins"]。否则,哪怕他们只是普通用户,也能够通过自己的账号登录进你的核心工具箱(如ztools.zhaopeng.site)。