Bỏ qua để đến nội dung
Search & RAG

7.20 Bảo mật, quan sát, checklist production

Bắt đầu bằng một câu cần nói thẳng:

Qdrant mặc định KHÔNG bật xác thực. Một instance vừa docker run xong, nếu cổng 6333 lộ ra Internet, là một cơ sở dữ liệu ai cũng đọc và xoá được.

Đây không phải sơ suất thiết kế — nó là mặc định hợp lý cho môi trường phát triển cục bộ. Nhưng nó có nghĩa: bật bảo mật là việc của bạn, và là việc đầu tiên.

service:
api_key: <khoá quản trị>
read_only_api_key: <khoá chỉ đọc>

Cũng đặt được bằng biến môi trường: QDRANT__SERVICE__API_KEY, QDRANT__SERVICE__READ_ONLY_API_KEY. Mọi request phải mang header api-key.

Hai khoá dùng đồng thời được, và nên dùng đồng thời: dịch vụ chỉ đọc (đường phục vụ truy vấn của ứng dụng) nhận khoá read-only; chỉ pipeline nạp dữ liệu mới cầm khoá quản trị. Đây là cách rẻ nhất để thu hẹp thiệt hại khi một khoá rò rỉ.

service:
enable_tls: true
tls:
cert: <chuỗi chứng chỉ .pem>
key: <khoá riêng>

Qdrant nói rõ: gửi api-key qua kênh không mã hoá là không an toàn. Nếu bật api_key mà không bật TLS (hoặc không đặt sau một reverse proxy có TLS), bạn đang gửi mật khẩu dạng rõ.

Giữa các peer trong cụm thì bật riêng: cluster.p2p.enable_tls: true. Chứng chỉ tự làm mới theo tls.cert_ttl.

Bật bằng jwt_rbac: true (kèm api_key). Token được ký bằng chính khoá quản trị, nên xoay khoá quản trị sẽ vô hiệu hoá toàn bộ token đang lưu hành.

Các claim:

ClaimNghĩa
expHạn dùng (Unix timestamp), có 30 giây dung sai
access"r" (chỉ đọc) / "m" (quản trị) toàn cục, hoặc mảng phân quyền theo từng collection với "r" / "rw"
value_existsRàng buộc token vào một giá trị payload cụ thể
subĐịnh danh chủ thể, xuất hiện trong nhật ký kiểm toán

value_exists là claim đáng chú ý nhất, và là câu trả lời cho vấn đề an toàn nêu ở 7.17:

Nó cho phép thực thi cách ly tenant ở tầng hạ tầng thay vì trông chờ mọi truy vấn của mọi lập trình viên đều nhớ kèm filter: tenant_id = X. Với value_exists, một truy vấn thiếu filter không trả về dữ liệu của người khác — nó bị từ chối.

Nó cũng cho phép thu hồi token mà không phải xoay khoá quản trị: xoá điểm mà claim trỏ tới, token hết hiệu lực.

Đây là lỗ hổng cụ thể, đáng nêu riêng vì nó không hiển nhiên.

API phục hồi snapshot nhận một URL và Qdrant sẽ đi tải URL đó (7.19). Nếu kẻ tấn công gọi được API này, họ khiến Qdrant gửi request tới bất kỳ địa chỉ nào mà Qdrant với tới được — kể cả metadata service nội bộ của cloud, hoặc dịch vụ nội bộ không lộ ra ngoài. Đó là server-side request forgery.

Hai cách chặn:

  1. enable_snapshot_url_recovery: false — tắt hẳn phục hồi từ URL. Bạn vẫn phục hồi được từ file cục bộ và từ file tải lên. (Qdrant Cloud chặn hẳn đường này, chính vì lý do trên.)
  2. Chặn ở tầng mạng — Qdrant khuyến nghị hạn chế truy cập mạng đi ra. Node đơn không cần kết nối ra ngoài; cụm chỉ cần TCP 6333–6335 giữa các peer. Docker, Docker Compose và Kubernetes đều có cách cô lập mạng cho việc này.
EndpointDùng để
/healthz, /livez, /readyzHealth check kiểu Kubernetes; luôn truy cập được, không cần xác thực
/metricsPrometheus / OpenMetrics
/telemetryTrạng thái chi tiết: số vector, shard, segment
/cluster/telemetryGộp telemetry của mọi peer, kèm tiến độ chuyển shard

⚠️ /metrics chỉ báo số liệu của đúng peer bạn kết nối tới. Trong cụm, bạn phải scrape từng peer riêng, kể cả khi có load balancer đứng trước. Scrape qua load balancer sẽ cho ra một chuỗi số liệu nhảy múa vô nghĩa giữa các node.

Tham số ?per_collection=true cho số liệu tách theo từng collection thay vì gộp.

Phiên bản, trạng thái recovery mode, vi phạm quota · Số điểm/vector, tình trạng replica, tác vụ tối ưu · Số lượt gọi REST và gRPC, latency, tỷ lệ lỗi · Bộ nhớ, luồng, file descriptor, page fault · Trạng thái đồng thuận Raft (chỉ chế độ phân tán).

Nếu chỉ dựng được bốn cảnh báo, dựng bốn cái này:

#Cảnh báoVì sao
1points_countindexed_vectors_count tăng liên tụcCảnh báo sớm cho vấn đề ở 7.6 — nó đến trước khi latency xấu
2Latency p95 theo endpointTriệu chứng của gần như mọi thứ
3Trạng thái collection ≠ green quá lâuOptimizer không đuổi kịp, hoặc lỗi
4RAM trên tổng RAM nodePhòng OOM; kèm quota ở 7.18

Cảnh báo số 1 là cảnh báo mà ít người dựng nhất và có giá trị nhất. Latency là triệu chứng; khoảng cách giữa hai con số đó là nguyên nhân, và nó xuất hiện sớm hơn.

Tổng hợp từ checklist của Qdrant, sắp lại theo thứ tự làm:

Bảo mật (làm trước tiên)

  • Đặt api_key. Đây là mức tối thiểu tuyệt đối cho instance tự host.
  • Cấp read_only_api_key cho mọi thứ chỉ cần đọc.
  • Bật TLS (hoặc đặt sau reverse proxy có TLS).
  • Bind vào network riêng, đừng lộ 6333 ra Internet.
  • Cân nhắc enable_snapshot_url_recovery: false.
  • Nếu nhiều tenant: JWT RBAC với value_exists (7.17).

Sẵn sàng cao

  • replication_factor ≥ 2. Mặc định là 1, tức là không có dự phòng.
  • Đủ shard để phân bố tải; ít nhất một shard hoặc replica mỗi node.
  • Load balancer trước cụm (bản tự host phải tự dựng).
  • Snapshot định kỳ mọi node, đẩy sang S3, và đã diễn tập phục hồi (7.19).

Hiệu năng

  • Payload index cho mọi trường xuất hiện trong filter — tạo trước khi nạp dữ liệu (7.9).
  • Đã đo recall có filter và không filter (7.8).
  • Nếu bật quantization: đã đo với quantization: {ignore: true} để biết mất bao nhiêu recall (7.10).
  • Chọn memory tier hợp với tỷ lệ RAM/dữ liệu; đĩa là SSD, không phải HDD.
  • Đã tính RAM có tính hệ số 1,5 và replication_factor (7.18).

Vận hành

  • Scrape /metrics từ từng peer.
  • Bốn cảnh báo ở trên.
  • Bật strict mode với unindexed_filtering_retrieve: false để bắt lỗi thiếu index sớm.
  • Ghi lại phiên bản Qdrant đang chạy; kế hoạch nâng cấp từng minor một.
Phần 7 — Qdrant