
Ejecute cualquier comando dentro de una vista restringida del sistema de archivos en Linux.
⚠️ PROYECTO DEPRECADO
El desarrollo de este proyecto se ha detenido porque otra persona estaba trabajando en la misma idea y construyó una solución mejor.
Recomendamos encarecidamente visitar: Fence by Use-Tusk.Nota: Este repositorio fue creado originalmente para FOSS HACK 2026, aunque desafortunadamente no pudimos completarlo a tiempo.
Sin embargo, construimos un proyecto similar para Hackathena '26 que ganó el 3er premio!
Si estás interesado, puedes encontrar ese repositorio aquí: A56-A5/lion.
Cordon ejecuta cualquier comando dentro de una vista restringida del sistema de archivos en Linux. Usa namespaces de Linux (a través de bubblewrap) para ocultar todo lo que tu proceso no necesita — tu directorio home, llaves SSH, credenciales de AWS, todo — mientras sigue permitiendo que el comando haga su trabajo.
cordon run --net=allow -- npm install
cordon run -- bash setup.sh
cordon run --profile python -- pip install -r requirements.txt
Sin root. Sin contenedores. Sin demonios ejecutándose en segundo plano.
Cuando ejecutas npm install o pip install, ese código se ejecuta con todos tus permisos de usuario. Puede leer ~/.ssh/id_rsa, extraerlo a un servidor, modificar archivos que te pertenecen — todo mientras parece que solo está instalando un paquete.
Esto no es paranoia. Ha sucedido:
La respuesta de Cordon: no dejes que el proceso vea lo que no debería, incluso si el código es malicioso.
Cada cordon run crea un entorno aislado nuevo:
/usr, /bin, /lib se montan en solo lectura — las cosas pueden ejecutarse, no rompen el sistemanpm install crea node_modules/, las compilaciones funcionansrc/ está en solo lectura si existe — los archivos fuente no pueden ser reescritos silenciosamente~/.ssh, ~/.aws, HOME — no se montan en absoluto por defecto--net=allowCuando el proceso termina, el sandbox desaparece. Nada persiste.
El modo --net=allow inicia un proxy HTTP/HTTPS integrado en Rust en un puerto localhost aleatorio y lo inyecta en el sandbox a través de vars de entorno (HTTP_PROXY, https_proxy, npm_config_proxy, etc.). Intercepta túneles CONNECT y verifica cada dominio contra una lista blanca antes de reenviar.
La lista blanca por defecto incluye registry.npmjs.org, pypi.org, crates.io, github.com. Cualquier cosa que no esté en la lista recibe un 403 — incluso si el script postinstall del paquete intenta contactar a su hogar.
# Only reaches npmjs.org and its CDNs — nothing else
cordon run --net=allow -- npm install
# Add a domain for a private registry
cordon run --net=allow --domain my.internal.registry -- npm install
Opcionalmente, agrega un filtro de llamadas al sistema:
# Blocks ptrace, kexec_load, mount, perf_event_open, process_vm_*
cordon run --seccomp basic --net=allow -- npm install
# Strict allowlist — only known-safe syscalls
cordon run --seccomp strict -- python3 untrusted.py
Esta es una segunda línea de defensa. Incluso si algo escapa de la restricción del sistema de archivos, todavía no puede llamar a ptrace para adjuntarse a otro proceso o perf_event_open para trabajo de canal lateral.
git clone https://github.com/LORDv1shnu/Cordon
cd Cordon
bash install.sh # builds release binary → ~/.local/bin/cordon
O manualmente:
cargo build --release
cp target/release/cordon ~/.local/bin/
Necesitas tener bubblewrap instalado:
sudo apt install bubblewrap # Ubuntu/Debian
sudo dnf install bubblewrap # Fedora
sudo pacman -S bubblewrap # Arch
Primera ejecución después de instalar:
cordon scan # scans your system once, takes ~30s, writes ~/.config/cordon/system.toml
cordon check # sanity check — makes sure everything's ready
# The basics
cordon run -- echo "hello"
cordon run --net=allow -- npm install
cordon run --net=allow -- pip install -r requirements.txt
cordon run --net=full -- curl https://example.com # unrestricted (no filtering)
# Seccomp
cordon run --seccomp basic --net=allow -- npm install
# GUI apps
cordon run --gui -- code .
cordon run --gui --optional audio_pipewire --optional dbus_session -- discord
# Built-in profiles (pre-configured for common runtimes)
cordon run --profile node -- npm install
cordon run --profile python -- python3 script.py
cordon run --profile rust -- cargo build
# Debug what's being blocked
cordon run --trace -- node server.js # strace wrapper, reports denied paths
cordon add --from-trace ~/.config/cordon/logs/last-trace.log # batch-add missing paths
# Resource limits (needs systemd)
cordon run --mem 512M --cpu 2.0 --timeout 60 -- npm install
# Dry run / verbose
cordon run --dry-run -- npm install # print the bwrap command, don't run it
cordon run --verbose -- npm install # print each bwrap arg as it runs
cordon.toml)cordon init # auto-detects Cargo.toml / package.json / pyproject.toml
cordon set --net=allow # persist flags so you don't type them every time
cordon add /path/to/assets --mode ro # expose extra paths into the sandbox
cordon edit # open cordon.toml in $EDITOR
cordon check # health check: bwrap, namespaces, AppArmor, modules
cordon doctor # deeper: kernel version, distro quirks, exact fix suggestions
cordon status # show what's in system.toml right now
cordon list # show every mount that would be active on next run
cordon log --errors # tail the last run's log, errors only
cordon syscalls --preset basic # list what each seccomp preset blocks
# Named profiles (stored in ~/.config/cordon/profiles.toml)
cordon profile create ci-node --net=allow --optional ld_so_cache
cordon run --profile ci-node -- npm test
# Lockfile for reproducible environments
cordon lock update # SHA-256 all mount paths → cordon.lock
cordon lock verify # check nothing drifted
# Share sandbox config with the team
cordon export > sandbox.json
cordon import sandbox.json
# Tab completions
cordon completions zsh > ~/.zfunc/_cordon
# Transparent wrappers — make "npm" always run sandboxed
cordon wrap npm
cordon wrap pip
npm install # actually runs: cordon run -- npm install "$@"
cordon unwrap npm
# Man page
cordon man | man -l -
Hay cuatro archivos de configuración, aplicados en este orden:
Las banderas de CLI siempre ganan. cordon.toml supera a un perfil nombrado. El core.toml integrado en el binario no se puede modificar en tiempo de ejecución.
Misma convención que bwrap y el shell.
Cordon no es un contenedor, no es un antivirus y no reemplaza a SELinux o AppArmor. Restringe la visibilidad del sistema de archivos y el acceso a la red — no intenta detectar malware. Si algo tiene un exploit del kernel, escapará. El objetivo es hacer que los ataques a la cadena de suministro sean significativamente más difíciles, no imposibles.
Además: actualmente solo Linux x86_64 y aarch64. Se requiere bubblewrap.
Construido en Rust. Usa bubblewrap para namespacing, seccompiler para compilación de filtros BPF, clap para CLI, tracing para registro estructurado. El proxy de filtrado de dominios está escrito desde cero en Rust puro (sin herramienta proxy externa).
→ COMMANDS.md — referencia completa de banderas
→ SCANNER_LOGIC.md — cómo funciona el escáner del sistema
→ MODULE_INFO.md — cada archivo fuente explicado
Construido con asistencia de IA (Gemini). Arquitectura, modelo de seguridad y decisiones de diseño son trabajo del autor.
| Ataque | Qué hizo |
|---|
| LiteLLM (2024) | Paquete malicioso de PyPI que leyó llaves SSH y variables de entorno en pip install |
| xz-utils (2024) | Puerta trasera en tiempo de compilación inyectada a través del paso make durante la instalación |
| event-stream (npm, 2018) | Paquete npm comprometido que robó silenciosamente billeteras Bitcoin |
| SolarWinds | Ataque a la cadena de suministro a través del pipeline de compilación/actualización |
| Capa | Dónde | Quién la escribe |
|---|
core.toml | compilado en el binario | no editable en tiempo de ejecución (a prueba de manipulaciones) |
system.toml | ~/.config/cordon/ | cordon scan |
profiles.toml | ~/.config/cordon/ | cordon profile create |
cordon.toml | directorio del proyecto | cordon init / cordon set / cordon add |
| Código | Significado |
|---|
| 0 | éxito |
| 1 | error interno de cordon |
| 2 | uso incorrecto de CLI |
| 125 | falló la configuración del sandbox (bwrap faltante, etc.) |
| 126 | comando encontrado pero no ejecutable dentro del sandbox |
| 127 | comando no encontrado dentro del sandbox |
| N | reenviado desde el proceso en sandbox |