Bài toán quản lý danh tính trong hạ tầng đang mở rộng
Hãy hình dung một đội ngũ gồm 45 kỹ sư phải quản lý thông tin đăng nhập trên 12 ứng dụng web nội bộ riêng biệt. Từ dashboard Jenkins, wiki nội bộ, hệ thống giám sát Grafana cho đến cụm staging, mỗi nơi đều duy trì một cơ sở dữ liệu người dùng cô lập của riêng mình.
Onboarding một kỹ sư mới đồng nghĩa với việc phải tạo tài khoản thủ công trên 5 đến 6 console khác nhau, tiêu tốn cả tiếng đồng hồ của đội ngũ DevOps cho mỗi nhân sự mới. Quy trình offboarding thậm chí còn nan giải hơn. Khi một kỹ sư rời công ty vào chiều thứ Sáu, việc thu hồi quyền truy cập trên từng hệ thống riêng lẻ rất dễ bỏ sót các session token còn hiệu lực hoặc các tài khoản mồ côi (orphaned accounts) chưa được thu hồi.
Hệ quả tất yếu là các thành viên trong nhóm rơi vào tình trạng “quá tải mật khẩu” (password fatigue). Họ bắt đầu tái sử dụng các mật khẩu yếu chỉ tầm 10 ký tự trên nhiều môi trường khác nhau, hoặc lưu trữ thông tin đăng nhập trong các tệp văn bản chia sẻ không mã hóa. Vận hành mà thiếu đi một lớp Identity and Access Management (IAM) thống nhất sẽ dẫn đến audit trail lộn xộn, không thể hủy phiên đăng nhập chỉ bằng một cú nhấp chuột và các tiêu chuẩn bảo mật bị phân mảnh nghiêm trọng trên các công cụ làm việc hàng ngày.
Các khái niệm IAM cốt lõi: Realm, Federation và Single Sign-On
Trước khi khởi chạy các container, hãy cùng nắm vững 4 khái niệm nền tảng sau để tiết kiệm hàng giờ debug về sau:
- Keycloak Realm: Một vùng bảo mật cô lập chứa người dùng, thông tin đăng nhập, role và các ứng dụng kết nối. Realm
mastermặc định chỉ đóng vai trò là admin control plane. Hãy luôn tạo một realm riêng biệt (chẳng hạn nhưinternal-corp) cho nhân viên và các dịch vụ thường nhật của bạn. - OpenID Connect (OIDC) & SAML: Keycloak đóng vai trò cầu nối cho các giao thức định danh hiện đại. Hầu hết các nền tảng web kết nối với Keycloak thông qua OIDC (xây dựng trên OAuth 2.0 và sử dụng JWT token ký bằng thuật toán RS256), nhờ đó các ứng dụng không bao giờ phải chạm vào hay lưu trữ mật khẩu gốc của người dùng.
- User Federation (LDAP): Thay vì phải quản lý các cơ sở dữ liệu trùng lặp, Keycloak liên kết (bind) trực tiếp với dịch vụ thư mục bên ngoài như OpenLDAP hoặc Active Directory. Hệ thống sẽ đọc cây người dùng (user tree), xác thực thông tin đăng nhập qua các yêu cầu LDAP bind và cache metadata hồ sơ cục bộ.
- Xác thực đa yếu tố (MFA / 2FA): Keycloak hỗ trợ chuẩn RFC 6238 Time-based One-Time Password (TOTP). Người dùng chỉ cần quét mã QR vào Google Authenticator hoặc FreeOTP, loại bỏ hoàn toàn nhu cầu sử dụng các SMS gateway tốn phí.
Thực hành: Thiết lập Keycloak, PostgreSQL và OpenLDAP
Bước 1: Thiết kế hạ tầng với Docker Compose
Keycloak vận hành trên Quarkus runtime và kết hợp mượt mà với PostgreSQL để lưu trữ metadata. Cùng với Keycloak, chúng ta sẽ khởi chạy OpenLDAP để lưu trữ bản ghi danh tính và web client phpLDAPadmin gọn nhẹ để quản lý schema.
Để tạo mật khẩu database và admin có độ dài tối thiểu 32 ký tự với entropy ngẫu nhiên cao, công cụ tạo mật khẩu phía client tại toolcraft.app/vi/tools/security/password-generator là một lựa chọn rất tốt vì nó tính toán entropy cục bộ trong bộ nhớ trình duyệt mà không gửi khóa qua mạng.
Lưu cấu hình sau thành tệp docker-compose.yml:
version: '3.8'
networks:
iam-network:
driver: bridge
volumes:
postgres_data:
ldap_data:
ldap_config:
services:
postgres:
image: postgres:15-alpine
container_name: keycloak-db
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak_admin
POSTGRES_PASSWORD: ReplaceWithAStrongSecretDbPass123!
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- iam-network
restart: unless-stopped
openldap:
image: osixia/openldap:1.5.0
container_name: openldap
environment:
LDAP_ORGANISATION: "Example Corp"
LDAP_DOMAIN: "example.com"
LDAP_ADMIN_PASSWORD: ReplaceWithLdapAdminPass123!
volumes:
- ldap_data:/var/lib/ldap
- ldap_config:/etc/ldap/slapd.d
networks:
- iam-network
restart: unless-stopped
phpldapadmin:
image: osixia/phpldapadmin:0.9.0
container_name: phpldapadmin
environment:
PHPLDAPADMIN_LDAP_HOSTS: openldap
PHPLDAPADMIN_HTTPS: "false"
ports:
- "8080:80"
networks:
- iam-network
depends_on:
- openldap
restart: unless-stopped
keycloak:
image: quay.io/keycloak/keycloak:24.0.1
container_name: keycloak-server
command: start-dev
environment:
KC_DB: postgres
KC_DB_URL_HOST: postgres
KC_DB_URL_PORT: 5432
KC_DB_URL_DATABASE: keycloak
KC_DB_USERNAME: keycloak_admin
KC_DB_PASSWORD: ReplaceWithAStrongSecretDbPass123!
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: ReplaceWithAdminConsolePass123!
ports:
- "8081:8080"
networks:
- iam-network
depends_on:
- postgres
restart: unless-stopped
Khởi động môi trường ở chế độ chạy nền:
docker compose up -d
docker compose logs -f keycloak
Theo dõi log. Trong khoảng 15 đến 20 giây, Keycloak sẽ in ra thông báo Running the server in development mode. Started.... Bây giờ bạn có thể truy cập Keycloak tại http://localhost:8081 và phpLDAPadmin tại http://localhost:8080.
Bước 2: Khởi tạo người dùng trong thư mục OpenLDAP
Mở http://localhost:8080 trên trình duyệt của bạn. Đăng nhập bằng admin DN cn=admin,dc=example,dc=com và mật khẩu LDAP_ADMIN_PASSWORD đã thiết lập. Tạo một Organizational Unit (OU) cấu trúc có tên là users, sau đó thêm một tài khoản thử nghiệm bên trong ou=users,dc=example,dc=com:
- Tên (givenName): Alex
- Họ (sn): Mercer
- Tên đăng nhập (uid): amercer
- Email (mail): [email protected]
- Mật khẩu (userPassword): TemporaryPass987!
Bước 3: Kết nối Keycloak với OpenLDAP qua User Federation
- Đăng nhập vào Keycloak admin console tại
http://localhost:8081bằng thông tin đăng nhậpKEYCLOAK_ADMINcủa bạn. - Nhấp vào bộ chọn realm ở góc trên bên trái, chọn Create Realm và đặt tên là
internal-corp. - Ở thanh điều hướng bên trái, đi đến User federation và chọn Add LDAP providers.
- Cấu hình các tham số kết nối:
- UI display name:
Company-OpenLDAP - Vendor:
Other - Connection URL:
ldap://openldap:389 - Users DN:
ou=users,dc=example,dc=com - Authentication type:
simple - Bind DN:
cn=admin,dc=example,dc=com - Bind credential:
ReplaceWithLdapAdminPass123! - Username LDAP attribute:
uid - RDN LDAP attribute:
uid - UUID LDAP attribute:
entryUUID - User object classes:
inetOrgPerson, organizationalPerson, person - Edit mode:
READ_ONLY(giữ chế độ chỉ đọc nếu LDAP là nguồn chân lý duy nhất (single source of truth), hoặc chuyển sangWRITABLEđể cho phép người dùng đồng bộ mật khẩu cập nhật ngược lại thư mục)
- UI display name:
- Nhấp vào Test connection, sau đó nhấn Test authentication. Khi cả hai đều hiển thị thông báo thành công màu xanh, nhấn Save.
- Cuộn xuống mục Sync settings và nhấn Sync all users. Kiểm tra tab Users trong Keycloak: tài khoản
amercersẽ xuất hiện ngay lập tức với đầy đủ email và các trường thông tin hồ sơ từ thư mục.
Bước 4: Bắt buộc áp dụng chính sách xác thực hai yếu tố (TOTP)
Sau khi danh tính người dùng đã được đồng bộ từ LDAP, việc triển khai 2FA bắt buộc trên mọi công cụ kết nối chỉ mất chưa đầy hai phút:
- Bên trong realm
internal-corp, nhấp vào Authentication > Required actions. - Tìm mục Configure OTP và bật Set as default action. Thao tác này sẽ đánh dấu mọi tài khoản chưa đăng ký ứng dụng xác thực phải tiến hành kích hoạt ngay trong lần đăng nhập tiếp theo.
- Điều hướng đến Authentication > Policies > OTP Policy. Bạn nên đặt thuật toán băm (hashing algorithm) thành SHA-256 với mã 6 chữ số tiêu chuẩn và chu kỳ token 30 giây.
Hãy kiểm tra quy trình ngay lập tức. Truy cập vào http://localhost:8081/realms/internal-corp/account/ và đăng nhập bằng tài khoản amercer. Keycloak sẽ xác thực mật khẩu với OpenLDAP, ngay lập tức tạm dừng phiên và hiển thị mã QR để thiết lập. Người dùng sẽ không thể truy cập các công cụ phía sau cho đến khi họ xác thực thành công mã 6 chữ số đầu tiên.
Kinh nghiệm thực tế & Góc nhìn kiến trúc
Sau quá trình triển khai Keycloak trên container ở các môi trường production có lưu lượng truy cập cao, đây là 3 nguyên tắc vận hành quan trọng bạn cần lưu ý:
- Chỉ sử dụng start-dev trên máy cục bộ (local): Cờ
start-devsẽ tắt các bước xác thực TLS quan trọng và liên kết trực tiếp với giao thức HTTP thông thường. Đối với staging và production, hãy tạo một multi-stage Dockerfile để build asset bằng lệnhkc.sh buildvới driver PostgreSQL được cache sẵn. Sau đó khởi động container bằngkc.sh start --optimizedphía sau một reverse proxy (như Traefik hoặc NGINX) đảm nhận việc terminate TLS trên cổng 443. - Giữ thời gian sống của access token ngắn: Thời hạn 5 phút cho access token là con số lý tưởng. Đừng kéo dài access token lên 8 tiếng chỉ để tránh bước refresh token; điều đó sẽ biến các bearer token bị rò rỉ thành một cơn ác mộng về mặt quản trị. Hãy kết hợp access token ngắn hạn 5 phút với refresh token dài hạn 12 giờ, đồng thời bật Revoke Refresh Token để xoay vòng (rotate) refresh token sau mỗi lần trao đổi.
- Tự động hóa các tác vụ đồng bộ nền: Với cấu hình LDAP ở chế độ
READ_ONLY, những thành viên mới được thêm vào sẽ không hiển thị trong danh sách tìm kiếm của Keycloak cho đến khi họ đăng nhập hoặc có một lệnh sync thủ công được kích hoạt. Hãy xử lý vấn đề này bằng cách bật Periodic Full Sync (mỗi 86.400 giây, tức 24 giờ) và Periodic Changed Users Sync (mỗi 300 giây, tức 5 phút). Điều này đảm bảo các nhóm LDAP mới và những thay đổi về nhân sự sẽ được phản ánh chính xác vào role mapping của Keycloak mà không tốn công thao tác thủ công.
Sự kết hợp giữa Keycloak và OpenLDAP trên Docker mang lại cho bạn một kiến trúc IAM mạnh mẽ và đã được kiểm chứng thực tế. Các ứng dụng ủy quyền xác thực thông qua OIDC, SysAdmin duy trì một thư mục tập trung gọn gàng, và các tiêu chuẩn an toàn bảo mật như TOTP bắt buộc được áp dụng đồng bộ trên toàn bộ dashboard nội bộ của bạn.
