Hướng dẫn cài đặt và cấu hình 389 Directory Server trên CentOS Stream 9: Xây dựng LDAP Server tập trung quản lý người dùng

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

Cài ngay — 5 phút có LDAP Server chạy được

Demo trước, lý thuyết sau. Chạy từng lệnh dưới đây theo thứ tự — 5 phút là có LDAP server sẵn sàng nhận kết nối:

# Cài đặt 389 Directory Server
sudo dnf install 389-ds-base -y

# Tạo file cấu hình instance
cat > /tmp/ds-setup.inf << 'EOF'
[general]
config_version = 2
full_machine_name = ldap.company.com

[slapd]
instance_name = company
root_dn = cn=Directory Manager
root_password = StrongP@ssword123!
port = 389
secure_port = 636

[backend-userRoot]
suffix = dc=company,dc=com
sample_entries = yes
EOF

sudo dscreate from-file /tmp/ds-setup.inf
# Kích hoạt và khởi động dịch vụ
sudo systemctl enable --now dirsrv@company

# Kiểm tra kết nối
ldapsearch -x -H ldap://localhost \
  -b "dc=company,dc=com" \
  -D "cn=Directory Manager" -W \
  "(objectClass=*)" dn

Lệnh cuối trả về danh sách DN? Tốt — LDAP server đang chạy. Tiếp theo mình giải thích từng phần để bạn hiểu vừa làm gì.

389 Directory Server — Tại sao chọn cái này?

Mình đã vận hành cả ba: OpenLDAP trên Debian, FreeIPA trên RHEL 7, và AD tích hợp Linux qua SSSD. Khi cần LDAP thuần trên môi trường RHEL/CentOS, 389 DS là lựa chọn mình quay lại nhiều nhất — không phải vì quen tay, mà vì nó thực sự phù hợp hơn trong hệ sinh thái Red Hat.

Khi CentOS 8 EOL năm 2021, mình migrate gấp 5 server sang Rocky Linux trong 1 tuần. Kết quả: server nào chạy 389 DS thì chuyển sang gần như zero-config — package tương thích hoàn toàn, data directory giữ nguyên, reinstall và point đúng chỗ là xong. Mấy server dùng OpenLDAP? Nửa ngày mỗi cái để rebuild schema.

So sánh nhanh:

  • vs OpenLDAP: 389 DS có web console (cockpit-389-ds), replication built-in dễ cấu hình hơn, logging chi tiết hơn
  • vs FreeIPA: 389 DS nhẹ hơn đáng kể, không kéo theo Kerberos/DNS/CA — thích hợp cho server RAM giới hạn hoặc khi bạn chỉ cần LDAP đơn thuần
  • vs Active Directory: Không cần Windows license, tích hợp native với Linux ecosystem

Chuẩn bị môi trường trước khi cài

Cấu hình hostname và firewall

389 DS yêu cầu hostname phải resolvable — bước này hay bị bỏ qua nhất, và khi thiếu nó dscreate fail với lỗi TLS khá khó hiểu:

# Đặt hostname đúng FQDN
sudo hostnamectl set-hostname ldap.company.com

# Thêm vào /etc/hosts nếu chưa có DNS nội bộ
echo "192.168.1.10 ldap.company.com ldap" | sudo tee -a /etc/hosts

# Mở port LDAP và LDAPS
sudo firewall-cmd --permanent --add-service=ldap
sudo firewall-cmd --permanent --add-service=ldaps
sudo firewall-cmd --reload

# Kiểm tra hostname resolve được
python3 -c "import socket; print(socket.getfqdn())"

Quản lý người dùng và group

Tạo cấu trúc OU

Instance đã sẵn sàng. Đầu tiên tạo OU để phân loại users và groups — đây là cấu trúc tối giản thường dùng nhất:

cat > /tmp/add-ou.ldif << 'EOF'
dn: ou=users,dc=company,dc=com
objectClass: organizationalUnit
ou: users

dn: ou=groups,dc=company,dc=com
objectClass: organizationalUnit
ou: groups
EOF

ldapadd -x -H ldap://localhost \
  -D "cn=Directory Manager" -W \
  -f /tmp/add-ou.ldif

Thêm user mới

# Tạo password hash trước
pwdhash -s SSHA "UserPassword123!"
# Ví dụ output: {SSHA}abc123...== — copy chuỗi đó thay vào trường userPassword bên dưới

# Tạo user entry
cat > /tmp/add-user.ldif << 'EOF'
dn: uid=john,ou=users,dc=company,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: john
cn: John Doe
sn: Doe
mail: [email protected]
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/john
loginShell: /bin/bash
userPassword: {SSHA}REPLACE_WITH_PWDHASH_OUTPUT
EOF

ldapadd -x -H ldap://localhost \
  -D "cn=Directory Manager" -W \
  -f /tmp/add-user.ldif

Tìm kiếm và xác minh

# Tìm user vừa tạo
ldapsearch -x -H ldap://localhost \
  -D "cn=Directory Manager" -W \
  -b "ou=users,dc=company,dc=com" \
  "(uid=john)" uid cn mail uidNumber

# Test login bằng chính account đó
ldapwhoami -x -H ldap://localhost \
  -D "uid=john,ou=users,dc=company,dc=com" \
  -W

Nâng cao — Bật TLS và tích hợp Linux client

Bật LDAPS (bắt buộc cho production)

LDAP không TLS trên production đồng nghĩa credentials đi plaintext qua network — đừng làm vậy. 389 DS có công cụ dsconf để quản lý certificate:

# Nếu dùng Let's Encrypt hoặc CA nội bộ
sudo dsconf company security certificate add \
  --file /etc/pki/tls/certs/ldap.crt \
  --name "server-cert"

sudo dsconf company security rsa enable

# Hoặc tạo self-signed cert với dsctl
sudo dsctl company tls generate-server-cert-csr \
  --subject "CN=ldap.company.com,O=Company,C=VN"

sudo systemctl restart dirsrv@company

# Test LDAPS
ldapsearch -x -H ldaps://ldap.company.com \
  -D "cn=Directory Manager" -W \
  -b "dc=company,dc=com" "(uid=john)"

Tích hợp Linux client với sssd

Muốn các server khác xác thực qua LDAP này? Cài sssd trên từng client và trỏ về LDAP server vừa setup:

# Trên máy client
sudo dnf install sssd sssd-ldap authselect -y
sudo authselect select sssd with-mkhomedir --force

sudo tee /etc/sssd/sssd.conf << 'EOF'
[sssd]
services = nss, pam
config_file_version = 2
domains = company.com

[domain/company.com]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldaps://ldap.company.com
ldap_search_base = dc=company,dc=com
ldap_default_bind_dn = cn=Directory Manager
ldap_default_authtok_type = password
ldap_default_authtok = StrongP@ssword123!
ldap_tls_cacert = /etc/pki/ca-trust/source/anchors/company-ca.crt
ldap_id_use_start_tls = True
cache_credentials = True
EOF

sudo chmod 600 /etc/sssd/sssd.conf
sudo systemctl enable --now sssd

# Kiểm tra user LDAP có thấy được không
id john

Cấu hình Password Policy

# Bật password policy built-in của 389 DS
sudo dsconf company pwpolicy set \
  --pwdminage 0 \
  --pwdmaxage 90 \
  --pwdminlength 8 \
  --pwdlockout on \
  --pwdmaxfailure 5

Tips thực tế từ kinh nghiệm vận hành

  • Backup tự động hàng ngày: Thêm cronjob chạy sudo dsctl company db2bak /backup/ldap-$(date +%Y%m%d) — save cả schema lẫn data. Mình giữ 7 ngày rồi dọn cũ hơn bằng find /backup -name 'ldap-*' -mtime +7 -delete.
  • Web console: Cài cockpit-389-ds và mở https://ldap.company.com:9090 — mình hay dùng cái này khi cần kéo schema ra xem hoặc debug replication status, nhanh hơn nhiều so với gõ ldapsearch thủ công.
  • SELinux không cần tắt: 389 DS hoạt động tốt với SELinux enforcing trên CentOS Stream 9. Đừng tin hướng dẫn từ 2015 bảo phải setenforce 0 — không cần thiết nữa.
  • Log rotation: Hệ thống 500+ user active có thể generate vài GB access log mỗi tháng. Giới hạn kích thước: sudo dsconf company config replace nsslapd-accesslog-maxlogsize=100
  • Monitor kết nối: Xem số kết nối hiện tại bằng sudo dsconf company monitor server | grep -i connection — bình thường khoảng 10–50 kết nối đồng thời. Đột ngột lên vài trăm là dấu hiệu client config bị lỗi reconnect loop.

Troubleshooting nhanh

Lỗi kết nối

# Kiểm tra port đang listen
sudo ss -tlnp | grep -E ':389|:636'

# Xem log lỗi realtime
sudo journalctl -u dirsrv@company -f

# Hoặc xem access log chi tiết
sudo tail -f /var/log/dirsrv/slapd-company/access

Lỗi xác thực

# Test bind thủ công
ldapwhoami -x -H ldap://localhost \
  -D "uid=john,ou=users,dc=company,dc=com" \
  -W

# Kiểm tra password hash có đúng format không
ldapsearch -x -H ldap://localhost \
  -D "cn=Directory Manager" -W \
  -b "uid=john,ou=users,dc=company,dc=com" \
  userPassword

Vậy là đủ để chạy LDAP server tập trung cho hạ tầng Linux của bạn. Không Windows, không license fee, và khi upgrade lên RHEL 10 sau này package vẫn tương thích hoàn toàn. Cần high availability? Bước tiếp theo là multi-master replication — 389 DS hỗ trợ setup 2–4 master node, cấu hình đơn giản hơn nhiều so với vài năm trước.

Share: