云安全部署实践 | Authelia+DCDN+WebApp
在进行进一步的操作前,请仔细阅读简介以降低出错的可能性

目录

  1. 简介
  2. 服务架构
  3. 部署Authelia
    • 准备工作
    • 安装Authelia
    • 为Authelia配置Nginx反向代理
    • 为Web应用配置Nginx反向代理
  4. 全站加速DCDN配置
    • 一些个人考虑
    • DCDN及DNS配置
  5. 脚注
  6. 参考资料

简介

Authelia是一款开源的单点登录SSO(Single Sign On)认证软件,用户通过在服务器上部署Authelia,搭配1例如Nginx,Nginx Proxy Manager,Traefik等可以提供反向代理服务的软件,即可为没有配备独立身份认证系统的自托管网页应用HomepageSuwayomi-Server,Stable Diffusion等暴露在公网之前提供一层较为强力的安全保障。

同时,因为Authelia的SSO属性,用户可以通过完成单个网关认证来一次性方便的访问到任何部署在Authelia之后的网页应用而无需二次认证2,可以在一定程度上减少用户的重复性负荷。

因为老K这几天在研究Homepage这一类的个人导航页Web应用,部署完成之后才恍然发现直接将服务暴露到公网是一个非常不明智的决定,所以才顺便研究了一下相对简单易行的认证网关方案。其间参考了Authelia、Keycloak等开源项目。最后出于部署难度,管理学习成本等等综合考虑选择了利用Docker部署Authelia这一项目,再搭配Nginx反向代理作为自托管Web服务的SSO网关认证系统。

再来谈谈DCDN,也就是阿里云所提供的全站加速服务(在其他云服务商可能有其他缩写名,如腾讯云叫做ECDN),全站加速也是一种按量付费或者订阅制的内容分发网络服务,可以简单理解为把内容缓存的服务范围扩展到了整个目标加速域名,同时可以提供隐藏真实IP以及一定的反DDoS的能力,用户将Authelia和Web应用部署到服务器之后,如果直接使用A或AAAA记录解析服务,还是存在一定的被打的风险。(虽然使用了DCDN服务也还是可能被打,但总比直接把攻击目标明着摆出来要好很多)对于个人站点来说,这样的安全架构选型属于比较够用和靠谱了。

本文由K.K.在chocolax.space首次发布,转载及引用请注明出处并贴出原文跳转链接!

服务架构

博主虽然不是特别专业,但可以用一张自制的简化流程图来帮助大家简单理解初步部署完成之后的完整服务架构:

用户访问网页应用B的请求通过Nginx转发到Authelia进行用户身份认证,这一步体现为:用户访问B.example.com的时候,请求将被转发到Authelia的域名(如auth.example.com)。用户被引导到并在Authelia的域名完成用户认证后,Authelia会将用户的原始请求附加上鉴权信息并送回Nginx,鉴权信息由用户留存,原始请求再最后通过第二次反向代理发送给在Nginx后的真实应用B的域名B.example.com。到此,一次用户认证和网页应用访问完成。

在这样一次用户认证之后,认证有效时间内(如1小时),用户访问在同一根域名example.com下的其他受Authelia保护的网站时,将不再需要认证,虽然请求还是会经过Authelia的域名转发,但是Authelia这一次将直接放行同一用户的请求直达目标应用(如图中的应用C),到此实现了SSO单点登录的功能。

部署Authelia

准备工作

在进行下一步操作前,请再次确认对Authelia的域名auth.example.com及Web应用的域名(必须在example.com根域名下)的DNS配置权限

安装Authelia

第1/5步
拉取Authelia的Docker镜像
SSH登录你的云服务器后台,docker pull拉取Authelia的镜像,本文发布时master分支的最新版本是v4.37.5-77fff31,该版本的配置文件可能会与latest分支有所区别,稍后请适当修改,请根据偏好自行选择,本文档使用的是master分支
docker pull authelia/authelia:master # 最新版本,发布时间较新
docker pull authelia/authelia:latest # v4.37.5正式版,22年发布
第2/5步
创建并初次启动Authelia容器
创建Authelia的Docker容器至少需要映射容器的/config目录和9091端口(端口可修改)到宿主机,同时为了安全起见,应避免容器使用uid=0的用户权限(root权限)运行,可以手动指定容器的PUID和PGID,这里设置为1000。同时应为Authelia初始设定一个时区,用于之后的2FA认证(虽然Authelia会通过ntp授时服务器自动校准,做了比没做好)
docker run --name authelia -p 9091:9091 -d --restart="unless-stopped" -e PUID=1000 -e PGID=1000 -e TZ="Asia/Shanghai" -v <你指定的宿主机目录>/config:/config authelia/authelia:master
由于设置的重启策略,在创建并初次启动容器之后,请手动停止容器一次,方便进行后续Authelia的设置
第3/5步
配置Authelia
初次启动容器后,容器会自动退出并在宿主机映射的/config目录处生成一个configuration.yml配置文件。通过管理面板的文本编辑器或者后台的vim编辑器等打开并进行后续配置
这是一个简化版的配置文件,生产环境的Authelia包括配置LDAP等比较复杂,本文仅对用于测试的通用条目进行说明,更多配置请参考Authelia官
---
# 此处指定 Authelia 的默认 2FA 认证方式(totp为动态口令)
default_2fa_method: 'totp'

# 此处指定 Authelia 服务器(docker容器)的访问地址,默认为 tcp 协议,9091端口
server:
  address: 'tcp://0.0.0.0:9091/'
  disable_healthcheck: false

# 此处指定用于 Authelia 存放日志的目录
log:
  file_path: '/config/authelia.log'

# 2FA-动态口令的相关配置
totp:
  disable: false
  issuer: '你自定的TOTP令牌签发者名字'    # 此处设置会在例如 Google/Microsoft Authenticator 等应用中显示为动态口令的标题
  algorithm: 'sha1'    # 动态口令的加密算法,默认为 SHA1,也支持 SHA256/512
  digits: 6    # 动态口令位数
  period: 30    # 口令的刷新周期,单位秒
  skew: 0    # 有效口令的相位差,若设置为 1,则当前周期 ±1 周期内的口令都会被视作正确口令,谨慎调整
  secret_size: 32    # 公钥长度,保持 32 默认即可

# 2FA-WebAuthn 的相关配置
webauthn:
  disable: false    # 保持默认以开启 WebAuthn 认证方式即可

# 访客身份认证相关配置
identity_validation:
  reset_password:    # 密码重置相关设置,除 JWT 密钥外保持默认即可
    expiration: '5m'
    jwt_algorithm: 'HS256'
    jwt_secret: '你自定的JWT加密密钥#1,尽量多于20个随机字符,很重要'
  elevated_session:    # Authelia 发送的一次性验证码相关设置
    expiration: '5m'    # 一次性验证码的过期时间
    elevation_expiration: '10m'
    characters: 6    # 验证码长度

# 时钟校准设置,由于 TOTP 依赖时间计算口令,不准确的系统时钟可能会造成认证错误
ntp:
  address: 'udp://ntp.aliyun.com:123'    # 你指定的授时服务器
  max_desync: '3s'    # 与授时服务器时间差的最大容错

# Authelia 后端认证配置
authentication_backend:
  password_reset:
    disable: false    # 开启密码重置功能
  file:
    path: '/config/users_database.yml'    # Authelia 用于保存已注册用户信息的目录

# 访问控制配置
access_control:
  default_policy: 'deny'    # 默认拒绝所有未授权的访问
  rules:
    - domain: '你准备的Authelia域名,如auth.example.com'    # 此处填写 Authelia 的域名用于绕过认证自己
      policy: 'bypass'
    - domain:     # 此处填写仅需要 Authelia 提供用户名及密码认证的受保护的域名
      - '仅需要密码验证的服务域名 #1'
      - '仅需要密码验证的服务域名 #2,3...'
      policy: 'one_factor'
    - domain:    # 此处填写需要 Authelia 提供 2FA 两步验证的受保护的域名
      - '需要两步验证2FA的服务域名 #1,如图中的B.exmaple.com'
      - '需要两步验证2FA的服务域名 #2,3...'
      policy: 'two_factor'

# 浏览器 Session 设置
session:
  secret: '你自定的Session加密密钥#2,尽量多于20个随机字符,推荐和上一个不一样'
    cookies:
      domain: '你的根域名,如example.com'    # 请务必填写你的根域名
      authelia_url: 'https://你准备的Authelia域名'    # 请务必要填 https,否则 Authelia 会自检不通过
    inactivity: '30m'    # Authelia 判定用户转为不活跃状态前的等待时间
    expiration: '2h'    # 用户未勾选 “记住我” 选项时的 Session 过期时间
    remember_me: '6h'    # 用户勾选 “记住我” 选项时的 Session 过期时间

# Authelia 本地存储配置
storage:
  encryption_key: '你自定的数据加密密钥#3,尽量多于20个随机字符'
  local:
    path: '/config/db.sqlite3'    # 默认的 Sqlite 数据库文件位置,如需要配置 Postgresql 或者 MySQL 请参考官网

# Authelia 一次性验证码相关配置
notifier:
  disable_startup_check: false
  filesystem:
    filename: '/config/notification.txt'    # 当未配置 SMTP 服务时,请配置本地文件位置以接收一次性验证码
...
第4/5步
保存并继续配置/config目录下的users_database.yml文件(先不要重启容器
users_database.yml文件存放了Authelia的默认注册用户信息,在重启docker容器前请一定要配置这个文件,如没有请手动创建
---
users:
  <你的用户名>:    # 用于登录的用户名
    disabled: false
    displayname: "<你的用户显示名称>"    # 显示在 Authelia 网页中的名字,不是用于登录的用户名
    password: "$argon2id$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    # 请前往网站 https://argon2.online/ 在线计算你的密码,默认的密码生成配置如下图,请手动填写并生成,复制 Encoded Form 并粘贴至此处
    email: "<你的邮箱>"
    groups:
      - admins
      - dev
...

如何在网站在线计算自己的密码
第5/5步
保存以上配置的两个文件,重启Authelia容器
保存好配置后重启Authelia容器,理论上你应该能看到容器在正常运行并监听9091端口了,如果遇到容器不能正常运行,一直重启的状况,请手动停止容器并到宿主机上映射容器/config的目录下检查authelia.log,根据报错信息再次检查自己的配置。

为 Authelia 配置 Nginx 反向代理

经过了以上的操作,你现在应该有一个运行正常的Authelia容器。现在你需要把Authelia服务暴露到公网并测试其工作情况,在添加Web应用反向代理到Authelia之前,最好先调试Authelia自身,确认其可以正常进行用户身份认证。下表列出了这一节以及下一节需要用到的说法及其指代内容。以下内容以1Panel作为面板工具演示,其他面板请进行相应操作即可。

项目服务地址/主机名域名
根域名Xexample.com
云服务器A本机127.0.0.1/111.2.3.4(公网)/ServerAX
Authelia服务127.0.0.1:9091(9091未暴露到公网)/ServerAauth.example.com
Web应用A(不受保护)127.0.0.1:1111(1111未暴露到公网)/ServerAa.example.com
Web应用B(受保护)127.0.0.1:2222(2222未暴露到公网)/ServerAb.example.com
Web应用C(受保护)222.3.4.5:3333(3333未暴露到公网)/ServerBc.example.com3
进行下一步操作之前,请准备好各个域名适用于Nginx格式的有效SSL证书,并提前打开云服务商的DNS解析管理控制台
第1/4步
在ServerA上为Authelia设置反向代理
进入网站管理并点击创建一个新网站,选择“反向代理”,并填写Authelia的相关信息,点击确定创建网站。然后为新创建的网站部署你准备好的SSL证书并启用HTTPS,其中HTTP请求选择强制跳转到HTTPS
在1Panel中创建新的反向代理类网站
第2/4步
修改Authelia网站的反向代理配置
因为Authelia需要接管所有对auth.example.com和其他受保护的应用域名的访问请求,我们需要参考官方的指导对反向代理进行更细致的配置。在Authelia网站的反向代理配置中删除掉原有的内容并输入以下新的配置并保存,如果你的面板报错,请尝试将proxy_buffers一行注释掉再保存。
location / {
    set $upstream_authelia http://127.0.0.1:9091;
    proxy_pass $upstream_authelia;

    client_body_buffer_size 128k;

    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;

    send_timeout 5m;
    proxy_read_timeout 360;
    proxy_send_timeout 360;
    proxy_connect_timeout 360;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    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_redirect  http://  $scheme://;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_cache_bypass $cookie_session;
    proxy_no_cache $cookie_session;
    proxy_buffers 64 256k;

    set_real_ip_from 10.0.0.0/8;
    set_real_ip_from 172.0.0.0/8;
    set_real_ip_from 192.168.0.0/16;
    set_real_ip_from fc00::/7;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
}
第3/4步
临时添加指向Authelia服务的DNS解析记录
DCDN尚未部署之前,可以先用A或者AAAA记录临时解析服务并测试服务是否工作正常,部署DCDN之后请一定记得删除对应的A或者AAAA记录
在DNS解析控制台添加A记录解析
第4/4步
在浏览器中访问https://auth.example.com并测试Authelia是否工作正常
如果你在浏览器中看到了以下画面,恭喜你,你的Authelia服务连通性正常,请尝试使用你在users_database.yml中留存的用户名和密码登录Authelia,第一次登录需要绑定新的2FA-TOTP设备,请使用Google Authenticator一类的应用尝试绑定并重新访问Authelia测试2FA是否工作正常。若提示口令错误,请考虑将configurations.yml中的skew改为1,重启容器后再测试
成功访问Authelia服务

为Web应用配置Nginx反向代理

第1/4步
在ServerA上为应用A、B,ServerB上的应用C设置反向代理
类似上一节中为Authelia设置基础的反向代理一样,需要给应用A/B/C在各自的服务器上创建网站并部署SSL证书,启用HTTPS(此步不可省略,Authelia仅接受到HTTPS站点的访问及重定向请求)
第2/4步
为应用B及应用C的网站修改Nginx反向代理配置
此步设置意在让用户访问应用B、C时的请求被Nginx重定向并转发至Authelia服务,并允许鉴权成功的请求被二次转发到B、C的真实域名。在新创建的应用B、C的网站的反向代理配置中删除掉原有的内容并输入以下新的配置并保存,如果你的面板报错,请尝试将 proxy_buffers 一行注释掉再保存。
# 此处以在 ServerA 上的应用 B 为例进行配置

location /authelia {
    internal; 
    set $upstream_authelia http://127.0.0.1:9091/api/verify;    # 配置 Authelia 服务的地址
    proxy_pass_request_body off; 
    proxy_pass $upstream_authelia; 
    proxy_set_header Content-Length ""; 

    client_body_buffer_size 128k; 
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; 

    send_timeout 5m; 
    proxy_read_timeout 360; 
    proxy_send_timeout 360; 
    proxy_connect_timeout 360; 

    proxy_set_header Host $http_host; 
    proxy_set_header X-Original-URL $scheme://$http_host$request_uri; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $remote_addr; 
    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_redirect http:// $scheme://; 
    proxy_http_version 1.1; 
    proxy_set_header Connection ""; 
    proxy_cache_bypass $cookie_session; 
    proxy_no_cache $cookie_session; 
    proxy_buffers 4 32k;
    add_header Strict-Transport-Security "max-age=31536000"; 
}
location / {
    set $upstream_webapp_b http://127.0.0.1:2222;    # upstreamm_webapp_b 请自行更改为自己方便识别的名称,后面是你的 Web 应用的地址
    proxy_pass $upstream_webapp_b;    # 同上
    auth_request /authelia; 
    auth_request_set $target_url $scheme://$http_host$request_uri; 
    auth_request_set $user $upstream_http_remote_user; 
    auth_request_set $groups $upstream_http_remote_groups; 
    proxy_set_header Remote-User $user; 
    proxy_set_header Remote-Groups $groups; 
    error_page 401 = 302 https://auth.example.com/?rd=$target_url;    # 修改成你的 Authelia 服务域名,注意是 HTTPS

    client_body_buffer_size 128k; 
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; 

    send_timeout 5m; 
    proxy_read_timeout 360; 
    proxy_send_timeout 360; 
    proxy_connect_timeout 360; 

    proxy_set_header Host $http_host; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    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_redirect http:// $scheme://; 
    proxy_http_version 1.1; 
    proxy_set_header Connection ""; 
    proxy_cache_bypass $cookie_session; 
    proxy_no_cache $cookie_session; 
    proxy_buffers 64 256k;

    set_real_ip_from 10.0.0.0/8; 
    set_real_ip_from 172.0.0.0/8; 
    set_real_ip_from 192.168.0.0/16; 
    set_real_ip_from fc00::/7; 
    real_ip_header X-Forwarded-For; 
    real_ip_recursive on; 
}
第3/4步
临时添加指向应用B、C的DNS解析记录
同上一节,DCDN尚未部署之前,可以先用A或者AAAA记录临时解析服务并测试服务是否工作正常,部署DCDN之后请一定记得删除对应的A或者AAAA记录
第 4/4步
在浏览器中访问 https://b.example.com 并测试 Authelia 是否工作正常
如果你在浏览器中看到了Authelia的登录画面,恭喜你,你的 Authelia 服务连通性正常,接下来用用户名密码+2FA登录并观察重定向是否工作正常,如果登陆成功后浏览器自动跳转回了b.example.com,恭喜你,你刚刚部署的Authelia一切正常!
到此,Authelia已经部署并初步测试完毕,接下来的DCDN部分属于可选配置,如果不想配置付费服务的DCDN,可以考虑使用Cloud Flare的免费CDN服务,或者不删除A/AAAA记录直接开始公网裸奔(笑),本文不对Cloud Flare的CDN服务做讲解,请参考其他文章

全站加速DCDN配置

一些个人考虑

互联网险恶,做个人文章分享还好,做点其他带点商业性质的,稍有不慎就会被打。在公网上暴露服务器的真实IP是很危险的一个操作,如何隐藏自己服务器的真实IP就显得非常重要。目前主流中简单易操作的方式就是利用CDN来给服务器嵌套一层壳,让CDN服务器挡在你的真实服务器之前。

选择全站加速无非是更省心省力,因此本文中才列为可选配置,想一起完成的朋友就跟老K继续接下来的配置吧
简易CDN工作原理

DCDN及DNS配置

第1/7步
进入全站加速控制台,为Authelia及Web应用添加及管理域名
点击管理,进入后添加加速域名,输入源站的详细信息
阿里云全站加速服务若要加速中国大陆区域,你的域名需要ICP备案,如果没有备案,请备案或选择其他CDN服务
添加DCDN加速域名

新增源站信息
第2/7步
在DNS控制台添加CNAME解析记录
成功创建加速域名后,按照页面提示在DNS管理控制台添加CNAME解析记录
第3/7步
回到全站加速控制台,配置刚才添加的域名,修改回源配置
回源配置-静态协议跟随回源:HTTPS
(重要)回源配置-回源SNI:auth.example.com (添加的加速域名是什么就填什么)
动静态加速规则-动态内容回源配置-动态内容协议跟随回源:HTTPS
第4/7步
为全站加速配置SSL证书并修改HTTP跳转方式
使用上一节在面板配置HTTPS时的SSL证书即可,分别上传证书公钥和私钥,保存
并修改HTTPS配置-强制跳转:HTTP -> HTTPS
第5/7步
除Authelia外,依次为受保护的Web应用域名添加加速域名
操作步骤同上
第6/7步
访问https://b.example.com,测试Authelia是否工作正常
主要测试Authelia的身份认证及请求重定向是否工作正常,若正常,恭喜你,已经完成了Authelia以及全站加速的安全配置,做完最后一点收尾工作就可以开始享受了!
第7/7步
收尾工作:删除Authelia以及Web应用的A/AAAA类型DNS解析记录
(重要)请务必记得删除A/AAAA记录,否则全站加速的安全功能不会生效!
恭喜你,你完成了本篇教程的所有内容,现在你拥有属于你自己的SSO单点登陆系统了!

脚注

  1. 请注意Authelia对不同的反向代理服务应用的支持情况不一,请参考官方提供的兼容性表↩︎
  2. 在Authelia配置的有效认证策略或认证有效时间内(如1小时内)无需二次认证,认证信息过期后仍需要重新认证。 ↩︎
  3. 此处的应用C虽然部署在另一台服务器上,但由于使用了*.example.com的域名,同样可以被同一个Authelia网关所保护,但如果应用C使用了其他域名如c.elpmaxe.com等,则需要更复杂的跨域SSO配置,本文不做讨论。 ↩︎

参考资料

本文由K.K.在chocolax.space首次发布,转载及引用请注明出处并贴出原文跳转链接!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇