Bài 89. (Lab) Triển khai SSO và MFA với Keycloak
Khóa học CompTIA Security+ SY0-801 · Phần 4: Vận hành bảo mật · Bài 89 · 🎯 Objective 4.5 · ⏱️ Làm khoảng 90 phút · 🧪 Có lab (1 máy ảo) · 📝 5 câu bài tập cuối bài
🎯 Mục tiêu bài học
- Dựng Keycloak (máy chủ quản lý danh tính mã nguồn mở) trong môi trường lab.
- Tạo realm, người dùng, vai trò (role) và một client OIDC đại diện cho ứng dụng.
- Bật MFA bằng OTP, đặt chính sách mật khẩu và phát hiện dò mật khẩu (brute force).
- Xem token để hiểu SSO và phân quyền theo vai trò hoạt động ra sao.
📎 Vị trí trong đề thi: Objective 4.5 về quản lý danh tính và truy cập. Bài này là lab của Bài 74 (SSO, federation, SAML, OAuth, OIDC), Bài 75 (MFA, mật khẩu), Bài 76 (RBAC) và Bài 77 (PAM, access review). Nhật ký đăng nhập có thể đưa vào SIEM của Bài 85. Lab kế tiếp: Bài 90 ôn tập Phần 4.
⚠️ Chỉ để học: Chế độ
start-devcủa Keycloak không dành cho môi trường thật (dùng cơ sở dữ liệu tạm, HTTP không mã hóa). Trong lab, chỉ cho Keycloak lắng nghe ở localhost và không mở ra Internet.
💡 Liên hệ thực tế: Nam muốn một cửa đăng nhập
Công ty của chị Lan có năm ứng dụng nội bộ, mỗi ứng dụng một bộ tài khoản riêng. Khi nhân viên nghỉ việc, IT phải vào từng ứng dụng để khóa; có lần sót một tài khoản kế toán vẫn dùng được hai tháng. Nam đề xuất SSO: người dùng đăng nhập một lần tại máy chủ danh tính, kèm MFA; các ứng dụng chỉ tin vào kết quả xác thực đó. Khi một người nghỉ việc, vô hiệu hóa một tài khoản là đủ. Trước khi đề xuất mua giải pháp, anh dựng thử Keycloak. Đây là tình huống minh họa, không phải vụ việc có thật.
🔑 Hình 89a. Ứng dụng không giữ mật khẩu: Keycloak xác thực rồi trao token.
🧰 Chuẩn bị
| Hạng mục | Gợi ý |
|---|---|
| Máy ảo | Ubuntu Server hoặc Desktop 22.04 hoặc 24.04, 2 vCPU, 4 GB RAM, 20 GB |
| Phần mềm | Docker (cài bằng hướng dẫn chính thức của Docker) |
| Điện thoại | Ứng dụng xác thực OTP như FreeOTP, Google Authenticator hoặc Microsoft Authenticator (làm MFA thật cho lab) |
| Trình duyệt | Trình duyệt trong máy ảo, hoặc từ máy thật qua SSH tunnel (xem bước 2) |
Kiểm tra Docker: docker --version. Nếu chưa có quyền chạy, thêm sudo trước lệnh docker.
🪜 Các bước thực hiện
Bước 1. Chạy Keycloak bằng Docker
bash
sudo docker run --name keycloak-lab -p 127.0.0.1:8080:8080 \ -e KC_BOOTSTRAP_ADMIN_USERNAME=admin \ -e KC_BOOTSTRAP_ADMIN_PASSWORD='Lab-Admin-2026!' \ quay.io/keycloak/keycloak:26.0 start-dev
-p 127.0.0.1:8080:8080chỉ mở cổng ở localhost của máy ảo.- Hai biến
KC_BOOTSTRAP_ADMIN_*tạo tài khoản quản trị ban đầu ở các bản Keycloak 26 trở lên. Với bản cũ hơn, tên biến làKEYCLOAK_ADMINvàKEYCLOAK_ADMIN_PASSWORD. Hãy đối chiếu với tài liệu của bản bạn tải; số phiên bản26.0ở trên chỉ là ví dụ. - Lần đầu chạy cần tải ảnh, nên chờ vài phút cho tới khi log báo Keycloak đã khởi động.
Bước 2. Mở bảng quản trị
Mở trình duyệt trong máy ảo tại http://localhost:8080 và đăng nhập bằng tài khoản quản trị ở bước 1.
Nếu muốn dùng trình duyệt trên máy thật, mở một SSH tunnel (đây vẫn chỉ là localhost, không mở ra mạng):
bash
ssh -L 8080:localhost:8080 <tên-người-dùng>@<IP-máy-ảo>
rồi mở http://localhost:8080 trên máy thật.
🧠 Thực hành tốt: tài khoản
adminở realm master chỉ dùng để quản trị Keycloak. Đừng dùng realm master cho ứng dụng; hãy tạo một realm riêng cho từng môi trường.
Bước 3. Tạo realm, vai trò và người dùng
- Góc trên bên trái, chọn Create realm, đặt tên
lab. - Vào Realm roles → Create role, tạo hai vai trò:
salesvàlab-admin. - Vào Users → Add user: tên
an.sales, bật Email verified, rồi Create. Trong tab Credentials, Set password (tắt Temporary để thuận tiện cho lab). - Trong tab Role mapping, gán vai trò
saleschoan.sales. - Tạo thêm
binh.adminvà gán vai tròlab-admin.
Đây là mô hình RBAC (Bài 76): quyền gắn với vai trò, người dùng nhận quyền thông qua vai trò.
🛡️ Hình 89b. Chính sách mật khẩu, MFA, chống dò mật khẩu, giới hạn phiên và token.
Bước 4. Đặt chính sách mật khẩu
Vào Authentication → Policies → Password policy → Add policy (tên menu có thể khác theo bản), thêm:
| Chính sách | Giá trị gợi ý | Mục đích |
|---|---|---|
| Minimum length | 12 | Mật khẩu dài khó dò hơn |
| Not username | bật | Không cho dùng tên đăng nhập làm mật khẩu |
| Password history | 5 | Không cho dùng lại mật khẩu cũ |
| Not recently used / Expire password | tùy chính sách | Chỉ bật khi tổ chức thực sự yêu cầu đổi định kỳ |
Lưu ý đổi mật khẩu bắt buộc định kỳ đã không còn được khuyến nghị rộng rãi nếu không có dấu hiệu bị lộ (Bài 75); hãy dựa vào độ dài, kiểm tra mật khẩu bị lộ và MFA.
Bước 5. Bật MFA bằng OTP
- Vào Users → an.sales → Details, mục Required user actions chọn Configure OTP, rồi Save.
- Mở cửa sổ ẩn danh, vào trang tài khoản người dùng:
http://localhost:8080/realms/lab/account. - Đăng nhập bằng
an.sales. Keycloak yêu cầu cấu hình OTP: quét mã QR bằng ứng dụng xác thực, nhập mã 6 số để hoàn tất. - Đăng xuất rồi đăng nhập lại: lần này phải nhập mật khẩu và mã OTP.
Đây là xác thực đa yếu tố: thứ bạn biết (mật khẩu) cộng thứ bạn có (điện thoại chứa khóa OTP). Với cả realm, bạn có thể bắt MFA cho mọi người dùng bằng cách tinh chỉnh luồng xác thực (Authentication flow) hoặc cấu hình điều kiện theo vai trò; xem tài liệu Keycloak cho bản bạn dùng. Với passkeys (Bài 75), Keycloak cũng hỗ trợ WebAuthn; thử nếu thiết bị của bạn hỗ trợ.
🧠 Lưu ý: giữ lại mã dự phòng (recovery codes) nếu có. Mất điện thoại mà không có mã dự phòng sẽ khóa chính bạn, đây là vấn đề thực tế khi triển khai MFA (Bài 75).
Bước 6. Bật phát hiện dò mật khẩu
Vào Realm settings → Security defenses → Brute force detection, bật và đặt, ví dụ: khóa tạm khi sai 5 lần liên tiếp, thời gian chờ tăng dần, tối đa vài phút.
Thử nghiệm: ở cửa sổ ẩn danh, cố đăng nhập binh.admin bằng mật khẩu sai nhiều lần. Sau ngưỡng, tài khoản bị khóa tạm. Trong Users → binh.admin bạn sẽ thấy trạng thái bị vô hiệu tạm thời. Đây là cách giảm brute force và password spraying (Bài 32). Cân nhắc: khóa quá chặt có thể bị lợi dụng để khóa tài khoản người khác (tấn công từ chối dịch vụ nhắm vào tài khoản), nên hãy đặt thời gian khóa tạm thời.
Bước 7. Tạo client OIDC đại diện cho ứng dụng
Vào Clients → Create client:
| Trường | Giá trị |
|---|---|
| Client type | OpenID Connect |
| Client ID | lab-app |
| Client authentication | Bật (client bí mật) |
| Valid redirect URIs | http://localhost:3000/* (địa chỉ giả định của ứng dụng lab) |
Valid redirect URIs nên đặt chính xác, tránh ký tự thay thế rộng, vì cấu hình lỏng có thể bị lợi dụng để chuyển hướng mã xác thực tới nơi khác.
Kiểm tra "bản đồ" của máy chủ danh tính (địa chỉ endpoint, thuật toán ký):
bash
curl -s http://localhost:8080/realms/lab/.well-known/openid-configuration | head -c 700
Bước 8. Xem token và vai trò
Vào Clients → lab-app → Client scopes → Evaluate, chọn người dùng an.sales rồi xem Generated access token và Generated ID token. Chú ý:
| Trường trong token | Ý nghĩa |
|---|---|
iss |
Nơi phát hành (issuer): ứng dụng phải kiểm tra |
aud |
Đối tượng token dành cho; ứng dụng phải kiểm tra |
exp |
Hạn dùng; token ngắn hạn giảm thiệt hại khi bị lộ |
preferred_username |
Tên người dùng |
realm_access.roles |
Các vai trò (ở đây có sales); ứng dụng dựa vào đây để phân quyền |
Token được ký; ứng dụng kiểm tra chữ ký bằng khóa công khai của Keycloak (Bài 10). Phân biệt (Bài 74): OAuth 2.0 là khung ủy quyền; OIDC thêm lớp xác thực danh tính trên OAuth 2.0; SAML là chuẩn federation dựa trên XML, hay dùng cho ứng dụng doanh nghiệp. Keycloak hỗ trợ cả OIDC và SAML.
Bước 9. Giới hạn phiên và ghi nhật ký
- Realm settings → Sessions và Tokens: xem thời hạn phiên và Access Token Lifespan (thường ngắn, tính bằng phút). Thử rút ngắn và nhận xét ảnh hưởng đến trải nghiệm.
- Realm settings → Events: bật Save events cho Login events để lưu nhật ký đăng nhập thành công và thất bại, bao gồm IP. Trong Events bạn sẽ thấy các lần sai mật khẩu ở bước 6. Đây chính là nguồn log có thể chuyển về SIEM (Bài 71, 85) để cảnh báo đăng nhập bất thường.
Bước 10. Mô phỏng nhân viên nghỉ việc (deprovisioning)
Trong Users → an.sales, tắt Enabled hoặc xóa tài khoản. Thử đăng nhập lại: không còn vào được. Nếu có nhiều ứng dụng cùng dùng SSO, mọi ứng dụng mất quyền theo; cần đăng xuất phiên đang mở (tab Sessions của người dùng) vì token đã cấp vẫn còn hiệu lực cho tới khi hết hạn. Đây là lý do cần token ngắn hạn và quy trình deprovisioning rõ ràng (Bài 74).
🛠️ Lỗi thường gặp
| Hiện tượng | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
| Không đăng nhập được admin | Sai biến môi trường theo bản Keycloak | Dùng đúng cặp KC_BOOTSTRAP_ADMIN_* (bản 26+) hoặc KEYCLOAK_ADMIN* (bản cũ) |
Không mở được localhost:8080 từ máy thật |
Cổng chỉ mở ở localhost của VM | Dùng SSH tunnel hoặc trình duyệt trong VM |
| Quét QR không ra mã OTP | Giờ điện thoại và máy chủ lệch | Bật giờ tự động trên điện thoại và đồng bộ giờ máy ảo |
| Mã OTP luôn sai | Lệch giờ hoặc nhập mã hết hạn | Đồng bộ giờ, nhập mã mới |
| Lỗi redirect URI khi đăng nhập ứng dụng | URI trong client không khớp | Sửa Valid redirect URIs chính xác |
| Mất dữ liệu khi khởi động lại container | start-dev dùng lưu trữ tạm |
Bình thường trong lab; cần cơ sở dữ liệu thật cho môi trường vận hành |
🧹 Dọn dẹp
bash
sudo docker stop keycloak-lab && sudo docker rm keycloak-lab
Xóa mục OTP trong ứng dụng xác thực trên điện thoại nếu không dùng nữa. Không dùng lại mật khẩu của lab ở nơi khác.
📘 Nối lý thuyết với lab
| Khái niệm | Trong lab |
|---|---|
| SSO, federation | Một lần đăng nhập tại Keycloak cho nhiều ứng dụng |
| OIDC, OAuth, SAML | Client OIDC, token, endpoint; có thể thêm client SAML |
| MFA | OTP bằng ứng dụng xác thực |
| Chính sách mật khẩu | Độ dài, lịch sử, không trùng tên đăng nhập |
| RBAC | Vai trò sales, lab-admin trong token |
| Chống brute force | Khóa tạm sau nhiều lần sai |
| Provisioning, deprovisioning | Tạo, vô hiệu hóa người dùng; xử lý phiên đang mở |
| Nhật ký, giám sát | Login events, nguồn log cho SIEM |
🎯 Mẹo làm bài
"Đăng nhập một lần cho nhiều ứng dụng" → SSO. "Chuẩn federation dựa trên XML" → SAML. "Khung ủy quyền cấp token truy cập" → OAuth 2.0. "Lớp xác thực danh tính trên OAuth" → OpenID Connect (OIDC). "Mật khẩu và OTP trên điện thoại" → MFA (biết và có). "Mật khẩu và câu hỏi bí mật" → không phải MFA đúng nghĩa (cùng yếu tố biết). "Quyền theo chức danh" → RBAC. "Khóa tài khoản sau nhiều lần sai" → account lockout chống brute force. "Thu hồi quyền ngay khi nghỉ việc" → deprovisioning. "Token ngắn hạn" → giảm thiệt hại khi bị lộ. "Đăng nhập không mật khẩu bằng khóa gắn thiết bị" → passkeys.
📌 Tóm tắt nhanh
- Keycloak là máy chủ danh tính mã nguồn mở hỗ trợ OIDC, OAuth 2.0, SAML.
- Cấu trúc: realm (không gian quản lý) → người dùng, vai trò, client.
- Các lớp bảo vệ: chính sách mật khẩu, MFA, chống brute force, token và phiên ngắn hạn.
- Ứng dụng phải kiểm tra chữ ký, issuer, audience, hạn của token.
- Deprovisioning phải đi kèm xử lý phiên đang mở; log đăng nhập nên đưa về SIEM.
📝 Bài tập đánh giá
Tự chọn đáp án cho từng câu, rồi đối chiếu với phần đáp án ở cuối bài.
Câu 1. Cơ chế nào cho phép người dùng đăng nhập một lần tại máy chủ danh tính rồi truy cập nhiều ứng dụng mà không phải đăng nhập lại?
- A. SSO
- B. DLP
- C. NAC
- D. SPF
Câu 2. Cặp xác thực nào được coi là MFA đúng nghĩa?
- A. Mật khẩu và câu hỏi bí mật
- B. Hai mật khẩu khác nhau
- C. Mật khẩu và mã OTP từ ứng dụng trên điện thoại
- D. Mã PIN và mật khẩu
Câu 3. Giao thức nào bổ sung lớp xác thực danh tính trên nền OAuth 2.0?
- A. LDAP
- B. OpenID Connect
- C. Kerberos
- D. RADIUS
Câu 4. Phát hiện nhiều lần đăng nhập sai liên tiếp rồi khóa tạm tài khoản nhằm giảm thiểu kiểu tấn công nào?
- A. SQL injection
- B. Cross-site scripting
- C. Brute force và dò mật khẩu
- D. Tràn bộ đệm
Câu 5. Một nhân viên nghỉ việc đã bị vô hiệu hóa tài khoản SSO nhưng vẫn truy cập được một ứng dụng thêm vài chục phút. Nguyên nhân hợp lý nhất?
- A. Token hoặc phiên đã cấp vẫn còn hiệu lực cho tới khi hết hạn hoặc bị thu hồi
- B. Ứng dụng không dùng mạng
- C. Mật khẩu chưa đủ dài
- D. Keycloak không hỗ trợ MFA
👉 Đáp án
Câu 1: A — SSO cho phép xác thực một lần để dùng nhiều ứng dụng.
Câu 2: C — Mật khẩu (yếu tố biết) cộng OTP trên điện thoại (yếu tố có) là hai yếu tố khác loại.
Câu 3: B — OIDC thêm lớp xác thực danh tính trên OAuth 2.0.
Câu 4: C — Khóa tạm sau nhiều lần sai giảm thiểu brute force và password spraying.
Câu 5: A — Token và phiên đã cấp vẫn hợp lệ tới khi hết hạn hoặc bị thu hồi; cần token ngắn hạn và đăng xuất phiên đang mở.
📚 Bài viết thuộc khóa học CompTIA Security+ của VNExperts
🧭 Điều hướng
| ⬅️ Bài trước | 🏠 Mục lục khóa học | Bài kế tiếp ➡️ |
|---|---|---|
| Bài 88: (Lab) Diễn tập ứng phó sự cố ransomware theo tình huống | Mục lục khóa học CompTIA Security+ | Bài 90: Ôn tập Phần 4 + Quiz tổng hợp 25 câu |