Traefik-sso-authelia ¶
什么是 SSO? ¶
单点登录(SSO)是一种身份验证解决方案,可让用户通过一次性用户身份验证登录多个应用程序和网站。鉴于当今的用户经常直接从其浏览器访问应用程序,因此组织正在优先考虑改善安全性和用户体验的访问管理策略。SSO 兼具这两方面的优点,因为一旦验证身份,用户就可以访问所有受密码保护的资源,而无需重复登录。
- 几种双因素身份验证方法。
- 注册第二因素设备时进行身份验证。
- 自助重置用户密码。
- 多次尝试后禁止帐户(称为监管)。
1. authelia 相关配置 ¶
什么是 authelia ? ¶
Authelia是 Traefik 等反向代理的伴侣( 有关完整列表,请参阅支持的代理)。它可以被视为提供身份验证功能和登录门户的那些代理的扩展。
如下架构图所示,Authelia 直接连接到反向代理,但从未直接连接到应用程序后端,因此受保护 API 的客户端发送的有效负载永远不会到达 Authelia,只有身份验证部分会到达,例如授权标头例如。因此,受保护的 API 可以是 REST、GraphQL 或 HTTP 之上的任何其他类型的 API。
authelia 的工作流程 ¶
配置反向代理,以便每个传入请求都会生成发送到 Authelia 的身份验证请求。 Authelia 做出响应,并指示反向代理允许传入请求通过,或者因为用户未经身份验证或没有充分授权而阻止它。
-
当未经身份验证的用户的第一个请求到达反向代理时,Authelia 会确定该用户未经过身份验证,因为没有随请求一起发送会话 cookie。因此,Authelia 将用户重定向到 Authelia 本身提供的身份验证门户。然后,用户可以使用该门户执行身份验证工作流程,以获得对 Authelia 保护的域的所有子域有效的会话 cookie。
-
当用户再次访问初始网站时,查询会与会话 cookie 一起发送,会话 cookie 在身份验证请求中转发到 Authelia。这次,Authelia 可以验证用户是否已通过身份验证,并命令反向代理让查询通过。
网站协议只能是 https
Authelia 仅适用于通过 HTTPS 提供服务的网站,因为会话 cookie 只能通过安全连接传输。
2. 部署 authelia ¶
1. docker 部署 Authelia ¶
1. 创建 Authelia 项目目录 ¶
...
mkdir -p /root/authelia/config
...
...
❯ tree authelia
authelia # 1. 创建 Authelia 项目数据文件夹
├── docker-compose.yml # 2. 编写 compose.yml 文件
└── config
├── configuration.yml # 3. 编写 configuration.yml 项目配置文件
├── users_database.yml # 4. 编写 users_database.yml 用户数据文件
└── create-user.sh # 5. 编写 create-user.sh 创建用户脚本
...
2. 编写 compose 编排文件 ¶
services:
authelia:
container_name: "${AUTHELIA_SERVICE_NAME:-authelia}"
image: authelia/authelia:v4.38.0-beta3
restart: unless-stopped
labels:
traefik.enable: true
traefik.http.routers.authelia.entryPoints: https
ports:
- "9091:9091"
user: "${AUTHELIA_RUN_USER:-2000:2000}"
environment:
TZ: "${TZ:-Australia/Melbourne}"
volumes:
- ./config:/config
3. 编写 configuration 配置 ¶
theme: 'auto'
server:
timeouts:
read: '6 seconds'
write: '6 seconds'
idle: '30 seconds'
buffers:
read: 409600
write: 409600
log:
level: debug
telemetry:
metrics:
enabled: false
totp:
disable: false
issuer: huichengcheng.com
algorithm: 'SHA1'
digits: 6
period: 30
skew: 1
secret_size: 32
webauthn:
disable: false
timeout: '60 seconds'
display_name: 'huichengcheng'
identity_validation:
reset_password:
jwt_secret: '<secret>'
ntp:
address: 'udp://ntp.tencent.com:123'
version: 4
max_desync: '3 seconds'
# 將用戶資訊(帳號,密碼)存在本地YAML文件中
# Ref: https://www.authelia.com/configuration/first-factor/file/
authentication_backend:
password_reset:
disable: false
file:
path: /config/users_database.yml
password:
algorithm: sha512
iterations: 50000
memory: 65536
parallelism: 4
key_length: 32
salt_length: 32
password_policy:
standard:
enabled: false
min_length: 8
max_length: 0
require_uppercase: true
require_lowercase: true
require_number: true
require_special: true
zxcvbn:
enabled: false
min_score: 3
privacy_policy:
enabled: false
require_user_acceptance: false
policy_url: ''
# 網域登入認證設定
# Ref: https://www.authelia.com/configuration/security/access-control/
access_control:
default_policy: deny
rules:
- domain_regex: '^.*\.?huichengcheng\.com$'
policy: 'two_factor' #需要两个验证条件
# Cookie 設置
# Ref: https://www.authelia.com/configuration/session/introduction/
session:
secret: '<secret>'
cookies:
- name: 'authelia_session'
domain: huichengcheng.com
authelia_url: 'https://authelia.huichengcheng.com:60000'
name: authelia_session
same_site: 'lax'
inactivity: '5m'
expiration: '1h'
remember_me: '1M'
redis:
host: <host>
password: <password>
port: <port>
database_index: 0
# 暫時禁止登入密碼錯誤且嘗試過多的帳號
# Ref: https://www.authelia.com/configuration/security/regulation/
regulation:
max_retries: 3
find_time: '2 minutes'
ban_time: '5 minutes'
# 本地資料庫
# Ref: https://www.authelia.com/configuration/storage/sqlite/
storage:
encryption_key: <encryption_key>
postgres:
host: <host>
port: <port>
database: <database>
username: <username>
password: <password>
#Ref: https://www.authelia.com/configuration/notifications/introduction/
notifier:
smtp:
username: <username>
password: <password>
host: smtp.feishu.cn
port: 465
sender: totp@EXAMPLE.com
identifier: localhost
subject: "[Authelia] {title}"
startup_check_address: <smtp>
disable_require_tls: false
disable_html_emails: false
4. 编写 users_database 文件 ¶
users:
admin:
password: <password> # authelia crypto hash generate argon2 --password "$password"|awk '{print $NF}'
displayname: admin User
email: <email>
groups:
- admin
disabled: false
test:
password: <password> # authelia crypto hash generate argon2 --password "$password"|awk '{print $NF}'
displayname: test User
email: <email>
groups:
- admin
disabled: false
5. create-user 创建用户脚本 ¶
#!/bin/bash
authelia_dir="/root/authelia/"
# 检查参数数量
if [[ $# -ne 4 ]]; then
echo "使用方法:create.sh <用户名> <密码> <邮箱> <角色>"
exit 1
fi
# 提取参数
username=$1
password=$2
email=$3
role=$4
# 检查用户是否存在
if grep -q "^ $username:" ${authelia_dir}config/users_database.yml; then
echo "用户 $username 已存在"
exit 1
fi
# 生成密码
generated_password=$(docker exec authelia authelia crypto hash generate argon2 --password "$password"|awk '{print $NF}')
password=$(echo "$password_result" | sed -n 's/^Digest: \(.*\)$/\1/p')
# 构建用户条目
cat << EOF >> ${authelia_dir}config/users_database.yml
$username:
password: $generated_password
displayname: $username User
email: $email
groups:
- $role
disabled: false
EOF
echo "用户 $username 创建成功" && docker compose -f ${authelia_dir}docker-compose.yml up -d --force-recreate authelia
6. 启动 Authelia 服务 ¶
docker compose up -d
7. Authelia 服务暴露 ¶
(authelia) {
forward_auth 192.168.1.99:9091 {
uri /api/verify?rd=https://authelia.huichengcheng.com:60000/
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
}
}
authelia.huichengcheng.com {
import dnspod
reverse_proxy 192.168.1.99:9091
}
tencent.k8s.huichengcheng.com {
import authelia
reverse_proxy 192.168.1.99
}
apiVersion: v1
kind: Endpoints
metadata:
name: authelia
namespace: default
#指定自定义的point的目标地址
subsets:
- addresses:
#外部的 authelia ip
- ip: 192.168.1.99
# 外部 authelia 的真实的工作端口
ports:
- port: 9091
# 定义端口的名称,必须与 service 中的 ports.name 一致
name: autheliaport
---
#这里的service配置大家都熟悉了,主要就是上面的endpoint而已
kind: Service
apiVersion: v1
metadata:
name: sso-authelia
namespace: default
spec:
ports:
- port: 9091
protocol: TCP
name: autheliaport
targetPort: 9091
type: ClusterIP
kubectl apply -f auth.endpoint.yaml
kubectl describe svc sso-authelia |grep Endpoints
# Endpoints: 192.168.1.99:9091
2. 部署 Authelia Pod 至 k8s ¶
> 选择 configmap 的方式,来部署 Authelia pod ,因为当前这个配置当中涉及的,配置项较多,有 config ,有用户列表,有 db
2. 在 traefik 当中定义 Middleware ¶
注意 address 中:
1. https://authelia.huichengcheng.com:60000/ # 跳转至这个外部地址去进行验证(authelia)
2. http://sso-authelia.default:9091 # 通过svc地址获得进一步验证信息
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: authelia
spec:
forwardAuth:
address: http://sso-authelia.default:9091/api/verify?rd=https://authelia.huichengcheng.com:60000/
trustForwardHeader: true
authResponseHeaders:
- "Remote-User"
- "Remote-Groups"
- "Remote-Name"
- "Remote-Email"
kubectl apply -f 003-traefik-Middleware.yaml
3. 在 traefik 当中调用 Middleware ¶
1. 编写 004-traefik-Middleware-ingressroute.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutetls
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`tencent.k8s.huichengcheng.com`)
kind: Rule
services:
- name: service-middle
port: 80
namespace: default
middlewares:
- name: authelia-ip
- name: authelia
tls:
secretName: tencent-tls
kubectl apply -f 004-traefik-Middleware-ingressroute.yaml
4. 测试跳转验证 ¶
1. 访问:测试 https://tencent.k8s.huichengcheng.com:50000
访问后自动跳转至验证页面