Authelia的学习
官网网站: Authelia | The Single Sign-On Multi-Factor portal for web apps
Github网站: authelia/authelia: The Single Sign-On Multi-Factor portal for web apps (github.com)
`部署过程踩了很多坑,由于英文水平有限,所以看官方文档稍微有点费力,过程中基本上是按照官方文档来的,如果有不清楚的地方,可以查阅原版文档
1.Authelia 介绍
Authelia 是一个开源身份验证和授权服务器和门户,通过 Web 门户为您的应用程序提供多因素身份验证和单点登录 (SSO),履行信息安全的身份和访问管理 (IAM) 角色。它充当常见反向代理的伴侣
1.1 Authelia 特点
1.轻 ????
压缩容器大小小于 20 MB,观察到的内存使用量通常低于 30 MB,是可用的最轻量级解决方案之一
2.极速 ⚡
使用 Go 和 React 编写的授权策略和许多其他后端任务只需几毫秒即可完成,登录门户加载时间为 100 毫秒,使其成为可用的最快解决方案之一
3.有效 ♻
处理器可以使用大量电力,但是当空闲使用率基本上低到您无法测量时,并且在小型企业环境中的活跃使用率低于 1%,您可以高枕无忧(不包括密码哈希)。
4.安全设计 ????
安全性不仅仅是另一个 IAM 门户,也是我们设计过程的重要组成部分
5.登录规定 ????️
通过在用户被锁定一段时间之前仅允许一定数量的登录来防止暴力登录尝试
6.密码重置 ????
内置支持用户直接从 Web 界面通过电子邮件验证重置其 LDAP 或内部密码
7.单点登录 ????️
让您的用户只需通过会话 Cookie、OpenID Connect 1.0 或受信任的标头登录一次即可方便地访问各种 Web 应用程序
8.授权策略 ????
通过极其精细的策略定义控制哪些用户和组有权访问哪些特定资源或域
9.身份验证✔
未配置第二因素设备的用户需要通过电子邮件验证其身份,从而减少攻击者利用懒惰用户的机会
10.可扩展性 ⚙
在设计时考虑到了高可用性,部署选项可轻松允许在 Kubernetes 等生命周期管理平台上使用多个并行容器
11.多重身份验证 ????️
支持多种第二因素方法,包括一次性密码、移动推送通知和 WebAuthn
12.直观的用户界面 ????
登录门户非常简单,工作流程对您的用户完全透明
2.Authelia开始使用
2.1 入门指南
前提条件:
最重要的前提是用户需要理解,并没有单一的方法来部署类似于Authelia的软件。我们提供了尽可能多的信息来帮助用户配置关键部分,通常是在最常见的场景下。然而,对于使用更高级架构的用户来说,可能需要进行一些调整。我们一般可以帮助解答关于此的一些非具体问题,如果提供了足够的信息,也可能回答更具体的问题
Authelia 必须通过 HTTPS 方案提供服务。这不仅适用于正式环境,在测试环境中也是如此。这是一个有意为之的设计决定,旨在直接通过加密通信提升安全性,并间接地通过减少复杂性来增强系统安全。
转发认证(Forwarded Authentication)
转发认证是一种简单的按请求授权流程,它通过检查请求的元数据和会话cookie来确定用户是否需要被重定向到认证门户。
除了对 Authelia 自身的 HTTPS 要求之外:
由于使用了cookie,因此所有通过这种方法保护的应用程序/域名必须使用安全的方案(HTTPS 和 WSS)来进行所有的通信。这是出于设计上的考虑,以保证数据传输的安全性
OpenID Connect 1.0
除了要求 Authelia 使用 HTTPS 外,没有其他额外的要求,除非是由相关规范强制规定的
重要说明
以下部分包含了一些用户开始使用时需要了解的一般重要说明
当将 Authelia 与代理集成时,用户应阅读特定的代理集成重要说明 (Proxies | Integration | Authelia)
文档变量
文档中展示的一些值可以自动替换为文档变量
Get started | Integration | Authelia
配置
在部署 Authelia 之前,定制配置是非常重要的。配置文件是静态的,并不是通过 Web GUI 进行配置的。您可以在 GitHub 上找到一个名为 config.template.yml
的配置模板,这个模板可以作为配置的基础;或者,当第一次启动 Authelia 时,它会根据您的版本写入相应的模板文件。用户应该预期到他们需要在初始设置时配置该文件中的某些元素。
初始配置时需要考虑的重要部分如下:
-
jwt_secret
:如果启用了密码重置功能,此密钥用于签署身份验证电子邮件 -
authentication_backend
:您需要选择 LDAP 或 YAML 文件作为后端,这对于用户的认证是必要的 -
storage
:您需要选择存储提供商,对于测试和轻量级部署推荐使用 SQLite3,而对于生产环境则推荐使用 PostgreSQL -
session:用于配置:
- 会话cookie部分应针对每个要保护的单点登录(SSO)域进行配置(这些域不能相互成为后缀),其中最重要的选项是
domain
和authelia_url
- 密钥是最关键的部分,对于生产环境推荐使用 Redis
- 会话cookie部分应针对每个要保护的单点登录(SSO)域进行配置(这些域不能相互成为后缀),其中最重要的选项是
-
notifier
:用于发送双因素认证(2FA)注册邮件等,虽然有本地文件传送的选项,但在生产环境中推荐使用 SMTP,并且只能配置其中一种 -
access_control
:同样重要,但最初应该只配置一个非常基础的策略。例如:`configuration.yaml access_control: default_policy: deny rules: - domain: '*.example.com' policy: one_factor
部署
部署 Authelia 的方法有多种,我们建议您阅读部署文档以执行部署
代理集成
使用 Authelia 的默认方法是通过代理集成。它 建议您阅读相关的 代理集成文档
重要提示
当您的 Deployment 在 Kubernetes 上时,我们会 建议先查看专用的 Kubernetes 文档,然后再查看代理集成文档。
其他有用的链接
请参阅 常见问题 ,了解 文档,该文档可能会回答特定问题。
迁移到生产环境
我们认为,在迁移到生产环境时,做几件事很重要
- 将所有密钥值移出配置,然后 变成秘密
- 花时间了解访问控制并对其进行精细配置 根据您的要求
- 查看 Security Measures and Threat Model 文档
- 确保您已查看 转发报头 文档,以确保您的 proxy 不允许将不安全的标头传递给 Authelia
- 查看其他 Configuration Options
2.2 部署
部署Authelia有三种主要方法
- Docker
- 非捆绑示例
- 捆绑包:lite
- 捆绑包:本地
- Kuberntetes
- 裸机
2.2.1 使用Docker 进行部署
本次部署使用Bundle:lite版本,基本上就是按照提供的docker-compose文件进行部署
1.克隆相关git存储库
# mkdir /root/Authelia
# cd /root/Authelia
# git clone https://github.com/authelia/authelia.git
2.下载authelia命令工具
Github下载链接: https://github.com/authelia/authelia/releases/tag/v4.38.10
# tar -xf authelia-v4.38.10-linux-amd64.tar.gz -C /root/Authelia
# chmod +x authelia-linux-amd64
# cp authelia-linux-amd64 /usr/bin
# authelia --help # 查看帮助信息
3.了解相关配置信息
# cd /root/Authelia/authelia/examples/compose/lite/authelia
users_database.yml
----> 存储用户密码文件
默认密码使用 Argon2
哈希算法进行加密
users:
authelia:
disabled: false # 是否失效
displayname: "Authelia User" # 显示名称
# Password is authelia
password: "$6$rounds=50000$BpLnfgDsc2WD8F2q$Zis.ixdg9s/UOJYrs56b5QEZFiZECu0qZVNsIYxBaNJ7ucIL.nlxVCT5tqh8KHG8X4tlwCFm5r6NTOZZ5qRFN/" # 使用某种加密算法后得出的密码, 解密后为: authelia
email: authelia@authelia.com # 邮箱
groups: # 所属组, 管理组和开发组
- admins
- dev
如果想新增用户,就只需要在user字段后新增用户信息
哈希使用的算法可通过其前缀进行识别:
算法 | 变体 | 前缀 |
---|---|---|
Argon2 | argon2id |
$argon2id$ |
Argon2 | argon2i |
$argon2i$ |
Argon2 | argon2d |
$argon2d$ |
Scrypt | 不适用 | $scrypt$ |
PBKDF2 | sha1 |
$pbkdf2$ |
PBKDF2 | sha224 |
$pbkdf2-sha224$ |
PBKDF2 | sha256 |
$pbkdf2-sha256$ |
PBKDF2 | sha384 |
$pbkdf2-sha384$ |
PBKDF2 | sha512 |
$pbkdf2-sha512$ |
SHA2 Crypt | SHA256 |
$5$ |
SHA2 Crypt | SHA512 |
$6$ |
Bcrypt | standard |
$2b$ |
Bcrypt | sha256 |
$bcrypt-sha256$ |
configuration.yml
—> 核心配置文件
server:
address: 'tcp://:9091' # 这个字段指定了服务器监听网络连接的地址和端口。这里的tcp://:9091意味着服务将在TCP协议上监听所有可用网络接口上的9091端口
log:
level: 'debug' # 日志记录等级
totp:
issuer: 'authelia.com' # 这里指定了时间基于一次性密码(TOTP)认证的发行者名称。在两步验证(2FA)中,发行者的名字会显示在用户的认证应用(如Google Authenticator)中,以帮助用户识别该条目对应的是哪个服务或应用
identity_validation:
reset_password:
jwt_secret: 'SohXnuGDLnHaPKb6vx77LAXC' # 这是一个用于生成JSON Web Tokens (JWT)的秘密密钥,特别用于重置密码的过程。JWT是一种紧凑的、URL安全的机制,用于作为主体之间进行安全的信息交换。这个秘密密钥应该保密,因为它用于签名JWT,防止令牌被篡改。任何知道这个密钥的人都可以生成有效的JWT,从而可能危及系统的安全性。因此,选择一个强随机字符串作为密钥非常重要,并且不应该在公开的地方暴露此密钥。
authentication_backend: # 指定了用于验证用户身份的方法。这里使用的是文件后端
file:
path: '/config/users_database.yml' # 用户数据库文件的路径。在这个例子中,用户信息存储在/config/users_database.yml文件中
access_control:
default_policy: 'deny' # 默认访问控制策略,当没有特定规则匹配时生效。在这个例子中,默认策略是拒绝访问(deny)
rules: # 定义了一系列访问控制规则。每个规则指定一个域(domain)和 相应的策略(policy)
- domain: 'public.example.com'
policy: 'bypass' # 意味着不需要任何形式的身份验证就可以访问
- domain: 'traefik.example.com'
policy: 'one_factor' # 意味着只需要通过用户名和密码这类单一因素的身份验证即可访问
- domain: 'secure.example.com'
policy: 'two_factor' # 意味着需要两步验证才能访问
session:
# 用于加密会话cookie的密钥。这个密钥应当保持机密,确保只有授权的服务能够解密会话信息。
secret: 'SohXnuGDLnHaPKb6vx77LAXC'
cookies: # 描述了会话cookie的详细信息
- name: 'authelia_session' # cookie的名称,在这个例子中是authelia_session
domain: 'example.com' # cookie可见的域。这里设置为example.com,意味着cookie只会在这个域下可见
authelia_url: 'https://authelia.example.com' # Authelia服务的URL,用于回调和其他相关操作。
expiration: '1 hour' # cookie的有效期。在这个例子中,设置为1小时
inactivity: '5 minutes' # 在无活动期间之后,会话将过期的时间。在这个例子中,设置为5分钟。这意味着如果用户在5分钟内没有任何操作,则会话将自动结束
redis: # 存储会话信息
host: 'redis' # 指定Redis服务器的地址
port: '6379' # 指定服务器端口
# password : authelia # 指定Redis服务器密码, 可以使用环境变量进行指定, 可选参数
regulation:
max_retries: 3 # 允许的最大失败登录尝试次数。超过这个次数后,系统可能会采取措施,例如暂时禁止登录
find_time: '2 minutes' # 在这个时间段内计算失败登录尝试次数。例如,如果设置为2分钟,那么在这2分钟内的所有失败登录都将被累计计算
ban_time: '5 minutes' # 如果达到最大失败登录尝试次数后,用户账户将会被锁定的时间长度。在这个例子中,如果用户连续三次尝试登录失败,则会被禁止登录5分钟
storage:
encryption_key: 'SohXnuGDLnHaPKb6vx77LAXC' # 用于加密存储数据的秘密密钥。这通常是用来保护敏感数据不被未经授权的访问
local: # 表示数据存储的位置是本地文件系统
path: '/config/db.sqlite3' # 存储文件的具体路径。在这个例子中,数据将被保存在/config/db.sqlite3这个文件中
notifier: # 这是 Authelia 的通知器配置部分。通知器负责处理所有与通知相关的任务,比如发送电子邮件或者其他形式的通知
disable_startup_check: false # 这个选项用来控制 Authelia 在启动时是否禁用启动检查。如果设置为 false,则 Authelia 会在启动时执行一些健康检查来确保一切配置都是正确的。如果设置为 true,则会跳过这些检查。通常情况下,建议保持为 false,以确保启动时可以捕捉到配置错误
filesystem: # 这是文件系统通知器的配置部分。文件系统通知器允许 Authelia 将通知写入到指定的文件中,而不是通过电子邮件或其他方式发送。这对于测试环境或不需要实际发送通知的情况非常有用。
filename: /config/notification.txt # 这个选项指定了文件系统通知器将要写入通知的文件位置。在这个例子中,所有的通知将会被记录到 /config/notification.txt 文件中。确保这个路径是可以访问的,并且 Authelia 进程有权限写入这个文件。
相比于Github上面给的实例文件, 修改的字段有:
-
所有路径换成了容器中的绝对路径
-
jwt_secret:使用一些在线站点生成就可以,但是没发现有什么用
-
session中的secret:生成随机字符串作为密钥
-
encryption_key:生成随机字符串作为密钥,不要求和上面的secret相同
-
notifier:github中还需要SMTP服务,还需要配置用户名密码,所以直接使用了最简单的方式,使用文件进行记录
添加域名解析
`Linux 操作系统, Authelia 服务端
127.0.0.1 authelia.example.com public.example.com traefik.example.com secure.example.com
`Windows 操作系统, Authelia 客户端
服务端IP authelia.example.com public.example.com traefik.example.com secure.example.com
验证阶段
访问https://public.example.com/
, 不需要验证
访问https://traefik.example.com/
, 跳转到https://authelia.example.com
,要求输入用户名密码进行验证
输入john/john@123
后访问到traefik的dashboard,这里没有使用系统设置的Authelia/authelia
访问https://secure.example.com
触发双重验证
点击注册设备
由于上面的配置文件选择将警告信息记录到文件中,所以这个一次性代码就在notification.txt
中
下面的链接表示注销掉一次性密码. 将一次性代码填入后,扫描二维码 添加身份账户
然后再次访问https://secure.example.com
, 直接使用二次登录码进行登录
2.3 使用MySQL进行存储
MySQL服务器需要满足的条件
- InnoDB为默认引擎
- 字符串编码为: utf8mb4
- 必须支持排序规则: utf8mb4_unicode_520_ci
- MySQL 8.0 或更高版本
-
MySQL 5.7 及以上版本提供
- innodb_large_prefix 选项为 ON
- MariaDB 10.3 或更高版本
- 必须支持 ANSI 标准时间行为。请参阅 ANSI 标准时间行为
configuration.yml
storage:
encryption_key: 'a_very_important_secret' # 用于加密存储数据的秘密密钥。这通常是用来保护敏感数据不被未经授权的访问
mysql: # 指定数据库为MySQL
address: 'tcp://127.0.0.1:3306' # MySQL的连接, 若MySQL为宿主机服务器,则为宿主机IP地址, 且允许docker网段进行访问
database: 'authelia'
username: 'authelia'
password: 'mypassword'
timeout: '5s' # 连接超时时间, 可选参数
tls: # TLS套接字配置, 可选参数
server_name: 'mysql.example.com'
skip_verify: false
minimum_version: 'TLS1.2'
maximum_version: 'TLS1.3'
certificate_chain: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
private_key: |
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
3.安全相关设计????
3.1 访问控制
访问控制是信息安全领域的一个核心概念,它涉及到对系统资源(如文件、目录、网络服务等)的访问权限管理,确保只有授权的主体(用户或进程)能够访问特定的对象。访问控制的目标是在保证系统可用性的同时,维护系统的机密性和完整性
access_control:
default_policy: 'deny'
networks:
- name: 'internal'
networks:
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/18'
rules:
- domain: 'private.example.com'
domain_regex: '^(\d+\-)?priv-img\.example\.com$'
policy: 'one_factor'
networks:
- 'internal'
- '1.1.1.1'
subject:
- ['user:adam']
- ['user:fred']
- ['group:admins']
methods:
- 'GET'
- 'HEAD'
resources:
- '^/api.*'
query:
- - operator: 'present'
key: 'secure'
- operator: 'absent'
key: 'insecure'
- - operator: 'pattern'
key: 'token'
value: '^(abc123|zyx789)$'
- operator: 'not pattern'
key: 'random'
value: '^(1|2)$'
各类配置选项说明:
default_policy:
默认策略定义了在没有规则部分适用于已知请求信息的情况下应用的策略。出于安全原因,建议将其配置为拒绝。出于性能原因,您不希望使用 Authelia 保护的站点不应在您的反向代理中配置为使用 Authelia 执行身份验证
networks:
主/全局网络部分包含带有名称标签的网络列表,这些网络可以在 规则部分中重复使用,而不必一遍又一遍地重新定义相同的网络。这还可以使复杂的网络相关配置更加清晰易读。
此部分有两个选项,name
和networks
。其中networks
部分是采用 CIDR 表示法的 IP 地址列表,而是name
一个友好名称,用于标记网络集合,以便在下面规则部分的网络部分中重复使用。
此配置选项本身不执行任何操作,仅当您在下面的规则部分中使用这些别名时才有用
rules:
规则有许多配置选项。当规则的所有条件都与请求匹配(不包括 应用于请求的策略)时规则就会匹配
规则定义了两个主要内容:
- 当所有条件都匹配时应用策略
- 提交给反向代理的请求的匹配条件
该标准分为几个部分:
-
domain:
private.example.com
— 请求必须来自或指向此域名 -
domain_regex:
'^(\d+\-)?priv-img\.example\.com$'
— 正则表达式用于匹配域名,这表示允许访问形如priv-img.example.com
或带有数字前缀的子域名,如1-priv-img.example.com
-
policy:
one_factor
— 这可能意味着请求需要通过某种单一因素认证(例如,仅凭用户名和密码) -
networks: 指定了请求来源或目标必须属于以下网络之一:
-
internal
(前面定义的内部网络) -
1.1.1.1
(这看起来像是一个外部 IP 地址,可能是 CDN 或其他服务的地址)
-
-
subject: 允许访问的主体(用户或组),这里指定了具体的用户和一个管理员组:
- 用户
adam
- 用户
fred
- 组
admins
- 用户
-
methods: 允许的 HTTP 方法,这里是
GET
和HEAD
-
resources: 资源路径匹配规则,这里允许任何以
/api
开头的路径 -
query: 查询参数的匹配规则,这里有两组条件:
- 第一组要求查询参数
secure
必须存在,同时insecure
必须不存在 - 第二组要求查询参数
token
的值必须匹配^(abc123|zyx789)$
正则表达式,同时random
的值不能匹配^(1|2)$
- 第一组要求查询参数
domain:
说明:本条目与 domain_regex
条目至少需要一个。该条目用于匹配请求的域名,并有两种配置方法:作为单一字符串或字符串列表。如果配置为字符串列表,则只要列表中的任何一个域名与请求域名匹配,规则即视为匹配成功。当与 domain_regex
结合使用时,只要 domain
或 domain_regex
中的任意一个条件满足,规则即视为匹配成功。
通配符使用
规则可以开始于几种不同的通配符:
-
标准通配符:
*.
,当位于域名前时,表示任何子域均视为匹配。例如,*.example.com
会匹配abc.example.com
和secure.example.com
。使用此类通配符时,字符串需要被引号包裹,例如'*.example.com'
。 -
用户通配符:
{user}.
,当位于域名前时,动态匹配登录用户的用户名。例如,{user}.example.com
如果登录用户的名称是fred
,则会匹配fred.example.com
。注意:此通配符已被官方标记为弃用,因为domain_regex
准则已完全取代了它的功能,并且以一种更加实用的方式实现。强烈建议不要使用这个通配符,因为它将在未来的版本中移除,很可能是版本 5.0.0。 -
组通配符:
{group}.
,当位于域名前时,如果登录用户具有该位置的组身份,则动态匹配。例如,{group}.example.com
如果登录用户属于admins
、users
、people
等组,则会匹配admins.example.com
,因为admins
在这些组列表中。
域名配置要求
本节中的域名必须是会话配置中定义的域名或该域名的子域。这是因为一个网站只能为其自身所属的域写入 Cookie。理论上,我们可以在多个域之间实现这一点,但是我们必须在实现过程中保持安全意识,目前这不是优先事项。
示例
假设我们配置了如下规则:
domain: '*.example.com'
domain_regex: '^([a-z]+)-sub\.example\.com$'
这将允许匹配所有的 example.com
的子域,如 mail.example.com
或 www.example.com
。同时,任何形如 abc-sub.example.com
的域名也将被匹配,其中 abc
可以是任何字母串。
通过这样的配置,我们可以灵活地控制对不同域名的访问权限,同时也提供了足够的灵活性来适应不同的使用场景。
# 匹配的单个域。此列表中的所有规则实际上都是相同的规则,只是以不同的方式表达
access_control:
rules:
- domain: '*.example.com'
policy: 'bypass'
- domain:
- '*.example.com'
policy: 'bypass'
# 多个域匹配。这些规则将匹配 或。此列表中的所有规则实际上都是相同的规则,只是以不同的方式表达
access_control:
rules:
- domain: ['apple.example.com', 'banana.example.com']
policy: 'bypass'
- domain:
- 'apple.example.com'
- 'banana.example.com'
policy: 'bypass'
# 通过静态域或domain_regex匹配的多个域。此规则将匹配
access_control:
rules:
- domain: 'apple.example.com'
domain_regex: '^(pub|img)-data\.example\.com$'
policy: bypass
domain_regex
此标准与域名匹配,有两种配置方法,即单个字符串或字符串列表。当它是字符串列表时,只要列表中的任何域与请求域匹配,规则就会匹配。当与域结合使用时,只要域或domain_regex标准匹配,规则就会匹配。
除了标准正则表达式模式之外,此标准还可以匹配一些命名正则表达式组
示例:
具有用户/组匹配的高级多域正则表达式示例。当请求发送到、 或 时,它将匹配john
组 example
和中的用户,而当请求发送到或时,它将不匹配。example1, user-john.example.com, group-example.example.com, group-example1.example.com, user-fred.example.com, group-admin.example.com
access_control:
rules:
- domain_regex:
- '^user-(?P<User>\w+)\.example\.com$'
- '^group-(?P<Group>\w+)\.example\.com$'
policy: 'one_factor'
# 多个域示例,一个域为静态域,另一个域为正则表达式域。这将匹配对 protected.example.com 、img-private.example.com 或 data-private.example.com 的请求
access_control:
rules:
- domain: 'protected.example.com'
- domain_regex: '^(img|data)-private\.example\.com'
policy: 'one_factor'
policy
应用于所选规则的特定策略。这不是匹配的标准,而是匹配时要采取的操作
subject
此标准用于匹配有关主体的标识特征。目前,它可以匹配用户或用户所属的组。这使得您可以有效地控制每个用户有权访问的资源,或特别要求某些用户必须使用双因素认证。主体必须使用以下前缀来精确匹配主体的一部分:
主体类型 | 前缀 | 描述 |
---|---|---|
用户 | user: |
匹配用户的用户名。 |
组 | group: |
如果用户拥有与此名称匹配的组,则匹配。 |
OAuth 2.0 客户端 | oauth2:client: |
如果请求通过一个利用指定客户端 ID 并使用客户端凭证授权类型颁发的令牌进行了授权,则匹配。 |
格式
此规则格式独特之处在于它是列表的列表。这种格式背后的逻辑是为了允许使用 OR 和 AND 逻辑。列表的第一层定义了 OR 逻辑,而第二层定义了 AND 逻辑。此外,这些列表的每一层都不需要明确定义。
示例
以下是一些使用 subject
准则的例子:
access_control:
rules:
- domain: 'example.com'
policy: 'two_factor'
subject:
- 'user:john'
- ['group:admin', 'group:app-name']
- 'group:super-admin'
- domain: 'example.com'
policy: 'two_factor'
subject:
- ['user:john']
- ['group:admin', 'group:app-name']
- ['group:super-admin']
当用户拥有用户名john
,或用户在群组admin
和 app-name
中,或用户在群组 中时匹配super-admin
。此列表中的所有规则实际上都是相同的规则,只是以不同的方式表达
# 当用户在super-admin组中时匹配。此列表中的所有规则实际上都是相同的规则,只是以不同的方式表达
access_control:
rules:
- domain: 'example.com'
policy: 'one_factor'
subject: 'group:super-admin'
- domain: 'example.com'
policy: 'one_factor'
subject:
- 'group:super-admin'
- domain: 'example.com'
policy: 'one_factor'
subject:
- ['group:super-admin']
解释
- 第一级列表:定义了 OR 逻辑,表示如果任何一个列表中的条件满足,则规则匹配成功。
- 第二级列表:定义了 AND 逻辑,表示同一列表内的所有条件必须全部满足,规则才匹配成功。
通过这种灵活的逻辑组合,可以创建出复杂而精确的访问控制规则,确保只有合适的用户或组能够访问特定的资源。这有助于加强系统的安全性,并确保资源访问符合预期的安全策略。
methods
描述
此标准用于匹配 HTTP 请求方法。当试图绕过特定请求类型的认证时,这一标准尤其有用,特别是当这些请求会影响到网站的基本或公共功能时。例如,当您需要执行跨源资源共享(CORS)预检请求时,可以将 bypass
策略应用于 OPTIONS
请求上。
注意事项
需要注意的是,Authelia 在重定向用户时无法保留请求数据。例如,如果用户有权执行 GET
请求,他们的认证级别为 one_factor
,而 POST
请求需要他们进行 two_factor
认证,那么用户可能会丢失表单数据。此外,有时候不可能重定向执行除了 HEAD
或 GET
之外的请求的用户,这意味着用户体验可能会受到影响。因此,仅推荐在必要时使用这种方法来提升安全性,特别是在处理 CORS 预检请求时。
可接受的方法
此配置选项接受并认为有效的方法是那些在知名 RFC 中指定的方法。下面是相关 RFC 及其对应的方法列表:
RFC | 方法 |
---|---|
RFC7231 | GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE |
RFC5789 | PATCH |
RFC4918 | PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK |
示例
以下是一个简单的示例,展示如何配置 Authelia 来绕过对 example.com
域名的 OPTIONS
请求:
access_control:
rules:
- domain: 'example.com'
policy: 'bypass'
methods:
- 'OPTIONS'
在这个示例中,任何针对 example.com
域名的 OPTIONS
请求都将被绕过认证过程,直接允许通过。这对于支持 CORS 的预检请求是非常有用的,因为这些请求通常是自动发送的,不需要用户交互,并且主要用于浏览器验证跨域请求的安全性。
networks:
此条件是一系列值,可以是 IP 地址、CIDR 表示法中的网络地址范围或来自全局部分的别名。它与标头中的第一个地址匹配X-Forwarded-For
,如果没有,它将返回到数据包 TCP 源 IP 地址的 IP 地址。因此,正确配置代理服务器以准确匹配符合此条件的请求非常重要。**注意:**您可以根据需要将 CIDR 网络与别名规则相结合
此标准的主要用例是根据用户的位置调整资源的安全要求。理论上,您可以将特定网络视为身份验证涉及的因素之一,也可以拒绝特定网络等
例如,如果您有一个应用程序同时在本地网络和外部网络上公开,那么您可以区分这些请求并对每个请求应用不同的策略。当用户在外部网络上时拒绝访问并允许特定的外部客户端和内部客户端访问它,或者当用户在本地网络上时要求较少的权限。有大量与网络和规则顺序有关的场景。这为管理员提供了很大的灵活性,可以根据需要调整安全性以满足他们的特定需求
示例:
要求除内部客户端和112.134.145.167
之外的所有客户端都使用two_factor。此列表中的前两个规则实际上是相同的规则,只是以不同的方式表达
access_control:
default_policy: 'two_factor'
networks:
- name: 'internal'
networks:
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/18'
rules:
- domain: 'secure.example.com'
policy: 'one_factor'
networks:
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/18'
- '112.134.145.167/32'
- domain: 'secure.example.com'
policy: 'one_factor'
networks:
- 'internal'
- '112.134.145.167/32'
- domain: 'secure.example.com'
policy: 'two_factor'
resources:
此标准使用正则表达式匹配请求的路径和查询。规则以字符串列表的形式表示。如果列表中的任何一个正则表达式与请求匹配,则视为匹配。用于调试这些正则表达式的有用工具称为Regex 101(确保您选择该Golang
选项)
除了标准正则表达式模式之外,此标准还可以匹配一些命名正则表达式组
配置资源规则时,务必将其括在引号中,否则您可能会遇到一些转义表达式的问题。如果不这样做,可能会导致 Authelia 无法启动。从技术上讲,这是可选的,但如果您对所有资源规则都这样做,可能会节省大量时间
示例:
当域名为app.example.com
且 URL 为/api
,或者以 /api/
或/api?
开头时,应用放行策略
access_control:
rules:
- domain: 'app.example.com'
policy: 'bypass'
resources:
- '^/api([/?].*)?$'
query:
查询条件是一种高级条件,可以配置将特定查询参数键与各种规则匹配的规则。建议使用资源规则来满足基本需求。
此规则的格式是独一无二的,因为它是列表的列表。此格式背后的逻辑是允许 OR
和AND
逻辑。列表的第一级定义OR
逻辑,第二级定义AND
逻辑。此外,这些列表的每一级都不必明确定义
key:
要检查的查询参数键
value:
要匹配的值。除非运算符是absent
或,否则这是必需的present
。建议始终按照示例引用此值
operator
此规则的规则运算符。可以在 规则运算符参考指南中找到有效的运算符。
如果指定了键和值,则默认为equal
,否则如果指定了键,则默认为present
access_control:
rules:
- domain: 'app.example.com'
policy: 'bypass'
query:
- - operator: 'present'
key: 'secure'
- operator: 'absent'
key: 'insecure'
- - operator: 'pattern'
key: 'token'
value: '^(abc123|zyx789)$'
- operator: 'not pattern'
key: 'random'
value: '^(1|2)$'
Policies
配置列表中第一个匹配规则的策略决定应用于请求的策略,如果没有规则与请求匹配,则应用default_policy
deny
这是默认应用的策略,也是我们建议所有安装的默认策略。其效果实际上是拒绝用户访问资源。此外,您还可以使用此策略在需要的情况下有条件地拒绝访问。示例包括拒绝访问没有内置身份验证机制的 API
bypass
此策略跳过所有身份验证并允许任何人使用资源。此策略不适用于包含主题限制的规则,因为获取有关主题的信息所需的最低身份验证级别是one_factor
one_factor
使用用户名和密码进行登录
two_factor
使用用户名和密码进行二次验证
规则匹配
在规则匹配方面,有两个重要概念需要理解. 您可以使用authelia access-control check-policy命令轻松评估您的访问控制规则部分是否与给定的请求匹配,以及为什么不匹配
-
规则匹配概念1: 顺序
规则按顺序匹配。列表中所有条件都匹配的第一个条目就是应用的规则。一些规则条件还允许使用条件列表,当列表中的其中一个条件与请求匹配时,该条件被视为与该特定规则匹配。
这对于绕过规则尤其重要。绕过规则通常应出现在规则列表的顶部附近。但是,您需要仔细评估规则列表**,以**查看哪条规则与特定场景相匹配。还建议全面了解规则的应用方式。
- domain: - 'example.com' - '*.example.com' policy: 'bypass' resources: - '^/api$' - '^/api/' - domain: - 'app.example.com' policy: 'two_factor'
-
规则匹配概念 2:主题标准需要身份验证
某些规则包含依赖于主体(如用户或用户组)的信息,这意味着在判断这些规则是否匹配之前,需要先进行身份验证。因此,这类规则不能与
bypass
策略一起使用,因为bypass
策略旨在绕过认证流程。依赖主体元素的标准
依赖主体元素的标准包括:
-
主体 (
subject
) 准则本身:用于匹配用户或用户组。 -
包含命名正则表达组的
domain_regex
准则:例如,使用{user}
或{group}
的正则表达式。
规则匹配顺序
如果一条规则包含
subject
准则,但其他所有准则都已经匹配,那么根据规则匹配概念1,如果先前的规则没有匹配请求,用户将会立即被重定向进行身份验证。这意味着如果有两条相同的规则,其中一条包含基于主体的准则,而另一条是bypass
规则,那么通常情况下bypass
规则应该排在前面。示例说明
假设我们有两个规则:
- 一个包含
subject
准则,用于匹配特定用户或用户组。 - 另一个则是
bypass
规则,用于绕过认证。
为了确保正确的规则匹配顺序,
bypass
规则应该排在前面。例如:access_control: rules: - domain: 'example.com' policy: 'bypass' methods: - 'GET' - 'HEAD' - domain:
-
主体 (