Del japonés 降ろす (órosu) — «descargar», «desembarcar».
El Problema
Los sistemas de CI son buenos construyendo software y malos entregándolo. Llevar un artefacto de compilación desde un pipeline hasta una máquina de producción suele reducirse a uno de varios patrones conocidos pero frágiles:
- Claves privadas SSH copiadas en los secretos de CI y repartidas por cada pipeline y repositorio que necesita desplegar
- Scripts SFTP/rsync copiados de un proyecto a otro, cada uno con sus propios pequeños errores
- Rutas y permisos codificados que se rompen en cuanto cambia la estructura de un servidor
- Servidores de producción directamente accesibles desde los runners de CI, ampliando la superficie de ataque con cada pipeline
- Proliferación de secretos, que convierte la rotación de una sola clave comprometida en una auditoría de todos los repositorios que podrían referenciarla
Nada de esto es específico de una plataforma de CI/CD en particular — es la forma por defecto de "ejecutar un script en una máquina remota desde un pipeline", y el riesgo se acumula con cada proyecto que la adopta.
Cómo lo Resuelve Orosu
Orosu se instala una vez en la máquina de destino como orosu-server y convierte el despliegue en una solicitud acotada y autenticada en lugar de una sesión SSH abierta:
- CI compila la aplicación — un binario, una imagen de contenedor, archivos estáticos, lo que sea que produzca el pipeline
- CI dispara una tarea a través de una conexión WebSocket, adjuntando archivos si es necesario
orosu-serverautentica la solicitud usando firmas Ed25519 — sin contraseñas ni secretos compartidos en tránsitoorosu-serverejecuta un script predefinido — uno de un conjunto fijo configurado en el servidor, nunca un comando arbitrario enviado por CI- El script despliega, usando los archivos y argumentos que la tarea adjuntó
Sin SSH directo, sin malabares de credenciales por pipeline y sin más superficie del lado del servidor que los scripts específicos que un operador ha configurado explícitamente.
Instalación
orosu-server y su CLI complementaria orosu-keygen se distribuyen como paquetes de Debian/Ubuntu desde un repositorio apt:
curl -fsSL https://packages.nerdy.pro/NerdyPro.gpg | sudo gpg --dearmor -o /usr/share/keyrings/nerdy-pro.gpg
echo "deb [signed-by=/usr/share/keyrings/nerdy-pro.gpg] https://packages.nerdy.pro/ stable main" | sudo tee /etc/apt/sources.list.d/nerdy-pro.list
sudo apt update
sudo apt install orosu
GitHub Releases también publica binarios precompilados de orosu-server y orosu-keygen directamente, para máquinas donde no se puede añadir un repositorio apt.
Primeros Pasos
Genera un par de claves de cliente con orosu-keygen, desde /etc/orosu:
orosu-keygen --name my-ci-client --private-key-output my-ci-client.key --public-key-output my-ci-client.pub
La clave pública va en la configuración del servidor; la clave privada se convierte en un secreto de CI.
Configura el servidor en /etc/orosu/orosu-server.toml — una dirección de escucha y la clave pública del cliente:
listen:
tcp: "127.0.0.1:8081"
clients:
- name: my-ci-client
secret_file: /etc/orosu/my-ci-client.pub
Un servidor escuchando en localhost normalmente está detrás de un proxy inverso que termina TLS y reenvía las actualizaciones de WebSocket — el README documenta una configuración de nginx para esto.
Define un script que el cliente tiene permitido disparar:
#!/bin/bash
echo "Hello, $1!"
clients:
- name: my-ci-client
secret_file: /etc/orosu/my-ci-client.pub
scripts:
- name: test-script
command:
- "bash"
- "/etc/orosu/scripts/test.sh"
Dispáralo desde CI con la GitHub Action complementaria, pasando la dirección del servidor y la clave privada del cliente como secretos:
- name: Remotely execute a script
uses: orosu-ci/orosu@v0
with:
address: ${{ secrets.OROSU_SERVER_URL }}
script: test-script
key: ${{ secrets.OROSU_CLIENT_KEY }}
arguments: "from CI pipeline"
Cifrado de Extremo a Extremo
WSS/:termTLS cubre la conexión, pero cuando TLS se termina en un proxy inverso frente a orosu-server — la configuración estándar de arriba — los argumentos del script, los archivos subidos y la salida en streaming quedan en texto plano en ese proxy. Un protocolo opcional de cifrado de extremo a extremo (X25519 + HKDF-SHA256 + ChaCha20-Poly1305) cierra esa brecha:
orosu-keygen --kind server --private-key-output server.key --public-key-output server.pub
La clave pública del servidor se añade a su configuración y se entrega a CI como el parámetro server_key de la Action. La actualización es opcional y aditiva de forma independiente en ambos extremos — un servidor con el cifrado configurado sigue sirviendo a los clientes que omiten server_key exactamente igual que antes, y no se requiere una migración coordinada.
Seguridad
La seguridad es una restricción de diseño de primer orden, no un añadido posterior:
- Autenticación criptográfica — cada tarea se firma con la clave Ed25519 del cliente; no hay contraseña ni secreto compartido en la conexión que un atacante pueda interceptar.
- Un conjunto cerrado de acciones — CI solo puede disparar scripts que un operador haya predefinido explícitamente en el servidor. No existe una ruta desde una tarea de CI hasta un comando de shell arbitrario.
- Manejo reforzado de adjuntos — los nombres de entrada de los zip se validan contra path traversal, y tanto el número de entradas como el tamaño descomprimido total tienen límite, de modo que un adjunto manipulado o desmesurado no puede salirse de su directorio de extracción ni agotar el disco.
- Cifrado en profundidad — el protocolo opcional de cifrado de extremo a extremo verifica ataques de low-order-point en su intercambio X25519, además de la confidencialidad que ya proporciona.
- Permisos de archivo seguros por defecto —
orosu-keygenescribe los archivos de claves privadas con permisos0600sin importar el umask vigente.
Estas protecciones llegaron en la versión 0.7.0 como una actualización directa — sin cambios de configuración, CLI ni protocolo. Consulta CHANGELOG.md para el historial completo de versiones.
Licencia
Orosu está licenciado bajo Apache-2.0.