【保姆级】从零构建家庭数据中心的安全堡垒:Caddy + Authelia 部署全指南
在折腾 NAS 和家庭实验室(HomeLab)的过程中,我们经常面临一个矛盾:想把服务暴露到公网方便访问,又担心后台裸奔被黑客扫爆。
单纯的 Basic Auth(浏览器弹窗输入密码)体验差且不支持双重验证(2FA),而 VPN 又稍显繁琐。今天,我们来部署一套企业级的零信任身份认证系统:Caddy + Authelia。
🌟 为什么选择这套方案?
- Caddy:配置最简单的现代化 Web 服务器,自动申请 HTTPS 证书,原生支持
forward_auth。 - Authelia:开源的轻量级认证中心,支持 2FA (两步验证)、单点登录 (SSO)。
- 效果:访问你所有的服务(飞牛、群晖、Portainer、Jellyfin)前,都会先跳转到一个漂亮的登录界面,验证通过后自动放行。
🛠️ 准备工作
- 一台服务器/NAS:安装好 Docker 和 Docker Compose。
- 一个域名:并解析到你的服务器 IP(推荐泛解析,如
*.example.com)。 - 基础知识:会使用 SSH 连接服务器。
第一步:目录结构与环境搭建
为了方便管理,建议在 /data/authelia 目录下统一存放文件。
mkdir -p /data/authelia/config
mkdir -p /data/caddy/config
mkdir -p /data/caddy/data创建 docker-compose.yml
在 /data 目录下创建一个 docker-compose.yml,我们将 Caddy 和 Authelia 放在同一个网络中。
version: '3.8'
services:
# --- 认证中心服务 ---
authelia:
image: authelia/authelia
container_name: authelia
restart: unless-stopped
volumes:
- ./authelia/config:/config
environment:
- TZ=Asia/Shanghai
networks:
- caddy_net
# Authelia 不需要端口映射到宿主机,因为它只跟 Caddy 对话
# --- Redis (可选,推荐) ---
# 用于存储 Session,比文件存储更稳定
redis:
image: redis:alpine
container_name: authelia_redis
restart: unless-stopped
networks:
- caddy_net
# --- 网关/反向代理 ---
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- ./caddy/data:/data
- ./caddy/config:/config
networks:
- caddy_net
networks:
caddy_net:
driver: bridge第二步:配置 Authelia (核心难点)
Authelia 的配置比较严格,请务必细心。我们需要在该目录下新建两个文件:configuration.yml (主配置) 和 users_database.yml (用户库)。
1. 生成用户密码 Hash
Authelia 不保存明文密码,我们需要先生成一个加密后的密码。运行以下命令(将 你的密码 换成你想设置的):
docker run --rm authelia/authelia authelia crypto hash generate pbkdf2 --password '你的密码'你会得到一串类似 $pbkdf2-sha512$.... 的字符串,复制下来。
2. 创建用户文件 (users_database.yml)
在 /data/authelia/config/ 下新建 users_database.yml:
users:
admin:
displayname: "Administrator"
password: "$pbkdf2-sha512$..." # 粘贴刚才生成的 Hash 字符串
email: [email protected]
groups:
- admins
- dev3. 创建主配置文件 (configuration.yml)
在 /data/authelia/config/ 下新建 configuration.yml。
⚠️ 注意: 请将文中 example.com 替换为你自己的域名!###############################################################
# Authelia Configuration #
###############################################################
theme: light
# 1. JWT 密钥 (生成一个随机字符串填进去)
jwt_secret: a_very_important_secret_random_string_12345
# 2. 默认访问策略
access_control:
default_policy: deny # 默认拒绝所有,必须登录
rules:
# 内网免密 (根据需要开启)
# - domain: "*.example.com"
# networks:
# - 192.168.1.0/24
# policy: bypass
# 特定子域名需要双重认证
- domain: "secure.example.com"
policy: two_factor
# 其他子域名只需要单因素密码
- domain: "*.example.com"
policy: one_factor
# 3. Session 存储 (使用 Redis)
session:
name: authelia_session
secret: another_very_important_secret_random_string
expiration: 3600 # 1小时过期
inactivity: 300 # 5分钟无操作过期
domain: example.com # ⚠️ 必须是根域名
redis:
host: authelia_redis
port: 6379
# 4. 存储后端 (这里使用轻量级的文件存储)
storage:
local:
path: /config/db.sqlite3
# 5. 通知方式 (用于发送 2FA 验证码或重置密码)
# 初次测试建议使用 filesystem,它会把邮件内容保存到文件中
notifier:
filesystem:
filename: /config/notification.txt
# 6. 身份验证后端 (引用刚才创建的文件)
authentication_backend:
file:
path: /config/users_database.yml第三步:配置 Caddy (连接桥梁)
在 /data/caddy/ 下创建 Caddyfile。这是 Caddy 能够通过 Authelia 验证的关键。
# --- 定义 Authelia 中间件 ---
(authelia) {
forward_auth authelia:9091 {
# 这里的地址是 Authelia 容器内部地址
uri /api/verify?rd=https://auth.example.com
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
}
}
# --- 1. Authelia 认证门户 ---
auth.example.com {
reverse_proxy authelia:9091
}
# --- 2. 需要保护的服务 (例如 Whoami 测试页) ---
whoami.example.com {
# 引用认证模块,这就加上了锁
import authelia
# 认证通过后转发给后端
reverse_proxy 127.0.0.1:2001
}
# --- 3. 保护飞牛/NAS ---
nas.example.com {
import authelia
reverse_proxy 192.168.1.100:5000
}第四步:启动与验证
启动服务
在 /data 目录下执行:
docker-compose up -d首次登录验证
- 在浏览器访问
https://whoami.example.com。 - 你会发现 URL 自动跳转到了
https://auth.example.com。 - 输入你在
users_database.yml里设置的账号admin和密码。 配置 2FA (双重认证):
- 页面会提示你注册设备。
- 点击注册,Authelia 会发送一封“邮件”。
查看邮件:由于我们配置的是
filesystem通知,请去服务器查看文件:cat /data/authelia/config/notification.txt- 复制文件里的链接,在浏览器打开。
- 你会看到一个二维码,使用 Google Authenticator 或 Microsoft Authenticator 扫码。
- 验证通过后,你将成功跳转回
whoami.example.com。
💡 进阶技巧:解决 WebDAV/App 无法连接问题
加上 Authelia 后,你会发现手机上的 Infuse、RaiDrive 或者 Emby 客户端连不上了。这是因为这些 App 不会处理网页跳转。
解决方案: 在 Caddy 中针对 API 路径绕过认证。
修改 Caddyfile 中的 NAS 配置:
nas.example.com {
# 定义 WebDAV 或 API 的路径匹配器
@bypass_paths {
path /dav* /webdav* /emby* /api*
}
# 1. 针对 App/API:直接放行 (或仅使用 Basic Auth)
handle @bypass_paths {
reverse_proxy 192.168.1.100:5000
}
# 2. 针对网页访问:强制 Authelia 认证
handle {
import authelia
reverse_proxy 192.168.1.100:5000
}
}❓ 常见问题排查 (Troubleshooting)
无限重定向 (Redirect Loop):
- 检查
configuration.yml中的session.domain是否设置正确,必须是根域名(如example.com),不能是子域名。 - 检查 Caddyfile 中的
rd=https://auth.example.com地址是否正确。
- 检查
Caddy 报错 "dial tcp: lookup authelia...":
- 确保 Caddy 和 Authelia 在同一个 Docker Network 下。
无法写入 notification.txt:
- 检查
/data/authelia/config目录的权限,Docker 容器内的用户需要有写入权限。
- 检查
结语
通过这套 Caddy + Authelia 的组合,你已经成功将家庭数据中心的安全等级提升到了企业标准。现在,你可以放心地将服务暴露在公网,享受随时随地访问的便利,同时把所有恶意扫描拒之门外!