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 标签(如 adminsusers)本身没有内置特权,其对应的访问限制由 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 规则中**只配置了 domainpolicy,而完全不配置 subject**,那么这条规则的含义会发生根本性的改变。

不写 subject 意味着解除用户组限制,只要能通过身份验证,任何人都可以访问

具体表现取决于你为该规则配置的 policy(认证策略):


🧭 两种典型配置下的实际效果

1. 当 policy: one_factor(单因子认证)且不写 subject

- domain: "dh.zhaopeng.site"
  policy: one_factor
  • 实际效果:只要是你的 Authelia 数据库(users_database.yml)里存在的用户,无论他属于哪个组(无论是 adminsusers 还是你随便创建的其他组),只要输入正确的账号密码,就全部能够成功登录并访问该网站。

2. 当 policy: two_factor(双因子认证)且不写 subject

- domain: "ztools.zhaopeng.site"
  policy: two_factor
  • 实际效果:任何在数据库中的合法用户,只要完成了【第一步:输入密码】以及【第二步:通过谷歌验证码(TOTP)/ 邮件确认】,都可以进入该网站。同样不再审查用户所属的组。

🎯 总结与安全建议

不配置 subject 相当于开启了“只要是合法账号一律放行”的广播模式。

  • 什么时候可以不写?
    如果你搭建的是一个纯私人的服务器,整个 Authelia 里面只有你自己的这一个账号,没有其他亲友或协同开发人员。此时不写 subject 是完全可以的,因为能通过密码和验证码的只有你一个人,不写可以精简配置文件。
  • 什么时候必须写?
    只要你的 Authelia 里面存在第二个人的账号(比如你给朋友或者合作者开了一个受限账号),你就必须在敏感域名的规则下精准写上 subject: - ["group:admins"]。否则,哪怕他们只是普通用户,也能够通过自己的账号登录进你的核心工具箱(如 ztools.zhaopeng.site)。

标签: none

添加新评论