934 字
5 分钟
Tinyauth 自托管 身份验证 中间件

Source && Doc#

https://github.com/steveiliop56/tinyauth?tab=readme-ov-file https://tinyauth.app/docs/about.html 强烈建议阅读,此文章只是个推荐,重复造轮子

介绍#

首先说一下需求,在Selfhost 缺少身份验证或者是类似PHP等这种很容易存在漏洞应用,需要多一层验证(当然最佳实践应该是直接使用VPN内部访问,不公开到公网,但是有些应用还是存在这种使用场景)。 本身其实有大量的身份验证应用比如Authelia/Authentik/Keycloack之类。

原因1#

大部分这些工具为了企业级生产力需求会十分复杂。比如之前使用的Authentik,他的compose需要简简单单147行(

services:
authentik-postgresql:
image: docker.io/library/postgres:16-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- ./database:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS:?database password required}
POSTGRES_USER: ${PG_USER:-authentik}
POSTGRES_DB: ${PG_DB:-authentik}
env_file:
- .env
networks:
- default
authentik-redis:
image: docker.io/library/redis:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
start_period: 20s
interval: 30s
retries: 5
timeout: 3s
volumes:
- redis_authentik:/data
networks:
- default
authentik-server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG}
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
volumes:
- ./authentik/media:/media
- ./authentik/custom-templates:/templates
# - /var/run/docker.sock:/var/run/docker.sock
env_file:
- .env
# ports:
# - "${COMPOSE_PORT_HTTP:-9000}:9000"
# - "${COMPOSE_PORT_HTTPS:-9443}:9443"
networks:
- public_web
- default
depends_on:
authentik-postgresql:
condition: service_healthy
authentik-redis:
condition: service_healthy
labels:
homepage.group: Networking
homepage.name: Authentik
homepage.icon: authentik
homepage.href: "https://auth.CHANGEME.com"
traefik.enable: true
traefik.http.routers.authentik.rule: Host(`auth.CHANGEME.com`)
traefik.http.services.authentik.loadbalancer.server.port: 9000
traefik.docker.network: public_web
traefik.public: true
authentik-proxy:
image: ghcr.io/goauthentik/proxy:${AUTHENTIK_TAG:-2024.10.5}
# ports:
# - 9000:9000
# - 9443:9443
networks:
- public_web
- default
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_HOST: http://authentik-server:9000
AUTHENTIK_INSECURE: "true"
AUTHENTIK_TOKEN: ${AUTHENTIK_TRAEFIK_EXT_OUTPOST_TOKEN}
# Starting with 2021.9, you can optionally set this too
# when authentik_host for internal communication doesn't match the public URL
AUTHENTIK_HOST_BROWSER: https://auth.CHANGEME.com
# for logging edit log_level in outpost config from ui
labels:
traefik.enable: true
traefik.port: 9000
traefik.http.routers.authentik-proxy.rule: Host(`CHANGEME.com`) && PathPrefix(`/outpost.goauthentik.io/`)
# `authentik-proxy` refers to the service name in the compose file.
traefik.http.middlewares.authentik-proxy.forwardauth.address: http://authentik-proxy:9000/outpost.goauthentik.io/auth/traefik
traefik.http.middlewares.authentik-proxy.forwardauth.trustForwardHeader: true
traefik.http.middlewares.authentik-proxy.forwardauth.authResponseHeaders: X-authentik-username,X-authentik-groups,X-authentik-entitlements,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version
traefik.public: true
kop.namespace: none
restart: unless-stopped
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.10.5}
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: authentik-redis
AUTHENTIK_POSTGRESQL__HOST: authentik-postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
# `user: root` and the docker socket volume are optional.
# See more for the docker socket integration here:
# https://goauthentik.io/docs/outposts/integrations/docker
# Removing `user: root` also prevents the worker from fixing the permissions
# on the mounted folders, so when removing this make sure the folders have the correct UID/GID
# (1000:1000 by default)
user: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./authentik/media:/media
- ./authentik/certs:/certs
- ./authentik/custom-templates:/templates
env_file:
- .env
depends_on:
authentik-postgresql:
condition: service_healthy
authentik-redis:
condition: service_healthy
networks:
- default
networks:
default:
internal: true
public_web:
external: true
volumes:
redis_authentik:
driver: local

原因2#

最近把家里的架构由Nginx手动创建变成了Compose + Traefik,现在我创建一个服务的反向代理,只需要向下面这样,在docker compose,反向代理将自动化生成。所以支持通过labels描述,并且自动加载

labels:
traefik.enable: true
traefik.public: true
traefik.docker.network: traefik_external_public_web
#-----
traefik.http.routers.hlpj-alist.rule: Host(`alist.homelabproject.cc`)||Host(`file.homelabproject.cc`)
traefik.http.routers.hlpj-alist.entrypoints: cf
traefik.http.services.hlpj-alist.loadbalancer.server.port: 5244
traefik.http.routers.hlpj-alist.service: hlpj-alist
#---cloudflared---
cloudflare.tunnel.enable: "true"
cloudflare.tunnel.0.hostname: alist.homelabproject.cc
cloudflare.tunnel.0.service: http://traefik:808
cloudflare.tunnel.0.zonename: homelabproject.cc
cloudflare.tunnel.1.hostname: file.homelabproject.cc
cloudflare.tunnel.1.service: http://traefik:808
cloudflare.tunnel.1.zonename: homelabproject.cc

配置#

基础容器#

首先你需要最基础3个条件

  • SECERT变量 直接在命令行行随机生成一个32字节的随机密钥
openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32
  • USERS 你的用户名密码,命令行输入下面,会进入交互,记得在问你是否使用docker的时候选择yes
docker run -i -t --rm ghcr.io/steveiliop56/tinyauth:v3 user create --interactive

你就会得到转换完用于登陆的账号密码的bcrypt 哈希。如果你有多个账号密码用,隔开

  • 用于验证的域名 tinyauth的访问流程:当你访问需要身份验证的域名,他会转条到tinyauth.你的域名.com验证账号密码,然后你再回到你服务的域名就能正常访问了。 所以需要提前配置好你的域名

最后,配置你下面的环境变量,启动即可

tinyauth:
image: ghcr.io/steveiliop56/tinyauth:v3
container_name: tinyauth
restart: unless-stopped
environment:
- SECRET=some-random-32-chars-string
- APP_URL=https://tinyauth.你的域名.com
- USERS=your-username-password-hash
labels:
traefik.enable: true
traefik.http.routers.tinyauth.rule: Host(`tinyauth.你的域名.com`)
traefik.http.middlewares.tinyauth.forwardauth.address: http://tinyauth:3000/api/auth/traefik

配置需要验证的应用#

你只需要附带Label,添加Router的中间件,即可访问

labels:
traefik.http.routers.[你的服务].middlewares: tinyauth@docker

总结#

tinyauth的目的本身就不是为了生产力,对于Homelab来说就是简洁高效,个人觉得还是挺好用。

Tinyauth 自托管 身份验证 中间件
https://www.homelabproject.cc/posts/container/tinyauth-自托管-身份验证-中间件/
作者
Channing He
发布于
2025-06-07
许可协议
CC BY-NC-SA 4.0