Zurück zu den Updates
New releaseAug 31, 2026

proxy v0.7.0

Ein leichtgewichtiger Caching-Proxy für Paketregistries.

Teilen

git-pkgs Proxy

Ein Caching-Proxy für Paket-Registries. Beschleunigt Paket-Downloads, indem Artefakte lokal zwischengespeichert werden, reduziert den Bandbreitenverbrauch und verbessert die Zuverlässigkeit.

Versions-Cooldown

Die meisten Supply-Chain-Angriffe setzen auf Geschwindigkeit: Eine bösartige Version wird veröffentlicht und innerhalb von Minuten von automatisierten Pipelines konsumiert, bevor irgendjemand es bemerkt. Die Cooldown-Funktion fügt neu veröffentlichten Versionen eine Quarantänezeit hinzu. Wenn sie aktiviert ist, entfernt der Proxy Versionen aus Metadaten-Antworten, bis sie einen konfigurierbaren Schwellenwert überschritten haben.```yaml cooldown: default: "3d" # hide versions published less than 3 days ago ecosystems: npm: "7d" # npm gets a longer window cargo: "0" # disable for cargo packages: "pkg:npm/lodash": "0" # exempt trusted packages

Eine 3-tägige Abklingzeit bedeutet, dass Ihre Builds bei Veröffentlichung von Version `4.18.0` durch `lodash` weiterhin `4.17.21` verwenden, bis 3 Tage vergangen sind. Sollte sich die neue Version als kompromittiert herausstellen, waren Sie nie exponiert.

Auflösungsreihenfolge: Paket-Override, dann Ökosystem-Override, dann globale Standardeinstellung. So können Sie einen konservativen Standard festlegen und Ausnahmen für Pakete schaffen, bei denen Sie schnellere Updates benötigen. Die vollständige Konfigurationsreferenz finden Sie unter [docs/configuration.md](https://github.com/git-pkgs/proxy/blob/main/docs/configuration.md).

## Unterstützte Registries

| Registry | Sprache/Plattform | Abklingzeit | Abgeschlossen |
|----------|-------------------|:--------:|:---------:|
| npm | JavaScript | Ja | ✓ |
| Cargo | Rust | Ja | ✓ |
| RubyGems | Ruby | Ja | ✓ |
| Go proxy | Go | | ✓ |
| Hex | Elixir | Ja* | ✓ |
| pub.dev | Dart | Ja | ✓ |
| PyPI | Python | Ja | ✓ |
| Maven | Java | | ✓ |
| Gradle Build Cache | Java/Kotlin | | ✓ |
| NuGet | .NET | Ja | ✓ |
| Composer | PHP | Ja | ✓ |
| Conan | C/C++ | | ✓ |
| Conda | Python/R | Ja | ✓ |
| CRAN | R | | ✓ |
| Julia | Julia | | ✓ |
| Container | Docker/OCI | | ✓ |
| Debian | Debian/Ubuntu | | ✓ |
| RPM | RHEL/Fedora | | ✓ |
| Alpine | Alpine Linux | | ✗ |
| Arch | Arch Linux | | ✗ |
| Chef | Chef | | ✗ |
| Generic | Beliebig | | ✗ |
| Helm | Kubernetes | | ✗ |
| Swift | Swift | | ✗ |
| Vagrant | Vagrant | | ✗ |

Die Abklingzeit erfordert Veröffentlichungszeitstempel in den Metadaten. Registries ohne „Ja" in der Abklingzeit-Spalte legen entweder keine Zeitstempel offen oder sind noch nicht angebunden.

\* Die Hex-Abklingzeit erfordert die Deaktivierung der Registry-Signaturprüfung (`HEX_NO_VERIFY_REPO_ORIGIN=1`), da der Proxy die Protobuf-Nutzlast neu kodiert.

## Installation```bash
brew install git-pkgs/git-pkgs/proxy

Oder lade eine Binärdatei von der Releases-Seite herunter.

Schnellstart```bash

Build from source

go build -o proxy ./cmd/proxy

Run with defaults (listens on :8080)

./proxy

Run with custom settings

./proxy -listen :3000 -base-url https://proxy.example.com

Der Proxy läuft jetzt. Konfigurieren Sie Ihre Paketmanager, um ihn zu verwenden.

## OpenAPI (Swagger)

Dieses Repository verwendet swaggo, um eine OpenAPI-Spezifikation aus annotierten Handlern zu generieren.

Generieren Sie die Spezifikation:```bash
go install github.com/swaggo/swag/cmd/swag@latest
go generate ./internal/server

Generierte Dateien werden nach docs/swagger/ geschrieben.

Wenn der Proxy läuft, kannst du die Live-Spezifikation abrufen unter:

  • http://localhost:8080/openapi.json

Oder ersetze http://localhost:8080 durch deine konfigurierte Basis-URL. Dieser Link wird auch auf dem Dashboard angezeigt.

Konfigurieren von Paketmanagern

npm

Erstelle oder bearbeite ~/.npmrc:``` registry=http://localhost:8080/npm/

Or legen Sie es pro Projekt in `.npmrc` fest:```
registry=http://localhost:8080/npm/

Oder verwenden Sie eine Umgebungsvariable:```bash npm_config_registry=http://localhost:8080/npm/ npm install

### Cargo

Erstellen oder bearbeiten Sie `~/.cargo/config.toml`:```toml
[source.crates-io]
replace-with = "proxy"

[source.proxy]
registry = "sparse+http://localhost:8080/cargo/"

Or set per-project in .cargo/config.toml in your project root.

RubyGems / Bundler

Set the gem source in your Gemfile:```ruby source "http://localhost:8080/gem"

Or global konfigurieren:```bash
gem sources --add http://localhost:8080/gem/
bundle config mirror.https://rubygems.org http://localhost:8080/gem

Go-Module

Legen Sie die Umgebungsvariable GOPROXY fest:```bash export GOPROXY=http://localhost:8080/go,direct

Or in your Shell-Profil für die Persistenz.

### Hex (Elixir)

Konfigurieren Sie in `~/.hex/hex.config`:```erlang
{default_url, <<"http://localhost:8080/hex">>}.

Oder setzen Sie die Umgebungsvariable:```bash export HEX_MIRROR=http://localhost:8080/hex

### pub.dev (Dart/Flutter)

Setzen Sie die Umgebungsvariable PUB_HOSTED_URL:```bash
export PUB_HOSTED_URL=http://localhost:8080/pub

PyPI (pip)

Konfiguriere pip so, dass der Proxy verwendet wird:```bash pip install --index-url http://localhost:8080/pypi/simple/ package_name

Or set in `~/.pip/pip.conf`:```ini
[global]
index-url = http://localhost:8080/pypi/simple/

Maven

Füge Folgendes zu deiner ~/.m2/settings.xml hinzu:```xml proxy central http://localhost:8080/maven/

The `/maven/`-Endpunkt verwendet Maven Central als primäre Upstream-Quelle und greift auf das Gradle Plugin Portal für Gradle-Plugin-Marker-Metadaten und zugehörige Artefakte zurück, wenn die primäre Upstream-Quelle „nicht gefunden“ zurückgibt.

Für die Gradle-Plugin-Auflösung über denselben Proxy-Endpunkt:```kotlin
pluginManagement {
  repositories {
    maven(url = "http://localhost:8080/maven/")
  }
}

Gradle-HTTP-Build-Cache

Konfiguration in settings.gradle(.kts):```kotlin buildCache { local { enabled = false } remote { url = uri("http://localhost:8080/gradle/") push = true } }

### NuGet

Konfiguration in `nuget.config`:```xml
<configuration>
  <packageSources>
    <clear />
    <add key="proxy" value="http://localhost:8080/nuget/v3/index.json" />
  </packageSources>
</configuration>

Oder nutze die CLI:```bash dotnet nuget add source http://localhost:8080/nuget/v3/index.json -n proxy

### Composer (PHP)

Konfiguriere in `composer.json`:```json
{
    "repositories": [
        {
            "type": "composer",
            "url": "http://localhost:8080/composer"
        }
    ]
}

Oder global festlegen:```bash composer config -g repositories.proxy composer http://localhost:8080/composer

### Conan (C/C++)

Fügen Sie den Proxy als Remote hinzu:```bash
conan remote add proxy http://localhost:8080/conan
conan remote disable conancenter

Or konfiguriere in ~/.conan2/remotes.json.

Conda

Konfiguriere in ~/.condarc:```yaml channels:

Oder per Befehl festlegen:```bash
conda config --add channels http://localhost:8080/conda/main

CRAN (R)

Legen Sie das Repository in R fest:```r options(repos = c(CRAN = "http://localhost:8080/cran"))

Or in `~/.Rprofile` for persistence:```r
local({
  r <- getOption("repos")
  r["CRAN"] <- "http://localhost:8080/cran"
  options(repos = r)
})

Julia

Setzen Sie den Pkg-Server, bevor Sie Julia starten:```bash export JULIA_PKG_SERVER=http://localhost:8080/julia

Oder innerhalb einer laufenden Sitzung:```julia
ENV["JULIA_PKG_SERVER"] = "http://localhost:8080/julia"
using Pkg; Pkg.update()

Docker / Container Registry

Konfigurieren Sie Docker so, dass der Proxy als Registry-Mirror in /etc/docker/daemon.json verwendet wird:```json { "registry-mirrors": ["http://localhost:8080"] }

Dann starten Sie Docker neu:```bash
sudo systemctl restart docker

Or pull images directly:```bash docker pull localhost:8080/library/nginx:latest

### Helm

Konfigurieren Sie jedes HTTP-Chart-Repository mit einem Namen und fügen Sie dann die passende Proxy-URL zu Helm hinzu:```yaml
upstream:
  helm:
    bitnami: "https://charts.bitnami.com/bitnami"

The -p flag is used to specify the port number. The -h flag is used to display the help menu. The -v flag is used to enable verbose output. The -t flag is used to specify the target IP address or hostname. The -f flag is used to specify the file containing the list of targets. The -o flag is used to specify the output file for the results. The -c flag is used to specify the number of concurrent threads. The -T flag is used to specify the timeout value in seconds. The -s flag is used to specify the source IP address for the scan. The -S flag is used to specify the source port for the scan. The -e flag is used to specify the network interface to use. The -g flag is used to specify the gateway IP address. The -r flag is used to specify the range of ports to scan. The -R flag is used to specify the range of IP addresses to scan. The -n flag is used to specify the number of packets to send. The -w flag is used to specify the wait time between packets. The -d flag is used to enable debug mode. The -q flag is used to enable quiet mode. The -i flag is used to specify the input file. The -x flag is used to specify the proxy server. The -y flag is used to specify the proxy port. The -z flag is used to specify the proxy type. The -a flag is used to specify the user agent. The -b flag is used to specify the cookie. The -k flag is used to specify the SSL certificate. The -l flag is used to specify the log file. The -m flag is used to specify the maximum number of retries. The -M flag is used to specify the maximum number of redirects. The -P flag is used to specify the password. The -U flag is used to specify the username. The -D flag is used to specify the domain. The -N flag is used to specify the netmask. The -A flag is used to specify the authentication type. The -B flag is used to specify the banner grabbing. The -C flag is used to specify the command to execute. The -E flag is used to specify the encoding. The -F flag is used to specify the file format. The -G flag is used to specify the group. The -H flag is used to specify the header. The -I flag is used to specify the interface. The -J flag is used to specify the JSON output. The -K flag is used to specify the key. The -L flag is used to specify the list. The -O flag is used to specify the output format. The -Q flag is used to specify the query. The -V flag is used to specify the version. The -W flag is used to specify the wordlist. The -X flag is used to specify the exclude list. The -Y flag is used to specify the include list. The -Z flag is used to specify the zone. The -1 flag is used to specify the first parameter. The -2 flag is used to specify the second parameter. The -3 flag is used to specify the third parameter. The -4 flag is used to specify the fourth parameter. The -5 flag is used to specify the fifth parameter. The -6 flag is used to specify the sixth parameter. The -7 flag is used to specify the seventh parameter. The -8 flag is used to specify the eighth parameter. The -9 flag is used to specify the ninth parameter. The -0 flag is used to specify the tenth parameter. The --help flag is used to display the help menu. The --version flag is used to display the version information. The --verbose flag is used to enable verbose output. The --quiet flag is used to enable quiet mode. The --debug flag is used to enable debug mode. The --output flag is used to specify the output file. The --input flag is used to specify the input file. The --target flag is used to specify the target. The --port flag is used to specify the port. The --threads flag is used to specify the number of threads. The --timeout flag is used to specify the timeout. The --source flag is used to specify the source. The --interface flag is used to specify the interface. The --gateway flag is used to specify the gateway. The --range flag is used to specify the range. The --packets flag is used to specify the number of packets. The --wait flag is used to specify the wait time. The --proxy flag is used to specify the proxy. The --user-agent flag is used to specify the user agent. The --cookie flag is used to specify the cookie. The --ssl flag is used to specify the SSL certificate. The --log flag is used to specify the log file. The --retries flag is used to specify the number of retries. The --redirects flag is used to specify the number of redirects. The --password flag is used to specify the password. The --username flag is used to specify the username. The --domain flag is used to specify the domain. The --netmask flag is used to specify the netmask. The --auth flag is used to specify the authentication type. The --banner flag is used to enable banner grabbing. The --command flag is used to specify the command. The --encoding flag is used to specify the encoding. The --format flag is used to specify the format. The --group flag is used to specify the group. The --header flag is used to specify the header. The --json flag is used to enable JSON output. The --key flag is used to specify the key. The --list flag is used to specify the list. The --output-format flag is used to specify the output format. The --query flag is used to specify the query. The --version flag is used to display the version. The --wordlist flag is used to specify the wordlist. The --exclude flag is used to specify the exclude list. The --include flag is used to specify the include list. The --zone flag is used to specify the zone. The --param1 flag is used to specify the first parameter. The --param2 flag is used to specify the second parameter. The --param3 flag is used to specify the third parameter. The --param4 flag is used to specify the fourth parameter. The --param5 flag is used to specify the fifth parameter. The --param6 flag is used to specify the sixth parameter. The --param7 flag is used to specify the seventh parameter. The --param8 flag is used to specify the eighth parameter. The --param9 flag is used to specify the ninth parameter. The --param10 flag is used to specify the tenth parameter.```bash helm repo add bitnami http://localhost:8080/helm/bitnami helm repo update helm pull bitnami/nginx

Der Proxy speichert `index.yaml` mit den normalen Metadaten-Cache-Einstellungen im Cache und
speichert Chart-Archive, nachdem er deren SHA-256-Digest aus dem Index verifiziert hat.

Für Charts, die in einer OCI-Registry gespeichert sind, konfigurieren Sie einen benannten OCI-Upstream und fügen
das reservierte Präfix `upstream/{name}` zur Chart-Referenz hinzu:```yaml
upstream:
  oci:
    ghcr: "https://ghcr.io"
## 🛡️ Sicherheitsfunktionen

- **Verschlüsselung im Ruhezustand**: Alle gespeicherten Daten werden mit AES-256-GCM verschlüsselt.
- **Verschlüsselung während der Übertragung**: Die Kommunikation zwischen Client und Server erfolgt über TLS 1.3.
- **Schlüsselverwaltung**: Schlüssel werden in einem Hardware-Sicherheitsmodul (HSM) gespeichert und rotieren automatisch alle 90 Tage.
- **Zugriffskontrolle**: Rollenbasierte Zugriffskontrolle (RBAC) mit granularen Berechtigungen für jede API-Ressource.
- **Audit-Protokollierung**: Unveränderliche Protokolle aller sicherheitsrelevanten Ereignisse, aufbewahrt für 365 Tage.
- **Ratenbegrenzung**: Integrierte Schutzmechanismen gegen Brute-Force-Angriffe und Denial-of-Service (DoS).
- **Sichere Konfiguration**: Härtungsrichtlinien für alle unterstützten Betriebssysteme und Container-Umgebungen.

## 📦 Installation

### Voraussetzungen

- **Node.js** v18.0.0 oder höher
- **npm** v9.0.0 oder höher
- **Docker** (optional, für Container-Bereitstellung)
- **PostgreSQL** v14 oder höher (für Produktionsumgebungen)

### Schnellstart

```bash
# Repository klonen
git clone https://github.com/example/security-tool.git
cd security-tool

# Abhängigkeiten installieren
npm install

# Umgebungsvariablen konfigurieren
cp .env.example .env
# Bearbeiten Sie .env und setzen Sie Ihre eigenen Werte

# Datenbank migrieren
npm run migrate

# Entwicklungsserver starten
npm run dev

Docker-Bereitstellung

# Image erstellen
docker build -t security-tool .

# Container ausführen
docker run -d -p 8080:8080 \
  -e DATABASE_URL=postgresql://user:pass@localhost:5432/security_tool \
  -e JWT_SECRET=your-secret-key \
  --name security-tool security-tool

🚀 Verwendung

API-Endpunkte

MethodeEndpunktBeschreibung
GET/api/v1/healthDienststatus prüfen
POST/api/v1/auth/loginBenutzerauthentifizierung
POST/api/v1/auth/refreshZugriffstoken erneuern
GET/api/v1/scansListe aller Scans abrufen
POST/api/v1/scansNeuen Scan starten
GET/api/v1/scans/:idScan-Details abrufen
DELETE/api/v1/scans/:idScan löschen
GET/api/v1/reportsBerichte auflisten
POST/api/v1/reports/generateNeuen Bericht generieren

Beispiel: Authentifizierung

# Login-Anfrage
curl -X POST https://api.example.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "your-password"}'

# Antwort
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
  "expiresIn": 3600
}

Beispiel: Scan starten

# Neuen Scan starten
curl -X POST https://api.example.com/api/v1/scans \
  -H "Authorization: Bearer <access-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "target": "https://example.com",
    "scanType": "full",
    "options": {
      "portScan": true,
      "vulnerabilityCheck": true,
      "sslCheck": true
    }
  }'

📊 Berichte

Das Tool generiert umfassende Berichte in mehreren Formaten:

  • PDF: Für formelle Dokumentation und Compliance-Zwecke
  • HTML: Interaktive Berichte mit Diagrammen und Filtern
  • JSON: Maschinenlesbare Ausgabe für CI/CD-Pipelines
  • CSV: Tabellarische Daten für Tabellenkalkulationen

Berichtsstruktur

Jeder Bericht enthält die folgenden Abschnitte:

  1. Zusammenfassung: Überblick über den Scan und die wichtigsten Ergebnisse
  2. Schwachstellen: Detaillierte Liste aller gefundenen Schwachstellen mit Schweregrad
  3. Empfehlungen: Konkrete Maßnahmen zur Behebung der identifizierten Probleme
  4. Anhang: Rohdaten und technische Details für weitere Analysen

🔧 Konfiguration

Umgebungsvariablen

VariableBeschreibungStandardwert
PORTPort, auf dem der Server lauscht8080
DATABASE_URLPostgreSQL-Verbindungszeichenfolge
JWT_SECRETGeheimer Schlüssel für JWT-Signierung
JWT_EXPIRES_INAblaufzeit für Zugriffstoken3600
LOG_LEVELProtokollierungsstufeinfo
MAX_SCAN_DURATIONMaximale Scan-Dauer in Minuten60
ALLOWED_ORIGINSKommagetrennte Liste erlaubter Ursprünge*

Konfigurationsdatei

Alternativ können Sie eine config.yaml-Datei verwenden:

server:
  port: 8080
  host: 0.0.0.0

database:
  url: postgresql://user:pass@localhost:5432/security_tool
  poolSize: 10

auth:
  jwtSecret: your-secret-key
  jwtExpiresIn: 3600
  refreshTokenExpiresIn: 86400

scan:
  maxDuration: 60
  concurrency: 5
  timeout: 30

logging:
  level: info
  format: json
  output: stdout

🧪 Tests

# Alle Tests ausführen
npm test

# Tests mit Coverage-Bericht
npm run test:coverage

# Linting
npm run lint

# TypeScript-Typen prüfen
npm run typecheck

📚 API-Dokumentation

Die vollständige API-Dokumentation ist unter /api/docs verfügbar, wenn der Server läuft. Sie können auch die OpenAPI-Spezifikation unter openapi.yaml im Repository einsehen.

🤝 Beitragen

Wir freuen uns über Beiträge! Bitte lesen Sie zuerst unsere Beitragsrichtlinien.

Entwicklungsumgebung einrichten

# Fork klonen
git clone https://github.com/your-username/security-tool.git
cd security-tool

# Branch erstellen
git checkout -b feature/your-feature-name

# Änderungen committen
git add .
git commit -m "Beschreibung Ihrer Änderungen"

# Push und Pull-Request erstellen
git push origin feature/your-feature-name

📄 Lizenz

Dieses Projekt ist unter der MIT-Lizenz lizenziert. Weitere Informationen finden Sie in der Datei LICENSE.

📞 Support

🙏 Danksagungen

  • Node.js – JavaScript-Laufzeitumgebung
  • Express – Web-Framework
  • PostgreSQL – Datenbank
  • Docker – Containerisierung
  • Alle Mitwirkenden und Unterstützer des Projekts

Hinweis: Dieses Tool ist für autorisierte Sicherheitstests und Bildungszwecke gedacht. Die Verwendung für nicht autorisierte Aktivitäten ist untersagt. Stellen Sie sicher, dass Sie die entsprechenden Genehmigungen haben, bevor Sie dieses Tool einsetzen.

helm pull oci://localhost:8080/upstream/ghcr/owner/charts/mychart --version 1.0.0 --plain-http
```
### Debian / APT

Konfigurieren Sie APT so, dass der Proxy in `/etc/apt/sources.list.d/proxy.list` verwendet wird:```
deb http://localhost:8080/debian stable main contrib
```
Ersetze deine vorhandenen sources.list-Einträge, dann:```bash
sudo apt update
```
Der Upstream-Standardwert ist `http://deb.debian.org/debian`. Um ein anderes APT-Repository (z. B. Ubuntu) zu proxen, setzen Sie `upstream.debian` in der Konfigurationsdatei oder `PROXY_UPSTREAM_DEBIAN` in der Umgebung:```yaml
upstream:
  debian: "http://archive.ubuntu.com/ubuntu"
```
### RPM / Yum / DNF

Konfigurieren Sie yum/dnf so, dass der Proxy in `/etc/yum.repos.d/proxy.repo` verwendet wird:```ini
[proxy-fedora]
name=Fedora via Proxy
baseurl=http://localhost:8080/rpm/releases/$releasever/Everything/$basearch/os/
enabled=1
gpgcheck=0
```
Then:```bash
sudo dnf clean all
sudo dnf update
```
## Konfiguration

Der Proxy kann konfiguriert werden über:

1. Kommandozeilen-Flags (höchste Priorität)
2. Umgebungsvariablen
3. Konfigurationsdatei (YAML oder JSON)

### Kommandozeilen-Flags```
-config string           Path to configuration file
-listen string           Address to listen on (default ":8080")
-base-url string         Public URL of this proxy (default "http://localhost:8080")
-storage-url string      Storage URL (file://, s3://, gs://, azblob://)
-storage-path string     Path to artifact storage directory (deprecated, use -storage-url)
-database-driver string  Database driver: sqlite or postgres (default "sqlite")
-database-path string    Path to SQLite database file (default "./cache/proxy.db")
-database-url string     PostgreSQL connection URL
-log-level string        Log level: debug, info, warn, error (default "info")
-log-format string       Log format: text, json (default "text")
-access-log string       Path to the JSONL access log
-version                 Print version and exit
```
### Umgebungsvariablen```bash
PROXY_LISTEN=:8080
PROXY_BASE_URL=http://localhost:8080
PROXY_UI_URL=http://localhost:8080  # Optional; defaults to PROXY_BASE_URL
PROXY_STORAGE_URL=file:///var/cache/proxy/artifacts
PROXY_DATABASE_DRIVER=sqlite
PROXY_DATABASE_PATH=./cache/proxy.db
PROXY_DATABASE_URL=postgres://user:pass@localhost/proxy?sslmode=disable
PROXY_LOG_LEVEL=info
PROXY_LOG_FORMAT=text
PROXY_ACCESS_LOG_PATH=/var/log/proxy/access.jsonl
```
### Konfigurationsdatei```yaml
listen: ":8080"
base_url: "http://localhost:8080"

storage:
  url: "file:///var/cache/proxy/artifacts"
  max_size: "10GB"  # Optional: evict LRU when exceeded

database:
  driver: "sqlite"
  path: "/var/lib/proxy/cache.db"

log:
  level: "info"
  format: "text"

access_log:
  path: "/var/log/proxy/access.jsonl"  # Optional JSONL activity log

# Optional: override upstream URLs
upstream:
  npm: "https://registry.npmjs.org"
  cargo: "https://index.crates.io"

# Optional: version cooldown (see above)
cooldown:
  default: "3d"
```
Siehe die [Konfigurationsreferenz](https://github.com/git-pkgs/proxy/blob/main/docs/configuration.md#upstream-registries) für jeden Upstream-Schlüssel, jede Umgebungsvariable und jede Standard-URL.

Mit Konfigurationsdatei ausführen:```bash
./proxy -config /etc/proxy/config.yaml
```
### PostgreSQL

SQLite ist die Standardeinstellung und funktioniert gut für Einzelknoten-Bereitstellungen. Für Multi-Node-Setups oder falls Sie eine verwaltete Datenbank bevorzugen, wechseln Sie zu Postgres:```yaml
database:
  driver: "postgres"
  url: "postgres://user:password@localhost:5432/proxy?sslmode=disable"
```
Oder über Umgebungsvariablen:```bash
PROXY_DATABASE_DRIVER=postgres
PROXY_DATABASE_URL=postgres://user:password@localhost:5432/proxy?sslmode=disable
```
Der Proxy erstellt Tabellen automatisch beim ersten Start.

### S3-Speicher

Der Proxy kann zwischengespeicherte Artefakte in S3 oder einem beliebigen S3-kompatiblen Dienst (MinIO, R2 usw.) anstelle des lokalen Dateisystems speichern.```yaml
storage:
  url: "s3://my-bucket-name?region=us-east-1"
```
Für S3-kompatible Dienste wie MinIO:```yaml
storage:
  url: "s3://my-bucket?endpoint=http://localhost:9000&disableSSL=true&s3ForcePathStyle=true"
```
Setzen Sie die Anmeldedaten über die standardmäßigen AWS-Umgebungsvariablen (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`).

### Google Cloud Storage

Der Proxy kann zwischengespeicherte Artefakte in einem GCS-Bucket über das `gs://`-URL-Schema speichern.```yaml
storage:
  url: "gs://my-bucket-name"
```
Authentication verwendet [Application Default Credentials](https://docs.cloud.google.com/docs/authentication/application-default-credentials), was bedeutet, dass keine Anmeldedaten in der Konfiguration oder Umgebung eingebettet werden müssen. Unterstützte Quellen, in der Reihenfolge:

- **GKE Workload Identity** — Binden Sie das Kubernetes-Dienstkonto, das den Proxy ausführt, an ein Google-Dienstkonto, das `roles/storage.objectAdmin` auf dem Bucket besitzt. Der Proxy verwendet automatisch das Token der Workload.
- **Angehängtes Dienstkonto** auf GCE, Cloud Run, Cloud Functions usw.
- **`GOOGLE_APPLICATION_CREDENTIALS`**-Umgebungsvariable, die auf eine JSON-Schlüsseldatei eines Dienstkontos verweist.
- **`gcloud auth application-default login`** für die lokale Entwicklung.

#### GKE Workload Identity Einrichtung```bash
# 1. Create a Google service account
gcloud iam service-accounts create git-pkgs-proxy \
  --project=PROJECT_ID

# 2. Grant it access to the bucket
gsutil iam ch \
  serviceAccount:git-pkgs-proxy@PROJECT_ID.iam.gserviceaccount.com:objectAdmin \
  gs://my-bucket-name

# 3. Bind the Kubernetes service account to it
gcloud iam service-accounts add-iam-policy-binding \
  git-pkgs-proxy@PROJECT_ID.iam.gserviceaccount.com \
  --role=roles/iam.workloadIdentityUser \
  --member="serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]"

# 4. Annotate the Kubernetes service account
kubectl annotate serviceaccount KSA_NAME \
  --namespace=NAMESPACE \
  iam.gke.io/gcp-service-account=git-pkgs-proxy@PROJECT_ID.iam.gserviceaccount.com
```
#### Direktes Ausliefern (signierte URLs) mit Workload Identity

Wenn `direct_serve: true` aktiviert ist, gibt der Proxy HTTP-302-Weiterleitungen auf vorab signierte GCS-URLs aus. Workload Identity stellt keinen privaten Schlüssel bereit, daher ruft das GCS-Backend die [IAM Credentials `signBlob`-API](https://docs.cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob) auf. Gewähren Sie dem Dienstkonto die Rolle `token-creator` auf sich selbst:```bash
gcloud iam service-accounts add-iam-policy-binding \
  git-pkgs-proxy@PROJECT_ID.iam.gserviceaccount.com \
  --role=roles/iam.serviceAccountTokenCreator \
  --member="serviceAccount:git-pkgs-proxy@PROJECT_ID.iam.gserviceaccount.com"
```
## CLI-Befehle

### serve (Standard)

Startet den Proxy-Server. Dies ist der Standardbefehl, wenn keiner angegeben wird.```bash
proxy serve [flags]
proxy [flags]  # same as 'proxy serve'
```
### mirror

Cache aus PURLs, SBOM-Dateien oder vollständigen Registries vorab befüllen. Nützlich, um die Offline-Verfügbarkeit sicherzustellen oder den Cache vor Bereitstellungen aufzuwärmen.```bash
# Mirror specific package versions
proxy mirror pkg:npm/[email protected] pkg:cargo/[email protected]

# Mirror all versions of a package
proxy mirror pkg:npm/lodash

# Mirror from a CycloneDX or SPDX SBOM
proxy mirror --sbom sbom.cdx.json

# Preview what would be mirrored
proxy mirror --dry-run pkg:npm/lodash

# Control parallelism
proxy mirror --concurrency 8 pkg:npm/[email protected]
```
Der Mirror-Befehl akzeptiert dieselben Speicher- und Datenbank-Flags wie `serve`. Bereits zwischengespeicherte Artefakte werden übersprungen.

Eine Mirror-API ist ebenfalls verfügbar, wenn der Server läuft:```bash
# Start a mirror job
curl -X POST http://localhost:8080/api/mirror \
  -H "Content-Type: application/json" \
  -d '{"purls": ["pkg:npm/[email protected]"]}'

# Check job status
curl http://localhost:8080/api/mirror/mirror-1

# Cancel a running job
curl -X DELETE http://localhost:8080/api/mirror/mirror-1
```
### stats

Zeigt Cache-Statistiken an, ohne den Server auszuführen.```bash
# Text output
proxy stats

# JSON output
proxy stats -json

# Custom database path
proxy stats -database-path /var/lib/proxy/cache.db

# With PostgreSQL
proxy stats -database-driver postgres -database-url postgres://user:pass@localhost/proxy

# Show top 20 most popular packages
proxy stats -popular 20
```
Beispielausgabe:```
Cache Statistics
================

Packages:   45
Versions:   128
Artifacts:  128
Total size: 892.4 MB
Total hits: 1547

Packages by ecosystem:
  npm        32
  cargo      13

Most popular packages:
   1. npm/lodash (342 hits, 24.7 KB)
   2. npm/react (198 hits, 89.3 KB)
   3. cargo/serde (156 hits, 234.1 KB)

Recently cached:
  npm/[email protected] (2024-01-15 14:32, 54.2 KB)
  cargo/[email protected] (2024-01-15 14:28, 412.8 KB)
```
## API-Endpunkte

### Registry-Protokolle

| Endpoint | Beschreibung |
|----------|-------------|
| `GET /` | Dashboard (Web-UI) |
| `GET /health` | Health-Check (JSON; HTTP 200 gesund, 503 ungesund) |
| `GET /stats` | Cache-Statistiken (JSON) |
| `GET /metrics` | Prometheus-Metriken |
| `GET /npm/*` | npm-Registry-Protokoll |
| `GET /cargo/*` | Cargo-Sparse-Index-Protokoll |
| `GET /gem/*` | RubyGems-Protokoll |
| `GET /go/*` | Go-Modul-Proxy-Protokoll |
| `GET /hex/*` | Hex.pm-Protokoll |
| `GET /pub/*` | pub.dev-Protokoll |
| `GET /pypi/*` | PyPI-Simple/JSON-API |
| `GET /maven/*` | Maven-Repository-Protokoll |
| `GET /nuget/*` | NuGet-V3-API |
| `GET /composer/*` | Composer/Packagist-Protokoll |
| `GET /conan/*` | Conan-C/C++-Protokoll |
| `GET /conda/*` | Conda/Anaconda-Protokoll |
| `GET /cran/*` | CRAN-Protokoll (R) |
| `GET /julia/*` | Julia-Pkg-Server-Protokoll |
| `GET /helm/{repository}/*` | HTTP-Helm-Chart-Repository-Protokoll |
| `GET /v2/*` | OCI/Docker-Registry-Protokoll |
| `GET /debian/*` | Debian/APT-Repository-Protokoll |
| `GET /rpm/*` | RPM/Yum-Repository-Protokoll |

### Mirror-API

| Endpoint | Beschreibung |
|----------|-------------|
| `POST /api/mirror` | Einen Mirror-Job starten (JSON-Body mit `purls`) |
| `GET /api/mirror/{id}` | Job-Status und Fortschritt abrufen |
| `DELETE /api/mirror/{id}` | Einen laufenden Job abbrechen |

### Anreicherungs-API

Der Proxy stellt REST-Endpunkte für Paketmetadaten-Anreicherung, Schwachstellen-Scans und Erkennung veralteter Pakete bereit.

| Endpoint | Beschreibung |
|----------|-------------|
| `GET /api/package/{ecosystem}/{name}` | Paketmetadaten abrufen |
| `GET /api/package/{ecosystem}/{name}/{version}` | Versionsmetadaten mit Schwachstellen abrufen |
| `GET /api/vulns/{ecosystem}/{name}` | Alle Schwachstellen für ein Paket abrufen |
| `GET /api/vulns/{ecosystem}/{name}/{version}` | Schwachstellen für eine bestimmte Version abrufen |
| `POST /api/outdated` | Mehrere Pakete auf veraltete Versionen prüfen |
| `POST /api/bulk` | Massenabfrage von Paketmetadaten |

#### Paketmetadaten abrufen```bash
curl http://localhost:8080/api/package/npm/lodash
```
```
## 🛡️ Sicherheitsfunktionen

- **Verschlüsselung im Ruhezustand**: Alle gespeicherten Daten werden mit AES-256-GCM verschlüsselt.
- **Verschlüsselung während der Übertragung**: Die Kommunikation zwischen Agent und Server erfolgt über TLS 1.3 mit gegenseitiger Authentifizierung.
- **Integritätsprüfung**: Jede Nachricht enthält einen HMAC-SHA256-Signatur, um Manipulationen zu erkennen.
- **Zugriffskontrolle**: Rollenbasierte Zugriffskontrolle (RBAC) stellt sicher, dass nur autorisierte Benutzer auf sensible Funktionen zugreifen können.
- **Audit-Protokollierung**: Alle sicherheitsrelevanten Ereignisse werden in einem manipulationssicheren Protokoll festgehalten.
- **Sichere Schlüsselverwaltung**: Kryptografische Schlüssel werden in einem Hardware-Sicherheitsmodul (HSM) gespeichert und rotiert regelmäßig.
- **Sandboxing**: Unvertrauenswürdige Plugins werden in isolierten Sandboxes ausgeführt, um die Auswirkungen von Kompromittierungen zu begrenzen.
- **Automatische Updates**: Sicherheitspatches werden automatisch angewendet, sobald sie verfügbar sind.
``````json
{
  "ecosystem": "npm",
  "name": "lodash",
  "latest_version": "4.17.21",
  "license": "MIT",
  "license_category": "permissive",
  "description": "Lodash modular utilities",
  "homepage": "https://lodash.com/",
  "repository": "https://github.com/lodash/lodash",
  "registry_url": "https://registry.npmjs.org"
}
```
#### Version mit Schwachstellen abrufen```bash
curl http://localhost:8080/api/package/npm/lodash/4.17.0
```
```
## Verwendung

```bash
python3 setup.py install
```

## Konfiguration

Die Konfigurationsdatei befindet sich unter `config/config.ini`. Bearbeiten Sie sie, um Ihre Einstellungen festzulegen:

```ini
[allgemein]
sprache = de
protokoll_ebene = info

[api]
schlüssel = Ihr_API_Schlüssel
endpunkt = https://api.example.com
``````json
{
  "package": {
    "ecosystem": "npm",
    "name": "lodash",
    "latest_version": "4.17.21",
    "license": "MIT",
    "license_category": "permissive"
  },
  "version": {
    "ecosystem": "npm",
    "name": "lodash",
    "version": "4.17.0",
    "license": "MIT",
    "published_at": "2016-06-17T03:59:56Z",
    "yanked": false,
    "is_outdated": true
  },
  "vulnerabilities": [
    {
      "id": "GHSA-p6mc-m468-83gw",
      "summary": "Prototype Pollution in lodash",
      "severity": "HIGH",
      "cvss_score": 7.4,
      "fixed_version": "4.17.12"
    }
  ],
  "is_outdated": true,
  "license_category": "permissive"
}
```
#### Veraltete Pakete prüfen```bash
curl -X POST http://localhost:8080/api/outdated \
  -H "Content-Type: application/json" \
  -d '{
    "packages": [
      {"ecosystem": "npm", "name": "lodash", "version": "4.17.0"},
      {"ecosystem": "pypi", "name": "requests", "version": "2.25.0"}
    ]
  }'
```
```
## Installation

To install `subfinder`, simply run the following command:

```bash
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
```

Alternatively, you can use the pre-built binaries from the [releases](https://github.com/projectdiscovery/subfinder/releases) page.

## Usage

```bash
subfinder -h
```

This will display help for the tool. Here are all the switches it supports.

```yaml
Usage:
  ./subfinder [flags]

Flags:
INPUT:
   -d, -domain string[]   domains to find subdomains for
   -l, -list string       file containing list of domains for subdomain discovery

OUTPUT:
   -o, -output string       file to output results to
   -oJ, -json               write output in JSON format
   -oD, -output-dir string  directory to write output (-results only)
   -cs, -collect-sources    include all sources in the output (-json only)
   -silent                  show only subdomains in output
   -version                 show version of subfinder
   -v, -verbose             show verbose output
   -nc, -no-color           disable colors in output

CONFIG:
   -config string                   flag config file (default "$HOME/.config/subfinder/config.yaml")
   -pc, -provider-config string     provider configuration file (default "$HOME/.config/subfinder/provider-config.yaml")
   -r, -resolvers string            list of resolvers to use (file or comma-separated)
   -rrecursive                     use recursive resolvers for subdomain discovery
   -l, -list string                 file containing list of domains for subdomain discovery
   -max-time int                    maximum time to run enumeration (in minutes)
   -timeout int                     seconds to wait for sources to respond (default 30)
   -max-retries int                 maximum number of retries for sources (default 3)
   -t, -threads int                 number of concurrent goroutines for resolving (default 10)
   -d, -domain string[]             domains to find subdomains for
   -l, -list string                 file containing list of domains for subdomain discovery

DEBUG:
   -debug                 display debugging information
   -version               show version of subfinder
   -v, -verbose           show verbose output
   -nc, -no-color         disable colors in output
```

### Examples

#### Basic usage

```bash
subfinder -d example.com
```

#### Using a list of domains

```bash
subfinder -dL domains.txt
```

#### Saving output to a file

```bash
subfinder -d example.com -o output.txt
```

#### JSON output

```bash
subfinder -d example.com -json
```

#### Silent mode (only subdomains)

```bash
subfinder -d example.com -silent
```

#### Using custom resolvers

```bash
subfinder -d example.com -r 8.8.8.8,1.1.1.1
```

#### Recursive resolution

```bash
subfinder -d example.com -rrecursive
```

#### Specifying a timeout

```bash
subfinder -d example.com -timeout 60
```

#### Using a provider configuration file

```bash
subfinder -d example.com -pc provider-config.yaml
```

#### Running with verbose output

```bash
subfinder -d example.com -v
```

#### Running with debug output

```bash
subfinder -d example.com -debug
```

#### Running with a maximum time limit

```bash
subfinder -d example.com -max-time 10
```

#### Running with custom threads

```bash
subfinder -d example.com -t 20
```

#### Running with custom retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml
```

#### Running with a custom list of resolvers

```bash
subfinder -d example.com -r resolvers.txt
```

#### Running with recursive resolvers

```bash
subfinder -d example.com -rrecursive
```

#### Running with a custom timeout

```bash
subfinder -d example.com -timeout 60
```

#### Running with a custom maximum time

```bash
subfinder -d example.com -max-time 10
```

#### Running with a custom number of threads

```bash
subfinder -d example.com -t 20
```

#### Running with a custom number of retries

```bash
subfinder -d example.com -max-retries 5
```

#### Running with a custom output directory

```bash
subfinder -d example.com -oD results/
```

#### Running with source collection

```bash
subfinder -d example.com -cs
```

#### Running with no color output

```bash
subfinder -d example.com -nc
```

#### Running with a custom config file

```bash
subfinder -d example.com -config custom-config.yaml
```

#### Running with a custom provider config file

```bash
subfinder -d example.com -pc custom-provider-config.yaml```json
{
  "results": [
    {
      "ecosystem": "npm",
      "name": "lodash",
      "version": "4.17.0",
      "latest_version": "4.17.21",
      "is_outdated": true
    },
    {
      "ecosystem": "pypi",
      "name": "requests",
      "version": "2.25.0",
      "latest_version": "2.31.0",
      "is_outdated": true
    }
  ]
}
```
#### Bulk-Paketabfrage```bash
curl -X POST http://localhost:8080/api/bulk \
  -H "Content-Type: application/json" \
  -d '{
    "purls": [
      "pkg:npm/[email protected]",
      "pkg:pypi/[email protected]"
    ]
  }'
```
## Installation

```bash
# Clone the repository
git clone https://github.com/yourusername/yourproject.git

# Navigate to the project directory
cd yourproject

# Install dependencies
pip install -r requirements.txt
```

## Usage

```bash
python main.py --help
```

## License

This project is licensed under the MIT License - see the [LICENSE](https://github.com/git-pkgs/proxy/blob/main/LICENSE) file for details.```json
{
  "packages": {
    "pkg:npm/lodash": {
      "ecosystem": "npm",
      "name": "lodash",
      "latest_version": "4.17.21",
      "license": "MIT",
      "license_category": "permissive"
    },
    "pkg:pypi/requests": {
      "ecosystem": "pypi",
      "name": "requests",
      "latest_version": "2.31.0",
      "license": "Apache-2.0",
      "license_category": "permissive"
    }
  }
}
```
### Stats-Antwort (HTTP-Endpunkt)```json
{
  "cached_artifacts": 142,
  "total_size_bytes": 523456789,
  "total_size": "499.2 MB",
  "storage_url": "file:///path/to/cache/artifacts",
  "database_path": "./cache/proxy.db"
}
```
## So funktioniert es

1. Der Paketmanager fordert Paketmetadaten vom Proxy an
2. Der Proxy ruft Metadaten vom Upstream ab und schreibt Artefakt-URLs so um, dass sie auf den Proxy verweisen
3. Der Paketmanager fordert das Artefakt an (Tarball, Crate usw.)
4. Der Proxy prüft den lokalen Cache:
   - **Cache-Treffer**: Aus dem lokalen Speicher ausliefern
   - **Cache-Fehltreffer**: Vom Upstream abrufen, lokal speichern, an den Client ausliefern
5. Nachfolgende Anfragen für dasselbe Artefakt werden aus dem Cache bedient```
┌─────────────┐     ┌─────────┐     ┌──────────┐
│   npm/cargo │────▶│  proxy  │────▶│ upstream │
│   client    │◀────│         │◀────│ registry │
└─────────────┘     └─────────┘     └──────────┘
                         │
                         ▼
                    ┌─────────┐
                    │  cache  │
                    │ storage │
                    └─────────┘
```
## Web-Oberfläche

Der Proxy stellt eine Web-UI unter `/ui` bereit. Es ist kein separater Frontend-Build erforderlich – Vorlagen und Assets sind in die Binärdatei eingebettet. `GET /` leitet auf `/ui/` weiter. Die UI ist unter einem eigenen Präfix gemountet, sodass ein Reverse-Proxy andere Zugriffsregeln darauf anwenden kann als auf die Paket-Endpunkte (z. B. Authentifizierung für `PathPrefix(/ui)` erforderlich, während `/npm`, `/pypi` usw. für Build-Maschinen offen bleiben).

- **Dashboard** (`/ui/`) – Cache-Statistiken, beliebte Pakete, zuletzt gecachte Artefakte und Schwachstellenübersicht.
- **Installationsanleitung** (`/ui/install`) – Konfigurationsanweisungen pro Ökosystem, damit Sie sie hier nicht nachschlagen müssen.
- **Paket-Browser** (`/ui/packages`) – Durchsuchen aller gecachten Pakete mit Filterung nach Ökosystem und Sortierung nach Treffern, Größe, Name oder Anzahl der Schwachstellen.
- **Suche** (`/ui/search?q=...`) – Durchsuchen gecachter Pakete nach Name.
- **Paketdetails** (`/ui/package/{ecosystem}/{name}`) – Metadaten, Lizenz, Schwachstellen und Versionsliste für ein Paket. Sie können zwei Versionen zum Vergleich auswählen.
- **Versionsdetails** (`/ui/package/{ecosystem}/{name}/{version}`) – Metadaten pro Version, Integritäts-Hash, Cache-Status des Artefakts und Trefferzahlen.
- **Quellcode-Browser** (`/ui/package/{ecosystem}/{name}/{version}/browse`) – Durchsuchen von Dateien in gecachten Archiven mit Syntaxhervorhebung für Textdateien und Bildvorschauen.
- **Versionsvergleich** (`/ui/package/{ecosystem}/{name}/compare/{v1}...{v2}`) – Nebeneinander-Vergleich zweier gecachter Versionen mit hinzugefügten, entfernten und geänderten Dateien.

## Überwachung

Der Proxy stellt Prometheus-Metriken unter `GET /metrics` bereit. Alle Metriknamen sind mit `proxy_` präfixiert.

| Metrik | Typ | Labels | Beschreibung |
|--------|------|--------|-------------|
| `proxy_requests_total` | counter | `ecosystem`, `status` | Proxy-Antworten nach Paket-Ökosystem und HTTP-Status |
| `proxy_request_duration_seconds` | histogram | `ecosystem`, `status` | Dauer der Proxy-Anfragen |
| `proxy_cache_hits_total` | counter | `ecosystem` | Cache-Treffer |
| `proxy_cache_misses_total` | counter | `ecosystem` | Cache-Fehlschläge |
| `proxy_cache_size_bytes` | gauge | | Gesamtgröße der gecachten Artefakte |
| `proxy_cached_artifacts_total` | gauge | | Anzahl der gecachten Artefakte |
| `proxy_upstream_fetch_duration_seconds` | histogram | `ecosystem` | Zeit für das Abrufen vom Upstream |
| `proxy_upstream_errors_total` | counter | `ecosystem`, `error_type` | Fehler beim Upstream-Abruf |
| `proxy_storage_operation_duration_seconds` | histogram | `operation` | Latenz beim Speicher-Lesen/-Schreiben |
| `proxy_storage_errors_total` | counter | `operation` | Fehler beim Speicher-Lesen/-Schreiben |
| `proxy_active_requests` | gauge | | Laufende Anfragen |
| `proxy_health_probe_failures_total` | counter | `step` | Fehler bei Speicher-Health-Probes nach fehlgeschlagenem Schritt (`write`, `size`, `read`, `verify`, `delete`). |

Cache-Größe und Artefaktanzahl werden alle 60 Sekunden aktualisiert. Die übrigen Metriken werden bei jeder Anfrage aktualisiert.

### Health-Check

`/health` gibt einen strukturierten JSON-Bericht über den Zustand der Subsysteme zurück. HTTP 200, wenn alle Prüfungen bestanden sind; 503, wenn eine fehlschlägt.```json
{
  "status": "ok",
  "checks": {
    "database": {"status": "ok"},
    "storage":  {"status": "ok"}
  }
}
```
Fehlgeschlagene Prüfungen enthalten ein `"error"`-Feld. Speicherfehler enthalten außerdem ein `"step"`-Feld, das angibt, welcher Prüfschritt fehlgeschlagen ist (`write`, `size`, `read`, `verify`, `delete`). Wenn die Datenbankprüfung fehlschlägt, meldet der Speichereintrag `{"status": "skipped"}`, sodass die Antwort immer denselben Schlüsselsatz enthält.

Ergebnisse der Speicherprüfung werden für `health.storage_probe_interval` (Standard 30s) zwischengespeichert, um die Kosten der Prüfung entfernter Backends zu begrenzen. Eine Prüfung hält einen internen Mutex für bis zu 10 Sekunden (das fest codierte Timeout pro Prüfung), daher ist `/health` als Kubernetes-**Readiness**-Probe gedacht und nicht als Liveness-Probe — ein langsamer S3-Roundtrip sollte den Pod aus der Rotation nehmen, nicht neu starten.

Scrape-Konfiguration für Prometheus:```yaml
scrape_configs:
  - job_name: git-pkgs-proxy
    static_configs:
      - targets: ["localhost:8080"]
```
## Produktionsbereitstellung

### Systemd-Dienst

Erstellen Sie `/etc/systemd/system/proxy.service`:```ini
[Unit]
Description=git-pkgs proxy
After=network.target

[Service]
Type=simple
User=proxy
ExecStart=/usr/local/bin/proxy -config /etc/proxy/config.yaml
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
```
Enable and start:```bash
sudo systemctl enable proxy
sudo systemctl start proxy
```
### Docker

Ein Dockerfile ist im Repository enthalten. Erstellen und ausführen:```bash
docker build -t proxy .
docker run -p 8080:8080 -v proxy-data:/data proxy
```
Mit Postgres und S3:```bash
docker run -p 8080:8080 \
  -e PROXY_DATABASE_DRIVER=postgres \
  -e PROXY_DATABASE_URL=postgres://user:pass@db:5432/proxy \
  -e PROXY_STORAGE_URL=s3://my-bucket?region=us-east-1 \
  -e AWS_ACCESS_KEY_ID=... \
  -e AWS_SECRET_ACCESS_KEY=... \
  proxy
```
### Hinter einem Reverse Proxy

Wenn du hinter nginx, Apache oder einem anderen Reverse Proxy läufst, setze `base_url` auf deine öffentliche URL:```yaml
base_url: "https://proxy.example.com"
```
Wenn die UI über einen anderen Hostnamen erreicht wird als die Paket-Endpunkte – zum Beispiel, wenn die UI öffentlich über eine Domain bereitgestellt wird, während Build-Maschinen einen Docker-Netzwerk-Alias verwenden – setzen Sie `ui_base_url` separat. `base_url` ist die URL, die Paketmanager und die Metadaten-Umschreibung verwenden; `ui_base_url` ist die URL, die Menschen angezeigt wird, die die Web-UI besuchen (canonical/`og:url`-Tags und das Installationsleitfaden-Banner):```yaml
base_url: "http://pkg-proxy:8080"        # internal alias for build machines
ui_base_url: "https://proxy.example.com/ui"  # public UI URL
```
Wenn nicht gesetzt, verwendet `ui_base_url` standardmäßig `base_url`.

> **Warnung:** Der Proxy bedient die UI- und Paket-Endpunkte auf demselben Listener. Das Setzen von `ui_base_url` ändert nur, welche URL die UI Menschen anzeigt; es verhindert nicht, dass Paket-Endpunkte auf demselben Hostnamen und Port erreichbar bleiben. Wenn der Proxy hinter einem öffentlichen Reverse-Proxy liegt, beschränken Sie die öffentliche Route auf `PathPrefix(/ui)` (oder das Äquivalent Ihres Proxys), andernfalls bleiben `/npm`, `/pypi` und die anderen Paket-Endpunkte neben der UI exponiert.

nginx-Beispiel, das den öffentlichen Host auf die UI beschränkt, während Paket-Endpunkte nur über den internen Listener erreichbar bleiben:```nginx
server {
    listen 443 ssl;
    server_name proxy.example.com;

    location /ui/ {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_buffering off;
    }

    location / {
        return 404;
    }
}
```
Traefik-Beispiel mit `PathPrefix(/ui)`, sodass der öffentliche Router nur UI-Datenverkehr abgleicht:```yaml
labels:
  traefik.enable: "true"
  traefik.http.services.pkg-proxy.loadbalancer.server.port: "8080"
  traefik.http.routers.pkg-proxy.rule: "Host(`proxy.example.com`) && PathPrefix(`/ui`)"
  traefik.http.routers.pkg-proxy.entrypoints: "websecure"
```
## Cache-Verwaltung

Der Proxy speichert Artefakte im konfigurierten Speicherverzeichnis mit dieser Struktur:```
cache/artifacts/
├── npm/
│   └── lodash/
│       └── 4.17.21/
│           └── lodash-4.17.21.tgz
├── cargo/
│   └── serde/
│       └── 1.0.193/
│           └── serde-1.0.193.crate
├── oci/
│   └── library/nginx/
│       └── sha256:abc123.../
│           └── sha256:abc123...
├── deb/
│   └── nginx/
│       └── 1.18.0-6/
│           └── nginx_1.18.0-6_amd64.deb
└── rpm/
    └── nginx/
        └── 1.24.0-1.fc39/
            └── nginx-1.24.0-1.fc39.x86_64.rpm
```
Cache-Metadaten werden in SQLite (Standard) oder PostgreSQL gespeichert. Um einen lokalen Cache zu leeren:```bash
rm -rf ./cache/artifacts/*
rm ./cache/proxy.db
```
Der Proxy erstellt die Datenbank beim nächsten Start neu.

## Aus dem Quellcode erstellen

Anforderungen:

- Go (die Projektversion ist in `go.mod` deklariert)```bash
git clone https://github.com/git-pkgs/proxy.git
cd proxy
go build -o proxy ./cmd/proxy
```
Run tests:```bash
go test ./...
```
## Lizenz

GPL-3.0-or-later

Kategorien