Authelia + Nginx 集成问题排查总结

Authelia + Nginx 集成问题排查总结 背景 本文记录了将 Authelia 与 Nginx 集成,保护 rclone Web UI 过程中遇到的所有问题及解决方法。 问题一:用户名理解错误 现象 输入用户名登录时提示 user not found。

Authelia + Nginx 集成问题排查总结

背景

本文记录了将 Authelia 与 Nginx 集成,保护 rclone Web UI 过程中遇到的所有问题及解决方法。


问题一:用户名理解错误

现象

输入用户名登录时提示 user not found

原因

users_database.yml 里的 displayname 不是登录用户名,yaml 的 key 才是。

users:
  admint:              # ← 这才是登录用户名
    displayname: "admint"  # ← 这只是显示名,不用于登录
    password: "..."

解决

登录时输入 yaml key,不是 displayname。


问题二:用户被禁用

现象

用户名密码正确但无法登录。

原因

官方初始模板里用户默认 disabled: true

users:
  admint:
    disabled: true  # ← 初始模板默认禁用

解决

改为 disabled: false


问题三:remember_me_duration 字段废弃

现象

Authelia 启动报错:configuration key not expected: session.cookies[].remember_me_duration

原因

新版(4.38+)将 remember_me_duration 改名为 remember_me

解决

# 旧版(废弃)
cookies:
  - remember_me_duration: '1M'

# 新版
cookies:
  - remember_me: '1 month'

问题四:default_redirection_url 不能与 authelia_url 相同

现象

Authelia 启动报错:option 'default_redirection_url' is effectively equal to option 'authelia_url' which is not permitted

原因

cookies 里的 default_redirection_url 必须指向非 Authelia 的地址。

解决

cookies:
  - authelia_url: 'https://auth.example.com'
    default_redirection_url: 'https://tool.example.com'  # 不能和 authelia_url 相同

现象

已登录状态下访问受保护资源,仍然被 302 重定向到登录页。

原因

Nginx 的 proxy_set_header 有一个继承规则:

一旦在某个配置块里写了任何一条 proxy_set_header,Nginx 就停止自动继承父级 Header,只传手动声明的那些。

官方的 proxy.conf 里包含大量 proxy_set_header 指令,打断了默认的 Cookie 继承。而官方的 authelia-location.conf 里没有补上 Cookie,导致子请求发给 Authelia 时没有携带 authelia_session cookie,Authelia 每次都认为是未登录用户。

用户请求 /rcl/core/stats
    │
    ▼
Nginx 发起 auth_request 子请求
    │
    proxy.conf 里有 proxy_set_header → 继承被打断 → Cookie 丢失
    │
    ▼
Authelia 收到子请求,没有 cookie → 返回 401
    │
    ▼
Nginx error_page 401 → 302 重定向到登录页

解决

authelia-location.conf 里手动补上 Cookie 转发:

location /internal/authelia/authz {
    internal;
    proxy_pass $upstream_authelia;
    proxy_set_header X-Original-Method $request_method;
    proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Cookie $http_cookie;  # 补上这行
    proxy_set_header Authorization "";     # 见问题六
    proxy_set_header Content-Length "";
    proxy_set_header Connection "";
    proxy_pass_request_body off;
    ...
}

备注

这是官方配置的疏漏,proxy.confauthelia-location.conf 组合使用时存在问题,官方未考虑到两个文件的副作用。


问题六:Nginx 注入的 Basic Auth 被 Authelia 误用

现象

Authelia 日志报错:failed to validate the credentials of user 'admin' parsed from the Authorization header: user not found

原因

Authelia 的 auth-request 端点会同时检查 Cookie 和 Authorization Header,两者都可以用来鉴权。

Nginx 为了让 rclone 放行,在请求里注入了 Authorization: Basic xxx(rclone 的用户名密码)。这个 Header 被子请求带到了 Authelia,Authelia 优先用它来鉴权,但 rclone 的用户名在 Authelia 里不存在,导致认证失败。

Nginx 注入 Authorization: Basic admin:password(rclone 凭据)
    │
    ▼
子请求带上这个 Header 发给 Authelia
    │
    ▼
Authelia 用 admin:password 查找用户 → user not found → 401

解决

authelia-location.conf 的子请求里清空 Authorization Header,让 Authelia 只用 Cookie 鉴权:

location /internal/authelia/authz {
    ...
    proxy_set_header Authorization "";  # 清空,不让 rclone 的凭据传给 Authelia
    proxy_set_header Cookie $http_cookie;
    ...
}

rclone 的 Basic Auth 只在转发给后端时注入,与鉴权子请求完全隔离:

location /rcl/ {
    include /etc/nginx/snippets-authelia.d/authelia-authrequest.conf;
    proxy_set_header Authorization "Basic xxx";  # 只在这里注入,不影响子请求
    proxy_pass http://127.0.0.1:5572/;
}

最终工作配置

架构

用户
  │
  ▼
Nginx
  ├─ auth_request → /internal/authelia/authz
  │       │
  │       ├─ 带 Cookie(authelia_session)
  │       ├─ 不带 Authorization(清空)
  │       │
  │       ▼
  │   Authelia 验证 Cookie → 200 放行 / 401 重定向
  │
  └─ 验证通过后
      │
      ├─ 注入 Authorization: Basic xxx(rclone/Kopia 凭据)
      │
      ▼
    下游服务(rclone / Kopia)

authelia-location.conf 关键修改

location /internal/authelia/authz {
    internal;
    proxy_pass $upstream_authelia;
    proxy_set_header X-Original-Method $request_method;
    proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Cookie $http_cookie;   # 必须手动加
    proxy_set_header Authorization "";      # 必须清空
    proxy_set_header Content-Length "";
    proxy_set_header Connection "";
    proxy_pass_request_body off;
}

Nginx location 配置

location /rcl/ {
    include /etc/nginx/snippets-authelia.d/proxy.conf;
    include /etc/nginx/snippets-authelia.d/authelia-authrequest.conf;
    proxy_set_header Authorization "Basic <base64(user:password)>";
    proxy_pass http://127.0.0.1:5572/;
}

核心教训

auth_request 子请求和转发给后端的请求必须严格隔离:

  • 子请求只传 Cookie 和原始请求元信息

  • 不传 Authorization Header(清空)

  • 后端凭据只在转发请求里注入

LICENSED UNDER CC BY-NC-SA 4.0
评论