# Bezpieczeństwo i wzmacnianie {#security-hardening}
SnapOtter przetwarza pliki w całości na twojej infrastrukturze. Domyślnie wysyła anonimową, pozbawioną treści analitykę produktu i raporty o awariach, aby pomóc ulepszać projekt. Nigdy nie wysyła twoich plików, nazw plików, zawartości plików, wyniku OCR, metadanych obrazów ani tekstu dokumentów. Opcjonalna informacja zwrotna jest wysyłana dopiero po jej przesłaniu przez użytkownika, tylko gdy analityka jest włączona, a pola kontaktowe są dołączane wyłącznie za wyraźną zgodą na kontakt. Administrator może wyłączyć analitykę i zbieranie informacji zwrotnej jednym kliknięciem w Ustawienia > System > Prywatność, bez konieczności przebudowy. Przetwarzanie plików zawsze pozostaje wewnątrz twojego kontenera.
Kontener działa jako dedykowany użytkownik nie-root (`snapotter`) z odrzuconymi wszystkimi uprawnieniami Linuksa poza minimalnym wymaganym zestawem. Po pełną politykę ujawniania podatności i architekturę bezpieczeństwa zobacz [SECURITY.md](https://github.com/snapotter-hq/SnapOtter/blob/main/SECURITY.md) na GitHub.
Źródłem prawdy są kanoniczne pliki [CPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose.yml) i [GPU](https://github.com/snapotter-hq/SnapOtter/blob/main/docker/docker-compose-gpu.yml). Nie kopiuj skróconego przykładu do produkcji; wdróż plik ze zweryfikowanego tagu wydania.
- Każda usługa powoduje utratę wszystkich możliwości Linuksa. Aplikacja dodaje tylko `CHOWN, SETUID, SETGID, DAC_OVERRIDE, FOWNER, KILL` dla własności wolumenu, jednokierunkową utratę tożsamości `gosu` i płynne przekazywanie sygnału. PostgreSQL i Redis otrzymują tylko podzbiór potrzebny ich oficjalnym punktom wejścia.
-`security_opt: [no-new-privileges:true]` uniemożliwia procesom w aplikacji, kontenerach PostgreSQL i Redis uzyskanie dodatkowych uprawnień. Pozostaje to zgodne z `gosu`: punkt wejścia zaczyna się jako root, przygotowuje woluminy i przechodzi tylko do dedykowanego użytkownika `snapotter`.
- Wejścia obrazów PostgreSQL i Redis są przypinane za pomocą skrótu. Aplikację należy również przypiąć do zweryfikowanego tagu wydania lub podsumowania, a nie `latest`.
— Kontrole stanu, ograniczona rotacja dzienników JSON, trwała funkcja Redis AOF i zasady ponownego uruchamiania są definiowane centralnie w plikach kanonicznych.
W przypadku wdrożenia z dostępem do Internetu powiąż port 1349 z pętlą zwrotną i zakończ protokół TLS na utrzymywanym zwrotnym serwerze proxy. Wygeneruj unikalne dane uwierzytelniające PostgreSQL i Redis, przechowuj sekrety w chronionych plikach lub menedżerze sekretów i natychmiast zmień początkowe hasło administratora.
`read_only: true` nie jest ustawiony, ponieważ ponowne mapowanie PUID/PGID zapisuje podczas uruchamiania `/etc/passwd` i `/etc/group`. Jeśli zamiast PUID/PGID użyjesz flagi `--user` Dockera lub Kubernetes `runAsUser`, możesz bezpiecznie włączyć główny system plików tylko do odczytu.
Przetwarzanie plików odbywa się lokalnie, ale instalacja domyślna **nie jest systemem bez ruchu wychodzącego**. Anonimowe analizy produktów korzystają z PostHog, a raportowanie o awariach korzysta z Sentry, gdy włączona jest telemetria. Ustaw `SNAPOTTER_TELEMETRY=0` (lub wyłącz analizę w obszarze Ustawienia > System > Prywatność), aby wyłączyć oba. SnapOtter nigdy nie uwzględnia w tych zdarzeniach przesłanych plików, nazw plików, danych wyjściowych OCR, tekstu dokumentu ani innej zawartości plików.
Pozostały ruch wychodzący jest oparty na funkcjach: instalacja pakietu/modelu AI powoduje pobranie podpisanych danych wejściowych wersji; Import adresu URL powoduje pobranie publicznego adresu URL żądanego przez użytkownika; i jawnie skonfigurowane OIDC, SAML, OpenTelemetry, webhooki, pamięć zgodna z S3 lub podobne integracje łączą się z miejscami docelowymi wybranymi przez administratora. Pobieranie modeli w czasie wykonywania jest domyślnie wyłączone. Ustaw `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=1` tylko po to, aby jawnie włączyć automatyczne pobieranie zastępcze. [Import pakietu offline](/pl/guide/deployment) może zapewnić funkcje AI bez konieczności wychodzenia z modelu środowiska wykonawczego.
|Szczelina powietrzna|Ustaw `SNAPOTTER_TELEMETRY=0` i `SNAPOTTER_ALLOW_MODEL_DOWNLOAD=0`, użyj importu pakietów AI offline, wyłącz import adresów URL i integracje zewnętrzne, a następnie zablokuj wyjście|
|Domyślna telemetria|Zezwól na punkty końcowe PostHog i Sentry wymienione w dziennikach przeglądarki/sieci; wyłącz telemetrię, jeśli zasady na to nie pozwalają|
|Potrzebne pakiety AI|Podczas instalacji zezwól HTTPS na `huggingface.co, *.xethub.hf.co, cdn-lfs.huggingface.co, github.com, objects.githubusercontent.com, storage.googleapis.com, pypi.org, files.pythonhosted.org`; następnie zablokuj te hosty|
|Integracje zewnętrzne|Zezwalaj tylko na dokładnie skonfigurowane przez administratora miejsca docelowe OIDC/SAML/OTLP/webhook/object-storage|
Archiwa pakietów są obsługiwane z pamięci Xet firmy Hugging Face, która jest przesyłana równolegle przez punkty końcowe `*.xethub.hf.co` i dzięki temu pobieranie pakietów o wielkości wielu GB jest szybkie. Jeśli twoja zapora sieciowa pozwala na `huggingface.co`, ale blokuje `*.xethub.hf.co`, instalacje nadal się powiodą, ale powrócą do wolniejszego pobierania w jednym strumieniu, więc umieść hosty Xet na liście dozwolonych, aby pozostały na szybkiej ścieżce. Instalacje w pełni offline mogą to wszystko pominąć i zamiast tego użyć [Import pakietu offline](/pl/guide/deployment).
Informacje na temat konfiguracji odwrotnego proxy (Nginx, Traefik, Caddy, Cloudflare Tunnels) można znaleźć w [Przewodniku wdrażania](/pl/guide/deployment#reverse-proxy).
Dla wdrożeń produkcyjnych unikaj przekazywania sekretów jako zmiennych środowiskowych w postaci zwykłego tekstu. Punkt wejścia obsługuje konwencję `_FILE` Dockera: zamontuj sekret jako plik i ustaw odpowiednią zmienną `_FILE` na jego ścieżkę.
Sekrety Docker Compose (bez Swarm) wymagają Compose v2.23 lub nowszego.
:::
## Wdrożenie Kubernetes {#kubernetes-deployment}
Punkt wejścia wykrywa, kiedy kontener już działa jako nie-root (np. przez `runAsUser` Kubernetes) i automatycznie pomija obniżenie uprawnień gosu. W takim przypadku nie może sam zmienić własności zamontowanych wolumenów przez chown, więc weryfikuje, czy są zapisywalne, i wcześnie kończy z praktycznymi wskazówkami, jeśli nie są, zobacz [Uprawnienia pamięci masowej](/pl/guide/deployment#storage-permissions) po `fsGroup` i konfiguracje z obcym UID (TrueNAS, OpenShift).
**Zalecany SecurityContext poda:**
```yaml
apiVersion:apps/v1
kind:Deployment
metadata:
name:snapotter
spec:
replicas:1
selector:
matchLabels:
app:snapotter
template:
metadata:
labels:
app:snapotter
spec:
securityContext:
runAsNonRoot:true
runAsUser:999
runAsGroup:999
fsGroup:999
containers:
- name:snapotter
image:snapotter/snapotter:latest
ports:
- containerPort:1349
securityContext:
allowPrivilegeEscalation:false
capabilities:
drop:[ALL]
resources:
requests:
cpu:"1"
memory:2Gi
limits:
cpu:"4"
memory:6Gi
livenessProbe:
httpGet:
path:/api/v1/health
port:1349
initialDelaySeconds:60
periodSeconds:30
timeoutSeconds:5
readinessProbe:
httpGet:
path:/api/v1/health
port:1349
initialDelaySeconds:10
periodSeconds:10
timeoutSeconds:5
volumeMounts:
- name:data
mountPath:/data
- name:workspace
mountPath:/tmp/workspace
volumes:
- name:data
persistentVolumeClaim:
claimName:snapotter-data
- name:workspace
emptyDir:
medium:Memory
sizeLimit:2Gi
```
Ponieważ `runAsUser: 999` jest ustawione na poziomie poda, punkt wejścia całkowicie pomija gosu. Pozwala to na uprawnienia `allowPrivilegeEscalation: false` i `drop: [ALL]` bez konfliktu.
Po dobór rozmiaru zasobów zobacz [Wymagania sprzętowe](/pl/guide/deployment#hardware-requirements).
Produkcyjny stos Compose definiuje cztery woluminy. Zatrzymaj ruch wejściowy i poczekaj na zakończenie aktywnych zadań przed wykonaniem skoordynowanej kopii zapasowej, tak aby PostgreSQL, Redis i stan pliku opisywały ten sam punkt w czasie.
|`SnapOtter-pgdata`|Użytkownicy PostgreSQL, ustawienia, potoki, zadania, metadane plików i dziennik audytu|Krytyczny; użyj niezawodnego zrzutu logicznego do odzyskiwania przenośnego|
|`SnapOtter-data`|Zapisane obiekty biblioteki, dzienniki i stan AI (`/data/files, /data/logs, /data/ai, /data/ai/venv`)|Utwórz kopię zapasową całego woluminu; aby zaoszczędzić miejsce, celowo pomiń cały stan AI i zainstaluj ponownie jego pakiety|
|`SnapOtter-redisdata`|Redis AOF dla trwałego stanu kolejki BullMQ|Utwórz kopię zapasową po wstrzymaniu aplikacji i wymuszeniu `SAVE`; wymagane do dokładnego wznowienia pracy w kolejce|
|`SnapOtter-workspace`|Tymczasowe klucze do przechowywania obiektów (`/tmp/workspace/uploads, /tmp/workspace/outputs`)|Nie twórz kopii zapasowych po wyczerpaniu lub anulowaniu wszystkich zadań; nigdy go nie wyrzucaj, gdy zadania są aktywne|
Funkcja Compose zwykle poprzedza nazwy woluminów nazwą projektu. Rozwiąż rzeczywisty wolumin źródłowy z zamontowanego kontenera, zamiast zakładać, że nazwa wyświetlana, taka jak `SnapOtter-data`, jest nazwą woluminu Docker.
Przetestuj każdą kopię zapasową, przywracając ją do izolowanego stosu, sprawdzając rekordy bazy danych i sumy kontrolne plików oraz uruchamiając aplikację. `tests/qa/backup-restore-drill.sh` repozytorium automatyzuje tę bramkę zwolnienia w stosunku do jawnego `QA_IMAGE`.
Jeśli zamiast tego Twoja platforma wykonuje migawki woluminów spójne w czasie awarii, najpierw zatrzymaj cały stos i wykonaj migawkę wszystkich krytycznych woluminów jako jeden zestaw. Surowa kopia katalogu danych PostgreSQL z działającego kontenera nie jest obsługiwaną logiczną kopią zapasową.
### Kopia zapasowa plików i kolejek {#file-and-queue-backup}
Wstrzymaj aplikację przed przechwyceniem woluminów plików i kolejek. Użyj `docker inspect`, aby rozwiązać rzeczywistą nazwę woluminu, wymuś na Redis zachowanie bieżącego stanu i zarchiwizuj z zachowaniem własności i uprawnień:
Uruchom ponownie Redis przed aplikacją. Jeśli celowo wykluczysz `/data/ai`, usuń całe poddrzewo AI, zamiast zachowywać rekord `installed.json` bez jego modeli i środowiska wirtualnego. Przechowuj pliki kopii zapasowych w sposób szyfrowany, z kontrolą dostępu i oddzielnie od hosta, na którym działa SnapOtter.
Manifest rejestruje oddzielnie `releaseTag`, `releaseCommit` i `workflowTriggerCommit`. Sprawdź, czy `releaseCommit` jest zatwierdzeniem usuniętym z niezmiennego znacznika, a następnie sprawdź skrót SHA-256 archiwum, obrazu, SBOM lub skanu, który wykorzystujesz, względem jego wpisu w `subjects`. To rozróżnienie jest zamierzone: sprawdzenie nowo utworzonego zatwierdzenia wydania nie zmienia tożsamości zatwierdzenia w poświadczeniu OIDC przepływu pracy.
Możesz także zeskanować pobrany plik SBOM lub obraz bezpośrednio:
Obraz SBOMs i skany odzwierciedlają dokładnie obraz specyficzny dla architektury opublikowany dla tej wersji. Archiwum SBOMs i skany opisują wstępnie zbudowane archiwum osobno. Pakiety modelu AI zainstalowane po wdrożeniu nie są uwzględnione w tych pakietach SBOMs, ponieważ są pobierane w czasie wykonywania.