
Proxy bastión SSH de confianza cero con gestión de claves respaldada por Vault, aplicación de políticas RBAC, grabación completa de sesiones y TUI de administración para acceso auditable a infraestructura de producción.
Un bastión SSH autohospedado y endurecido con gestión de claves respaldada por Vault, aplicación de políticas RBAC, grabación completa de sesiones y una TUI administrativa interactiva — diseñado para equipos que necesitan acceso auditable y de confianza cero a la infraestructura de producción.
Los equipos de ingeniería modernos necesitan una forma de dar a los desarrolladores el acceso mínimo requerido para hacer su trabajo — ni más, ni menos. La distribución tradicional de claves SSH es propensa a errores: las claves se comparten, se olvidan en los portátiles y se revocan demasiado tarde.
ZTTP resuelve esto actuando como la única puerta hacia tu infraestructura:
Portátil del Desarrollador
│
│ zttp
│ (Internamente: SSH en el puerto 2224)
▼
┌─────────────────────────────────────────────────────────┐
│ Proxy ZTTP │
│ │
│ ① Puerta de Autenticación — TUI de inicio de sesión bcrypt/Argon2id │
│ ② Motor RBAC — verificación de política consciente del entorno │
│ ③ Obtención de Vault — recuperación efímera de claves SSH │
│ ④ Puente — túnel TCP transparente │
│ ⑤ Escritor de Auditoría — grabador de tramas ttyrec │
└──────────┬──────────────────────────────────────────────┘
│ ssh (IP privada, clave efímera)
▼
Servidor de Destino
Servicios de infraestructura (Docker Compose):
.ttyrec con tramas con marca de tiempoServidor (host del proxy):
2224make (opcional, pero recomendado)Desarrollador (cliente):
ssh)git clone https://gitlab.com/Nihal799/zttp.git
cd zttp
cp .env.example .env
Edita .env y establece como mínimo:
PROXY_NODE_IP=<ip-publica-de-tu-servidor>
POSTGRES_PASSWORD=<una-contraseña-fuerte>
VAULT_TOKEN=<un-token-de-vault-fuerte>
⚠️ Nunca hagas commit de tu archivo
.env. Está listado en.gitignore.
make docker-up
# o directamente:
docker compose -f deploy/docker-compose.yml up -d --build
make docker-ps
curl http://localhost:8080/healthz
make release PROXY_ADDR=<ip-de-tu-servidor>:2224
Esto compila de forma cruzada los clientes para todas las plataformas y actualiza automáticamente dist/install.sh y dist/install.ps1 con la URL correcta del servidor. El contenedor Nginx sirve estos archivos en http://<ip-de-tu-servidor>:8555/.
curl -fsSL http://<ip-del-proxy>:8555/install.sh | bash
irm http://<ip-del-proxy>:8555/install.ps1 | iex
Una vez instalado, conéctate a la puerta de enlace ZTTP:
zttp
# o directamente:
ssh -p 2224 <tu-nombre-de-usuario>@<ip-del-proxy>
Se te presentará una pantalla de inicio de sesión de terminal. Después de la autenticación, verás una lista de servidores a los que estás autorizado a acceder.
Toda la configuración se realiza mediante variables de entorno (o archivo .env). Consulta .env.example para la referencia completa.
ZTTP utiliza un modelo basado en roles. A cada usuario se le asigna un rol; cada rol tiene una política que define a qué entornos de servidores puede acceder.
Los roles y las asignaciones de servidores se gestionan a través de la Consola de Administración (ver más abajo). El motor RBAC realiza todas las verificaciones en una sola consulta PostgreSQL — nunca expone por qué se denegó el acceso al cliente (protección contra enumeración).
Conéctate al servidor zttp-admin desde el menú de la puerta de enlace, o inicia sesión con una cuenta que tenga el rol security-admin.
La Consola de Administración proporciona:
Todas las acciones administrativas se registran en
admin-actions.logdentro del volumen de auditoría.
Todas las sesiones se almacenan en el volumen Docker zttp-audit-logs (/var/log/zttp/audit/ dentro del contenedor).
security-adminCtrl+C para volver# Listar grabaciones
sudo ls /var/lib/docker/volumes/zttp-audit-logs/_data/
# Reproducir una grabación con ttyplay
sudo ttyplay /var/lib/docker/volumes/zttp-audit-logs/_data/<id-de-sesión>.ttyrec
# Leer el registro de acciones administrativas
sudo cat /var/lib/docker/volumes/zttp-audit-logs/_data/admin-actions.log
Requisitos: Go 1.25+, Docker (para compilación cruzada)
# Compilar proxy + CLI para la plataforma actual
make build
# Compilación cruzada del CLI para todas las plataformas (Linux, macOS, Windows)
make release PROXY_ADDR=<ip-del-proxy>:2224
# Ejecutar pruebas
make test
# Ejecutar proxy localmente (requiere Postgres + Vault ya en ejecución)
make run-proxy
(Haz clic para reproducir la demo)
(Haz clic para reproducir la demo)
(Haz clic para reproducir la demo)
(Haz clic para reproducir la demo)
(Haz clic para reproducir la demo)
zttp/
├── cmd/
│ ├── proxy/ # Punto de entrada del servidor proxy
│ └── zttp/ # Punto de entrada del cliente CLI
├── db/
│ └── migrations/ # Migraciones de esquema de PostgreSQL
├── deploy/
│ ├── docker-compose.yml
│ ├── Dockerfile.proxy
│ └── vault-seed.sh # Siembra claves SSH de prueba en Vault
├── dist/
│ ├── install.sh # Script de instalación para Linux/macOS
│ └── install.ps1 # Script de instalación para Windows
├── internal/
│ ├── audit/ # Registro de acciones administrativas
│ ├── auth/ # Autenticación de usuarios (bcrypt, bloqueo)
│ ├── cli/ # TUI del cliente CLI y lógica de conexión
│ ├── config/ # Configuración basada en entorno
│ ├── killswitch/ # Servicio gRPC de interruptor de emergencia
│ ├── proxy/ # Proxy SSH, TUI de puerta de enlace, TUI administrativa, puente
│ ├── rbac/ # Motor de control de acceso basado en roles
│ ├── ratelimit/ # Limitación de velocidad por IP
│ ├── session/ # Seguimiento de sesiones y almacenamiento en BD
│ └── vault/ # Cliente de claves SSH de HashiCorp Vault
├── proto/ # Definiciones de protocolo gRPC
├── tools/
│ └── hashpw/ # Herramienta CLI: generar hash de contraseña bcrypt
├── .env.example # Plantilla de configuración
├── go.mod
└── Makefile
git checkout -b feat/tu-característicamake testPor favor, no hagas commit de:
.env o cualquier archivo que contenga secretoszttp en la raíz está en .gitignore)Este proyecto es propietario. Todos los derechos reservados.
Construido con Go, PostgreSQL, HashiCorp Vault y Docker.
| Problema | Solución ZTTP |
|---|
| Claves SSH compartidas en portátiles | Las claves viven solo en HashiCorp Vault — nunca en disco |
| Sin visibilidad de quién hizo qué | Cada pulsación de tecla se graba en formato .ttyrec |
| Acceso generalizado a producción | El motor de políticas basado en roles aplica reglas por entorno |
| Sin forma de detener una sesión activa | Endpoint gRPC de interrupción que termina cualquier sesión en vivo |
| Acceso opaco para auditores | TUI administrativa con reproducción de sesiones, registros de texto y registros de acciones administrativas |
| Servicio | Propósito |
|---|
zttp-proxy | El bastión SSH (binario Go) |
zttp-postgres | Base de datos del plano de control (usuarios, servidores, políticas RBAC) |
zttp-vault | HashiCorp Vault — almacena las claves privadas SSH |
zttp-nginx | Sirve los instaladores CLI en /release/ |
zttp-init-audit | Contenedor de un solo uso que corrige los permisos de volumen |
| Variable | Valor por Defecto | Descripción |
|---|
PROXY_LISTEN_ADDR | 0.0.0.0:2222 | Dirección de enlace del proxy SSH |
HTTP_LISTEN_ADDR | 0.0.0.0:8080 | Dirección HTTP de verificación de salud |
GRPC_LISTEN_ADDR | 0.0.0.0:9090 | Dirección gRPC del interruptor de emergencia |
PROXY_NODE_IP | 127.0.0.1 | IP externa integrada en los binarios CLI |
DATABASE_URL | postgres://zttp:... | Cadena de conexión de PostgreSQL |
VAULT_ADDR | http://localhost:8201 | URL del servidor Vault |
VAULT_TOKEN | dev-root-token-zttp | Token raíz de Vault (solo desarrollo — usa AppRole en producción) |
MAX_FAILED_ATTEMPTS | 5 | Umbral de bloqueo |
LOCKOUT_DURATION | 15m | Duración del bloqueo de cuenta |
RATE_LIMIT_PER_MIN | 10 | Máximo de intentos de inicio de sesión por minuto por IP |
AUDIT_LOG_DIR | /var/log/zttp/audit | Ruta del directorio de grabación de sesiones |
SOC_WEBHOOK_URL | (vacío) | Webhook opcional para alertas del SOC |
| Rol | Acceso |
|---|
security-admin | Acceso completo a todos los entornos + Consola de Administración |
sre-tier1 | Todos los entornos, incluida producción |
sre-tier2 | Solo puesta en escena y desarrollo |
dev | Solo entorno de desarrollo |
readonly | Entorno de desarrollo, conjunto de comandos restringido |
| Opción de Menú | Descripción |
|---|
| Agregar Usuario | Crear un nuevo usuario con asignación de rol |
| Agregar Servidor | Registrar un servidor de destino (hostname, IP, entorno, usuario SSH) |
| Gestionar Acceso a Servidores | Otorgar o revocar acceso de usuarios a servidores específicos |
| Ver Usuarios | Listar todos los usuarios y sus roles |
| Ver Servidores | Listar todos los servidores registrados |
| Ver Registros de Auditoría | Explorar sesiones, reproducir grabaciones, leer registros de texto |
| [ Atrás ] | Volver a la puerta de enlace de servidores |
| Comando | Descripción |
|---|
make build | Compilar proxy y CLI para la plataforma actual |
make release | Compilación cruzada de binarios CLI para todas las plataformas |
make release-docker | Compilación cruzada dentro de un contenedor Docker (evita problemas de snap/WSL) |
make docker-up | Iniciar todos los servicios de Docker Compose |
make docker-down | Detener todos los servicios y eliminar volúmenes |
make docker-logs | Seguir los registros del proxy |
make docker-ps | Mostrar el estado de los contenedores |
make test | Ejecutar todas las pruebas Go |
make migrate | Aplicar migraciones de base de datos |
make seed | Sembrar datos de desarrollo |
make hashpw PW=micontraseña | Generar un hash bcrypt para la siembra manual de la base de datos |
make clean | Eliminar binarios compilados y caché de compilación |
| Capa | Mecanismo |
|---|
| Transporte | Todas las conexiones de clientes son SSH (cifradas en tránsito) |
| Autenticación | bcrypt (costo 12) / Argon2id — el texto plano está estructuralmente prohibido en el esquema |
| Protección contra fuerza bruta | Bloqueo de cuenta (5 intentos / 15 min) + limitador de velocidad por IP |
| Autorización | Consulta RBAC de un solo JOIN — las denegaciones son siempre genéricas ("Permiso denegado") |
| Gestión de secretos | Las claves privadas SSH se almacenan exclusivamente en HashiCorp Vault, obtenidas efímeramente |
| Pista de auditoría | Grabación completa de pulsaciones de teclas en formato .ttyrec, registro administrativo inmutable de solo anexión |
| Aislamiento de procesos | El proxy se ejecuta como no root (UID 65532) dentro de un contenedor distroless |
| Interruptor de emergencia | Cualquier sesión en vivo puede terminarse vía gRPC sin reiniciar el proxy |