From f151b89fa5030b359cd0b8458a2773709b9b928b Mon Sep 17 00:00:00 2001 From: aiyimickey <39365912+aiyimickey@users.noreply.github.com> Date: Mon, 18 May 2026 14:51:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20LLDAP=20=E7=94=A8=E6=88=B7=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E6=9C=8D=E5=8A=A1=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 基于 lldap/lldap:stable-alpine,Dockerfile 预装 sqlite3 - docker-compose.yml:本地含端口映射 (6178:17170, 3890:3890),生产由 deploy-ai.sh 自动去除 - 支持 env_file 配置,本地与生产环境变量分离 --- .env.example | 8 +++ .gitignore | 2 + CHANGELOG.md | 15 +++++ CLAUDE.md | 115 +++++++++++++++++++++++++++++++++++++++ Dockerfile | 2 + README.md | 49 +++++++++++++++++ docker-compose.local.yml | 5 ++ docker-compose.yml | 23 ++++++++ 8 files changed, 219 insertions(+) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 CLAUDE.md create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 docker-compose.local.yml create mode 100644 docker-compose.yml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..d4c9699 --- /dev/null +++ b/.env.example @@ -0,0 +1,8 @@ +# === LLDAP 配置 === +LLDAP_JWT_SECRET=replace_with_openssl_rand_hex_32 +LLDAP_LDAP_USER_PASS=replace_with_admin_password +LLDAP_LDAP_BASE_DN=dc=tlyq,dc=ai +LLDAP_HTTP_PORT=17170 +LLDAP_LDAP_PORT=3890 +LLDAP_DATABASE_PATH=/data/users.db +LLDAP_ADMIN_PASSWORD=replace_with_admin_password diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..24f9f8d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +data/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8ab9eb6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,15 @@ +# 变更日志 + +## 2026-05-14 + +- [安全] 各站点(issue/assets)改为运行时通过 `docker exec lldap printenv` 动态获取 admin 密码,不再写入站点 `.env` 文件,LLDAP 密码修改后即时生效,无需重新部署 +- [新增] 创建 CLAUDE.md、README.md、CHANGELOG.md 项目文档 + +## 2026-05-12 + +- [新增] LLDAP 容器安装 sqlite3,支持 OA 用户管理页面跨站点查询 + +## 2026-05-11 + +- [新增] 从 sso-ai 独立拆出 LLDAP 用户目录服务 +- [调整] 域名改为 tlyq.ai(dc=tlyq,dc=ai) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..dd39d3b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,115 @@ +# CLAUDE.md — LLDAP 用户目录服务 + +## 项目概述 + +ldap-ai 是基于 [LLDAP](https://github.com/lldap/lldap) 的轻量级 LDAP 用户目录服务,域名为内部服务(不对外暴露)。为 OA 统一门户、工单系统、资产管理系统提供统一的 LDAP 用户认证。`dc=tlyq,dc=ai`。 + +--- + +## 快速参考 + +| 属性 | 值 | +|------|-----| +| 用途 | 统一用户目录(LDAP 认证) | +| 服务器 | txjp(IP: 43.133.38.210) | +| 代码路径 | `/root/docker/ldap-ai/` | +| 容器名 | `lldap` | +| 镜像 | `lldap/lldap:stable-alpine` | +| LDAP Base DN | `dc=tlyq,dc=ai` | +| 本地端口 | 6178(Web UI)/ 3890(LDAP) | +| 默认管理员 | `admin` / `admin123` | +| 数据目录 | `data/lldap/`(宿主机挂载) | + +--- + +## 关键文件 + +| 文件 | 职责 | +|------|------| +| `docker-compose.yml` | 生产部署(共用 webnet,不暴露端口) | +| `docker-compose.local.yml` | 本地开发(暴露 6178 + 3890 端口) | +| `.env` | 环境变量(JWT secret、admin 密码、LDAP 端口等) | +| `.env.example` | 环境变量模板 | +| `data/lldap/` | LLDAP 持久化数据(SQLite 用户数据库) | + +--- + +## 环境变量 + +| 变量 | 说明 | +|------|------| +| `LLDAP_JWT_SECRET` | LLDAP JWT 签名密钥 | +| `LLDAP_ADMIN_PASSWORD` | LLDAP admin 用户的 LDAP 密码(也是 Web UI 登录密码) | +| `LLDAP_LDAP_USER_PASS` | LDAP 只读用户的绑定密码(供应用 bind 用) | +| `LLDAP_LDAP_BASE_DN` | LDAP Base DN(`dc=tlyq,dc=ai`) | +| `LLDAP_HTTP_PORT` | Web UI 端口(容器内 17170) | +| `LLDAP_LDAP_PORT` | LDAP 端口(容器内 3890) | +| `LLDAP_DATABASE_PATH` | SQLite 数据库路径 | + +--- + +## Docker 部署 + +``` +txjp 服务器 +├── lldap(容器) ← LLDAP stable-alpine,暴露 :3890 +├── oa-ai / assets-ai / issue-ai ← 各站点直连 lldap:3890 做 LDAP 认证 +└── webnet(external) ← 共享网络 +``` + +**启动**: +```bash +# 本地开发 +cd ldap-ai +docker compose -f docker-compose.yml -f docker-compose.local.yml up -d + +# 云服务器 +ssh txjp "cd /root/docker/ldap-ai && docker compose up -d" +``` + +**Web UI**:`http://localhost:6178`(admin / admin123) + +--- + +## 认证机制 + +各站点(OA/assets/issue)直连 LLDAP 进行 LDAP bind 认证: + +1. **ldapAuth(username, password)**:用户 DN bind 验证 → 成功返回用户信息 +2. **ldapUserExists(username)**:用 admin 凭据搜索用户是否存在(Q1 安全需求:已删除用户需强制退出) +3. **LDAP 密码管理**:OA 通过 `docker exec lldap lldap_set_password` 修改密码 + +--- + +## 开发规范 + +- **新增用户**:通过 OA 用户管理页面创建,底层调用 LLDAP API +- **删除用户**:OA 标记 LLDAP 用户为 inactive,各站点 `ldapUserExists()` 检测到后清除 cookie 踢出 +- **改密码**:OA 调用 `docker exec lldap` 执行 `lldap_set_password` 脚本 +- **LLDAP 故障容错**:`ldapUserExists()` 在 LLDAP 不可达时返回 `true`(放行),不阻断正常登录 +- **admin 密码**:`LLDAP_ADMIN_PASSWORD` 是唯一来源,各站点通过运行时 `docker exec lldap printenv` 动态获取,不写入各站点 `.env` + +--- + +## 服务器操作 + +```bash +# 重启 +ssh txjp "cd /root/docker/ldap-ai && docker compose restart" + +# 重建(配置变更后) +ssh txjp "cd /root/docker/ldap-ai && docker compose down && docker compose up -d" + +# 安装 sqlite3(LLDAP 容器内,用于 OA 用户管理) +ssh txjp "docker exec lldap apk add --no-cache sqlite" + +# 查看日志 +ssh txjp "docker logs lldap" +``` + +### 容器重建后 + +LLDAP 容器重建后,OA 容器需能访问 `sqlite3`(用于查询跨站点用户数据)。每次容器重建后需重新安装: +```bash +docker exec lldap apk add --no-cache sqlite +``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ac5774e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,2 @@ +FROM lldap/lldap:stable-alpine +RUN apk add --no-cache sqlite diff --git a/README.md b/README.md new file mode 100644 index 0000000..6e2a32f --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# ldap-ai — LLDAP 用户目录服务 + +基于 [LLDAP](https://github.com/lldap/lldap) 的统一用户目录,为 tlyq.ai 全部站点提供 LDAP 身份认证。 + +## 快速启动 + +```bash +cd ldap-ai + +# 本地开发(暴露 Web UI :6178 + LDAP :3890) +docker compose -f docker-compose.yml -f docker-compose.local.yml up -d + +# 云服务器(仅内网,不暴露端口) +docker compose up -d +``` + +Web UI:`http://localhost:6178`(admin / admin123) + +## 目录结构 + +``` +ldap-ai/ +├── docker-compose.yml # 生产部署 +├── docker-compose.local.yml # 本地开发端口映射 +├── .env # 环境变量(不提交) +├── .env.example # 环境变量模板 +├── data/lldap/ # 用户数据库(持久化) +├── CLAUDE.md # AI 助手上下文 +├── README.md # 本文件 +└── CHANGELOG.md # 变更历史 +``` + +## 关联站点 + +| 站点 | 用途 | LDAP 交互 | +|------|------|-----------| +| `oa-ai` | 统一门户 | 用户登录认证 + 密码修改 + 用户管理 | +| `issue-ai` | 工单系统 | 用户登录认证 + SSO 用户存在性检查 | +| `assets-ai` | 资产管理 | 用户登录认证 + SSO 用户存在性检查 | + +## 管理操作 + +```bash +# 查看数据 +docker exec lldap ls /data/ + +# 备份数据库 +cp data/lldap/users.db data/lldap/users.db.bak.$(date +%Y%m%d) +``` diff --git a/docker-compose.local.yml b/docker-compose.local.yml new file mode 100644 index 0000000..a4a82e4 --- /dev/null +++ b/docker-compose.local.yml @@ -0,0 +1,5 @@ +services: + lldap: + ports: + - "6178:17170" # LLDAP Web UI + - "3890:3890" # LDAP 端口(供本地站点直连) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4efde50 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +services: + lldap: + build: . + container_name: lldap + ports: + - "6178:17170" + - "3890:3890" + env_file: + - .env + volumes: + - ./data/lldap:/data + networks: + - webnet + healthcheck: + test: ["CMD-SHELL", "wget -q -O - http://127.0.0.1:17170 || exit 1"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + +networks: + webnet: + external: true