需求

某个后台管理平台需要添加账号登录功能,需要实现以下需求

https://www.example.com/ 平台地址,如果未登录则跳转到登录页面

https://www.example.com/auth/ 登录页面,使用authelia

nginx,authelia,后台管理平台服务均为由docker-compose定义的服务文件,也就是三个docker-compose文件。

authelia使用文件的形式存储用户表,数据库使用SQLite,并使用redis作为缓存。

开始搭建

首先创建一个docker的网络nginx_master,所有nginx需要反代的服务都连接到该网络内,这样每个服务不需要再使用宿主机的端口,更安全也更方便维护。

PLAINTEXT
docker network create nginx_master
点击展开查看更多

搭建authelia

首先创建一下用于authelia的docker-compose文件 authelia/docker-compose.yml :

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),跳转到对应的配置段落,取消配置项filefile.pathfile.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的注释。 修改后如下:

YML
  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,跳转到对应的配置段落,取消下面的storagestorage.encryption_keystorage.localstorage.local.path的注释。 修改后如下:

YML
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:

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:

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:

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:

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文件对应配置项内即可。

版权声明

作者: CometDust

链接: https://blog.codu.tech/posts/2023/02/authelia-with-nginx-for-login-authentication/

许可证: CC BY-NC-SA 4.0

如需转载, 请署名出处.

开始搜索

输入关键词搜索文章内容

↑↓
ESC
⌘K 快捷键