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 目录下创建以下两个核心配置文件。

  1. **创建主配置文件 configuration.yml**

    touch /data/auth/configuration.yml
    

(注:具体内容见下文“2.1 主配置文件模板”)

  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 进行数学签名。
  • 安全保障:每次你访问 zpiczblog 时,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...

步骤二:修改配置文件

  1. 编辑 users_database.yml 文件。
  2. 将对应用户下的 password 字段替换为刚才复制的新哈希字符串并保存。
  3. 由于在 configuration.yml 中开启了 watch: true,Authelia 会在几秒钟内自动热加载,无需手动重启容器。

5. 双因子认证(2FA)优化方案

在 Authelia 中,验证器(Google Authenticator / Microsoft Authenticator 等生成的 6 位一次性动态验证码 TOTP)不能独立用于免密登录。因为 TOTP 动态码本身不包含用户名等身份信息,登录时必须先输入用户名和密码。

你可以根据使用习惯对双因子认证进行以下优化:

方案 A:配置单因子登录(仅密码登录)

如果你想关闭两步验证,直接输入账号密码便进入相册:

  1. 编辑 Authelia 的主配置文件 configuration.yml
  2. 将安全规则中的 policy 修改为 one_factor

    access_control:
      default_policy: deny
      rules:
     - domain: "*.zhaopeng.site"
       policy: one_factor  # one_factor 表示仅密码验证即可放行
    
  3. 保存并重启容器:

    podman restart authelia
    

方案 B:保持安全且免去频繁输入(延长会话时间)

如果你想保留两步验证,但延长 Session 保持时间(最长保持 30 天免登录),可以直接沿用 2.1 节中已经调整完毕的 session 参数(inactivity: 604800expiration: 2592000 以及开启 remember_me: 30d)。并在登录页面勾选 “记住我 (Remember Me)” 选项。

标签: none

添加新评论