Bảo mật Docker Container với Authentik Forward Auth: Thêm SSO và MFA trong 10 phút

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

Vấn đề: Khi ứng dụng “ngon” nhưng lại “hở sườn”

Bạn vừa tìm thấy một công cụ tự host (self-hosted) cực hay trên GitHub, chẳng hạn như dashboard theo dõi hệ thống Glances hoặc trình quản lý file. Bạn deploy nó lên VPS bằng Docker trong nháy mắt. Thế nhưng, bạn chợt nhận ra một lỗ hổng lớn: Ứng dụng này không hề có trang đăng nhập.

Bất kỳ ai có IP của bạn đều có thể vào xem và xóa dữ liệu. Việc công khai các app này ra Internet mà không có bảo vệ chẳng khác nào mở cửa mời trộm vào nhà. Trước đây, mình thường dùng tạm Basic Auth của Nginx. Tuy nhiên, cách này rất bất tiện. Giao diện đăng nhập trông như từ thập niên 90, không có MFA, và mỗi lần thêm user mới lại phải hì hục sửa file config rồi reload server.

Tại sao Authentik là lựa chọn hàng đầu hiện nay?

Để bảo vệ các app “không có login”, chúng ta thường cân nhắc vài phương án:

  • Basic Auth: Dễ làm nhưng lạc hậu và thiếu an toàn.
  • Authelia: Nhẹ nhưng cấu hình file YAML khá nhức đầu cho người mới.
  • OAuth2 Proxy: Mạnh mẽ nhưng thiết lập cho từng app riêng lẻ rất tốn thời gian.
  • Authentik: Đây là giải pháp All-in-one mình tin dùng nhất. Nó vừa là Identity Provider (như Google/Okta), vừa hỗ trợ Forward Auth với giao diện quản trị cực kỳ hiện đại.

Kể từ khi chuyển sang Authentik, mình chỉ cần nhớ đúng một mật khẩu duy nhất (SSO) cho hơn 20 ứng dụng nội bộ. Quan trọng hơn, mình có thể ép buộc mọi truy cập phải đi kèm mã OTP từ điện thoại, giúp giảm rủi ro bị hack tài khoản xuống gần như bằng không.

Cơ chế Forward Auth hoạt động thế nào?

Hãy tưởng tượng Authentik giống như một anh bảo vệ đứng trước cửa quán bar (ứng dụng của bạn). Reverse Proxy (Traefik) sẽ đóng vai trò người soát vé.

  1. Khi khách đến, Traefik hỏi Authentik: “Người này có thẻ thành viên chưa?”.
  2. Nếu chưa: Authentik mời khách sang quầy đăng ký (Trang Login).
  3. Nếu rồi: Authentik gật đầu, Traefik mở cửa cho khách vào ứng dụng.

Toàn bộ quá trình này diễn ra bên ngoài ứng dụng gốc. Bạn không cần động vào một dòng code nào của app vẫn có bảo mật chuẩn doanh nghiệp.

Hướng dẫn triển khai chi tiết

Trong bài này, mình dùng Traefik vì khả năng tự động nhận diện container qua labels cực kỳ thông minh. Hãy đảm bảo bạn đã cài sẵn Docker Compose v2 trên máy.

Bước 1: Khởi tạo Authentik

Tạo thư mục riêng để quản lý. Mình khuyên dùng Docker Compose v2 để các container kết nối với nhau ổn định hơn.

mkdir authentik && cd authentik
wget https://goauthentik.io/docker-compose.yml -O docker-compose.yml

# Tự động tạo mật khẩu ngẫu nhiên cho database
echo "PG_PASS=$(openssl rand -base64 36)" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 36)" >> .env

docker compose up -d

Sau khoảng 1 phút, hãy truy cập http://<IP-Của-Bạn>:9000/if/flow/initial-setup/ để thiết lập tài khoản admin.

Bước 2: Cấu hình Provider và Application

Để bảo vệ một app cụ thể, bạn cần thực hiện 2 bước trong giao diện Admin:

  1. Vào Resources -> Providers -> Create. Chọn Proxy Provider.
  2. Chọn chế độ Forward auth (single application). Nhập domain ứng dụng, ví dụ: https://uptime.example.com.
  3. Vào Resources -> Applications -> Create. Đặt tên app và gắn Provider vừa tạo vào.

Bước 3: Gắn “bảo vệ” vào Docker Container

Đây là lúc phép màu xảy ra. Dưới đây là ví dụ cấu hình cho app whoami. Bạn chỉ cần thêm các labels này vào file docker-compose.yml của bất kỳ ứng dụng nào muốn bảo mật.

services:
  whoami:
    image: traefik/whoami
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`uptime.example.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls=true"
      
      # Kích hoạt Middleware Authentik
      - "traefik.http.routers.whoami.middlewares=authentik@docker"
      
      # Cấu hình Middleware kết nối tới Authentik server
      - "traefik.http.middlewares.authentik.forwardauth.address=http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
      - "traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true"
      - "traefik.http.middlewares.authentik.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email"

Mẹo nhỏ: Hãy đặt Authentik và Traefik chung một Docker network. Cách này giúp dữ liệu đi nội bộ, tăng tốc độ phản hồi nhanh hơn khoảng 20-30ms so với việc gọi qua IP public.

Thành quả sau khi thiết lập

Bây giờ, khi truy cập vào ứng dụng, bạn sẽ thấy màn hình login chuyên nghiệp. Bạn có thể bật MFA (TOTP) trong phần User settings của Authentik. Chỉ những ai có mã 6 số trên điện thoại mới có thể vào được hệ thống. Ngoài ra, bạn còn có thể xem log chi tiết ai đã đăng nhập vào lúc nào, từ IP nào.

Khắc phục lỗi thường gặp

Nếu bạn gặp lỗi “Too many redirects”, hãy kiểm tra lại mục External Host trong Provider. Nó phải khớp 100% với domain bạn khai báo trong Traefik, bao gồm cả https://. Nếu thiếu dòng authResponseHeaders, ứng dụng phía sau sẽ không biết ai đang truy cập, dẫn đến các lỗi phân quyền khó chịu.

Việc triển khai Authentik ban đầu có vẻ hơi phức tạp. Tuy nhiên, lợi ích về bảo mật và sự tiện lợi mà nó mang lại là cực kỳ xứng đáng. Bạn sẽ không còn phải lo lắng mỗi khi public một ứng dụng mới lên Internet nữa.

Share: