需求
某个后台管理平台需要添加账号登录功能,需要实现以下需求
https://www.example.com/ 平台地址,如果未登录则跳转到登录页面
https://www.example.com/auth/ 登录页面,使用authelia
nginx,authelia,后台管理平台服务均为由docker-compose定义的服务文件,也就是三个docker-compose文件。
authelia使用文件的形式存储用户表,数据库使用SQLite,并使用redis作为缓存。
开始搭建
首先创建一个docker的网络nginx_master,所有nginx需要反代的服务都连接到该网络内,这样每个服务不需要再使用宿主机的端口,更安全也更方便维护。
docker network create nginx_master搭建authelia
首先创建一下用于authelia的docker-compose文件 authelia/docker-compose.yml :
version: '3.3'
networks:
net: # 默认网络,仅用于与redis进行通信
driver: bridge
nginx_master: # 刚刚创建好的外部网络,用于让nginx连接authelia服务
name: nginx_master
external: true
services:
authelia:
image: authelia/authelia:4
volumes:
- ./authelia:/config # 配置文件路径
networks:
- net
- nginx_master
restart: unless-stopped
redis:
image: redis:alpine
volumes:
- ./redis:/data # redis的数据存放的路径
networks:
- net
expose:
- 6379
restart: unless-stopped然后在authelia目录下执行docker-compose up
此时authelia会报错,只需要根据提示的错误信息修改authelia/authelia/configuration.yml文件中对应的配置项即可,如下:
"Configuration: authentication_backend: you must ensure either the 'file' or 'ldap' authentication backend is configured"
没有定义用户数据源导致的,configuration.yml中搜索## File (Authentication Provider),跳转到对应的配置段落,取消配置项file、file.path、file.watch的注释即可
"Configuration: access control: 'default_policy' option 'deny' is invalid: when no rules are specified it must be 'two_factor' or 'one_factor'"
由于没有定义任何规则,所以default_policy不能为deny。这时候只需要添加一个规则即可,在configuration.yml中搜索default_policy: deny,跳转到对应的配置段落,在下方取消# rules:的注释以及下方紧挨着的# - domain: 'public.example.com'与# policy: bypass的注释。
修改后如下:
default_policy: deny # 如果没有匹配到任何规则,则拒绝访问
rules:
## Rules applied to everyone
- domain: 'www.example.com'
policy: one_factor # 访问www.example.com的时候,需要登录账号密码"Configuration: storage: configuration for a 'local', 'mysql' or 'postgres' database must be provided"
"Configuration: storage: option 'encryption_key' is required"
这两个错误为没有设置数据库和加密密钥的原因,这里我们使用SQLite,只需要在configuration.yml中搜索Storage Provider Configuration,跳转到对应的配置段落,取消下面的storage、storage.encryption_key、storage.local与storage.local.path的注释。
修改后如下:
storage:
encryption_key: #这里请填写随机生成的一串字符串作为数据库的加密密码
local:
path: /config/db.sqlite3"Configuration: notifier: you must ensure either the 'smtp' or 'filesystem' notifier is configured"
没有设置消息通知方式的原因,这里我们使用邮件的方式,在configuration.yml中搜索关键字SMTP (Notification Provider),取消下面的smtp以及其子配置项的注释,按需填写即可。
设置登录页面的子路径,在配置项server.path设置,这里我们想在 https://www.example.com/auth 路径来登录,所以我们这里填auth即可。
搜索secret关键词,把一些需要设置的值都设置一下,具体要求与解释可以看上面的注释,一般都是随机字符串越长越好。
设置cookie的有效域,在配置项session.domain设置,填写域名即可。
然后再运行docker-compose up此时authelia成功运行。
搭建nginx
创建docker-compose文件:
nginx/docker-compose.yml:
version: '3'
services:
nginx:
image: nginx:1.23.3-alpine
volumes:
- ./nginx:/etc/nginx # nginx的配置文件目录直接映射到./nginx目录下
networks:
- nginx_master
ports:
- "80:80"
- "443:443"
environment:
DOCKER_MODS: 'linuxserver/mods:nginx-proxy-confs'
networks:
nginx_master:
name: nginx_master # 最初创建的外部网络,用于让nginx连接authelia与其他服务
external: true创建nginx的代码段
nginx/nginx/snippets/authelia-location.conf:
## Virtual endpoint created by nginx to forward auth requests.
location /authelia {
## Essential Proxy Configuration
internal;
proxy_pass $upstream_authelia;
## Headers
## The headers starting with X-* are required.
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Original-Method $request_method;
proxy_set_header X-Forwarded-Method $request_method;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Content-Length "";
proxy_set_header Connection "";
## Basic Proxy Configuration
proxy_pass_request_body off;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; # Timeout if the real server is dead
proxy_redirect http:// $scheme://;
proxy_http_version 1.1;
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
proxy_buffers 4 32k;
client_body_buffer_size 128k;
## Advanced Proxy Configuration
send_timeout 5m;
proxy_read_timeout 240;
proxy_send_timeout 240;
proxy_connect_timeout 240;
}nginx/nginx/snippets/authelia-authrequest.conf:
## Send a subrequest to Authelia to verify if the user is authenticated and has permission to access the resource.
auth_request /authelia;
## Set the $target_url variable based on the original request.
## Comment this line if you're using nginx without the http_set_misc module.
# set_escape_uri $target_url $scheme://$http_host$request_uri;
## Uncomment this line if you're using NGINX without the http_set_misc module.
set $target_url $scheme://$http_host$request_uri;
## Save the upstream response headers from Authelia to variables.
auth_request_set $user $upstream_http_remote_user;
auth_request_set $groups $upstream_http_remote_groups;
auth_request_set $name $upstream_http_remote_name;
auth_request_set $email $upstream_http_remote_email;
## Inject the response headers from the variables into the request made to the backend.
proxy_set_header Remote-User $user;
proxy_set_header Remote-Groups $groups;
proxy_set_header Remote-Name $name;
proxy_set_header Remote-Email $email;创建nginx的站点配置
nginx/nginx/conf.d/www.example.com.conf:
server { # http访问自动跳转到https
listen 80;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name www.example.com;
# 这里填入你的https证书相关配置
# 必填,否则nginx无法根据服务名解析到对应的虚拟网络ip
resolver 127.0.0.11;
# 设置authelia的验证接口的地址
set $upstream_authelia http://authelia:9091/api/verify;
# 设置给auth_request使用的虚拟端点
include /etc/nginx/snippets/authelia-location.conf;
# authelia的地址
set $upstream http://authelia:9091;
# 前端登录界面的路径
location /auth {
proxy_set_header Host $host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass $upstream;
}
location /auth/api/verify {
proxy_pass $upstream;
}
location / {
# 每个location块加入下面这行,则会为该location块添加保护,如果用户未登录则要求登录
include /etc/nginx/snippets/authelia-authrequest.conf;
proxy_set_header Host $host;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-For $remote_addr;
# 用户未登录时,跳转到哪个地址
error_page 401 =302 https://www.example.com/auth?rd=$target_url;
# 你要保护的后台管理服务的服务端地址,如果用户登录成功,则执行这个
proxy_pass http://your-service-name:8080;
}
}此时运行docker-compose up,nginx登录成功,访问https://www.example.com,会自动被跳转到https://www.example.com/auth 也就是authelia的登录界面。
添加一个用户
配置好了nginx与authelia,此时还需要创建一个用户才能登录,参考 https://www.authelia.com/reference/guides/passwords/
简而言之,可以直接使用docker run authelia/authelia:latest authelia crypto hash generate argon2 --password '你要设置的密码'来生成密码,填入authelia/authelia/users_database.yml文件对应配置项内即可。
