This page was machine-translated. Spotted a mistake?Help improve it.
Skip to content

Güvenlik ve Sıkılaştırma

SnapOtter dosyaları tamamen kendi altyapınızda işler. Projeyi geliştirmeye yardımcı olmak için varsayılan olarak anonim, içerik içermeyen ürün analitiği ve çökme raporları gönderir. Dosyalarınızı, dosya adlarınızı, dosya içeriklerinizi, OCR çıktısını, görsel meta verilerini veya belge metnini asla göndermez. İsteğe bağlı geri bildirim yalnızca bir kullanıcı gönderdikten sonra, yalnızca analitik etkinken gönderilir ve iletişim alanları yalnızca açık iletişim onayıyla dahil edilir. Bir yönetici, Settings > System > Privacy altında tek tıklamayla analitik ve geri bildirim yakalamayı yeniden derleme gerekmeden kapatabilir. Dosya işleme her zaman konteynerinizin içinde kalır.

Konteyner, gerekli minimum küme dışında tüm Linux yetenekleri düşürülmüş özel bir root olmayan kullanıcı (snapotter) olarak çalışır. Tam güvenlik açığı açıklama politikası ve güvenlik mimarisi için GitHub'daki SECURITY.md dosyasına bakın.

Konteyner Sıkılaştırma

Varsayılan docker-compose.yml üretim güvenlik sıkılaştırması içerir. İşte her seçeneğin bir dökümü ve neden önemli olduğu:

yaml
services:
  SnapOtter:
    image: snapotter/snapotter:latest
    ports:
      # Bind to localhost only for internet-facing deployments:
      - "127.0.0.1:1349:1349"
    volumes:
      - SnapOtter-data:/data
      - SnapOtter-workspace:/tmp/workspace
    environment:
      - AUTH_ENABLED=true
      - DEFAULT_PASSWORD=change-me-immediately
      - RATE_LIMIT_PER_MIN=1000
      - DATABASE_URL=postgres://snapotter:snapotter@postgres:5432/snapotter
      - REDIS_URL=redis://redis:6379
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

    # --- Resource limits ---
    mem_limit: 6g            # Prevents runaway memory from crashing the host
    memswap_limit: 6g        # No swap - fail fast instead of degrading the host
    cpus: 4                  # Cap CPU usage to 4 cores
    pids_limit: 512          # Prevents fork bombs

    # --- Capability restrictions ---
    cap_drop:
      - ALL                  # Drop ALL Linux capabilities first
    cap_add:
      - CHOWN                # Needed for volume permission setup
      - SETUID               # Needed for gosu privilege drop (root -> snapotter)
      - SETGID               # Needed for gosu privilege drop
      - DAC_OVERRIDE         # Needed for volume permission setup
      - FOWNER               # Needed for volume permission setup

    # --- Logging ---
    logging:
      driver: json-file
      options:
        max-size: "50m"      # Rotate logs at 50 MB
        max-file: "5"        # Keep 5 rotated log files

    # --- Health check ---
    healthcheck:
      test: ["CMD", "curl", "-sf", "--max-time", "5", "http://localhost:1349/api/v1/health"]
      interval: 30s
      timeout: 5s
      start_period: 60s
      retries: 3

    shm_size: "2gb"          # Required for Python ML shared memory
    restart: unless-stopped

  postgres:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: snapotter
      POSTGRES_PASSWORD: snapotter
      POSTGRES_DB: snapotter
    volumes:
      - SnapOtter-pgdata:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U snapotter"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 15s

  redis:
    image: redis:8-alpine
    command: ["redis-server", "--maxmemory-policy", "noeviction", "--appendonly", "yes"]
    volumes:
      - SnapOtter-redisdata:/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 12
      start_period: 10s

volumes:
  SnapOtter-data:
  SnapOtter-workspace:
  SnapOtter-pgdata:
  SnapOtter-redisdata:

Neden no-new-privileges Ayarlanmıyor

security_opt: [no-new-privileges:true] kasıtlı olarak atlanmıştır. Giriş noktası, birim sahipliğini düzeltmek için root olarak başlar, ardından setuid gerektiren gosu aracılığıyla snapotter kullanıcısına düşer. Ayrıcalık düşürme tamamlandığında, işlem yukarıda listelenen beşi dışındaki tüm yeteneklerden arındırılmış olarak snapotter olarak çalışır.

Doğrudan root olmayan olarak çalıştırmak için Kubernetes veya Docker'ın --user bayrağını kullanırsanız (gosu'yu atlayarak), no-new-privileges etkinleştirmek güvenlidir.

Neden read_only Ayarlanmıyor

read_only: true ayarlanmamıştır çünkü PUID/PGID yeniden eşleme başlangıçta /etc/passwd ve /etc/group dizinlerine yazar. PUID/PGID yerine Docker'ın --user bayrağını veya Kubernetes runAsUser kullanırsanız, salt-okunur bir root dosya sistemini güvenle etkinleştirebilirsiniz.

Ağ Yalıtımı

Normal çalışma sırasında konteyner sıfır giden ağ bağlantısı yapar. Tüm dosya işleme, birlikte gelen kitaplıklar kullanılarak yerel olarak gerçekleşir.

Browser  -->  Reverse Proxy (TLS)  -->  SnapOtter container  -->  (nothing)

Tek istisna AI model indirmeleridir: bir kullanıcı arayüz aracılığıyla bir AI özellik paketi kurduğunda, konteyner önceden derlenmiş paket arşivini Hugging Face'ten, ayrıca GitHub Releases, Google Storage ve PyPI'dan birkaç bireysel model dosyasını indirir. Bu indirmeler paket başına bir kez gerçekleşir ve /data biriminde saklanır.

Güvenlik duvarı önerileri:

SenaryoGiden kural
Hava boşluklu (AI yok)Konteynerden tüm giden trafiği engelle
AI paketleri gerekliKurulum sırasında huggingface.co, *.xethub.hf.co, cdn-lfs.huggingface.co, github.com, objects.githubusercontent.com, storage.googleapis.com, pypi.org, files.pythonhosted.org adreslerine HTTPS'ye izin ver, ardından engelle
AI kurulumundan sonraTüm giden trafiği engelle - modeller yerel olarak önbelleğe alınır

Paket arşivleri, *.xethub.hf.co uç noktaları üzerinden paralel olarak aktarılan ve çoklu GB paket indirmelerini hızlı yapan Hugging Face'in Xet depolamasından sunulur. Güvenlik duvarınız huggingface.co adresine izin veriyor ancak *.xethub.hf.co adresini engelliyorsa, kurulumlar yine de başarılı olur ancak daha yavaş bir tek akışlı indirmeye geri döner, bu nedenle hızlı yolda kalmak için Xet ana bilgisayarlarını izin listesine ekleyin. Tamamen çevrimdışı kurulumlar tüm bunları atlayabilir ve bunun yerine Çevrimdışı Paket İçe Aktarma kullanabilir.

Ters proxy yapılandırması (Nginx, Traefik, Caddy, Cloudflare Tunnels) için Dağıtım kılavuzuna bakın.

Docker Secrets

Üretim dağıtımları için, secret'ları düz metin ortam değişkenleri olarak geçirmekten kaçının. Giriş noktası Docker'ın _FILE kuralını destekler: bir secret'ı dosya olarak bağlayın ve karşılık gelen _FILE değişkenini yoluna ayarlayın.

Desteklenen secret'lar:

Değişken_FILE eşdeğeri
DEFAULT_PASSWORDDEFAULT_PASSWORD_FILE
COOKIE_SECRETCOOKIE_SECRET_FILE
OIDC_CLIENT_SECRETOIDC_CLIENT_SECRET_FILE
S3_ACCESS_KEY_IDS3_ACCESS_KEY_ID_FILE
S3_SECRET_ACCESS_KEYS3_SECRET_ACCESS_KEY_FILE
SNAPOTTER_LICENSE_KEYSNAPOTTER_LICENSE_KEY_FILE

Docker Compose secrets ile örnek:

yaml
services:
  SnapOtter:
    image: snapotter/snapotter:latest
    environment:
      - AUTH_ENABLED=true
      - DEFAULT_USERNAME=admin
      - DEFAULT_PASSWORD_FILE=/run/secrets/snapotter_password
      - COOKIE_SECRET_FILE=/run/secrets/cookie_secret
    secrets:
      - snapotter_password
      - cookie_secret

secrets:
  snapotter_password:
    file: ./secrets/snapotter_password.txt
  cookie_secret:
    file: ./secrets/cookie_secret.txt

TIP

Docker Compose secrets (Swarm olmadan) Compose v2.23 veya üstünü gerektirir.

Kubernetes Dağıtımı

Giriş noktası, konteynerin zaten root olmayan olarak çalıştığını algılar (ör. Kubernetes runAsUser aracılığıyla) ve gosu ayrıcalık düşürmesini otomatik olarak atlar. Bu durumda bağlanan birimleri kendisi chown yapamaz, bu nedenle bunların yazılabilir olduğunu doğrular ve değilse eyleme geçirilebilir yönlendirmeyle erken çıkar - fsGroup ve yabancı-UID kurulumları (TrueNAS, OpenShift) için Depolama izinleri bölümüne bakın.

Önerilen Pod SecurityContext:

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

runAsUser: 999 pod düzeyinde ayarlandığından, giriş noktası gosu'yu tamamen atlar. Bu, allowPrivilegeEscalation: false ve drop: [ALL] yeteneklerine çakışma olmadan izin verir.

Kaynak boyutlandırma için Donanım Gereksinimleri bölümüne bakın.

Yedekleme ve Kurtarma

Kalıcı durum iki birim arasında bölünmüştür:

BirimİçerikKritik mi?
SnapOtter-pgdataPostgreSQL veritabanı (kullanıcılar, ayarlar, ardışık düzenler, işler, denetim günlüğü)Evet
/data (uygulama birimi)Kullanıcı tarafından yüklenen dosyalar, AI modelleri, Python venvKısmen (aşağıya bakın)

/data birimi içinde:

YolİçerikKritik mi?
/data/uploads/, /data/outputs/Kullanıcı dosyaları ve işleme sonuçlarıEvet
/data/ai/İndirilen AI model dosyalarıHayır (yeniden indirilebilir)
/data/venv/Python sanal ortamıHayır (başlangıçta yeniden derlenir)

Veritabanı yedekleme

Yığın çalışırken veritabanını yedeklemek için pg_dump kullanın:

bash
# Dump the database
docker exec SnapOtter-postgres pg_dump -U snapotter snapotter > backup.sql

# Restore into a fresh database
cat backup.sql | docker exec -i SnapOtter-postgres psql -U snapotter snapotter

Alternatif olarak, yığını durdurun ve SnapOtter-pgdata biriminin anlık görüntüsünü alın:

bash
docker compose down
docker run --rm -v SnapOtter-pgdata:/data -v $(pwd)/backup:/backup \
  alpine tar czf /backup/snapotter-pgdata.tar.gz -C /data .

Kullanıcı dosyaları yedekleme

bash
# Snapshot the app data volume (excluding re-downloadable AI models)
docker run --rm -v SnapOtter-data:/data -v $(pwd)/backup:/backup \
  alpine tar czf /backup/snapotter-files.tar.gz \
    --exclude='ai' --exclude='venv' -C /data .

AI modelleri tüm paketlerde toplamda yaklaşık 24 GB'a kadar çıkar. Yeniden indirilebilir olduklarından, yerden tasarruf etmek için /data/ai/ ve /data/venv/ dizinlerini yedeklemelerden hariç tutun. Yalnızca veritabanı ve kullanıcı dosyaları kritiktir.

Uyumluluk Yapıtları

Her SnapOtter sürümü aşağıdaki güvenlik yapıtlarını içerir:

YapıtFormatNerede bulunur
SBOM (CycloneDX)JSONGitHub Sürümü varlığı: snapotter-v{version}-sbom.cdx.json
SBOM (SPDX)JSONGitHub Sürümü varlığı: snapotter-v{version}-sbom.spdx.json
Güvenlik açığı taramasıTrivy JSONGitHub Sürümü varlığı: snapotter-v{version}-trivy.json
Güvenlik açığı taramasıSARIFGitHub Security sekmesi
Statik analizCodeQL (JS/TS + Python)GitHub Security sekmesi, haftalık + PR başına çalışır
Bağımlılık incelemesiGitHub yerelPR başına kontrol, yüksek önem dereceli eklemelerde başarısız olur
Python bağımlılık denetimipip-auditHer push'ta CI çalıştırma günlüğü
Güvenlik politikasıMarkdownDepodaki SECURITY.md
Bağımlılık güncellemeleriDependabotnpm, pip, Docker, Actions için otomatik haftalık PR'ler

Kendi taramanızı çalıştırma:

SBOM'u sürümden indirin ve tercih ettiğiniz araçla tarayın:

bash
# Scan with Grype using the CycloneDX SBOM
grype sbom:snapotter-v1.17.2-sbom.cdx.json

# Scan with Trivy using the SPDX SBOM
trivy sbom snapotter-v1.17.2-sbom.spdx.json

# Scan the Docker image directly
trivy image snapotter/snapotter:1.17.2

INFO

SBOM ve güvenlik açığı taraması, o sürüm için yayınlanan tam imajı yansıtır. Dağıtımdan sonra kurulan AI model paketleri, çalışma zamanında indirildiğinden SBOM'a dahil edilmez.