Bezpieczeństwo
Prosimy o uważne zapoznanie się z tą stroną. Chociaż istnieje wiele sposobów zabezpieczania instancji Qdrant, są one domyślnie niezabezpieczone. Przed użyciem produkcyjnym należy włączyć środki bezpieczeństwa. W przeciwnym razie są całkowicie otwarte dla każdego
Uwierzytelnianie
Dostępne od wersji 1.2.0
Qdrant obsługuje prostą formę uwierzytelniania klienta przy użyciu statycznego klucza API. Można to wykorzystać do zabezpieczenia Twojej instancji.
Aby włączyć uwierzytelnianie oparte na kluczu API we własnej instancji Qdrant, należy Określ klucz w konfiguracji:
service:
# Set an api-key.
# If set, all requests must include a header with the api-key.
# example header: `api-key: <API-KEY>`
#
# If you enable this you should also enable TLS.
# (Either above or via an external service like nginx.)
# Sending an api-key over an unencrypted channel is insecure.
api_key: your_secret_api_key_here
Alternatywnie możesz użyć zmiennej środowiskowej:
docker run -p 6333:6333 \
-e QDRANT__SERVICE__API_KEY=your_secret_api_key_here \
qdrant/qdrant
Aby uzyskać informacje na temat korzystania z uwierzytelniania opartego na kluczu API w chmurze Qdrant, zapoznaj się z sekcją Uwierzytelnianie w chmurze.
Klucz interfejsu API musi być następnie obecny we wszystkich żądaniach REST lub gRPC do wystąpienia. Wszyscy oficjalni klienci Qdrant dla języków Python, Go, Rust, .NET i Java obsługują parametr klucza API.
curl \
-X GET https://localhost:6333 \
--header 'api-key: your_secret_api_key_here'
Klucz interfejsu API tylko do odczytu
Dostępne od wersji 1.7.0
Oprócz zwykłego klucza API Qdrant obsługuje również klucz API tylko do odczytu. Ten klucz może służyć do uzyskiwania dostępu do operacji tylko do odczytu w wystąpieniu.
service:
read_only_api_key: your_secret_read_only_api_key_here
Lub ze zmienną środowiskową:
export QDRANT__SERVICE__READ_ONLY_API_KEY=your_secret_read_only_api_key_here
Oba klucze API mogą być używane jednocześnie.
Szczegółowa kontrola dostępu za pomocą JWT
Dostępne od wersji 1.9.0
W bardziej złożonych przypadkach Qdrant obsługuje szczegółową kontrolę dostępu za pomocą tokenów internetowych JSON (JWT). Dzięki temu można tworzyć tokeny, które ograniczają dostęp do danych przechowywanych w klastrze, a następnie tworzyć kontrolę dostępu opartą na rolach (RBAC). W ten sposób można zdefiniować uprawnienia dla użytkowników i ograniczyć dostęp do wrażliwych punktów końcowych.
Aby włączyć uwierzytelnianie oparte na JWT we własnej instancji Qdrant, należy określić i włączyć tę funkcję w konfiguracji:api-keyjwt_rbac
service:
api_key: you_secret_api_key_here
jwt_rbac: true
Lub ze zmiennymi środowiskowymi:
export QDRANT__SERVICE__API_KEY=your_secret_api_key_here
export QDRANT__SERVICE__JWT_RBAC=true
To, co ustawisz w konfiguracji, będzie używane do kodowania i dekodowania JWT, więc – nie trzeba dodawać – zachowaj je bezpiecznie. Jeśli wprowadzisz zmiany, wszystkie istniejące tokeny będą nieważne.api_keyapi_key
Aby korzystać z uwierzytelniania opartego na JWT, należy podać go jako token elementu nośnego w nagłówku lub jako klucz w nagłówku żądań.AuthorizationApi-Key
Authorization: Bearer <JWT>
// or
Api-Key: <JWT>
Generowanie tokenów internetowych JSON
Ze względu na charakter JWT, każdy, kto zna się na tym, może generować tokeny za pomocą dowolnej z istniejących bibliotek i narzędzi, nie jest konieczne, aby miał dostęp do instancji Qdrant, aby je wygenerować.api_key
Dla wygody dodaliśmy narzędzie do generowania JWT interfejs internetowy Qdrant pod 🔑 kartą, jeśli używasz domyślnego adresu URL, będzie to .http://localhost:6333/dashboard#/jwt
Nagłówek JWT — Qdrant używa algorytmu do dekodowania tokenów.
HS256{ "alg": "HS256", "typ": "JWT" }JWT Payload — można dołączyć dowolną kombinację parametrów dostępnych w ładunku. Czytaj dalej, aby uzyskać więcej informacji na temat każdego z nich.
{ "exp": 1640995200, // Expiration time "value_exists": ..., // Validate this token by looking for a point with a payload value "access": "r", // Define the access level. }
Podpisywanie tokenu — aby potwierdzić, że wygenerowany token jest prawidłowy, należy go podpisać za pomocą ustawionego w konfiguracji identyfikatora. Oznaczałoby to, że ktoś, kto zna się na rzeczy, udziela autoryzacji na użycie nowego tokena w instancji Qdrant. Qdrant może zweryfikować podpis, ponieważ zna token i może go zdekodować.api_keyapi_keyapi_key
Proces generowania tokenów może odbywać się po stronie klienta w trybie offline i nie wymaga żadnej komunikacji z instancją Qdrant.
Oto przykład bibliotek, które można wykorzystać do generowania tokenów JWT:
- Python: PyJWT
- JavaScript: jsonwebtoken
- Rdza: jsonwebtoken
Konfiguracja JWT
Są to dostępne opcje, czyli twierdzenia w żargonie JWT. Można ich użyć w ładunku JWT, aby zdefiniować jego funkcjonalność.
exp– Czas wygaśnięcia tokena. Jest to uniksowy znacznik czasu w sekundach. Po tym czasie token będzie nieważny. Sprawdzenie tego twierdzenia obejmuje 30-sekundową swobodę w celu uwzględnienia niesymetryczności zegara.{ "exp": 1640995200, // Expiration time }value_exists— jest to oświadczenie, którego można użyć do zweryfikowania tokenu względem danych przechowywanych w kolekcji. Struktura tego roszczenia jest następująca:{ "value_exists": { "collection": "my_validation_collection", "matches": [ { "key": "my_key", "value": "value_that_must_exist" } ], }, }Jeśli to oświadczenie jest obecne, Qdrant sprawdzi, czy w kolekcji znajduje się punkt z określonymi parami klucz-wartość. Jeśli tak, token jest ważny.
To twierdzenie jest szczególnie przydatne, jeśli chcesz mieć możliwość unieważniania tokenów bez zmiany . Rozważmy przypadek, w którym masz kolekcję użytkowników i chcesz odwołać dostęp do określonego użytkownika.
api_key{ "value_exists": { "collection": "users", "matches": [ { "key": "user_id", "value": "andrey" }, { "key": "role", "value": "manager" } ], }, }Możesz utworzyć token z tym oświadczeniem, a gdy chcesz odwołać dostęp, możesz zmienić użytkownika na inny, a token będzie nieprawidłowy.
roleaccess— to oświadczenie definiuje poziom dostępu tokenu. Jeśli to stwierdzenie jest obecne, Qdrant sprawdzi, czy token ma wymagany poziom dostępu do wykonania operacji. Jeśli to oświadczenie nie jest obecne, zakłada się, że zarządza dostępem.Może zapewnić globalny dostęp tylko do odczytu lub do zarządzania. Na przykład:
rm{ "access": "r" }Może być również specyficzny dla jednej lub kilku kolekcji. Poziom dla każdej kolekcji jest przeznaczony tylko do odczytu lub do odczytu i zapisu, w następujący sposób:
accessrrw{ "access": [ { "collection": "my_collection", "access": "rw" } ] }Można również określić, do którego podzbioru kolekcji użytkownik może uzyskać dostęp, określając ograniczenie, które muszą mieć punkty.
payload{ "access": [ { "collection": "my_collection", "access": "r", "payload": { "user_id": "user_123456" } } ] }To roszczenie zostanie użyte do niejawnego filtrowania punktów w kolekcji. Będzie to równoznaczne z dołączeniem tego filtru do każdego żądania:
payload{ "filter": { "must": [{ "key": "user_id", "match": { "value": "user_123456" } }] } }
Tabela dostępu
Zapoznaj się z tą tabelą, aby zobaczyć, które akcje są dozwolone lub odrzucane w zależności od poziomu dostępu.
Dotyczy to również używania kluczy interfejsu API zamiast tokenów. W takim przypadku mapuje się do zarządzania, a mapuje do tylko do odczytu.api_keyread_only_api_key
| Akcja | zarządzać | tylko do odczytu | Odczyt i zapis kolekcji | Kolekcja tylko do odczytu | Odbiór z oświadczeniem o ładowności (R / RW) |
|---|---|---|---|---|---|
| Wyświetlanie listy kolekcji | ✅ | ✅ | 🟡 | 🟡 | 🟡 |
| Uzyskaj informacje o kolekcji | ✅ | ✅ | ✅ | ✅ | ❌ |
| Utwórz kolekcję | ✅ | ❌ | ❌ | ❌ | ❌ |
| Usuń kolekcję | ✅ | ❌ | ❌ | ❌ | ❌ |
| Aktualizowanie parametrów kolekcji | ✅ | ❌ | ❌ | ❌ | ❌ |
| Pobieranie informacji o klastrze kolekcji | ✅ | ✅ | ✅ | ✅ | ❌ |
| kolekcja istnieje | ✅ | ✅ | ✅ | ✅ | ✅ |
| Aktualizowanie konfiguracji klastra kolekcji | ✅ | ❌ | ❌ | ❌ | ❌ |
| Aktualizowanie aliasów | ✅ | ❌ | ❌ | ❌ | ❌ |
| Aliasy kolekcji list | ✅ | ✅ | 🟡 | 🟡 | 🟡 |
| Wyświetlanie listy aliasów | ✅ | ✅ | 🟡 | 🟡 | 🟡 |
| Tworzenie klucza fragmentu | ✅ | ❌ | ❌ | ❌ | ❌ |
| Usuń klucz fragmentu | ✅ | ❌ | ❌ | ❌ | ❌ |
| Utwórz indeks ładunku | ✅ | ❌ | ✅ | ❌ | ❌ |
| Usuń indeks ładunku | ✅ | ❌ | ✅ | ❌ | ❌ |
| Migawki kolekcji list | ✅ | ✅ | ✅ | ✅ | ❌ |
| Utwórz migawkę kolekcji | ✅ | ❌ | ✅ | ❌ | ❌ |
| Usuwanie migawki kolekcji | ✅ | ❌ | ✅ | ❌ | ❌ |
| Pobierz migawkę kolekcji | ✅ | ✅ | ✅ | ✅ | ❌ |
| Przekazywanie migawki kolekcji | ✅ | ❌ | ❌ | ❌ | ❌ |
| Odzyskiwanie migawki kolekcji | ✅ | ❌ | ❌ | ❌ | ❌ |
| Wyświetlanie listy migawek fragmentów | ✅ | ✅ | ✅ | ✅ | ❌ |
| Tworzenie migawki fragmentu | ✅ | ❌ | ✅ | ❌ | ❌ |
| Usuwanie migawki fragmentu | ✅ | ❌ | ✅ | ❌ | ❌ |
| Pobierz migawkę fragmentu | ✅ | ✅ | ✅ | ✅ | ❌ |
| Przekazywanie migawki fragmentu | ✅ | ❌ | ❌ | ❌ | ❌ |
| Odzyskiwanie migawki fragmentu | ✅ | ❌ | ❌ | ❌ | ❌ |
| Wyświetlanie listy pełnych migawek | ✅ | ✅ | ❌ | ❌ | ❌ |
| Utwórz pełną migawkę | ✅ | ❌ | ❌ | ❌ | ❌ |
| Usuń pełną migawkę | ✅ | ❌ | ❌ | ❌ | ❌ |
| Pobierz pełną migawkę | ✅ | ✅ | ❌ | ❌ | ❌ |
| Pobieranie informacji o klastrze | ✅ | ✅ | ❌ | ❌ | ❌ |
| Przywróć stan tratwy | ✅ | ❌ | ❌ | ❌ | ❌ |
| Usuń element równorzędny | ✅ | ❌ | ❌ | ❌ | ❌ |
| zdobądź punkt | ✅ | ✅ | ✅ | ✅ | ❌ |
| Zdobywaj punkty | ✅ | ✅ | ✅ | ✅ | ❌ |
| Punkty upsert | ✅ | ❌ | ✅ | ❌ | ❌ |
| Aktualizuj partię punktów | ✅ | ❌ | ✅ | ❌ | ❌ |
| Usuwanie punktów | ✅ | ❌ | ✅ | ❌ | ❌ / 🟡 |
| Aktualizuj wektory | ✅ | ❌ | ✅ | ❌ | ❌ |
| Usuwanie wektorów | ✅ | ❌ | ✅ | ❌ | ❌ / 🟡 |
| Ustawianie ładunku | ✅ | ❌ | ✅ | ❌ | ❌ |
| nadpisywanie ładunku | ✅ | ❌ | ✅ | ❌ | ❌ |
| Pakiet danych delete | ✅ | ❌ | ✅ | ❌ | ❌ |
| Wyczyść ładunek | ✅ | ❌ | ✅ | ❌ | ❌ |
| Punkty przewijania | ✅ | ✅ | ✅ | ✅ | 🟡 |
| Punkty zapytania | ✅ | ✅ | ✅ | ✅ | 🟡 |
| Punkty wyszukiwania | ✅ | ✅ | ✅ | ✅ | 🟡 |
| Szukaj grup | ✅ | ✅ | ✅ | ✅ | 🟡 |
| Poleć punkty | ✅ | ✅ | ✅ | ✅ | ❌ |
| Polecanie grup | ✅ | ✅ | ✅ | ✅ | ❌ |
| Odkrywanie punktów | ✅ | ✅ | ✅ | ✅ | ❌ |
| Policz punkty | ✅ | ✅ | ✅ | ✅ | 🟡 |
| Wersja | ✅ | ✅ | ✅ | ✅ | ✅ |
| Readyz, Healthz, Livez | ✅ | ✅ | ✅ | ✅ | ✅ |
| telemetria | ✅ | ✅ | ❌ | ❌ | ❌ |
| Metryki | ✅ | ✅ | ❌ | ❌ | ❌ |
| Aktualizuj blokady | ✅ | ❌ | ❌ | ❌ | ❌ |
| Pobieranie zamków | ✅ | ✅ | ❌ | ❌ | ❌ |
Protokół TLS
Dostępne od wersji 1.2.0
Protokół TLS dla połączeń szyfrowanych można włączyć w instancji Qdrant w celu zabezpieczenia Połączenia.
Najpierw upewnij się, że masz certyfikat i klucz prywatny dla TLS, zwykle w formacie. Na komputerze lokalnym możesz użyć mkcert do wygenerowania pliku z podpisem własnym certyfikat..pem
Aby włączyć protokół TLS, ustaw następujące właściwości w konfiguracji Qdrant za pomocą polecenia Popraw ścieżki i uruchom ponownie:
service:
# Enable HTTPS for the REST and gRPC API
enable_tls: true
# TLS configuration.
# Required if either service.enable_tls or cluster.p2p.enable_tls is true.
tls:
# Server certificate chain file
cert: ./tls/cert.pem
# Server private key file
key: ./tls/key.pem
W przypadku komunikacji wewnętrznej podczas uruchamiania trybu klastra protokół TLS można włączyć za pomocą:
cluster:
# Configuration of the inter-cluster communication
p2p:
# Use TLS for communication between peers
enable_tls: true
Po włączeniu protokołu TLS należy zacząć korzystać z połączeń HTTPS. Na przykład:
curl -X GET https://localhost:6333
Rotacja certyfikatów jest włączona z domyślnym czasem odświeżania wynoszącym jedną godzinę. Ten ponownie wczytuje pliki certyfikatów co godzinę, gdy Qdrant jest uruchomiony. Ten sposób się zmienił Certyfikaty są pobierane, gdy są aktualizowane zewnętrznie. Czas odświeżania można dostroić, zmieniając ustawienie. Możesz zostawić to włączone, nawet , jeśli nie planujesz aktualizować certyfikatów. Obecnie jest to obsługiwane tylko dla interfejsu API REST.tls.cert_ttl
Opcjonalnie można włączyć sprawdzanie poprawności certyfikatu klienta na serwerze względem Lokalny urząd certyfikacji. Ustaw następujące właściwości i uruchom ponownie:
service:
# Check user HTTPS client certificate against CA file specified in tls config
verify_https_client_certificate: false
# TLS configuration.
# Required if either service.enable_tls or cluster.p2p.enable_tls is true.
tls:
# Certificate authority certificate file.
# This certificate will be used to validate the certificates
# presented by other nodes during inter-cluster communication.
#
# If verify_https_client_certificate is true, it will verify
# HTTPS client certificate
#
# Required if cluster.p2p.enable_tls is true.
ca_cert: ./tls/cacert.pem
Stwardnienie
Zalecamy zmniejszenie liczby uprawnień przyznawanych kontenerom Qdrant, aby zmniejszyć ryzyko wykorzystania. Oto kilka sposobów na zmniejszenie uprawnień kontenera Qdrant:
Uruchom Qdrant jako użytkownik inny niż root. Może to pomóc w ograniczeniu ryzyka przyszłych luk w zabezpieczeniach kontenerów. Qdrant w żadnym celu nie potrzebuje uprawnień użytkownika root.
- Możesz użyć obrazu zamiast domyślnego obrazu Qdrant.
qdrant/qdrant:<version>-unprivileged - Flagi można użyć podczas uruchamiania
docker run.--user=1000:2000 - Możesz ustawić
użytkownika: 1000podczas korzystania z Docker Compose. - Możesz ustawić
runAsUser: 1000podczas uruchamiania na platformie Kubernetes (nasz wykres Helm robi to domyślnie).
- Możesz użyć obrazu zamiast domyślnego obrazu Qdrant.
Uruchom Qdrant z głównym systemem plików tylko do odczytu. Może to pomóc w ograniczeniu luk w zabezpieczeniach, które wymagają możliwości modyfikowania plików systemowych, czego Qdrant nie potrzebuje. Tak długo, jak kontener używa zamontowanych woluminów do przechowywania ( i domyślnie), Qdrant może nadal działać, nie mogąc zapisywać danych poza tymi woluminami.
/qdrant/storage/qdrant/snapshots- Flagi można użyć podczas uruchamiania
docker run.--read-only - Możesz ustawić
wartość read_only: truew przypadku korzystania z narzędzia Docker Compose. - Możesz ustawić
readOnlyRootFilesystem: truepodczas uruchamiania na platformie Kubernetes (nasz wykres Helm robi to domyślnie).
- Flagi można użyć podczas uruchamiania
Blokuj dostęp do sieci zewnętrznej firmy Qdrant. Może to pomóc w ograniczeniu ataków polegających na fałszowaniu żądań po stronie serwera, na przykład za pośrednictwem interfejsu API odzyskiwania migawek. Jednowęzłowe klastry Qdrant nie wymagają żadnego wychodzącego dostępu do sieci. Wielowęzłowe klastry Qdrant wymagają jedynie możliwości łączenia się z innymi węzłami Qdrant za pośrednictwem portów TCP 6333, 6334 i 6335.
- Możesz użyć
docker network create --internal <name>i użyć tej sieci podczas uruchamianiadocker run --network <nazwa>. - Sieć wewnętrzną można utworzyć podczas korzystania z narzędzia Docker Compose.
- Zasadę sieciową można utworzyć w przypadku korzystania z platformy Kubernetes. Należy pamiętać, że wielowęzłowe klastry Qdrant będą również potrzebować dostępu do systemu DNS klastra w Kubernetes.
- Możesz użyć
Istnieją inne techniki zmniejszania uprawnień, takie jak porzucanie możliwości systemu Linux w zależności od metody wdrażania, ale metody wymienione powyżej są najważniejsze.