
Establece acceso remoto seguro a una máquina con shell interactivo, transferencia de archivos y proxy web a través de WebRTC peer-to-peer cifrado de extremo a extremo, usando un navegador o CLI sin reenvío de puertos ni cuentas.
BitBang CLI es una herramienta de acceso remoto multiusos en un único binario estático: abre un shell interactivo, navega y transfiere archivos, y accede a las aplicaciones web de la red de la máquina remota desde cualquier navegador, sin reenvío de puertos, sin configuración y sin cuenta.

En la máquina a la que quieres acceder:
curl -sSfL bitba.ng/install | sh
bitbang serve
serve imprime una URL. Ábrela en cualquier navegador y obtendrás una terminal, un explorador de archivos y un proxy a la red de esa máquina -- o conéctate desde otra terminal con bitbang connect <url> usando el mismo binario. La conexión está cifrada de extremo a extremo y es peer-to-peer; el servidor bitba.ng presenta los dos extremos y luego se hace a un lado.
bitbang es un único binario estático de Go. Forma parte del proyecto BitBang; este whitepaper cubre el diseño en profundidad.
Cuando no puedes pegar una URL ni escanear un código QR, como cuando estás al teléfono o a distancia de voz, bitbang serve también imprime un código de emparejamiento corto. La otra parte abre bitba.ng/<code> (o ejecuta bitbang connect <code>), su pantalla muestra un segundo número de 6 dígitos, y te lee ese número en voz alta. Tú lo escribes para aprobar. Un intermediario (machine-in-the-middle) no puede hacer que los dos números coincidan, y el emparejamiento guarda las credenciales de conexión del dispositivo para la próxima vez, p. ej. bitbang connect nas1. Si conoces Magic Wormhole, la forma es similar -- un código hablado que presenta dos máquinas de forma segura.

bitbang tiene la misma forma que ssh: serve, connect y cp se corresponden con sshd, ssh y scp, con WebRTC como transporte en lugar de TCP. Para una máquina a la que ya puedes acceder cómodamente por SSH, esa diferencia no te aporta mucho. Pero la mayor parte de bitbang surgió de molestias que parezco encontrarme más a menudo de lo que debería:
Alcance. El acceso SSH remoto necesita una ruta entrante, y en la mayoría de las redes abrir una no depende de ti -- CGNAT (móvil, Starlink, muchos ISP), corporativo, universitario, municipal. Así que en la práctica acoplas un segundo sistema: Tailscale, una VPN, ngrok -- otra instalación, otra cuenta, otro demonio que mantener en marcha. bitbang serve no necesita ningún puerto abierto y funciona desde cualquier lugar.
Configuración. SSH debe estar habilitado y configurado antes de dejarte entrar. Está deshabilitado por defecto en Raspberry Pi OS y a menudo es solo con claves, lo que significa que primero tienes que llevar tu clave pública a la máquina. ¿Y cómo lo haces? El correo electrónico o una memoria USB suelen ser las opciones menos dolorosas. bitbang establece la conexión con un intercambio de un código de 6 dígitos -- algo que puedes hacer con seguridad por teléfono, o gritando al otro lado de la habitación. También se ejecuta como un usuario normal -- sin root, sin demonio, sin archivo de configuración.
Proxy. Si quieres una aplicación web en la red de esa máquina, SSH te da un túnel separado por aplicación, nombrado de antemano. El proxy de bitbang es genérico: especifica la URL de la aplicación web en el momento de la conexión.
Cliente de navegador. SSH necesita un cliente SSH y una clave o contraseña en el lado que se conecta. bitbang necesita un navegador -- lo que significa un teléfono, un portátil prestado o alguien que nunca ha abierto una terminal. Entrégales la URL y obtienen el acceso que les has concedido.
bitbangCada conexión tiene dos extremos: un listener (bitbang serve, ejecutándose en la máquina a la que se accede) y un connector (un navegador, o la CLI de bitbang, en la máquina que realiza el acceso). Una URL de listener sirve para ambos tipos de connector.
bitbang servebitbang serve # everything: shell + files + proxy on one URL
bitbang serve shell # shell only
bitbang serve files ~/share # files only (add -upload to allow uploads)
bitbang serve proxy # proxy; pick the target in the browser
bitbang serve proxy localhost:8080 # ...or pin a single target
Cada uno imprime un código QR, una URL y un código de emparejamiento.
Abre la URL. Dependiendo de lo que se sirva, obtienes:
nas.local, 192.168.1.10:8080, localhost:3000/admin) y usa la aplicación como si estuvieras en local. Los inicios de sesión, las cookies, las subidas y el streaming funcionan todos.bitbang connect <url> # interactive shell
bitbang connect <url> -- tail -f /var/log/syslog # one-shot command
bitbang cp <url>:/var/log/app.log ./app.log # copy files, scp-style
bitbang cp - <url>:/tmp/firmware.bin < firmware.bin # stdin/stdout work too
Cada conexión o emparejamiento exitoso se guarda en ~/.bitbang/devices.json, así que a partir de entonces un nombre corto es suficiente: bitbang connect nas1.
El comando de una línea detecta tu arquitectura (amd64, arm64, armv7), descarga el binario de la última versión de GitHub, verifica su SHA-256 contra el checksums.txt de la versión y lo instala en ~/.local/bin/bitbang.
Fija una versión, cambia la ubicación o audita el script primero:
curl -sSfL bitba.ng/install | sh -s -- --version v0.5.0
curl -sSfL bitba.ng/install | sh -s -- --prefix /usr/local/bin
curl -sSfL bitba.ng/install -o install.sh && less install.sh && sh install.sh
Las compilaciones para macOS y Windows están en camino -- se han creado issues para cada una (macOS, windows); solo reacciona o comenta para mostrarme que te interesa. Instalación manual: descarga el binario desde Releases y colócalo en tu PATH. Compilar desde el código fuente: consulta más abajo.
bitba.ng/install es una redirección, no un script alojado. La cadena:
curl accede a https://bitba.ng/install, que hace un 302 a install.sh en este repositorio (en main).https://github.com/richlegrand/bitbang-cli/releases/latest/download/bitbang-linux-<arch>.checksums.txt de la misma versión y verifica el SHA-256 del binario.~/.local/bin (se puede cambiar).El script de instalación vive en este repositorio, junto al código que instala -- así puedes revisarlo junto al binario, y el host canónico bitba.ng solo posee la URL corta. Quienes se auto-alojen pueden apuntar el /install de su propio host al script que distribuyan: la variable de entorno INSTALL_URL del servidor de señalización controla el destino de la redirección (vacía → 404).
bitbang genera un par de claves RSA en ~/.bitbang/<program>/; el UID del dispositivo se deriva de la clave pública, por lo que suplantar un dispositivo implica encontrar una segunda preimagen de su UID.#…), que los navegadores nunca envían -- bitba.ng media la conexión sin ver jamás la credencial que la autoriza.--pin) para configuraciones permanentes o headless, y modo desechable (-ephemeral) para una identidad nueva en cada ejecución.Cómo se autentican mutuamente los dos extremos sin confiar en el servidor de señalización se explica en detalle aquí: Señalización sin confianza: autenticación sin una autoridad central.
Las banderas aceptan cualquiera de las dos formas (-pin o --pin). Las banderas booleanas están desactivadas por defecto salvo que se indique lo contrario.
bitbang serve [flags] All capabilities: shell + files + proxy on one URL
bitbang serve shell [flags] Shell only
bitbang serve files [PATH] [flags] Files only (PATH defaults to cwd)
bitbang serve proxy [TARGET] [flags] HTTP/WebSocket reverse proxy (TARGET pins one host:port)
bitbang connect <target> [-- cmd …] Client shell (interactive or one-shot)
bitbang cp <src> <dst> Copy files (one side is <URL>:/path, or '-')
bitbang version Print version (also --version)
bitbang help Usage (also --help, -h)
bitbang serve -- ejecutar un listenerBanderas compartidas (las cuatro formas de serve):
Banderas de Shell (serve y serve shell):
Banderas de Files:
| Forma | Ruta | Bandera de subida |
|---|---|---|
serve (todas las capacidades) | -files PATH (por defecto cwd) | -files-upload |
(Avanzado: -video-fd N pasa un FD de socketpair heredado a un helper de video externo; para uso interno/embebido.)
bitbang connect <target> [-- command …] -- shell de cliente<target> puede ser cualquiera de estos:
nas1; resuelto desde la tabla de hosts conocidos (ver más abajo)482731; ejecuta el flujo de emparejamiento y luego conectahttps://bitba.ng/<id>#<code>, bitba.ng/<id>#<code> o solo <id>#<code>Sin -- command, abre un shell interactivo (una PTY cuando stdin es una terminal). Con -- command args…, ejecuta ese único comando de forma no interactiva y sale con su estado de salida (las salidas por señal informan 128).
bitbang cp <src> <dst> -- copiar archivosExactamente uno de <src> / <dst> es remoto, escrito como <URL>:/path (URL en cualquier forma aceptada por connect). - significa stdin/stdout, así que cp <URL>:/f - transmite a stdout y cp - <URL>:/f sube desde stdin. Un / o . final en el lado local conserva el nombre base remoto (estilo scp).
Cada conexión o emparejamiento exitoso se recuerda en ~/.bitbang/devices.json (modo 0600), para que puedas reconectar con un nombre corto en lugar de una URL o un código:
bitbang connect 482731 -name nas1 # pair once, save it as "nas1"
bitbang connect nas1 # thereafter, just the name
-name NAME elige el nombre; solo se aplica a un host nuevo. Sin él, se asigna e imprime un nombre automático (device1, device2, …) (Saved as "device1".).- o _. Eso garantiza que nunca pueda confundirse con un código de 6 dígitos ni con una URL. Las búsquedas y la unicidad no distinguen entre mayúsculas y minúsculas.bitbang connect nas1 -name nas2 se rechaza -- -name es solo para guardados de la primera vez.{name, uid, access_code, server, paired_at}. Reconectar un host conocido (por nombre o URL) lo actualiza en su lugar y conserva el nombre.Requiere Go 1.25+. Go puro, enlazado estáticamente (CGO_ENABLED=0) -- compilación cruzada trivial, sin dependencias de ejecución.
go build ./cmd/bitbang/
# cross-compile:
GOOS=linux GOARCH=arm64 go build -o bitbang-arm64 ./cmd/bitbang/
GOOS=linux GOARCH=arm GOARM=7 go build -o bitbang-armv7 ./cmd/bitbang/
GOOS=windows GOARCH=amd64 go build -o bitbang.exe ./cmd/bitbang/
GOOS=darwin GOARCH=arm64 go build -o bitbang-macos ./cmd/bitbang/
Disponible hoy: shell, files y proxy, accesibles desde el navegador o la CLI, además de copia de archivos estilo scp y emparejamiento ad-hoc con una tabla de dispositivos guardada. Diseñado y en camino:
/dev/ttyUSB0 remoto desde un puerto virtual local (p. ej. ejecutar Arduino IDE a través de internet). Se ha abierto un issue aquí.-L 5432:db.internal:5432 para alcanzar servicios solo disponibles en la LAN. Se ha abierto un issue aquí.MIT -- consulta LICENSE.
Se aceptan issues y PRs.
| ngrok | Cloudflare Tunnel | Tailscale | bitbang |
|---|
| Cuenta requerida | Sí | Sí | Sí | No |
| Instalación en el lado que se conecta | No | No | Sí | No (navegador) |
| Cifrado de extremo a extremo | No por defecto | No | Sí | Sí |
| Ruta de datos | Sus servidores | Sus servidores | P2P | P2P |
| Servidor auto-alojable (código abierto) | No | No | No (Headscale es de terceros) | Sí |
| Configuración antes del primer uso | Cuenta + authtoken | Cuenta + DNS | Cuenta + inicio de sesión en cada dispositivo | Ejecuta un comando |
| Flag | Default | Descripción |
|---|
-server HOST | bitba.ng | Nombre de host del servidor de señalización |
-pin PIN | (ninguno) | Exigir este PIN para las conexiones |
-ephemeral | off | Identidad temporal (una URL nueva en cada ejecución) |
-nocode | off | Deshabilitar el emparejamiento por intercambio de código -- no se emite ningún código de 6 dígitos; la URL sigue funcionando. Úsalo para listeners headless/no-TTY que no pueden completar el prompt de SAS. |
-program NAME | bitbang | Nombre de identidad; el par de claves se guarda en ~/.bitbang/<NAME>/identity.pem |
-target HOST:PORT | (dinámico) | Objetivo del proxy fijo (modo proxy); vacío = elegir el objetivo en el navegador. serve proxy host:port es una abreviatura de esto. |
-v | off | Registro detallado (verbose) (añade la superposición !debug en el navegador) |
| Flag | Default | Descripción |
|---|
-shell-cmd CMD | $SHELL o /bin/sh | Shell a iniciar |
-shell-max-sessions N | 1 | Máximo de sesiones de shell concurrentes (0 = ilimitado) |
-shell-mirror | on | Reflejar la salida del shell en la consola del listener |
serve files [PATH] | PATH posicional (por defecto cwd) | -upload |
| Flag | Default | Descripción |
|---|
-name NAME | (auto) | Recordar este host bajo NAME (solo hosts nuevos; asigna automáticamente device<N> si se omite) |
-relay | off | Solicitar un relé TURN desde el principio en lugar de solo en la caída (ICE sigue prefiriendo una ruta directa si alguna tiene éxito) |
-pin PIN | (prompt) | PIN a enviar si el listener lo requiere (omite el prompt interactivo) |
-timeout DUR | 30s | Tiempo de espera de dial (p. ej. 45s, 1m) |
-server HOST | bitba.ng | Servidor de señalización -- solo en modo código de emparejamiento; la forma de URL lleva su propio host |
-v | off | Registro detallado (verbose) |
| Flag | Default | Descripción |
|---|
-relay | off | Solicitar un relé TURN desde el principio (como en connect) |
-pin PIN | (prompt) | PIN a enviar si se requiere |
-timeout DUR | 30s | Tiempo de espera de dial |
-v | off | Registro detallado (verbose) |