
Mensajero cifrado peer-to-peer en Rust con Noise IK y UDP NAT hole punching
Chat peer-to-peer cifrado de extremo a extremo sobre UDP. Sin cuentas, sin servidor central que retransmita/almacene mensajes, sin intermediarios. Solo dos pares, una conexión directa y cifrado mediante el protocolo Noise.
https://github.com/user-attachments/assets/939e96d3-45e3-4484-9a27-28c3a0457b05
Dos personas ejecutan punchline connect <peer> en sus máquinas. Punchline atraviesa sus NATs, realiza un handshake cifrado y los introduce en un chat privado, todo en milisegundos. Los servidores STUN y de señalización incluidos manejan el descubrimiento y luego se apartan.

cargo build --release
Inicia los servidores (en una máquina a la que ambos pares puedan acceder), o usa los públicos que tengo alojados en 64.225.107.28 (STUN: puerto 3478, señalización: puerto 8743):
punchline-stund # STUN server - tells peers their public IP
punchline-signald # Signal server - matches peers who want to talk
En la máquina de cada par:
# Generate your identity (X25519 keypair)
punchline keygen
# Share your public key with your peer
punchline pubkey
# Save their key
punchline peers add alice a1b2c3d4...64_hex_chars
# Connect (both peers run this, targeting each other)
punchline connect alice --stun <server>:3478 --signal <server>:8743
La TUI se inicia con una vista en vivo del progreso de conexión:
Descubrimiento STUN - resolviendo tu dirección externa mediante punchline-stund
Servidor de señalización - conectándose a punchline-signald
Esperando al par - el servidor de señalización empareja a ambos pares
Perforación de NAT - estableciendo la ruta UDP directa
Handshake Noise - intercambio de claves cifrado
Una vez completado, estás en el chat. Escribe y presiona Enter. Presiona Esc para salir.
El sistema completo consta de tres binarios, todos incluidos en este repositorio:
| Binario | Rol | Cuándo se usa |
|---|---|---|
punchline-stund | Servidor STUN (UDP) - responde con la IP:puerto externa del cliente | Solo durante la configuración |
punchline-signald | Servidor de señalización (WebSocket) - empareja pares e intercambia direcciones | Solo durante la configuración |
punchline | El mensajero en sí - CLI, TUI, criptografía, perforación de NAT | Siempre |
Después de la configuración inicial, ya no se contacta a los servidores STUN y de señalización. Todo fluye directamente entre pares.
punchline| Comando | Descripción |
|---|---|
keygen [--force] [-i path] | Genera un nuevo par de claves de identidad X25519. Usa --force para sobrescribir sin preguntar. Usa -i para especificar la ruta de salida. |
pubkey [-i path] | Imprime tu clave pública (64 caracteres hexadecimales). Usa -i para derivar de un archivo de clave específico. |
connect <peer> [-i path] [--stun addr] [--signal addr] | Conéctate a un par por alias o clave hexadecimal directa. Usa -i para especificar la clave de identidad. Inicia la TUI. |
peers | Lista todos los pares conocidos. |
peers add <name> <key> | Guarda la clave pública de un par bajo un apodo. |
peers remove <name> | Elimina un par por apodo. |
config path | Imprime la ruta del archivo de configuración. |
config show | Muestra los valores de configuración actuales. |
status | Muestra identidad, configuración, accesibilidad del servidor y número de pares. |
completions <shell> | Genera completados de shell (bash, zsh o fish). |
Banderas globales:
| Bandera | Descripción |
|---|---|
-v | Aumenta la verbosidad del registro (-v = debug, -vv = trace). |
-q, --quiet | Suprime toda la salida de registro. |
punchline-stund| Bandera | Descripción |
|---|---|
--address <addr> | Dirección de enlace (por defecto: 0.0.0.0). |
--port <port> | Puerto de enlace (por defecto: 3478). |
-v / -vv | Registro debug / trace. |
-q | Modo silencioso. |
punchline-signald| Bandera | Descripción |
|---|---|
--address <addr> | Dirección de enlace (por defecto: 0.0.0.0). |
--port <port> | Puerto de enlace (por defecto: 8743). |
-v / -vv | Registro debug / trace. |
-q | Modo silencioso. |
En lugar de pasar --stun y --signal cada vez, crea ~/.config/punchline/config.toml:
stun_server = "203.0.113.10:3478"
signal_server = "203.0.113.10:8743"
punchline peers # list all
punchline peers add alice a1b2c3d4... # add
punchline peers remove alice # remove
Los alias se almacenan en ~/.punchline/known_peers.toml. También puedes conectarte directamente con una clave hexadecimal de 64 caracteres.
punchline status
Muestra tu identidad, configuración, accesibilidad del servidor (envía una sonda STUN real y una conexión TCP) y número de pares.
Ambos servidores soportan -v (debug), -vv (trace), -q (quieto), --address y --port:
punchline-stund -v --port 3478
punchline-signald -v --port 8743
Personaliza la TUI a través de ~/.config/punchline/style.toml
Estilos usados en el vídeo:
[colors]
my_text = "#ebdbb2"
peer_text = "#bdae93"
input_text = "#ebdbb2"
border = "#ebdbb2"
sidebar_key = "#ebdbb2"
sidebar_value = "#bdae93"
[padding]
chat_horizontal = 2
chat_vertical = 1
Todos los colores son RGB hexadecimal. Si el archivo no existe, se usan los colores predeterminados del terminal.
punchline completions bash > ~/.local/share/bash-completion/completions/punchline
punchline completions zsh > ~/.zfunc/_punchline
punchline completions fish > ~/.config/fish/completions/punchline.fish
Nombre completo del protocolo: Noise_IK_25519_ChaChaPoly_SHA256