Chuyển tới nội dung chính

Cloudflare cho DX-OS

Tổng hợp các khái niệm và cấu hình Cloudflare đang dùng cho máy chủ công khai khuongdev.io.vn. Cấu hình nằm trên tài khoản Cloudflare, không nằm trong repo; các bước bật và kiểm ở deploy/OPERATIONS.md. Máy chủ nằm sau NAT và không mở cổng nào ra Internet ngoài SSH.

1. Cách request đi vào hệ thống​

Người dùng
→ Cloudflare (DNS, chứng chỉ HTTPS, WAF, giới hạn, Access)
→ Cloudflare Tunnel
→ container cloudflared trên máy chủ
→ APISIX hoặc Mattermost trong mạng Docker

Mọi request công khai đi qua Cloudflare trước khi chạm vào máy chủ. Máy chủ tự kết nối ra Cloudflare qua tunnel, nên không cần IP công khai hay mở cổng vào.

2. Khái niệm​

Khái niệmLà gìDùng để làm gì ở đây
Proxy (đám mây cam)Cloudflare đứng giữa người dùng và máy chủ, domain trỏ về CloudflareGiấu máy chủ gốc, áp dụng HTTPS, chặn bot và giới hạn tốc độ
Tunnel (cloudflared)Kết nối đi ra từ máy chủ tới Cloudflare, Cloudflare gửi request ngược xuống qua kết nối đóCông khai dịch vụ mà không mở cổng
Published application routeÁnh xạ một hostname công khai sang một dịch vụ nội bộ của tunnelMỗi tên miền con trỏ tới một dịch vụ riêng
Transform RuleQuy tắc sửa header của request ở edgeĐặt X-Forwarded-Port bằng 443
Bot fight modeThử thách các request nghi là botGiảm quét và dò tự động
Managed rulesetBộ rule WAF do Cloudflare duy trìChặn các khai thác đã biết
Rate limiting ruleGiới hạn số request trong một khoảng thời gian theo một đặc điểm (IP)Chặn gửi form đăng nhập dồn dập
Zero Trust, AccessCổng đăng nhập đặt trước một ứng dụng, chỉ người trong policy mới quaBảo vệ các trang quản trị
Policy (Access)Quy tắc Allow hoặc Block theo email, nhóm hoặc điều kiện khácChỉ quản trị viên và kỹ sư vào được trang quản trị

3. Cấu hình đang dùng​

Domain và HTTPS​

  • Domain khuongdev.io.vn do Cloudflare quản lý DNS, gói Free.
  • Chứng chỉ HTTPS do Cloudflare cấp cho domain gốc và các tên miền con cấp một.
  • Always Use HTTPS bật: http:// luôn chuyển 301 sang https://.
  • Minimum TLS Version 1.2: TLS 1.0 và 1.1 bị từ chối.

Tunnel dxos-vps và bốn route​

HostnameDịch vụ trong mạng DockerNội dung
khuongdev.io.vnhttp://apisix:9080Web app, API, Keycloak, portal, Swagger, link ảnh
bi.khuongdev.io.vnhttp://apisix:9081BI (Superset)
files.khuongdev.io.vnhttp://apisix:9082Quản trị lưu ảnh
chat.khuongdev.io.vnhttp://mattermost:8065Chat (Mattermost)

Token của tunnel nằm trong deploy/.env trên máy chủ (CLOUDFLARE_TUNNEL_TOKEN), không nằm trong repo. Cloudflare chỉ nhận người dùng qua cổng 443, nên mỗi dịch vụ có một tên miền con riêng.

Request Header Transform Rule​

  • Rule Forward public port 443 đặt header X-Forwarded-Port bằng 443 cho mọi request.
  • Thiếu rule, gateway gắn cổng của listener vào header này.
  • Khi đó Superset dựng địa chỉ chuyển hướng có thêm :9081 và backend từ chối request ghi bằng 403 Invalid CORS request.
  • Rule này bắt buộc.

Bot fight mode​

  • Bật ở Security → Settings → Bot traffic.
  • Tải ảnh báo cáo và chẩn đoán AI chạy bình thường khi bật.

Managed ruleset (gói Free)​

  • Luôn bật, không có công tắc.
  • Chặn các khai thác đã biết (ví dụ cảnh báo php2shell trên trang Security rules).
  • Không chặn SQLi hay XSS chung.
  • Bộ đầy đủ cần gói trả phí.
  • Backend dùng truy vấn tham số hóa, nên SQLi không phải rủi ro của ứng dụng.

Rate limiting rule​

  • Một rule (gói Free cho một rule), áp dụng cho đường dẫn bắt đầu bằng /realms/ và chứa /login-actions/, tức là form mật khẩu của Keycloak.
  • Giới hạn 10 lượt trong 10 giây mỗi IP, vượt thì Block 10 giây.
  • Response bị chặn có mã lỗi Cloudflare 1015 và header retry-after: 10.

Cloudflare Access​

Bốn ứng dụng Self-hosted dùng chung policy Admins and engineers (Allow theo email):

Ứng dụngHostnameĐường dẫn
BI Supersetbi.khuongdev.io.vntoàn bộ
Quản trị lưu ảnhfiles.khuongdev.io.vntoàn bộ
Keycloak Admin Consolekhuongdev.io.vnadmin/*
Màn hình giám sátkhuongdev.io.vnmonitor/*
  • Request chưa có phiên Access nhận 302 sang trang đăng nhập Access (*.cloudflareaccess.com).
  • Người dùng đăng nhập bằng phương thức đã bật: tài khoản Cloudflare hoặc mã gửi qua email.
  • Màn hình giám sát còn đòi đăng nhập SSO Keycloak và vai ADMIN sau lớp Access.
  • Gateway gửi sự kiện cho monitor trong mạng Docker, không qua Cloudflare, nên Access không ảnh hưởng.
  • Không đặt Access cho web app, API, /realms/*, portal, chat và link ảnh, vì nông dân, sinh viên và mobile dùng các đường này.
  • Thêm người vào: Zero Trust → Access controls → Policies → Admins and engineers → thêm email.
  • Bị khóa ngoài thì gỡ ứng dụng Keycloak Admin Console ở trang Applications.

Không dùng​

  • Chặn theo quốc gia: hội đồng chấm có thể truy cập từ nước ngoài.
  • Swagger (/swagger-ui/) để công khai cho hội đồng xem API.
  • WAF managed rules đầy đủ, HSTS: chưa bật.

4. Các lớp bảo vệ và việc mỗi lớp làm​

LớpChặn hoặc ghi gì
Cloudflare edgeHTTPS bắt buộc, TLS tối thiểu 1.2, bot, khai thác đã biết, form đăng nhập dồn dập
Cloudflare AccessNgười lạ vào trang quản trị (Superset, quản trị lưu ảnh, Keycloak Admin, màn hình giám sát)
APISIX120 lượt mỗi phút mỗi IP cho form đăng nhập và token, 600 lượt cho /api/*, kiểm token, log JSON kèm X-Request-Id
KeycloakKhóa tạm tài khoản sau 5 lần sai mật khẩu, sự kiện đăng nhập kèm IP thật
BackendPhân quyền theo vai, audit_log cho request bị từ chối và thao tác quản trị
  • Cloudflare thêm header CF-Connecting-IP với IP thật của người dùng.
  • APISIX tin header này khi request đến từ mạng Docker.
  • Header CF-Connecting-IP giả gửi từ ngoài bị Cloudflare từ chối ở edge (mã lỗi 1000).
  • IP thật có trong log gateway, sự kiện Keycloak và audit_log.

5. Mã lỗi và hiện tượng thường gặp​

Hiện tượngNguyên nhânCách xử lý
error code: 1000Request có header CF-Connecting-IP giảKhông gửi header này; Cloudflare tự đặt
error code: 1015, retry-after: 10Vượt rate limiting rule của form đăng nhậpChờ 10 giây
429 kèm X-RateLimit-LimitVượt giới hạn của APISIXChờ một phút hoặc tăng ngưỡng ở deploy/apisix/common.yaml
Chuyển sang trang cloudflareaccess.comChưa có phiên AccessĐăng nhập Access bằng email trong policy
504 ở chẩn đoán AIGateway chờ AI tối đa 60 giây; lần gọi đầu sau khi khởi động lại phải nạp mô hìnhGọi lại; các lần sau khoảng 53 giây
Superset chuyển hướng sai cổngThiếu Transform Rule X-Forwarded-PortTạo lại rule ở mục 3
Cloudflare 502 hoặc 1033cloudflared không chạy hoặc không tới được apisixdocker compose ps và docker compose logs cloudflared trên máy chủ

6. Kiểm nhanh từ bên ngoài​

curl -sI http://khuongdev.io.vn/portal/ | head -3 # 301 sang https
curl -sI https://bi.khuongdev.io.vn/ | grep -i location # trang đăng nhập Access
curl -sI https://khuongdev.io.vn/admin/ | grep -i location # trang đăng nhập Access
curl -s https://khuongdev.io.vn/cdn-cgi/trace | grep ip= # IP mà Cloudflare thấy

Gửi nhiều POST liên tiếp vào /realms/dxos/login-actions/authenticate sẽ thấy 1015. Gửi hơn 120 POST trong một phút vào /realms/dxos/protocol/openid-connect/token sẽ thấy 429 của APISIX.