本文介绍了 OpenLDAP 的基本概念与数据结构,阐述了其作为目录服务的作用与存储特点,并通过 Docker Compose 提供了两种部署方式示例:一种为无证书的测试环境,另一种为启用 TLS 与 Nginx 反向代理的生产环境配置。同时附带了 nginx 配置文件,方便将 phpLDAPadmin 接入 HTTPS 访问。
1. OpenLDAP介绍
OpenLDAP 是一个开源的轻量级目录访问协议LDAP(Lightweight Directory Access Protocol)的实现。当谈到“目录访问协议”时,LDAP是目前唯一广泛使用和被公认为标准的协议。它被广泛应用于企业中,用于实现账号的集中管理和认证。
1.1 目录服务
目录服务是一种特殊的数据库系统,它优化了数据的读取、浏览和搜索操作。 它以树状结构组织数据,类似于文件系统。 OpenLDAP默认以Berkeley DB作为后端数据库,主要以键值对(key-value pair)的方式存储数据,这种方式通常非常适合快速读取和查找的场景。目录数据库与传统的关系型数据库不同,它写入性能相对较差,并且不支持复杂的事务管理或回滚策略,因此不适合存储频繁修改的数据。
1.2 数据结构
- 目录信息树 (DIT):OpenLDAP目录中的信息以树形结构组织。
- 条目 (Entry):目录树中的每个节点都是一个条目,可以看作是关系数据库中的一条记录。条目是LDAP中最基本的颗粒,添加、删除、更改、检索等操作都以条目为基本对象。
- 区别名 (Distinguished Name, DN):每个条目都有一个唯一的区别名(DN),由一系列的相对区别名 (RDN) 组成,例如
cn=admin,dc=example,dc=com
。 - 属性 (Attribute):条目由一个或多个属性组成,每个属性由类型(type)和一个或多个值(value)构成,类似于关系数据库中的字段。
- 定义与Schema (模式):
- 所有的属性类型都必须在LDAP服务器的 Schema(模式) 中进行定义。Schema 是LDAP目录的蓝图,它规定了哪些 对象类(ObjectClass) 可以使用,以及每个对象类可以包含哪些属性类型。
- 每个属性类型都有一个唯一的对象标识符(Object Identifier, OID),这是一个数字串,用于在全球范围内唯一标识该属性类型。
- 常见属性:
- DC(Domain Component): 域的组成部分,譬如是你的域名是google.com,则可以写成 dc=google,dc=com。
- CN(Common Name) :可以用于标识目录条目的名称,譬如admin,billgates。再一个域下的用户名应该是是唯一的。CN + DC = DN,这是条目的唯一标识。
- OU(Organizational Unit) :可以用于标识公司或组织内部的信息分类,譬如人事部,设计部,ou=hr 或 ou=engineering。
- UID(User ID):可以用于标识用户的属性类型,或者是数字UID譬如1000,或是用户名譬如admin。
2. 部署OpenLDAP
2.1 OpenLDAP和WebUI无任何证书
OpenLDAP对外发布了389和636端口。Phpldapadmin作为WebUI,通过ldap协议在docker network内部连接到OpenLDAP,它们之间没有启用SSL加密。Phpldapadmin的访问也只是通过HTTP来访问,没有启用证书。这是最简单的方式来进行OpenLDAP的测试。
services:
ldap:
image: osixia/openldap:latest
container_name: openldap
environment:
- LDAP_ORGANISATION=MyOrg
- LDAP_DOMAIN=example.com
- LDAP_ADMIN_PASSWORD=LDAP_password
ports:
- "389:389" # LDAP port
- "636:636" # LDAPS port
volumes:
- ./ldap_data:/var/lib/ldap # Persistent data for LDAP
- ./ldap_config:/etc/ldap/slapd.d # Configuration for LDAP
restart: always
phpldapadmin:
image: osixia/phpldapadmin:latest
container_name: phpldapadmin
environment:
- PHPLDAPADMIN_LDAP_HOSTS=ldap
- PHPLDAPADMIN_HTTPS=false
ports:
- "8080:80" # HTTP port for phpLDAPadmin
depends_on:
- ldap
restart: always
2.2 OpenLDAP和WebUI有证书和代理
如果是生产环境,phpldapadmin在Nginx后面。
services:
ldap:
image: osixia/openldap:latest
container_name: openldap
environment:
- LDAP_ORGANISATION=MyOrg
- LDAP_DOMAIN=example.com
- LDAP_ADMIN_PASSWORD=LDAP_password
expose:
- 389 # LDAP port
- 636 # LDAPS port
volumes:
- ./ldap_data:/var/lib/ldap # Persistent data for LDAP
- ./ldap_config:/etc/ldap/slapd.d # Configuration for LDAP
restart: always
networks:
- ldap-net
phpldapadmin:
image: osixia/phpldapadmin:latest
container_name: phpldapadmin
environment:
- PHPLDAPADMIN_LDAP_HOSTS=ldap
- PHPLDAPADMIN_HTTPS=false
expose:
- 80 # HTTP port for phpLDAPadmin
depends_on:
- ldap
restart: always
networks:
- nginx-reverse-proxy
- ldap-net
networks:
nginx-reverse-proxy:
external: true
ldap-net:
external: true
Nginx配置文件
server {
listen 8005 ssl;
server_name HOST_IP;
ssl_certificate /etc/nginx/certs/HOST_IP.crt;
ssl_certificate_key /etc/nginx/certs/HOST_IP.key;
# Optional security headers
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
location / {
proxy_pass http://phpldapadmin:80/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# To support login forms and large payloads
client_max_body_size 10M;
}
}
📚 延伸阅读
更多内容持续更新于我的博客:https://www.zenseek.site