Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
proxy — Un proxy ligero de caché para registros de paquetes. | Kitploit
Herramientas/GitHubGitHub/git-pkgs/proxy
Análisis de VulnerabilidadesSeguridad en la NubeDevSecOpsSeguridad de Cadena de SuministroSeguridad de APIs
GitHubgit-pkgs/proxy

proxy

Un proxy ligero de caché para registros de paquetes.

Ver Repositorio
1552115hace 1 díaRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

git-pkgs proxy

Un proxy con caché para registros de paquetes. Acelera las descargas de paquetes almacenando artefactos en caché localmente, lo que reduce el uso de ancho de banda y mejora la fiabilidad.

Enfriamiento de versiones

La mayoría de los ataques a la cadena de suministro dependen de la velocidad: una versión maliciosa se publica y es consumida por pipelines automatizados en cuestión de minutos, antes de que nadie lo note. La función de enfriamiento añade un periodo de cuarentena a las versiones recién publicadas. Cuando está habilitada, el proxy elimina las versiones de las respuestas de metadatos hasta que hayan superado un umbral configurable.```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

root@kitploit:~
Un período de enfriamiento de 3 días significa que cuando `lodash` publica la versión `4.18.0`, tus compilaciones siguen usando `4.17.21` hasta que hayan pasado 3 días. Si la nueva versión resulta estar comprometida, nunca estuviste expuesto.

Orden de resolución: anulación de paquete, luego anulación de ecosistema, luego valor predeterminado global. Esto te permite establecer un valor predeterminado conservador y crear excepciones para paquetes donde necesitas actualizaciones más rápidas. Consulta [docs/configuration.md](https://github.com/git-pkgs/proxy/blob/main/docs/configuration.md) para la referencia completa de configuración.

## Escaneo de artefactos

El enfriamiento solo examina la marca de tiempo de publicación de una versión — nunca inspecciona los bytes reales. El escaneo de artefactos cierra esa brecha: cuando está habilitado, cada artefacto se almacena temporalmente en el almacenamiento y es escaneado por uno o más servicios externos (trivy, ClamAV, Wiz, o cualquier otra cosa que hable un pequeño contrato HTTP/JSON) antes de ser confirmado en la caché y servido a los clientes.```yaml
scanning:
  enabled: true
  signing_key: ${PROXY_SCANNING_SIGNING_KEY}
  scanners:
    - name: clamav
      url: http://clamav-adapter:8080/scan
      mode: block             # a block verdict deletes the artifact and returns 403
    - name: trivy
      url: http://trivy-adapter:8081/scan
      mode: monitor            # findings are logged, never gate caching
      ecosystems: [npm, pypi]
Descargar herramienta

El proxy nunca sube los bytes de los artefactos a un escáner. Cada escáner es notificado con metadatos del paquete más una URL firmada de corta duración; el escáner descarga los bytes por sí mismo desde el almacenamiento propio del proxy. Los escáneres se ejecutan de forma concurrente, y el primer escáner en modo block que reporte un veredicto de no permitido gana de inmediato, cancelando el resto. Consulta docs/configuration.md para la referencia completa de configuración y el contrato HTTP del escáner.

Registros compatibles

RegistroLenguaje/PlataformaEnfriamientoCompletado
npmJavaScriptSí✓
CargoRustSí✓
RubyGemsRubySí✓
Go proxyGo✓
HexElixirSí*✓
pub.devDartSí✓
PyPIPythonSí✓
MavenJava✓
Gradle Build CacheJava/Kotlin✓
NuGet.NETSí✓
ComposerPHPSí✓
ConanC/C++✓
CondaPython/RSí✓
CRANR✓
JuliaJulia✓
SwiftSwift✓
ContainerDocker/OCI✓
HomebrewmacOS/Linux✓
DebianDebian/Ubuntu✓
RPMRHEL/Fedora✓
AlpineAlpine Linux✓
ArchArch Linux✗

El enfriamiento requiere marcas de tiempo de publicación en los metadatos. Los registros sin un "Sí" en la columna de enfriamiento o bien no exponen marcas de tiempo o aún no han sido integrados.

* El enfriamiento de Hex requiere deshabilitar la verificación de firma del registro (HEX_NO_VERIFY_REPO_ORIGIN=1) ya que el proxy recodifica la carga útil del protobuf.

Instalación```bash

brew install git-pkgs/git-pkgs/proxy

root@kitploit:~
O descarga un binario desde la [página de releases](https://github.com/git-pkgs/proxy/releases).

### Helm

Instala el chart desde GHCR, configurando la URL pública que los clientes de gestores de paquetes usarán para acceder al proxy:```bash
helm install proxy oci://ghcr.io/git-pkgs/charts/proxy \
  --set config.data.base_url=https://proxy.example.com

El chart predeterminado despliega una réplica respaldada por un volumen persistente de 10 GiB, usando SQLite y almacenamiento de artefactos en el sistema de archivos bajo /data. Consulte deploy/charts/proxy/values.yaml para las opciones de configuración de ingress, base de datos externa y almacenamiento de objetos.

Inicio rápido```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

root@kitploit:~
El proxy ya está en ejecución. Configure sus gestores de paquetes para usarlo.

## OpenAPI (Swagger)

Este repositorio utiliza swaggo para generar una especificación OpenAPI a partir de los manejadores anotados.

Genere la especificación:```bash
go install github.com/swaggo/swag/cmd/swag@latest
go generate ./internal/server

Los archivos generados se escriben en docs/swagger/.

Cuando el proxy está en ejecución, obtén la especificación en vivo desde:

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

O reemplaza http://localhost:8080 con tu URL base configurada. Este enlace también se muestra en el panel de control.

Configuración de gestores de paquetes

npm

Crea o edita ~/.npmrc:``` registry=http://localhost:8080/npm/

root@kitploit:~
O configurar por proyecto en `.npmrc`:```
registry=http://localhost:8080/npm/

O utilice la variable de entorno:```bash npm_config_registry=http://localhost:8080/npm/ npm install

root@kitploit:~
### Cargo

Crea o edita `~/.cargo/config.toml`:```toml
[source.crates-io]
replace-with = "proxy"

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

O configúralo por proyecto en .cargo/config.toml en la raíz de tu proyecto.

RubyGems / Bundler

Configura la fuente de gemas en tu Gemfile:```ruby source "http://localhost:8080/gem"

root@kitploit:~
O configurar globalmente:```bash
gem sources --add http://localhost:8080/gem/
bundle config mirror.https://rubygems.org http://localhost:8080/gem

Módulos de Go

Establece la variable de entorno GOPROXY:```bash export GOPROXY=http://localhost:8080/go,direct

root@kitploit:~
O en el perfil de tu shell para que sea persistente.

### Homebrew

Apunta la API JSON y el dominio de artefactos de Homebrew al proxy:```bash
export HOMEBREW_API_DOMAIN=http://localhost:8080/homebrew
export HOMEBREW_ARTIFACT_DOMAIN=http://localhost:8080

El dominio de artefactos actúa como proxy de manifiestos y blobs de bottle bajo /v2/homebrew/core/. El enrutamiento de GHCR está limitado a ese repositorio. Los archivos fuente, las descargas de aplicaciones de cask, los artefactos de taps personalizados y los mirrors de bottles de archivo plano heredados utilizan las URLs de fallback normales de Homebrew. Mantén el fallback habilitado dejando HOMEBREW_ARTIFACT_DOMAIN_NO_FALLBACK sin establecer.

Habilita cache_metadata o establece PROXY_CACHE_METADATA=true para conservar las respuestas de la API JSON de Homebrew para el fallback sin conexión. Los blobs de bottle y sus manifiestos OCI se almacenan en caché sin esta configuración.

Los upstreams predeterminados son https://formulae.brew.sh/api para la API JSON y https://ghcr.io para los artefactos. Para encadenar este proxy a otro proxy, configura sus endpoints de Homebrew como los upstreams:```yaml upstream: homebrew_api: "https://upstream-proxy.example.com/homebrew" homebrew_artifact: "https://upstream-proxy.example.com"

root@kitploit:~
Las variables de entorno equivalentes son `PROXY_UPSTREAM_HOMEBREW_API` y `PROXY_UPSTREAM_HOMEBREW_ARTIFACT`.

### Hex (Elixir)

Configurar en `~/.hex/hex.config`:```erlang
{default_url, <<"http://localhost:8080/hex">>}.

O establece la variable de entorno:```bash export HEX_MIRROR=http://localhost:8080/hex

root@kitploit:~
### pub.dev (Dart/Flutter)

Establezca la variable de entorno PUB_HOSTED_URL:```bash
export PUB_HOSTED_URL=http://localhost:8080/pub

PyPI (pip)

Configura pip para usar el proxy:```bash pip install --index-url http://localhost:8080/pypi/simple/ package_name

root@kitploit:~
O configúralo en `~/.pip/pip.conf`:```ini
[global]
index-url = http://localhost:8080/pypi/simple/

Maven

Añade a tu ~/.m2/settings.xml:```xml proxy central http://localhost:8080/maven/

root@kitploit:~
El endpoint `/maven/` utiliza Maven Central como upstream principal y recurre al Gradle Plugin Portal para los metadatos de los marcadores de plugins de Gradle y los artefactos relacionados cuando el upstream principal devuelve no encontrado.

Para la resolución de plugins de Gradle a través del mismo endpoint del proxy:```kotlin
pluginManagement {
  repositories {
    maven(url = "http://localhost:8080/maven/")
  }
}

Caché de compilación HTTP de Gradle

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

root@kitploit:~
### NuGet

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

O usa la CLI:```bash dotnet nuget add source http://localhost:8080/nuget/v3/index.json -n proxy

root@kitploit:~
### Composer (PHP)

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

O establecer globalmente:```bash composer config -g repositories.proxy composer http://localhost:8080/composer

root@kitploit:~
### Conan (C/C++)

Añade el proxy como un remoto:```bash
conan remote add proxy http://localhost:8080/conan
conan remote disable conancenter

O configurar en ~/.conan2/remotes.json.

Conda

Configurar en ~/.condarc:```yaml channels:

  • http://localhost:8080/conda/main
  • http://localhost:8080/conda/conda-forge default_channels:
  • http://localhost:8080/conda/main
root@kitploit:~
O establecer mediante comando:```bash
conda config --add channels http://localhost:8080/conda/main

CRAN (R)

Configura el repositorio en R:```r options(repos = c(CRAN = "http://localhost:8080/cran"))

root@kitploit:~
O en `~/.Rprofile` para persistencia:```r
local({
  r <- getOption("repos")
  r["CRAN"] <- "http://localhost:8080/cran"
  options(repos = r)
})

Julia

Configure el servidor Pkg antes de iniciar Julia:```bash export JULIA_PKG_SERVER=http://localhost:8080/julia

root@kitploit:~
O dentro de una sesión en ejecución:```julia
ENV["JULIA_PKG_SERVER"] = "http://localhost:8080/julia"
using Pkg; Pkg.update()

Swift

Configura el proxy como el registro predeterminado para el paquete Swift actual:```bash swift package-registry set --allow-insecure-http http://localhost:8080/swift

root@kitploit:~
Las dependencias del registro utilizan su identificador de paquete con ámbito en `Package.swift`:```swift
dependencies: [
    .package(id: "apple.swift-argument-parser", from: "1.2.0")
]

El proxy admite la resolución de dependencias y las descargas de código fuente. La publicación con swift package-registry publish no es compatible.

Docker / Registro de contenedores

Configure Docker para usar el proxy como espejo de registro en /etc/docker/daemon.json:```json { "registry-mirrors": ["http://localhost:8080"] }

root@kitploit:~
Luego reinicia Docker:```bash
sudo systemctl restart docker

O extraer imágenes directamente:```bash docker pull localhost:8080/library/nginx:latest

root@kitploit:~
### Helm

Configure cada repositorio de gráficos HTTP con un nombre, luego añada la URL del proxy correspondiente a Helm:```yaml
upstream:
  helm:
    bitnami: "https://charts.bitnami.com/bitnami"

| --no-color | Desactiva la salida con color | | --debug | Habilita el registro de depuración | | --verbose | Habilita el registro detallado | | --silent | Suprime toda la salida excepto los resultados | | --json | Salida en formato JSON | | --csv | Salida en formato CSV | | --html | Salida en formato HTML | | --markdown | Salida en formato Markdown | | --output <file> | Escribe la salida en un archivo | | --config <file> | Ruta al archivo de configuración | | --threads <n> | Número de hilos a utilizar | | --timeout <seconds> | Tiempo de espera de la solicitud en segundos | | --retries <n> | Número de reintentos para solicitudes fallidas | | --proxy <url> | URL del proxy a utilizar | | --user-agent <string> | Cadena de User-Agent a utilizar | | --cookie <string> | Cadena de cookie a enviar | | --header <header> | Encabezado personalizado a enviar | | --method <method> | Método HTTP a utilizar | | --data <data> | Datos a enviar en el cuerpo de la solicitud | | --follow-redirects | Seguir redirecciones HTTP | | --max-redirects <n> | Número máximo de redirecciones a seguir | | --insecure | Deshabilitar la verificación del certificado SSL | | --rate-limit <n> | Limitar la tasa de solicitudes por segundo | | --random-agent | Utilizar una cadena de User-Agent aleatoria | | --tor | Enrutar el tráfico a través de Tor | | --check-tor | Verificar si Tor está funcionando correctamente | | --update | Actualizar la herramienta a la última versión | | --version | Mostrar la versión de la herramienta | | --help | Mostrar el mensaje de ayuda |```bash helm repo add bitnami http://localhost:8080/helm/bitnami helm repo update helm pull bitnami/nginx

root@kitploit:~
El proxy almacena en caché `index.yaml` utilizando la configuración normal de caché de metadatos y
almacena en caché los archivos de charts tras verificar su digest SHA-256 del índice.

Para charts almacenados en un registro OCI, configure un upstream OCI con nombre y añada
el prefijo reservado `upstream/{name}` a la referencia del chart:```yaml
upstream:
  oci:
    ghcr: "https://ghcr.io"
-h, --helpMuestra el mensaje de ayuda y sale
-v, --versionMuestra la versión del programa y sale
-d, --debugHabilita el registro de depuración
-c, --configRuta al archivo de configuración
-o, --outputRuta del archivo de salida
-f, --formatFormato de salida (json, yaml, xml)
-q, --quietModo silencioso, suprime la salida
-V, --verboseModo detallado, aumenta la salida
helm pull oci://localhost:8080/upstream/ghcr/owner/charts/mychart --version 1.0.0 --plain-http
root@kitploit:~
### Debian / APT

Configura APT para usar el proxy en `/etc/apt/sources.list.d/proxy.list`:```
deb http://localhost:8080/debian stable main contrib

Reemplace sus entradas existentes en sources.list, luego:```bash sudo apt update

root@kitploit:~
El upstream por defecto es `http://deb.debian.org/debian`. Para hacer proxy de un repositorio APT diferente (por ejemplo, Ubuntu), configure `upstream.debian` en el archivo de configuración o `PROXY_UPSTREAM_DEBIAN` en el entorno:```yaml
upstream:
  debian: "http://archive.ubuntu.com/ubuntu"

RPM / Yum / DNF

Configure yum/dnf para usar el proxy en /etc/yum.repos.d/proxy.repo:```ini [proxy-fedora] name=Fedora via Proxy baseurl=http://localhost:8080/rpm/releases/$releasever/Everything/$basearch/os/ enabled=1 gpgcheck=0

root@kitploit:~
Luego:```bash
sudo dnf clean all
sudo dnf update

Alpine / apk

Apunte /etc/apk/repositories al proxy. El nombre de repositorio predeterminado alpine actúa como proxy del mirror oficial (https://dl-cdn.alpinelinux.org/alpine):``` http://localhost:8080/apk/alpine/v3.22/main http://localhost:8080/apk/alpine/v3.22/community

root@kitploit:~
Luego:```bash
apk update

Los índices del repositorio (v2 APKINDEX.tar.gz y v3 Packages.adb), las firmas separadas y los paquetes se sirven byte por byte sin cambios, por lo que la verificación de firmas normal de apk sigue funcionando. Los índices utilizan la caché de metadatos (metadata_ttl, respaldo obsoleto); los paquetes .apk se almacenan en la caché compartida de artefactos y permanecen disponibles cuando el upstream es inaccesible.

Para actuar como proxy de otros mirrors o repositorios privados, configure upstreams con nombre bajo upstream.apk (esto reemplaza el valor predeterminado integrado; vuelva a agregar alpine si aún lo desea):```yaml upstream: apk: alpine: "https://dl-cdn.alpinelinux.org/alpine" private: "https://apk.example.com"

root@kitploit:~
| `--no-color` | Desactiva la salida con color |
| `--verbose` | Habilita el registro detallado |
| `--quiet` | Suprime toda la salida excepto los errores |
| `--config <path>` | Especifica una ruta de archivo de configuración personalizada |
| `--timeout <seconds>` | Establece un tiempo de espera para las operaciones de red |
| `--retry <count>` | Número de reintentos para solicitudes fallidas |
| `--proxy <url>` | Usa el proxy especificado para las conexiones |
| `--output <format>` | Formato de salida (json, yaml, table) |
| `--log-level <level>` | Establece el nivel de registro (debug, info, warn, error) |

### Ejemplos

```bash
# Ejecutar con configuración predeterminada
tool run --target example.com

# Especificar un archivo de configuración personalizado
tool run --config /path/to/config.yaml

# Establecer el nivel de registro en debug
tool run --log-level debug

# Usar proxy para las conexiones
tool run --proxy http://127.0.0.1:8080

# Establecer un tiempo de espera de 30 segundos
tool run --timeout 30

Variables de entorno

VariableDescripción
TOOL_CONFIGRuta al archivo de configuración
TOOL_LOG_LEVELNivel de registro
TOOL_PROXYURL del proxy
TOOL_TIMEOUTTiempo de espera en segundos
TOOL_API_KEYClave de API para servicios remotos

Códigos de salida

CódigoDescripción
0Éxito
1Error general
2Argumentos de línea de comandos no válidos
3Error de configuración
4Error de red
5Permiso denegado

Solución de problemas

El comando no se encuentra

Asegúrese de que el directorio de instalación esté en su PATH:

root@kitploit:~
export PATH=$PATH:/usr/local/tool/bin

Permiso denegado

Ejecute con privilegios elevados o ajuste los permisos de archivo:

root@kitploit:~
chmod +x /usr/local/tool/bin/tool

Errores de conexión

Verifique la configuración de su proxy y la conectividad de red:

root@kitploit:~
curl -v https://api.example.com/health

Problemas de configuración

Valide su archivo de configuración:

root@kitploit:~
tool validate --config /path/to/config.yaml

http://localhost:8080/apk/private

root@kitploit:~
apk añade la arquitectura y el nombre del archivo de índice a cada línea de repositorio por sí mismo.

### GitHub Releases / mise (backend de aqua)

Configurar upstreams genéricos con nombre:```yaml
upstream:
  generic:
    github: "https://github.com"
    github-api: "https://api.github.com"

Luego reescribe las URL de GitHub en la configuración de mise (~/.config/mise/config.toml, mise ≥ 2025.9.3):```toml [settings.url_replacements] "regex:^https://github\\.com/([^/]+)/([^/]+)/releases/download/(.+)" = "http://localhost:8080/generic/github/$1/$2/releases/download/$3" "regex:^https://api\\.github\\.com/(.*)" = "http://localhost:8080/generic/github-api/$1"

root@kitploit:~
Los recursos de la versión se almacenan en caché de forma permanente después de la primera descarga y siguen
instalándose mientras GitHub está caído. Las búsquedas de etiquetas a través de `api.github.com` se
almacenan en caché durante `metadata_ttl` y se sirven obsoletas durante una interrupción o límite de tasa.
Confirma un `mise.lock` e instala con `mise install --locked` para que las
instalaciones fijadas no necesiten ninguna llamada a la API. Añade un token de portador para `https://api.github.com`
en `upstream.auth` si el conjunto supera el límite de tasa anónimo de GitHub.

## Configuración

El proxy se puede configurar mediante:

1. Indicadores de línea de comandos (mayor prioridad)
2. Variables de entorno
3. Archivo de configuración (YAML o JSON)

### Indicadores de línea de comandos```
-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

Variables de Entorno```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 PROXY_UPSTREAM_SWIFT=https://tuist.dev/api/registry/swift

root@kitploit:~
### Archivo de Configuración```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"
  swift: "https://tuist.dev/api/registry/swift"

# Optional: version cooldown (see above)
cooldown:
  default: "3d"

Consulta la referencia de configuración para conocer cada clave de upstream, variable de entorno y URL predeterminada.

Ejecutar con archivo de configuración:```bash ./proxy -config /etc/proxy/config.yaml

root@kitploit:~
### PostgreSQL

SQLite es la opción predeterminada y funciona bien para implementaciones de un solo nodo. Para configuraciones de múltiples nodos o si prefieres una base de datos gestionada, cambia a Postgres:```yaml
database:
  driver: "postgres"
  url: "postgres://user:password@localhost:5432/proxy?sslmode=disable"

O mediante variables de entorno:```bash PROXY_DATABASE_DRIVER=postgres PROXY_DATABASE_URL=postgres://user:password@localhost:5432/proxy?sslmode=disable

root@kitploit:~
El proxy crea las tablas automáticamente en la primera ejecución.

### Almacenamiento S3

El proxy puede almacenar artefactos en caché en S3 o en cualquier servicio compatible con S3 (MinIO, R2, etc.) en lugar del sistema de archivos local.```yaml
storage:
  url: "s3://my-bucket-name?region=us-east-1"

Para servicios compatibles con S3 como MinIO:```yaml storage: url: "s3://my-bucket?endpoint=http://localhost:9000&disableSSL=true&s3ForcePathStyle=true"

root@kitploit:~
Configura las credenciales mediante las variables de entorno estándar de AWS (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`).

### Google Cloud Storage

El proxy puede almacenar artefactos en caché en un bucket de GCS utilizando el esquema de URL `gs://`.```yaml
storage:
  url: "gs://my-bucket-name"

La autenticación utiliza Application Default Credentials, lo que significa que no es necesario incrustar credenciales en la configuración ni en el entorno. Fuentes compatibles, en orden:

  • GKE Workload Identity — vincula la cuenta de servicio de Kubernetes que ejecuta el proxy a una cuenta de servicio de Google que tenga roles/storage.objectAdmin en el bucket. El proxy utilizará el token de la carga de trabajo automáticamente.
  • Cuenta de servicio adjunta en GCE, Cloud Run, Cloud Functions, etc.
  • Variable de entorno GOOGLE_APPLICATION_CREDENTIALS que apunta a un archivo de clave JSON de cuenta de servicio.
  • gcloud auth application-default login para desarrollo local.

Configuración de GKE Workload Identity```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

root@kitploit:~
#### Servicio directo (URL firmadas) con Workload Identity

Cuando `direct_serve: true` está habilitado, el proxy emite redirecciones HTTP 302 a URLs de GCS prefirmadas. Workload Identity no proporciona ninguna clave privada, por lo que el backend de GCS llama a la [API `signBlob` de IAM Credentials](https://docs.cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob). Otorga a la cuenta de servicio el rol de creador de tokens sobre sí misma:```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"

Comandos CLI

serve (predeterminado)

Inicia el servidor proxy. Este es el comando predeterminado si no se especifica ninguno.```bash proxy serve [flags] proxy [flags] # same as 'proxy serve'

root@kitploit:~
### mirror

Precarga la caché desde PURLs, archivos SBOM o registros completos. Útil para garantizar la disponibilidad sin conexión o calentar la caché antes de los despliegues.```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]

El comando mirror acepta los mismos flags de almacenamiento y base de datos que serve. Los artefactos ya en caché se omiten.

También hay disponible una API de mirror cuando el servidor está en ejecución:```bash

Start a mirror job

curl -X POST http://localhost:8080/api/mirror
-H "Content-Type: application/json"
-d '{"purls": ["pkg:npm/[email protected]"]}'

Start a mirror job from an inline CycloneDX or SPDX JSON SBOM

curl -X POST http://localhost:8080/api/mirror
-H "Content-Type: application/json"
-d '{"sbom":{"bomFormat":"CycloneDX","components":[{"purl":"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

root@kitploit:~
### stats

Muestra estadísticas de la caché sin ejecutar el servidor.```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

Ejemplo de salida:``` 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)

root@kitploit:~
## Endpoints de API

### Protocolos de Registro

| Endpoint | Descripción |
|----------|-------------|
| `GET /` | Panel de control (interfaz web) |
| `GET /health` | Verificación de estado y estado del circuit breaker upstream (JSON; HTTP 200 saludable, 503 no saludable) |
| `GET /stats` | Estadísticas de caché (JSON) |
| `GET /metrics` | Métricas de Prometheus |
| `GET /npm/*` | Protocolo de registro npm |
| `GET /cargo/*` | Protocolo de índice disperso de Cargo |
| `GET /gem/*` | Protocolo de RubyGems |
| `GET /go/*` | Protocolo de proxy de módulos de Go |
| `GET /hex/*` | Protocolo de Hex.pm |
| `GET /pub/*` | Protocolo de pub.dev |
| `GET /pypi/*` | API simple/JSON de PyPI |
| `GET /maven/*` | Protocolo de repositorio Maven |
| `GET /nuget/*` | API V3 de NuGet |
| `GET /composer/*` | Protocolo de Composer/Packagist |
| `GET /conan/*` | Protocolo de Conan C/C++ |
| `GET /conda/*` | Protocolo de Conda/Anaconda |
| `GET /cran/*` | Protocolo de CRAN (R) |
| `GET /julia/*` | Protocolo de servidor de paquetes de Julia |
| `GET /swift/*` | Protocolo de registro de paquetes de Swift v1 |
| `GET /helm/{repository}/*` | Protocolo de repositorio de charts de Helm HTTP |
| `GET /homebrew/*` | API JSON de Homebrew |
| `GET /v2/*` | Protocolo de registro OCI/Docker |
| `GET /v2/homebrew/core/*` | Manifiestos y blobs de botellas core de Homebrew desde GHCR |
| `GET /apk/{repository}/*` | Protocolo de repositorio APK de Alpine |
| `GET /generic/{name}/*` | Proxy de descarga HTTP genérico (recursos de lanzamiento de GitHub, mise/aqua) |
| `GET /debian/*` | Protocolo de repositorio Debian/APT |
| `GET /rpm/*` | Protocolo de repositorio RPM/Yum |

### API de Espejo

| Endpoint | Descripción |
|----------|-------------|
| `POST /api/mirror` | Iniciar un trabajo de espejo (cuerpo JSON con `purls` o un `sbom` en línea) |
| `GET /api/mirror/{id}` | Obtener el estado y el progreso del trabajo |
| `DELETE /api/mirror/{id}` | Cancelar un trabajo en ejecución |

### API de Enriquecimiento

El proxy proporciona endpoints REST para el enriquecimiento de metadatos de paquetes, el escaneo de vulnerabilidades y la detección de versiones obsoletas.

| Endpoint | Descripción |
|----------|-------------|
| `GET /api/package/{ecosystem}/{name}` | Obtener metadatos del paquete |
| `GET /api/package/{ecosystem}/{name}/{version}` | Obtener metadatos de la versión con vulnerabilidades |
| `GET /api/vulns/{ecosystem}/{name}` | Obtener todas las vulnerabilidades de un paquete |
| `GET /api/vulns/{ecosystem}/{name}/{version}` | Obtener vulnerabilidades de una versión específica |
| `POST /api/outdated` | Verificar múltiples paquetes en busca de versiones obsoletas |
| `POST /api/bulk` | Búsqueda masiva de metadatos de paquetes |

#### Obtener Metadatos del Paquete```bash
curl http://localhost:8080/api/package/npm/lodash

I need the actual content to translate. You've provided the instructions and metadata, but the INPUT section is empty — there's no Markdown text for chunk 143 to translate.

Please paste the source content for this chunk and I'll return the Spanish translation following all the rules above.```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" }

root@kitploit:~
#### Obtener versión con vulnerabilidades```bash
curl http://localhost:8080/api/package/npm/lodash/4.17.0

Response:```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" }

root@kitploit:~
#### Comprobar Paquetes Desactualizados```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"}
    ]
  }'

(empty)```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 } ] }

root@kitploit:~
#### Búsqueda masiva de paquetes```bash
curl -X POST http://localhost:8080/api/bulk \
  -H "Content-Type: application/json" \
  -d '{
    "purls": [
      "pkg:npm/[email protected]",
      "pkg:pypi/[email protected]"
    ]
  }'

(no content provided)```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" } } }

root@kitploit:~
### Respuesta de estadísticas (endpoint HTTP)```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"
}

Cómo funciona

  1. El gestor de paquetes solicita los metadatos del paquete al proxy
  2. El proxy obtiene los metadatos del upstream, reescribe las URL de los artefactos para que apunten al proxy
  3. El gestor de paquetes solicita el artefacto (tarball, crate, etc.)
  4. El proxy comprueba la caché local:
    • Acierto de caché: Sirve desde el almacenamiento local
    • Fallo de caché: Obtiene del upstream, lo almacena localmente y lo sirve al cliente
  5. Las solicitudes posteriores del mismo artefacto se sirven desde la caché``` ┌─────────────┐ ┌─────────┐ ┌──────────┐ │ npm/cargo │────▶│ proxy │────▶│ upstream │ │ client │◀────│ │◀────│ registry │ └─────────────┘ └─────────┘ └──────────┘ │ ▼ ┌─────────┐ │ cache │ │ storage │ └─────────┘
root@kitploit:~
## Interfaz Web

El proxy sirve una interfaz web bajo `/ui`. No se necesita una compilación de frontend separada -- las plantillas y los recursos están integrados en el binario. `GET /` redirige a `/ui/`. La interfaz está montada bajo su propio prefijo para que un proxy inverso pueda aplicar reglas de acceso diferentes a las de los endpoints de paquetes (por ejemplo, requerir autenticación para `PathPrefix(/ui)` mientras se dejan abiertos `/npm`, `/pypi`, etc. para las máquinas de compilación).

- **Panel** (`/ui/`) -- estadísticas de caché, paquetes populares, artefactos almacenados en caché recientemente y resumen de vulnerabilidades.
- **Guía de instalación** (`/ui/install`) -- instrucciones de configuración por ecosistema, para que no tengas que buscarlas aquí.
- **Explorador de paquetes** (`/ui/packages`) -- explora todos los paquetes en caché con filtrado por ecosistema y ordenación por hits, tamaño, nombre o número de vulnerabilidades.
- **Búsqueda** (`/ui/search?q=...`) -- busca paquetes en caché por nombre.
- **Detalle del paquete** (`/ui/package/{ecosystem}/{name}`) -- metadatos, licencia, vulnerabilidades y lista de versiones de un paquete. Puedes seleccionar dos versiones para compararlas.
- **Detalle de la versión** (`/ui/package/{ecosystem}/{name}/{version}`) -- metadatos por versión, hash de integridad, estado de la caché de artefactos y recuentos de hits.
- **Explorador de código fuente** (`/ui/package/{ecosystem}/{name}/{version}/browse`) -- explora los archivos dentro de los archivos comprimidos en caché con resaltado de sintaxis para archivos de texto y vistas previas de imágenes.
- **Diff de versiones** (`/ui/package/{ecosystem}/{name}/compare/{v1}...{v2}`) -- diff lado a lado de dos versiones en caché que muestra los archivos añadidos, eliminados y modificados.

## Monitorización

El proxy expone métricas de Prometheus en `GET /metrics`. Todos los nombres de las métricas llevan el prefijo `proxy_`.

| Métrica | Tipo | Etiquetas | Descripción |
|--------|------|--------|-------------|
| `proxy_requests_total` | counter | `ecosystem`, `status` | Respuestas del proxy por ecosistema de paquetes y estado HTTP |
| `proxy_request_duration_seconds` | histogram | `ecosystem`, `status` | Duración de las peticiones al proxy |
| `proxy_cache_hits_total` | counter | `ecosystem` | Aciertos de caché |
| `proxy_cache_misses_total` | counter | `ecosystem` | Fallos de caché |
| `proxy_cache_size_bytes` | gauge | | Tamaño total de los artefactos en caché |
| `proxy_cached_artifacts_total` | gauge | | Número de artefactos en caché |
| `proxy_upstream_fetch_duration_seconds` | histogram | `ecosystem` | Tiempo empleado en obtener datos del upstream |
| `proxy_upstream_errors_total` | counter | `ecosystem`, `error_type` | Fallos de obtención del upstream |
| `proxy_storage_operation_duration_seconds` | histogram | `operation` | Latencia de lectura/escritura del almacenamiento |
| `proxy_storage_errors_total` | counter | `operation` | Fallos de lectura/escritura del almacenamiento |
| `proxy_active_requests` | gauge | | Peticiones en curso |
| `proxy_health_probe_failures_total` | counter | `step` | Fallos de la sonda de salud del almacenamiento por paso fallido (`write`, `size`, `read`, `verify`, `delete`). |
| `proxy_circuit_breaker_state` | gauge | `registry` | Estado del cortacircuitos de obtención de artefactos por registro upstream (0 cerrado, 2 abierto). Se publica una vez que el cortacircuitos de ese registro ha saltado. |
| `proxy_circuit_breaker_trips_total` | counter | `registry` | Saltos del cortacircuitos por registro upstream. |

El tamaño de la caché y el recuento de artefactos se actualizan cada 60 segundos. El estado del cortacircuitos se lee del fetcher en cada scrape de `/metrics` y en cada petición a `/health`, por lo que `proxy_circuit_breaker_trips_total` cuenta los saltos visibles entre esas lecturas — un cortacircuitos que se abre y se recupera por completo entre dos scrapes no se cuenta. El resto de métricas se actualizan en cada petición.

Las métricas del cortacircuitos llevan una serie por host upstream, pero solo para los hosts cuyo cortacircuitos ha saltado al menos una vez desde el arranque. Se crea un cortacircuitos por cada host del que el proxy obtiene artefactos, y para algunos ecosistemas ese host proviene de los metadatos del upstream en lugar de la configuración (composer lo toma del `dist.url` de un paquete, helm de las URLs de los charts en `index.yaml`), por lo que publicar todos los hosts permitiría que el contenido del upstream hiciera crecer el número de series durante toda la vida del proceso. Una vez que un host ha saltado, sigue reportando, por lo que una recuperación sigue apareciendo como una transición a 0 en lugar de como una serie que desaparece. `/health` no es una serie temporal persistente y lista todos los cortacircuitos, hayan saltado o no.

La etiqueta `registry` es el host de la URL desde la que se obtuvo el artefacto. Como esa URL puede provenir de los metadatos del upstream, no siempre se puede extraer un host de ella — por ejemplo, un `dist.url` firmado que no se puede parsear — y en tal caso el cortacircuitos se etiqueta como `hostless-url-<digest>`, donde el digest se genera a partir de un valor obtenido en el arranque. Ni `/metrics` ni `/health` requieren autenticación, por lo que una URL de obtención nunca se publica como etiqueta ni como clave; el digest identifica el cortacircuitos mientras el proceso esté en ejecución sin revelar la URL que hay detrás ni permitir que una URL elegida se compare con él.

Alerta sobre `proxy_circuit_breaker_state == 2` sostenido durante más de unos minutos: mientras un cortacircuitos está abierto, las descargas de artefactos de ese upstream fallan con HTTP 502 en cada fallo de caché, y solo llega al upstream una única petición de sonda por intervalo de retroceso. Los artefactos en caché siguen sirviéndose, y también los metadatos del mismo ecosistema (los metadatos no pasan por el cortacircuitos), por lo que las instalaciones fallan de una forma que parece una interrupción parcial del upstream.

### Comprobación de Salud

`/health` devuelve un informe JSON estructurado del estado de los subsistemas. HTTP 200 si todas las comprobaciones pasan; 503 si alguna falla.```json
{
  "status": "ok",
  "checks": {
    "database": {"status": "ok"},
    "storage":  {"status": "ok"}
  },
  "circuit_breakers": {
    "registry.npmjs.org": "closed",
    "static.crates.io":   "open"
  }
}

Las comprobaciones fallidas incluyen un campo "error". Los fallos de almacenamiento también incluyen un campo "step" que identifica qué paso de la sonda falló (write, size, read, verify, delete). Cuando la comprobación de la base de datos falla, la entrada de almacenamiento informa {"status": "skipped"} para que la respuesta siempre contenga el mismo conjunto de claves.

circuit_breakers informa el estado del circuit breaker de obtención de artefactos de cada upstream ("open" o "closed"), indexado por host de upstream — o por el marcador hostless-url-<digest> descrito en Monitoring cuando la URL de obtención no tiene host que leer. La clave se omite hasta que el proxy haya obtenido un artefacto de al menos un upstream, y un host aparece solo una vez que se ha creado un breaker para él. Los breakers se disparan tras fallos repetidos del upstream y reintentan el upstream tras un backoff exponencial. Mientras uno está abierto, las descargas de artefactos para ese host devuelven HTTP 502 en un fallo de caché sin contactar al upstream; los artefactos ya en caché se siguen sirviendo desde el almacenamiento, ya que la caché se comprueba antes que el fetcher. Un breaker se informa como "open" durante todo su backoff, incluida la ventana half-open en la que admite una solicitud de sonda para probar la recuperación. El estado del breaker es por proceso y en memoria, por lo que un reinicio lo borra, pero no se necesita un reinicio para la recuperación: el backoff sigue reintentando mientras el breaker esté abierto, por lo que se cierra por sí solo una vez que el upstream vuelve a servir.

Un breaker abierto no establece status a "error" ni cambia el código de estado HTTP: informa de un upstream específico que se niega a servir, no de que este proxy no sea apto para recibir tráfico, y fallar la sonda de readiness por un upstream no saludable sacaría el pod de rotación también para todos los demás ecosistemas. Use proxy_circuit_breaker_state para alertar sobre ello.

Los resultados de la sonda de almacenamiento se almacenan en caché durante health.storage_probe_interval (por defecto 30s) para acotar el coste de sondear backends remotos. Una sonda mantiene un mutex interno durante hasta 10 segundos (el timeout por sonda codificado de forma fija), por lo que /health está pensado como una sonda de readiness de Kubernetes en lugar de una sonda de liveness — un ida y vuelta lento a S3 debería sacar el pod de rotación, no reiniciarlo.

Configuración de scrape para Prometheus:```yaml scrape_configs:

  • job_name: git-pkgs-proxy static_configs:
    • targets: ["localhost:8080"]
root@kitploit:~
## Despliegue en Producción

### Servicio Systemd

Crea `/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

Habilitar e iniciar:```bash sudo systemctl enable proxy sudo systemctl start proxy

root@kitploit:~
### Docker

Se incluye un Dockerfile en el repositorio. Compilar y ejecutar:```bash
docker build -t proxy .
docker run -p 8080:8080 -v proxy-data:/data proxy

Con Postgres y 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

root@kitploit:~
### Detrás de un Proxy Inverso

Cuando se ejecuta detrás de nginx, Apache u otro proxy inverso, configure `base_url` con su URL pública:```yaml
base_url: "https://proxy.example.com"

Si se accede a la interfaz de usuario a través de un nombre de host diferente al de los endpoints del paquete —por ejemplo, la interfaz de usuario expuesta públicamente en un dominio mientras las máquinas de compilación acceden a un alias de red de Docker—, configure ui_base_url por separado. base_url es la URL que utilizan los gestores de paquetes y la reescritura de metadatos; ui_base_url es la URL que se anuncia a las personas que visitan la interfaz web (etiquetas canonical/og:url y el banner de la guía de instalación):```yaml base_url: "http://pkg-proxy:8080" # internal alias for build machines ui_base_url: "https://proxy.example.com/ui" # public UI URL

root@kitploit:~
Cuando no se establece, `ui_base_url` toma por defecto el valor de `base_url`.

> **Advertencia:** el proxy sirve la UI y los endpoints de paquetes en el mismo listener. Establecer `ui_base_url` solo cambia la URL que la UI anuncia a los humanos; no impide que los endpoints de paquetes sean accesibles en el mismo hostname y puerto. Al poner el proxy detrás de un reverse proxy público, restringe la ruta pública a `PathPrefix(/ui)` (o el equivalente de tu proxy), de lo contrario `/npm`, `/pypi` y los demás endpoints de paquetes quedan expuestos junto con la UI.

Ejemplo de nginx, restringiendo el host público a la UI mientras se dejan los endpoints de paquetes accesibles solo en el listener interno:```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;
    }
}

Ejemplo de Traefik usando PathPrefix(/ui) para que el router público solo coincida con el tráfico de la UI:```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"

root@kitploit:~
## Gestión de Caché

El proxy almacena los artefactos en el directorio de almacenamiento configurado con esta estructura:```
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

Los metadatos de la caché se almacenan en SQLite (por defecto) o PostgreSQL. Para borrar una caché local:```bash rm -rf ./cache/artifacts/* rm ./cache/proxy.db

root@kitploit:~
El proxy recreará la base de datos en el próximo inicio.

## Compilar desde el código fuente

Requisitos:

- Go (la versión del proyecto se declara en `go.mod`)```bash
git clone https://github.com/git-pkgs/proxy.git
cd proxy
go build -o proxy ./cmd/proxy

Ejecutar pruebas:```bash go test ./...

root@kitploit:~
## Licencia

GPL-3.0-or-later
ChefChef✗
GenericAny✓
HelmKubernetes✓
VagrantVagrant✗