跳过正文
  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 分钟
Docker Redis Centos7 Docker
Docker 部署 OpenWrt 软路由及宿主机通信配置
·370 字·2 分钟
Fix Openwrt N1 Docker-Compose Docker Openwrt
Kind 部署本地k8s集群的使用记录
·238 字·2 分钟
Kubernetes Docker DevOps Centos7 Kind