Directory Service คืออะไร?

ลองนึกภาพ สมุดโทรศัพท์ — เปิดหา “สมชาย” ก็เจอเบอร์โทร, ที่อยู่, แผนกที่ทำงาน ข้อมูลเรียงเป็นโครงสร้าง หาง่าย

Directory Service ก็คือสมุดโทรศัพท์ดิจิทัล — ระบบที่เก็บข้อมูลเป็นโครงสร้าง (hierarchical) ออกแบบมาเพื่อ อ่านเร็ว มากกว่าเขียน:

Directory Service = สมุดโทรศัพท์ดิจิทัล

┌─────────────────────────────────────────┐
│         example.com (องค์กร)             │
│                                         │
│   ┌──────────┐      ┌──────────┐        │
│   │  People  │      │  Groups  │        │
│   │          │      │          │        │
│   │  alice   │      │  devops  │        │
│   │  bob     │      │  hr      │        │
│   │  charlie │      │  finance │        │
│   └──────────┘      └──────────┘        │
│                                         │
│   "หา alice" → ได้ email, เบอร์, แผนก    │
│   "หาคนในแผนก devops" → ได้ทั้ง list     │
└─────────────────────────────────────────┘

ลักษณะเด่นของ Directory Service:

  • Read-heavy — ถูกออกแบบให้อ่านเร็วมาก เพราะข้อมูล (ชื่อ, email, แผนก) ไม่ค่อยเปลี่ยน แต่ถูกค้นหาบ่อย
  • Hierarchical — จัดข้อมูลเป็นต้นไม้ (tree) ไม่ใช่ตาราง (table)
  • Distributed — กระจาย replicate ไปหลาย servers ได้ เพื่อรองรับ load

LDAP คืออะไร?

LDAP (Lightweight Directory Access Protocol) คือ protocol สำหรับเข้าถึง directory service — เหมือน HTTP เป็น protocol สำหรับเข้าถึง web server LDAP ก็เป็น protocol สำหรับเข้าถึง directory

สำคัญ: LDAP เป็น protocol ไม่ใช่ database ตัว database ที่อยู่ข้างหลังเรียกว่า directory server หรือ LDAP server ส่วน LDAP เป็นภาษาที่ใช้คุยกับมัน

เหมือน SQL เป็น language สำหรับคุยกับ database — LDAP เป็น protocol สำหรับคุยกับ directory

LDAP Implementations ที่นิยม

Implementationผู้พัฒนาจุดเด่นLicense
OpenLDAPCommunityเบา, ยืดหยุ่น, ใช้ทั่วไปใน LinuxOpen source
Active DirectoryMicrosoftเชื่อมกับ Windows ecosystem ดีมากCommercial
389 Directory ServerRed Hatenterprise-grade, มี GUIOpen source
Apache DirectoryApacheเขียนด้วย Java, มี Studio UIOpen source
FreeIPARed Hatครบวงจร (LDAP + Kerberos + DNS + CA)Open source

LDAP vs Database

คำถามที่พบบ่อย: “ทำไมไม่ใช้ database ปกติแทน LDAP?”

LDAPRelational Database (SQL)
โครงสร้างTree (hierarchical)Table (relational)
Optimized สำหรับRead-heavy workloadRead + Write balanced
Schemaยืดหยุ่น, entries ไม่จำเป็นต้องมี attributes เหมือนกันเข้มงวด, ทุก row ใน table มี columns เดียวกัน
QueryLDAP filter (cn=alice)SQL SELECT * FROM users WHERE name='alice'
ReplicationBuilt-in multi-masterต้อง config เพิ่ม
StandardsRFC 4511 (ทุก implementation ใช้ protocol เดียวกัน)SQL dialect ต่างกันในแต่ละ DB
เหมาะกับUser directory, org hierarchy, address bookTransaction, e-commerce, analytics

Rule of thumb: ถ้าข้อมูลถูก อ่านบ่อย เขียนน้อย และมีโครงสร้างเป็น hierarchy → LDAP ถ้าข้อมูลถูก อ่านและเขียนเท่าๆ กัน หรือต้องการ JOIN ข้าม tables → SQL database

โครงสร้าง DIT (Directory Information Tree)

LDAP เก็บข้อมูลเป็น tree เรียกว่า DIT (Directory Information Tree) — ทุก entry มีตำแหน่งในต้นไม้นี้:

dc=example,dc=com                    ← root (domain component)
    ├── ou=People                    ← Organizational Unit (กลุ่ม)
    │    │
    │    ├── cn=alice                ← entry (คน)
    │    │   ├── mail: alice@example.com
    │    │   ├── uid: alice
    │    │   └── title: Developer
    │    │
    │    └── cn=bob
    │        ├── mail: bob@example.com
    │        ├── uid: bob
    │        └── title: Manager
    ├── ou=Groups
    │    │
    │    ├── cn=devops
    │    │   └── member: cn=alice,ou=People,dc=example,dc=com
    │    │
    │    └── cn=hr
    │        └── member: cn=bob,ou=People,dc=example,dc=com
    └── ou=Services
         └── cn=mail-server
             └── description: Internal mail service

ศัพท์ที่ต้องรู้

คำย่อจากคืออะไรตัวอย่าง
DNDistinguished Name“ที่อยู่เต็ม” ของ entry ไม่ซ้ำกันในทั้ง treecn=alice,ou=People,dc=example,dc=com
RDNRelative Distinguished Nameชื่อของ entry (เฉพาะ level นี้)cn=alice
DCDomain Componentส่วนของ domain namedc=example, dc=com
OUOrganizational Unitกลุ่ม/แผนกou=People, ou=Groups
CNCommon Nameชื่อที่ใช้เรียกcn=alice, cn=devops
UIDUser IDusernameuid=alice

DN เปรียบเทียบกับ file path: ถ้า file path คือ /com/example/People/alice → DN คือ cn=alice,ou=People,dc=example,dc=com (เขียนกลับจากล่างขึ้นบน)

Entry Structure

แต่ละ entry ใน LDAP ประกอบด้วย:

  1. DN — ที่อยู่เต็มของ entry
  2. objectClass — “ประเภท” ของ entry กำหนดว่าต้องมี/อาจมี attributes อะไรบ้าง
  3. Attributes — ข้อมูลจริงๆ เป็นคู่ key-value

objectClass ที่ใช้บ่อย

objectClassใช้แทนattributes ที่ต้องมีattributes ที่เพิ่มได้
inetOrgPersonคน (user)cn, snmail, uid, title, telephoneNumber
organizationalUnitแผนก/กลุ่มoudescription
groupOfNamesgroup ของ userscn, memberdescription
organizationองค์กรodescription
dcObjectdomain componentdc

sn = Surname (นามสกุล), cn = Common Name (ชื่อเต็ม), o = Organization

LDIF Format

LDIF (LDAP Data Interchange Format) คือ text format สำหรับแสดง/นำเข้า LDAP entries — เหมือน CSV สำหรับ database แต่ LDIF สำหรับ LDAP:

# สร้าง root
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
dc: example
o: Example Inc.

# สร้าง OU สำหรับ People
dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People

# สร้าง user alice
dn: cn=alice,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
cn: alice
sn: Wonderland
mail: alice@example.com
uid: alice
title: Senior Developer
userPassword: {SSHA}encrypted_password_here

แต่ละ entry คั่นด้วยบรรทัดว่าง แต่ละ attribute เป็น key: value

LDAP Operations

LDAP มี operations หลักๆ สำหรับจัดการข้อมูล:

Operationทำอะไรเปรียบเทียบกับ SQL
Bindยืนยันตัวตน (login กับ LDAP server)CONNECT + authenticate
Searchค้นหา entries ตาม filterSELECT ... WHERE ...
Addเพิ่ม entry ใหม่INSERT
Modifyแก้ไข attributes ของ entryUPDATE
Deleteลบ entryDELETE
Compareเช็คว่า attribute มีค่าตามที่ระบุไหมSELECT ... WHERE attr='value'
ModifyDNย้าย/เปลี่ยนชื่อ entryUPDATE ... SET name=... (+ move)
Unbindปิดการเชื่อมต่อDISCONNECT

Search Filter Syntax

Search เป็น operation ที่ใช้บ่อยที่สุด filter syntax ของ LDAP หน้าตาแบบนี้:

# หา user ที่ชื่อ alice
(cn=alice)

# หา user ที่ email ลงท้ายด้วย @example.com
(mail=*@example.com)

# หา user ที่เป็น developer AND อยู่ใน devops
(&(title=Developer)(memberOf=cn=devops,ou=Groups,dc=example,dc=com))

# หา user ที่เป็น developer OR manager
(|(title=Developer)(title=Manager))

# หาทุกคนที่ไม่ใช่ admin
(!(title=Admin))
Operatorความหมายตัวอย่าง
=เท่ากับ(cn=alice)
=*มีค่า (ไม่ว่างเปล่า)(mail=*)
* (ใน value)wildcard(cn=a*) = ขึ้นต้นด้วย a
&AND(&(a=1)(b=2))
|OR(|(a=1)(b=2))
!NOT(!(a=1))

Schema

Schema คือ “กฎ” ของ directory — กำหนดว่า:

  • มี objectClass อะไรบ้าง
  • แต่ละ objectClass ต้องมี attributes อะไร (MUST) และมีได้ (MAY)
  • แต่ละ attribute เป็น data type อะไร (string, integer, boolean)

ตัวอย่าง: inetOrgPerson schema กำหนดว่า:

  • MUST: cn, sn (ต้องมี ถ้าไม่มี → error)
  • MAY: mail, uid, title, telephoneNumber (มีหรือไม่มีก็ได้)
objectClass: inetOrgPerson
    ├── MUST (ต้องมี)
    │    ├── cn (Common Name)
    │    └── sn (Surname)
    └── MAY (มีได้)
         ├── mail
         ├── uid
         ├── title
         ├── telephoneNumber
         ├── jpegPhoto
         └── ... (อีกหลาย attributes)

ข้อดี: schema ทำให้ data มีมาตรฐาน — ทุก user entry รับประกันว่ามี cn และ sn เสมอ app ที่อ่านข้อมูลไม่ต้องเช็คว่า field นี้มีหรือเปล่า

Schema สามารถ extend ได้ — ถ้า attributes มาตรฐานไม่พอ ก็สร้าง custom objectClass เพิ่ม เช่น เพิ่ม employeeID หรือ department

Use Cases

1. Centralized Authentication

use case ที่พบบ่อยที่สุด — ทุก app ในองค์กรเช็ค username/password กับ LDAP ที่เดียว:

┌──────────┐    ┌──────────┐    ┌──────────┐
│  App A   │    │  App B   │    │  App C   │
│ (web)    │    │ (VPN)    │    │ (email)  │
└────┬─────┘    └────┬─────┘    └────┬─────┘
     │               │               │
     └───────────────┼───────────────┘
              ┌──────────────┐
              │  LDAP Server │  ← user database กลาง
              │              │
              │  alice ✓     │
              │  bob ✓       │
              │  charlie ✓   │
              └──────────────┘

ข้อดี: เพิ่ม/ลบ user ที่เดียว มีผลกับทุก app ทันที ไม่ต้องไปสร้าง account ใน app แต่ละตัว

2. Address Book & Organization Chart

เก็บข้อมูลพนักงาน — ชื่อ, email, เบอร์โทร, แผนก, หัวหน้า — ค้นหาได้เร็วมาก email client เช่น Thunderbird รองรับ LDAP address book โดยตรง

3. Service Configuration

เก็บ config ของ services เป็นศูนย์กลาง เช่น printer settings, DNS records, mail routing rules

LDAP + Keycloak Federation

LDAP มักถูกใช้คู่กับ Keycloak ในรูปแบบ User Federation — Keycloak เป็น front-end ที่รองรับ modern protocols (OAuth 2.0, OIDC) ส่วน LDAP เป็น backend เก็บ users:

┌──────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────┐
│ User │────▶│ OAuth2 Proxy │────▶│   Keycloak   │────▶│   LDAP   │
│      │     │ (หน้า app)   │     │   (IdP)      │     │ (user DB)│
│      │◀────│              │◀────│              │◀────│          │
└──────┘     └──────────────┘     └──────────────┘     └──────────┘
                                   ออก JWT token
                                   ให้ app ใช้

Federation Modes

Modeวิธีทำงานข้อดีข้อเสีย
Read-onlyKeycloak อ่าน users จาก LDAP อย่างเดียวLDAP ยังเป็น source of truthสร้าง user ผ่าน Keycloak ไม่ได้
WritableKeycloak อ่าน + เขียนกลับ LDAPสร้าง/แก้ user จากทั้ง 2 ทางได้ต้องระวัง conflict
ImportCopy users จาก LDAP มา Keycloakเร็วกว่า (query local DB)ข้อมูลอาจ outdated ถ้า sync ไม่ทัน
On-demandQuery LDAP ทุกครั้งที่ loginข้อมูล real-time เสมอช้ากว่า ถ้า LDAP ล่ม login ไม่ได้

ทำไมต้อง Keycloak + LDAP? เพราะ LDAP เก่ง centralized user management แต่ไม่รองรับ modern protocols อย่าง OAuth 2.0/OIDC โดยตรง Keycloak ทำหน้าที่แปล — app ที่ต้องการ OAuth 2.0 คุยกับ Keycloak ส่วน Keycloak ไปดึง users จาก LDAP

สนใจเรื่อง Keycloak เพิ่มเติม อ่านต่อได้ที่ Keycloak: ทำความรู้จัก Identity & Access Management ตั้งแต่พื้นฐาน

OpenLDAP

OpenLDAP เป็น implementation ที่ได้รับความนิยมมากที่สุดในโลก open-source:

  • เบา — ใช้ resource น้อย เหมาะกับ VPS
  • ยืดหยุ่น — config ผ่าน cn=config (LDAP-based config) ไม่ต้อง restart เมื่อเปลี่ยน config
  • Replication — รองรับ multi-provider replication สำหรับ HA
  • Backend — ใช้ LMDB (Lightning Memory-Mapped Database) เร็วมากสำหรับ read operations
  • Community — ใช้มานานกว่า 20 ปี documentation เยอะ

ทางเลือกอื่นที่น่าสนใจ:

  • LLDAP — lightweight LDAP server เขียนด้วย Rust มี web UI เหมาะกับ self-hosting ที่ต้องการแค่ user management
  • GLAuth — tiny LDAP server ที่ config ด้วย file เดียว เหมาะกับ small team

Security

Threats ที่ต้องระวัง

Threatคืออะไรป้องกันด้วย
Eavesdroppingดักฟัง traffic ระหว่าง client กับ LDAP serverLDAPS (LDAP over TLS)
LDAP Injectionใส่ filter พิเศษเพื่อดึงข้อมูลที่ไม่ควรเห็นEscape/validate input
Unauthorized accessเข้าถึง entries ที่ไม่มีสิทธิ์ACL (Access Control Lists)
Password theftขโมย password จาก directoryHash passwords (SSHA, PBKDF2)
DoSส่ง query หนักๆ ทำให้ server ล่มRate limiting, size limits

แนวทางป้องกัน

1. LDAPS (LDAP over TLS)

  • ใช้ LDAPS (port 636) หรือ StartTLS (port 389 + upgrade) เสมอ
  • ห้ามส่ง password ผ่าน plain-text LDAP

2. ACL (Access Control Lists)

  • กำหนดว่า user ไหนอ่าน/เขียน entry ไหนได้
  • ตัวอย่าง: user ธรรมดาอ่านได้แค่ข้อมูลตัวเอง admin อ่านได้ทุกคน

3. Password Hashing

  • เก็บ password เป็น hash (SSHA, PBKDF2, bcrypt) ไม่เก็บ plain-text
  • LDAP server จะเทียบ hash เวลา login ไม่เคยเก็บ password จริง

4. Network Isolation

  • LDAP server ไม่ควรเปิดให้เข้าถึงจาก internet โดยตรง
  • เข้าถึงได้เฉพาะจาก internal network หรือ VPN

5. Bind DN ที่เหมาะสม

  • Application ที่เชื่อม LDAP ควรใช้ service account ที่มีสิทธิ์น้อยที่สุด (least privilege)
  • ไม่ใช้ admin DN สำหรับ read-only operations

สรุป

หัวข้อสิ่งสำคัญ
LDAP คืออะไรProtocol สำหรับเข้าถึง directory service (ไม่ใช่ database)
เหมาะกับRead-heavy, hierarchical data เช่น user directory
โครงสร้างDIT (tree), แต่ละ entry มี DN เป็น unique address
Entryประกอบด้วย objectClass + attributes กำกับด้วย schema
OperationsBind, Search, Add, Modify, Delete — Search ใช้บ่อยที่สุด
ImplementationsOpenLDAP (open source), Active Directory (Microsoft)
คู่กับ KeycloakLDAP เก็บ users, Keycloak แปลเป็น OAuth 2.0/OIDC
SecurityLDAPS (TLS), ACL, password hashing, network isolation

LDAP อาจดูเป็นเทคโนโลยีเก่า แต่ยังเป็นมาตรฐานสำหรับ centralized user management ในองค์กร — Active Directory ที่ใช้กันทั่วโลกก็ทำงานบน LDAP ถ้ากำลังสร้าง infrastructure ที่ต้องจัดการ users หลายระบบ การเข้าใจ LDAP จะช่วยให้เลือกเครื่องมือได้ถูกต้อง