自托管服务越来越多,账号怎么统一:LLDAP 的部署、应用接入与权限边界

从目录、登录和权限的区别出发,部署 LLDAP,配置只读绑定账号,验证组权限,并处理本地账号迁移、会话撤销与恢复。

·10 min身份认证
把应用部署到土耳其|BRNCHOST · 土耳其 VDS
云服务器,积分可续期|雨云 · 国内外节点 · 积分兑换权益
低价年付,大流量 VPS|RackNerd · SSD 存储 · 1Gbps 端口
香港轻量,搭个小站|晚安云 · 香港云服务器
香港 VPS,大带宽可选|野草云 · BGP 直连
大陆访问,精品线路|搬瓦工 · CN2 GIA / CTGNet 套餐
资料归档,交给 AI 整理|WorkBuddy · 本地文件处理
建站起步,先看应用镜像|腾讯云 · 轻量应用服务器
CN2 GIA,中国方向优化|DMIT · Premium 网络
双 ISP 原生住宅 IP|丽萨主机 · 美国 9929 精品线路
高频 CPU,多地部署|Evoxt · 云服务器 · 每周异地备份
京东云轻量云主机:129元/年,新人专享,限购1台

家里或团队里已经有文件服务、照片库和代码仓库,每增加一个应用,就多出一套账号。新成员加入要逐个开通,离开时又怕漏关一个;密码改了一次,有的地方生效,有的地方还在使用旧密码。

LLDAP 可以作为一个轻量的用户目录,集中保存用户、组和相关属性,让支持 LDAP 的应用到这里核对身份。它适合规模不大、愿意自己维护账号体系的环境。真正决定能否用好它的,是应用接入方式、权限范围和停用用户后的实际行为。

先分清目录、登录和应用权限

用户目录回答“这个人是谁,属于哪些组”。应用登录回答“这次访问是否完成了认证”。应用权限还要决定“登录以后能看哪些文件、管理哪些项目”。把账号搬进 LLDAP,并不会自动让所有应用的这三层行为一致。

LDAP 也不等于浏览器里的单点登录。一个应用接入 LDAP 以后,可能仍然要求用户在自己的登录框里输入用户名和密码。只有在另外的认证系统和兼容应用之间配置了相应协议,才可能得到一次登录后跨应用访问的体验。不要因为账号和密码一样,就把两次登录理解成一套共享会话。

LLDAP 项目说明明确把自己定位为简化的目录服务,并非完整替代所有企业目录功能。打算接入之前,先核对应用支持的 LDAP 字段、用户搜索方式和组过滤方式。如果应用要求的是 OIDC 或 SAML,而没有 LDAP 支持,应先研究它真正需要的认证服务,不能把一个 LDAP 地址填进去试运气。

可以先挑一个不重要的应用接入,用两名测试用户验证。一次改动全部服务,看似节省安装时间,后面却很难区分是目录问题、应用配置问题还是旧会话问题。

让3890端口留在需要它的网络里

LLDAP 的容器示例使用17170端口提供 Web 管理界面,3890端口提供 LDAP。Web 页面有了 HTTPS,LDAP 连接并不会因此自动得到加密。这是部署时最容易混在一起的两条路径。

试用环境中,可以让管理端口只监听宿主机本地,应用和 LLDAP 在专门的 Docker 网络里通信。下面的配置使用具名卷保存数据,并通过环境文件传入初始化参数:

services:
  lldap:
    image: lldap/lldap:stable
    restart: unless-stopped
    env_file:
      - lldap.env
    ports:
      - "127.0.0.1:17170:17170"
    volumes:
      - lldap-data:/data
    networks:
      - directory

volumes:
  lldap-data:

networks:
  directory:

这是单机接入的起点,正式使用时将镜像固定为经过验证的标签或摘要。把支持 LDAP 的应用接入 directory 网络,它就能使用 ldap://lldap:3890 访问目录。若应用属于另一个 Compose 项目,应明确创建共享网络并配置双方接入,不能假定不同项目的默认网络会互通。

管理页面可以通过 SSH 隧道访问:

ssh -N -L 17170:127.0.0.1:17170 user@server.example.com

在本机浏览器打开 http://127.0.0.1:17170。不要在公网映射3890端口,只因为某个远端应用连接不上就把目录开放给所有来源。跨主机连接要根据实际拓扑选用受控私人网络或 LDAPS,并验证对端证书。

初始化的三个秘密要分开保存

依照安装文档,环境变量使用 LLDAP_ 前缀。首次运行之前创建 lldap.env:

UID=1000
GID=1000
TZ=Asia/Shanghai
LLDAP_LDAP_BASE_DN=dc=example,dc=com
LLDAP_JWT_SECRET=替换为独立生成的随机值
LLDAP_KEY_SEED=替换为另一份独立随机值
LLDAP_LDAP_USER_PASS=替换为管理员初始密码

每个值分别生成,不能把管理员密码重复用作 JWT secret 和 key seed。可以用 openssl rand -hex 32 生成随机字符串,随后设置环境文件权限:

chmod 600 lldap.env
docker compose config --quiet
docker compose up -d
docker compose logs --tail=100 lldap

UID、GID需要按选用镜像和数据目录的实际权限配置。默认镜像与 rootless 镜像的用户配置方式不同,不应在更换镜像类型时只改一个标签。出现数据写入失败,先检查卷权限,再检查应用日志,别直接把整个目录改成任意用户可写。

Base DN 是目录结构的一部分。例如 dc=example,dc=com 会出现在用户和组的完整 DN 中。已经接入多个应用以后,再修改它,涉及各应用的搜索基准和绑定配置。因此尽量在试用阶段确定,不要随着公开网站域名变化随手调整。

给应用一个只负责查询的账号

应用连接目录时通常需要一个绑定账号。把管理员账号填到每个应用里,虽然容易跑通,却把完整的目录管理能力扩散到了所有这些服务。

LLDAP 提供 lldap_strict_readonly、lldap_password_manager 等不同用途的组。普通认证集成通常应使用只读账号;是否需要密码管理能力,取决于该应用是否真的承担目录密码修改工作。权限与客户端说明列出了这些差异。

可以创建一个专用于应用查询的用户,例如 svc_files,让它加入适合的只读组,不加入 lldap_admin。不同应用分别建立查询账号,日后撤销某一服务访问时,能够单独轮换凭据,而不必一起改动所有系统。

按照当前项目给出的 DN 结构,用户通常位于 ou=people 下。例如:

绑定 DN:cn=svc_files,ou=people,dc=example,dc=com
用户搜索基准:ou=people,dc=example,dc=com
用户 DN 示例:cn=alice,ou=people,dc=example,dc=com
组 DN 示例:cn=editors,ou=groups,dc=example,dc=com

这些是示例值。接入具体应用时,照它的 LDAP 适配说明确认登录名字段和搜索过滤器,不要根据其他目录服务的经验,把 cn 随手改成 uid。同一个用户在某应用能登录,不足以证明另一个应用的查询字段也正确。

组成员关系必须在应用里验证

目录里建立 editors、readers 之类的业务组,再由应用决定这些组对应什么权限。可以用 memberOf 过滤组成员,项目示例的形式如下:

(memberOf=cn=editors,ou=groups,dc=example,dc=com)

但过滤用户和授予权限仍是两件事。一个应用可能只用这个过滤器决定允许谁登录,文件夹权限还由应用自己的角色管理;另一个应用则支持同步组。迁移前写清楚每个应用是哪一种,不要把它们当成同一套行为。

测试时至少准备一个编辑用户和一个只读用户。让两人分别登录,看得到的目录、按钮和实际写入操作都检查一遍。仅仅隐藏按钮不够,还应尝试对应操作是否被服务端拒绝。把用户移出某个业务组后,重复登录与操作,观察权限是即时读取、下次登录更新,还是需要同步任务。

LLDAP 的管理员组是目录管理员组,不应拿它当作所有应用的“超级管理员”业务组。目录管理权限与某个应用的管理权限分开命名,也能减少以后误配。

停用账号以后,为什么还能访问

账号停用、密码修改、组成员移除和已有会话失效,不一定同时发生。应用可能在登录时查询目录,登录成功以后用自己的 cookie 或 token 维持会话。

这意味着从目录移除用户以后,他已经登录的浏览器可能还能够访问应用。是否支持强制登出、是否有独立 API token、是否允许本地账号绕过 LDAP,都要在应用端检查。为成员离开准备一条可执行流程:目录侧处理账号,应用侧撤销会话、API token 和其他授权,再用原账号验证。

保留一个受控的本地应急管理员通常有价值,但不能让它变成团队共享的日常登录方式。把凭据单独保存,并明确哪些人有权使用。否则目录一出问题,既可能所有人被锁在外面,也可能大家绕过目录继续操作,权限治理失去意义。

已有本地账号迁入目录,要先核对身份映射

一个用户名看起来相同,不代表应用认为它是同一个账户。文件服务或代码仓库可能用内部 ID 关联数据,LDAP 登录则可能依据用户名或邮箱创建新记录。接入前用测试账号验证:原有文件、项目、权限与新登录能否正确关联,避免给同一个人生成两套身份。

需要批量迁移时,先整理本地用户、目录用户和应用内部标识的对应表。重名、邮箱变化以及已经停用的账户单独处理,不要依靠自动匹配猜测。应用若提供正式迁移方法,按其说明执行;没有明确路径时,先保留原系统可恢复状态,小范围验证后再扩大。

密码也不能假定能够原样搬迁。不同系统的保存方式与导出能力不同,可能需要用户重新设置。迁移通知要说明何时切换、哪些服务受影响,以及旧凭据何时失效,避免用户在几个登录入口间反复尝试。

完成后再检查自动化账户。同步程序、备份工具和机器人可能使用长期令牌或本地服务账户,并不受目录组变更控制。它们应登记用途与负责人,不能仅因为人员名单已统一,就认为所有访问凭据都已纳入管理。

目录故障会把多少应用拖进去

集中账号以后,目录成为多个应用的共同依赖。服务器重启、磁盘写满、证书错误或网络隔离,都可能表现为不同应用突然无法登录。

排查时按顺序确认:目录进程是否正常、应用是否能到达 LDAP 地址、绑定账号是否可用、用户搜索能否返回预期记录。HTTP 管理页面能打开,只能证明 Web 路径正常;3890或6360的连接仍需单独检查。

先接入一两个应用,再决定目录应该部署在哪里。小环境未必需要复杂的多节点架构,但至少要避免把所有登录入口与唯一备份一起放在一台容易被随手重装的测试机上。

恢复目录比重新创建管理员更重要

默认数据保存在 /data,其中包含目录配置和 SQLite 数据库。采用外部数据库时,数据库与配置又成为两部分。配置模板可以帮助核对哪些参数放在文件里,哪些由环境变量覆盖。

小规模单机可以在维护时间停止 LLDAP,对具名卷做一致的离线备份,同时保存环境文件和秘密值。备份交给独立存储,不要把密钥明文与公开代码放在一起。恢复时保持原有目录结构和所需秘密,不要为了“换新服务器”重新生成所有值。

在隔离环境恢复后,检查用户数量、组成员关系、普通用户登录和只读绑定账号,再用一个测试应用确认认证流程。整个过程中禁用真实通知和密码重置邮件,避免测试环境给成员发出误导消息。

统一账号的成果,应当是成员开通和撤销能做得更清楚。最终验收可以选一次完整的成员变更:新建用户、加入业务组、登录应用、降为只读、撤销账号与会话。每一步都能解释清楚,才值得继续把更多应用接进来。