跳过正文
  1. 博客文章/

Docker 部署 OpenLDAP 统一身份认证服务

·2305 字·11 分钟·
DevOps Openldap Docker Authentication DevOps
Zayn
作者
Zayn
专注 Kubernetes、CI/CD、可观测性等云原生技术栈,记录生产环境中的实战经验与踩坑复盘。
目录

OpenLDAP 简介
#

什么是 OpenLDAP
#

OpenLDAP 是一个开源的轻量级目录访问协议(LDAP)实现,广泛用于企业级统一身份认证和目录服务。它提供了集中化的用户管理、身份验证和授权功能。

核心特性
#

  • 统一身份认证:为多个应用系统提供统一的用户认证服务
  • 目录服务:提供层次化的信息存储和检索
  • 高性能:支持高并发的读写操作
  • 可扩展性:支持主从复制和分布式部署
  • 标准兼容:完全兼容 LDAP v3 标准

应用场景
#

  • 企业统一认证:员工账号统一管理
  • DevOps 工具链集成:Jenkins、GitLab、Nexus 等工具的统一认证
  • 应用系统集成:为各类业务系统提供认证服务
  • 权限管理:基于组织架构的权限控制

环境要求
#

系统环境
#

  • 操作系统:CentOS 7+、Ubuntu 18.04+、RHEL 7+
  • Docker 版本:19.03.8+
  • Docker Compose 版本:1.25.0+
  • 内存要求:最少 2GB RAM
  • 存储要求:至少 10GB 可用空间

使用的 Docker 镜像
#

组件镜像用途
OpenLDAP 服务osixia/openldap:latestLDAP 目录服务
Web 管理界面osixia/phpldapadmin:latestLDAP 可视化管理
密码自助服务grams/ltb-self-service-password:latest用户密码自助修改

网络端口规划
#

服务端口协议说明
OpenLDAP389TCPLDAP 标准端口
OpenLDAP SSL636TCPLDAPS 加密端口(可选)
phpLDAPadmin30004TCPWeb 管理界面
密码自助服务8765TCP用户密码修改界面

部署 OpenLDAP 服务
#

步骤 1:准备部署环境
#

创建项目目录
#

# 创建项目根目录
mkdir -p /data/openldap && cd /data/openldap

# 创建数据持久化目录
mkdir -p {data,config,backup,scripts}

# 设置目录权限
chmod -R 755 /data/openldap

创建 Docker 网络
#

# 创建专用网络(可选,用于服务间通信)
docker network create ldap-network

步骤 2:配置 Docker Compose
#

基础配置文件
#

cat > docker-compose.yaml << 'EOF'
version: "3.8"

services:
  openldap:
    container_name: openldap-server
    image: osixia/openldap:1.5.0
    restart: unless-stopped
    hostname: ldap.treesir.pub
    environment:
      # 基础配置
      LDAP_ORGANISATION: "TreeSir Organization"
      LDAP_DOMAIN: "treesir.pub"
      LDAP_BASE_DN: "dc=treesir,dc=pub"

      # 管理员密码
      LDAP_ADMIN_PASSWORD: "AdminPass123!"
      LDAP_CONFIG_PASSWORD: "ConfigPass123!"

      # 安全配置
      LDAP_READONLY_USER: "false"
      LDAP_RFC2307BIS_SCHEMA: "false"
      LDAP_BACKEND: "mdb"
      LDAP_TLS: "true"
      LDAP_TLS_CRT_FILENAME: "ldap.crt"
      LDAP_TLS_KEY_FILENAME: "ldap.key"
      LDAP_TLS_DH_PARAM_FILENAME: "dhparam.pem"
      LDAP_TLS_CA_CRT_FILENAME: "ca.crt"
      LDAP_TLS_ENFORCE: "false"
      LDAP_TLS_CIPHER_SUITE: "SECURE256:-VERS-SSL3.0"
      LDAP_TLS_VERIFY_CLIENT: "demand"

      # 日志配置
      LDAP_LOG_LEVEL: "256"

      # 复制配置(可选)
      LDAP_REPLICATION: "false"

    volumes:
      - ./data:/var/lib/ldap
      - ./config:/etc/ldap/slapd.d
      - ./backup:/data/backup
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "389:389"
      - "636:636"
    networks:
      - ldap-network

  phpldapadmin:
    container_name: phpldapadmin-web
    image: osixia/phpldapadmin:0.9.0
    restart: unless-stopped
    hostname: phpldapadmin.treesir.pub
    environment:
      PHPLDAPADMIN_LDAP_HOSTS: "openldap-server"
      PHPLDAPADMIN_HTTPS: "false"
      PHPLDAPADMIN_TRUST_PROXY_SSL: "true"
    volumes:
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "30004:80"
    depends_on:
      - openldap
    networks:
      - ldap-network

networks:
  ldap-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16
EOF

生产环境配置(推荐)
#

cat > docker-compose.prod.yaml << 'EOF'
version: "3.8"

services:
  openldap:
    container_name: openldap-server
    image: osixia/openldap:1.5.0
    restart: unless-stopped
    hostname: ldap.example.com
    environment:
      LDAP_ORGANISATION: "Example Corporation"
      LDAP_DOMAIN: "example.com"
      LDAP_BASE_DN: "dc=example,dc=com"
      LDAP_ADMIN_PASSWORD_FILE: "/run/secrets/ldap_admin_password"
      LDAP_CONFIG_PASSWORD_FILE: "/run/secrets/ldap_config_password"
      LDAP_TLS: "true"
      LDAP_TLS_ENFORCE: "true"
      LDAP_LOG_LEVEL: "0"
    volumes:
      - ./data:/var/lib/ldap
      - ./config:/etc/ldap/slapd.d
      - ./certs:/container/service/slapd/assets/certs
      - ./backup:/data/backup
    ports:
      - "389:389"
      - "636:636"
    secrets:
      - ldap_admin_password
      - ldap_config_password
    networks:
      - ldap-network

  phpldapadmin:
    container_name: phpldapadmin-web
    image: osixia/phpldapadmin:0.9.0
    restart: unless-stopped
    environment:
      PHPLDAPADMIN_LDAP_HOSTS: "openldap-server"
      PHPLDAPADMIN_HTTPS: "true"
    volumes:
      - ./web-certs:/container/service/phpldapadmin/assets/apache2/certs
    ports:
      - "443:443"
    depends_on:
      - openldap
    networks:
      - ldap-network

secrets:
  ldap_admin_password:
    file: ./secrets/ldap_admin_password.txt
  ldap_config_password:
    file: ./secrets/ldap_config_password.txt

networks:
  ldap-network:
    driver: bridge
EOF

步骤 3:启动服务
#

开发环境启动
#

# 启动服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f openldap

生产环境启动
#

# 创建密码文件
mkdir -p secrets
echo "YourStrongAdminPassword123!" > secrets/ldap_admin_password.txt
echo "YourStrongConfigPassword123!" > secrets/ldap_config_password.txt
chmod 600 secrets/*.txt

# 启动生产环境
docker-compose -f docker-compose.prod.yaml up -d

步骤 4:验证部署
#

检查服务状态
#

# 检查容器状态
docker ps | grep ldap

# 检查端口监听
netstat -tlnp | grep -E "(389|636|30004)"

# 测试 LDAP 连接
ldapsearch -x -H ldap://localhost:389 -b "dc=treesir,dc=pub" -D "cn=admin,dc=treesir,dc=pub" -W

访问管理界面
#

  1. 打开浏览器访问:http://your-server-ip:30004
  2. 登录信息:
    • 服务器openldap-server
    • 用户名cn=admin,dc=treesir,dc=pub
    • 密码AdminPass123!(或您设置的密码)

健康检查脚本
#

cat > scripts/health-check.sh << 'EOF'
#!/bin/bash

echo "=== OpenLDAP Health Check ==="
echo "Date: $(date)"
echo

# 检查容器状态
echo "=== Container Status ==="
docker ps --filter "name=openldap" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
echo

# 检查 LDAP 服务
echo "=== LDAP Service Check ==="
if ldapsearch -x -H ldap://localhost:389 -b "" -s base > /dev/null 2>&1; then
    echo "✓ LDAP service is running"
else
    echo "✗ LDAP service is not responding"
fi

# 检查管理界面
echo "=== Web Interface Check ==="
if curl -s http://localhost:30004 > /dev/null; then
    echo "✓ phpLDAPadmin is accessible"
else
    echo "✗ phpLDAPadmin is not accessible"
fi

echo
echo "=== Resource Usage ==="
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
EOF

chmod +x scripts/health-check.sh
./scripts/health-check.sh

LDAP 目录结构设计与初始化
#

目录结构规划
#

标准企业目录结构
#

dc=treesir,dc=pub
├── ou=people                    # 用户组织单元
│   ├── uid=john.doe            # 用户条目
│   ├── uid=jane.smith          # 用户条目
│   └── ...
├── ou=groups                   # 组织单元
│   ├── cn=developers          # 开发组
│   ├── cn=administrators      # 管理员组
│   ├── cn=users              # 普通用户组
│   └── ...
├── ou=roles                    # 角色组织单元(可选)
│   ├── cn=project-manager     # 项目经理角色
│   ├── cn=team-lead          # 团队负责人角色
│   └── ...
└── ou=services                 # 服务账号组织单元(可选)
    ├── uid=jenkins            # Jenkins 服务账号
    ├── uid=gitlab             # GitLab 服务账号
    └── ...

使用 LDIF 文件初始化目录结构
#

创建初始化脚本
#

cat > scripts/init-ldap-structure.sh << 'EOF'
#!/bin/bash

LDAP_HOST="localhost"
LDAP_PORT="389"
LDAP_ADMIN_DN="cn=admin,dc=treesir,dc=pub"
LDAP_BASE_DN="dc=treesir,dc=pub"

echo "正在初始化 LDAP 目录结构..."

# 创建组织单元
ldapadd -x -H ldap://${LDAP_HOST}:${LDAP_PORT} -D "${LDAP_ADMIN_DN}" -W << 'LDIF'
# 创建 people 组织单元
dn: ou=people,dc=treesir,dc=pub
objectClass: organizationalUnit
ou: people
description: 用户组织单元

# 创建 groups 组织单元
dn: ou=groups,dc=treesir,dc=pub
objectClass: organizationalUnit
ou: groups
description: 用户组组织单元

# 创建 roles 组织单元
dn: ou=roles,dc=treesir,dc=pub
objectClass: organizationalUnit
ou: roles
description: 角色组织单元

# 创建 services 组织单元
dn: ou=services,dc=treesir,dc=pub
objectClass: organizationalUnit
ou: services
description: 服务账号组织单元
LDIF

echo "目录结构初始化完成!"
EOF

chmod +x scripts/init-ldap-structure.sh

创建默认用户组
#

cat > scripts/create-default-groups.sh << 'EOF'
#!/bin/bash

LDAP_HOST="localhost"
LDAP_PORT="389"
LDAP_ADMIN_DN="cn=admin,dc=treesir,dc=pub"

echo "正在创建默认用户组..."

ldapadd -x -H ldap://${LDAP_HOST}:${LDAP_PORT} -D "${LDAP_ADMIN_DN}" -W << 'LDIF'
# 管理员组
dn: cn=administrators,ou=groups,dc=treesir,dc=pub
objectClass: groupOfUniqueNames
cn: administrators
description: 系统管理员组
uniqueMember: cn=admin,dc=treesir,dc=pub

# 开发人员组
dn: cn=developers,ou=groups,dc=treesir,dc=pub
objectClass: groupOfUniqueNames
cn: developers
description: 开发人员组
uniqueMember: cn=admin,dc=treesir,dc=pub

# 普通用户组
dn: cn=users,ou=groups,dc=treesir,dc=pub
objectClass: groupOfUniqueNames
cn: users
description: 普通用户组
uniqueMember: cn=admin,dc=treesir,dc=pub

# DevOps 组
dn: cn=devops,ou=groups,dc=treesir,dc=pub
objectClass: groupOfUniqueNames
cn: devops
description: DevOps 工程师组
uniqueMember: cn=admin,dc=treesir,dc=pub
LDIF

echo "默认用户组创建完成!"
EOF

chmod +x scripts/create-default-groups.sh

通过 Web 界面管理目录
#

访问 phpLDAPadmin
#

  1. 打开浏览器访问:http://your-server-ip:30004
  2. 点击左侧的 “login” 链接
  3. 输入登录信息:
    • Login DNcn=admin,dc=treesir,dc=pub
    • Password:您设置的管理员密码

创建组织单元(OU)
#

步骤 1:创建 people 组织单元

image-20210304153242949

  1. 点击根节点 dc=treesir,dc=pub
  2. 选择 “Create a child entry”
  3. 选择 “Generic: Organisational Unit”
  4. 输入 OU 名称:people
  5. 点击 “Create Object”

步骤 2:创建 groups 组织单元

重复上述步骤,创建名为 groups 的组织单元。

image-20210304153525116

创建用户账号
#

步骤 1:选择用户模板

image-20210304154011218

  1. 点击 ou=people 节点
  2. 选择 “Create a child entry”
  3. 选择 “Default” 以自定义属性
  4. 选择 inetOrgPerson 对象类

步骤 2:填写用户信息

image-20210304155017955

必填字段:

  • RDN: uid (推荐使用用户名作为标识)
  • cn (Common Name): 用户全名
  • sn (Surname): 姓氏
  • uid: 用户名
  • userPassword: 用户密码
  • mail: 邮箱地址(可选)

创建用户组
#

步骤 1:选择组模板

image-20210304155549187

  1. 点击 ou=groups 节点
  2. 选择 “Create a child entry”
  3. 选择 “Default”
  4. 选择 groupOfUniqueNames 对象类

步骤 2:配置组信息

image-20210304160001868

必填字段:

  • RDN: cn (组名)
  • cn: 组名称
  • uniqueMember: 组成员的 DN

步骤 3:添加组成员

image-20210304160137645

  1. 复制用户的完整 DN,例如:uid=john.doe,ou=people,dc=treesir,dc=pub
  2. 粘贴到 uniqueMember 字段
  3. 点击 “Add” 添加更多成员
  4. 点击 “Create Object” 完成创建

批量用户管理
#

创建批量用户脚本

cat > scripts/bulk-create-users.sh << 'EOF'
#!/bin/bash

LDAP_HOST="localhost"
LDAP_PORT="389"
LDAP_ADMIN_DN="cn=admin,dc=treesir,dc=pub"

# 用户列表文件格式:username:fullname:email:password
USER_LIST="users.txt"

if [ ! -f "$USER_LIST" ]; then
    echo "创建示例用户列表文件..."
    cat > "$USER_LIST" << 'USERS'
john.doe:John Doe:john.doe@treesir.pub:password123
jane.smith:Jane Smith:jane.smith@treesir.pub:password123
bob.wilson:Bob Wilson:bob.wilson@treesir.pub:password123
USERS
fi

echo "正在批量创建用户..."

while IFS=':' read -r username fullname email password; do
    echo "创建用户: $username"

    # 生成密码哈希
    password_hash=$(slappasswd -s "$password")

    ldapadd -x -H ldap://${LDAP_HOST}:${LDAP_PORT} -D "${LDAP_ADMIN_DN}" -W << LDIF
dn: uid=${username},ou=people,dc=treesir,dc=pub
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: ${username}
cn: ${fullname}
sn: ${fullname##* }
givenName: ${fullname%% *}
mail: ${email}
userPassword: ${password_hash}
uidNumber: $(( 1000 + RANDOM % 9000 ))
gidNumber: 1000
homeDirectory: /home/${username}
loginShell: /bin/bash
LDIF

done < "$USER_LIST"

echo "批量用户创建完成!"
EOF

chmod +x scripts/bulk-create-users.sh

功能扩展与优化
#

部署密码自助服务
#

服务简介
#

密码自助服务允许用户自行修改 LDAP 密码,减少管理员工作量,提升用户体验。

部署步骤
#

步骤 1:创建配置目录

mkdir -p /data/openldap/self-service-password/{config,logs}
cd /data/openldap/self-service-password

步骤 2:创建配置文件

cat > config/config.inc.php << 'EOF'
<?php
#==============================================================================
# LTB Self Service Password
#
# Copyright (C) 2009 Clement OUDOT
# Copyright (C) 2009 LTB-project.org
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# GPL License: http://www.gnu.org/licenses/gpl.txt
#
#==============================================================================

#==============================================================================
# Configuration
#==============================================================================

# LDAP 连接配置
$ldap_url = "ldap://openldap-server:389";
$ldap_starttls = false;
$ldap_binddn = "cn=admin,dc=treesir,dc=pub";
$ldap_bindpw = "AdminPass123!";
$ldap_base = "dc=treesir,dc=pub";
$ldap_login_attribute = "uid";
$ldap_fullname_attribute = "cn";
$ldap_filter = "(&(objectClass=inetOrgPerson)($ldap_login_attribute={login}))";

# Active Directory 模式
$ad_mode = false;
$ad_options = array(
    LDAP_OPT_PROTOCOL_VERSION => 3,
    LDAP_OPT_REFERRALS => 0
);

# 密码策略
$pwd_min_length = 8;
$pwd_max_length = 64;
$pwd_min_lower = 1;
$pwd_min_upper = 1;
$pwd_min_digit = 1;
$pwd_min_special = 1;
$pwd_special_chars = "^a-zA-Z0-9";
$pwd_no_reuse = true;
$pwd_diff_login = true;
$pwd_complexity = 3;

# 密码哈希
$hash = "SSHA";
$hash_options['crypt_salt_prefix'] = "$6$";
$hash_options['crypt_salt_length'] = "6";

# 本地密码策略
$use_pwnedpasswords = false;
$pwd_show_policy = "always";
$pwd_show_policy_pos = "above";

# 邮件配置
$mail_from = "admin@treesir.pub";
$mail_from_name = "Password Self Service";
$mail_signature = "";
$notify_on_change = true;
$mail_sendmailpath = '/usr/sbin/sendmail';
$mail_protocol = 'mail';
$mail_smtp_debug = 0;
$mail_debug_format = 'error_log';
$mail_smtp_host = 'localhost';
$mail_smtp_auth = false;
$mail_smtp_user = '';
$mail_smtp_pass = '';
$mail_smtp_port = 25;
$mail_smtp_timeout = 30;
$mail_smtp_keepalive = false;
$mail_smtp_secure = 'tls';
$mail_smtp_autotls = true;
$mail_contenttype = 'text/plain';
$mail_wordwrap = 0;
$mail_charset = 'utf-8';
$mail_priority = 3;

# SMS 配置
$use_sms = false;

# 问题配置
$use_questions = false;

# 令牌配置
$use_tokens = true;
$token_lifetime = 3600;

# 验证码配置
$use_recaptcha = false;

# 默认操作
$default_action = "change";

# 调试模式
$debug = false;

# 日志配置
$use_syslog = true;
$syslog_facility = LOG_USER;
$syslog_priority = LOG_INFO;

# 界面配置
$lang = "zh-CN";
$show_help = true;
$logo = "images/ltb-logo.png";
$background_image = "images/unsplash-space.jpeg";

# 安全配置
$use_change = true;
$use_reset = true;
$change_sshkey = false;
$who_can_change_password = "everybody";
$use_checkpassword = true;
$change_sshkey_attribute = "sshPublicKey";

# 密码历史
$pwd_no_reuse = true;
$pwd_history_length = 5;

?>
EOF

步骤 3:部署服务

# 添加到 docker-compose.yaml
cat >> docker-compose.yaml << 'EOF'

  self-service-password:
    container_name: ldap-self-service
    image: ltbproject/self-service-password:1.4.4
    restart: unless-stopped
    environment:
      LDAP_SERVER: "openldap-server"
      LDAP_BINDDN: "cn=admin,dc=treesir,dc=pub"
      LDAP_BINDPW: "AdminPass123!"
      LDAP_BASE_SEARCH: "dc=treesir,dc=pub"
    volumes:
      - ./self-service-password/config/config.inc.php:/var/www/conf/config.inc.php:ro
      - ./self-service-password/logs:/var/log/self-service-password
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "8765:80"
    depends_on:
      - openldap
    networks:
      - ldap-network
EOF

# 重启服务
docker-compose up -d

步骤 4:配置防火墙

# CentOS/RHEL
firewall-cmd --zone=public --add-port=8765/tcp --permanent
firewall-cmd --reload

# Ubuntu/Debian
ufw allow 8765/tcp

访问密码自助服务
#

  1. 打开浏览器访问:http://your-server-ip:8765
  2. 用户可以使用 LDAP 用户名登录并修改密码

image-20210304152035767

数据备份与恢复
#

自动备份脚本
#

创建备份脚本

cat > scripts/ldap-backup.sh << 'EOF'
#!/bin/bash

##########################################################
# OpenLDAP 自动备份脚本
# 功能:定期备份 LDAP 数据并清理过期备份
##########################################################

# 配置变量
BACKUP_DIR="/data/openldap/backup"
LDAP_HOST="localhost"
LDAP_PORT="389"
LDAP_ADMIN_DN="cn=admin,dc=treesir,dc=pub"
LDAP_ADMIN_PW="AdminPass123!"
LDAP_BASE_DN="dc=treesir,dc=pub"
KEEP_DAYS=30
LOG_FILE="/var/log/ldap-backup.log"

# 创建备份目录
mkdir -p "$BACKUP_DIR"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 备份函数
backup_ldap() {
    local backup_file="${BACKUP_DIR}/ldap-backup-$(date +%Y%m%d-%H%M%S).ldif"

    log "开始备份 LDAP 数据..."

    # 执行备份
    if ldapsearch -x -H "ldap://${LDAP_HOST}:${LDAP_PORT}" \
        -D "${LDAP_ADMIN_DN}" -w "${LDAP_ADMIN_PW}" \
        -b "${LDAP_BASE_DN}" -LLL > "$backup_file"; then

        # 压缩备份文件
        gzip "$backup_file"
        log "备份完成: ${backup_file}.gz"

        # 验证备份文件
        if [ -s "${backup_file}.gz" ]; then
            log "备份文件验证成功"
            return 0
        else
            log "错误: 备份文件为空"
            return 1
        fi
    else
        log "错误: 备份失败"
        return 1
    fi
}

# 清理过期备份
cleanup_old_backups() {
    log "清理 ${KEEP_DAYS} 天前的备份文件..."

    find "$BACKUP_DIR" -name "ldap-backup-*.ldif.gz" -mtime +${KEEP_DAYS} -delete

    local remaining=$(find "$BACKUP_DIR" -name "ldap-backup-*.ldif.gz" | wc -l)
    log "当前保留备份文件数量: $remaining"
}

# 发送备份报告(可选)
send_report() {
    local status=$1
    local backup_size=$(du -sh "$BACKUP_DIR" | cut -f1)

    if command -v mail >/dev/null 2>&1; then
        {
            echo "LDAP 备份报告"
            echo "=============="
            echo "时间: $(date)"
            echo "状态: $status"
            echo "备份目录大小: $backup_size"
            echo "备份目录: $BACKUP_DIR"
        } | mail -s "LDAP 备份报告 - $status" admin@treesir.pub
    fi
}

# 主函数
main() {
    log "=== LDAP 备份任务开始 ==="

    if backup_ldap; then
        cleanup_old_backups
        send_report "成功"
        log "=== LDAP 备份任务完成 ==="
        exit 0
    else
        send_report "失败"
        log "=== LDAP 备份任务失败 ==="
        exit 1
    fi
}

# 执行主函数
main "$@"
EOF

chmod +x scripts/ldap-backup.sh

配置定时任务

# 编辑 crontab
crontab -e

# 添加以下行(每天凌晨 2 点执行备份)
0 2 * * * /data/openldap/scripts/ldap-backup.sh

# 或者每周一到周五执行
0 2 * * 1-5 /data/openldap/scripts/ldap-backup.sh

数据恢复
#

创建恢复脚本

cat > scripts/ldap-restore.sh << 'EOF'
#!/bin/bash

##########################################################
# OpenLDAP 数据恢复脚本
##########################################################

BACKUP_DIR="/data/openldap/backup"
LDAP_HOST="localhost"
LDAP_PORT="389"
LDAP_ADMIN_DN="cn=admin,dc=treesir,dc=pub"
LDAP_ADMIN_PW="AdminPass123!"
LDAP_BASE_DN="dc=treesir,dc=pub"

# 显示可用备份
show_backups() {
    echo "可用的备份文件:"
    ls -la "$BACKUP_DIR"/ldap-backup-*.ldif.gz 2>/dev/null | nl
}

# 恢复数据
restore_ldap() {
    local backup_file="$1"

    if [ ! -f "$backup_file" ]; then
        echo "错误: 备份文件不存在: $backup_file"
        exit 1
    fi

    echo "警告: 此操作将删除现有数据并恢复到备份状态"
    read -p "确认继续? (yes/no): " confirm

    if [ "$confirm" != "yes" ]; then
        echo "操作已取消"
        exit 0
    fi

    # 停止相关服务(如果需要)
    echo "准备恢复数据..."

    # 清空现有数据(谨慎操作)
    echo "清空现有数据..."
    ldapdelete -x -H "ldap://${LDAP_HOST}:${LDAP_PORT}" \
        -D "${LDAP_ADMIN_DN}" -w "${LDAP_ADMIN_PW}" \
        -r "${LDAP_BASE_DN}" 2>/dev/null || true

    # 恢复数据
    echo "恢复备份数据..."
    if [ "${backup_file##*.}" = "gz" ]; then
        zcat "$backup_file" | ldapadd -x -H "ldap://${LDAP_HOST}:${LDAP_PORT}" \
            -D "${LDAP_ADMIN_DN}" -w "${LDAP_ADMIN_PW}"
    else
        ldapadd -x -H "ldap://${LDAP_HOST}:${LDAP_PORT}" \
            -D "${LDAP_ADMIN_DN}" -w "${LDAP_ADMIN_PW}" \
            -f "$backup_file"
    fi

    if [ $? -eq 0 ]; then
        echo "数据恢复完成"
    else
        echo "数据恢复失败"
        exit 1
    fi
}

# 主函数
main() {
    if [ $# -eq 0 ]; then
        show_backups
        echo
        echo "使用方法: $0 <backup_file>"
        echo "示例: $0 /data/openldap/backup/ldap-backup-20231201-020000.ldif.gz"
        exit 1
    fi

    restore_ldap "$1"
}

main "$@"
EOF

chmod +x scripts/ldap-restore.sh

使用恢复脚本

# 查看可用备份
./scripts/ldap-restore.sh

# 恢复指定备份
./scripts/ldap-restore.sh /data/openldap/backup/ldap-backup-20231201-020000.ldif.gz

第三方服务集成
#

Jenkins 集成
#

Jenkins 的 LDAP 配置说明请参考此文档

GitLab 集成
#

编辑 GitLab 配置文件 gitlab.rb,在文件末尾添加以下配置:

gitlab_rails['ldap_enabled'] = true
gitlab_rails['ldap_servers'] = YAML.load <<-'EOS'
    main: # 'main' is the GitLab 'provider ID' of this LDAP server
      label: 'LDAP'
      host: 'treesir.pub'
      port: 389 # usually 636 for SSL
      uid: 'uid' # This should be the attribute, not the value that maps to uid.
      # Examples: 'america\\momo' or 'CN=Gitlab Git,CN=Users,DC=mydomain,DC=com'
      bind_dn: 'cn=admin,dc=treesir,dc=pub'
      password: '123456'
      encryption: 'plain' # "start_tls" or "simple_tls" or "plain"
      active_directory: false
      allow_username_or_email_login: false
      base: 'ou=users,dc=treesir,dc=pub'
      user_filter: ''
      attributes:
        username: ['uid', 'userid', 'sAMAccountName']
        email:    ['mail', 'email', 'userPrincipalName']
        name:       'cn'
        first_name: 'givenName'
        last_name:  'sn'
EOS

修改完成后,需要重新加载 GitLab 配置使其生效:

gitlab-ctl reconfigure

gitlab-ctl restart  # 重新加载配置后重启服务

Rancher 集成
#

(此部分内容待补充)

Nexus 集成
#

创建 LDAP 认证

image-20210528140743869

image-20210528140907136

image-20210528141034768

按照上述配置连接后,建议输入账号进行测试验证。

image-20210528141157818

监控与维护
#

性能监控
#

创建监控脚本
#

cat > scripts/ldap-monitor.sh << 'EOF'
#!/bin/bash

LDAP_HOST="localhost"
LDAP_PORT="389"
LDAP_ADMIN_DN="cn=admin,dc=treesir,dc=pub"
LDAP_BASE_DN="dc=treesir,dc=pub"
LOG_FILE="/var/log/ldap-monitor.log"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 检查 LDAP 服务状态
check_ldap_service() {
    if ldapsearch -x -H "ldap://${LDAP_HOST}:${LDAP_PORT}" -b "" -s base > /dev/null 2>&1; then
        log "✓ LDAP 服务正常运行"
        return 0
    else
        log "✗ LDAP 服务异常"
        return 1
    fi
}

# 检查认证功能
check_auth() {
    if ldapwhoami -x -H "ldap://${LDAP_HOST}:${LDAP_PORT}" -D "${LDAP_ADMIN_DN}" -w "AdminPass123!" > /dev/null 2>&1; then
        log "✓ LDAP 认证功能正常"
        return 0
    else
        log "✗ LDAP 认证功能异常"
        return 1
    fi
}

# 检查用户数量
check_user_count() {
    local count=$(ldapsearch -x -H "ldap://${LDAP_HOST}:${LDAP_PORT}" -D "${LDAP_ADMIN_DN}" -w "AdminPass123!" -b "ou=people,${LDAP_BASE_DN}" "(objectClass=inetOrgPerson)" | grep -c "^dn:")
    log "当前用户数量: $count"
}

# 主函数
main() {
    log "=== LDAP 监控检查开始 ==="
    check_ldap_service
    check_auth
    check_user_count
    log "=== LDAP 监控检查完成 ==="
}

main "$@"
EOF

chmod +x scripts/ldap-monitor.sh

故障排除
#

常见问题
#

1. 容器启动失败

# 查看容器日志
docker logs openldap-server

# 检查配置文件
docker exec openldap-server slaptest

# 检查权限
ls -la /data/openldap/

2. 无法连接 LDAP 服务

# 检查端口监听
netstat -tlnp | grep 389

# 测试连接
telnet localhost 389

# 检查防火墙
firewall-cmd --list-ports

3. 认证失败

# 验证管理员密码
ldapwhoami -x -D "cn=admin,dc=treesir,dc=pub" -W

# 检查用户 DN
ldapsearch -x -b "dc=treesir,dc=pub" "(uid=username)"

总结
#

部署优势
#

  • 统一认证:为企业提供集中化的身份认证服务
  • 易于管理:通过 Web 界面和脚本实现便捷管理
  • 高可用性:支持容器化部署和自动重启
  • 可扩展性:支持与多种第三方服务集成
  • 安全性:支持 SSL/TLS 加密和访问控制

最佳实践
#

  • 定期备份:建立完善的数据备份机制
  • 监控告警:实施全面的服务监控
  • 安全加固:启用 SSL/TLS 和强密码策略
  • 权限控制:实施最小权限原则
  • 文档维护:保持配置文档的及时更新

扩展建议
#

  • 高可用部署:配置主从复制或集群模式
  • 性能优化:根据用户规模调整配置参数
  • 集成更多服务:扩展到更多企业应用系统
  • 自动化运维:开发自动化部署和维护脚本

通过本指南,您可以成功部署一个功能完整的企业级 OpenLDAP 统一身份认证服务,为您的 DevOps 工具链提供可靠的认证基础。

相关文章

使用 Docker 快速部署 Redis 服务器
·259 字·2 分钟
Redis Docker Centos7 Docker
Docker 部署 OpenWrt 软路由及宿主机通信配置
·370 字·2 分钟
Fix N1 Openwrt Docker Openwrt Docker-Compose
Kind 部署本地k8s集群的使用记录
·238 字·2 分钟
Kind Kubernetes Docker DevOps Centos7