Saltar al contenido
v0.1.0Instaladores nativos para Windows y Linux ya disponibles

Un mouse. Un teclado.
Todas tus máquinas.

IonConnect es la alternativa moderna a Barrier e Input Leap, reescrita en Rust. Mové el cursor hasta el borde de la pantalla y seguí trabajando en la otra computadora — con el mismo teclado y el mismo portapapeles.

MIT · sin telemetría · sin cuenta · sin servidores en la nube

sesión activa · TLS 1.3 mutuo
ubuntu-desk · X11

$ ionconnect-core

rol=servidor puerto=44890

peer win-lab autenticado

borde derecho → hand-off

win-lab · Windows 11
portapapeles sincronizado
teclado remoto activo

100%

Rust

11 crates, sin unsafe suelto

TLS 1.3

mutuo + TOFU

ambos extremos se verifican

~250 Hz

de movimiento

canal UDP cifrado aparte

0

servidores externos

todo vive en tu LAN

Qué es IonConnect

Tus computadoras, un solo escritorio

Tenés una torre con Linux y una laptop con Windows en el mismo escritorio, y dos teclados peleando por el espacio. IonConnect convierte los bordes de tus pantallas en puertas: movés el cursor hacia la derecha y aparece en la otra máquina, con el teclado siguiéndolo.

Sin KVM por hardware

Nada de switches, cables ni dongles. El "cable" es tu red local y el software que ya corre en las dos máquinas.

Sin escritorio remoto

No mirás la pantalla de la otra máquina: cada una usa su propio monitor. Solo viajan el mouse, el teclado y el portapapeles.

Sin la nube en el medio

Las máquinas hablan directo entre ellas por la LAN. No hay cuenta, ni relay, ni telemetría, ni nada que se suba a ningún lado.

Antes

Barrier / Input Leap

  • C++ heredado de Synergy, con mantenimiento a tirones
  • Configurar la pantalla vecina a mano en cada equipo
  • Cifrado opcional y frágil de configurar
  • Todos los eventos por el mismo canal TCP

Ahora

IonConnect

  • Rust, arquitectura hexagonal, un crate por responsabilidad
  • GUI de escritorio: pegás el ID del vecino y elegís el borde
  • TLS 1.3 mutuo obligatorio, confianza por huella (TOFU)
  • UDP cifrado dedicado para el movimiento, TCP para el resto

Funciones

Todo lo que necesitás para trabajar entre máquinas

Cada pieza vive en su propio crate y se prueba contra recursos reales — TLS real sobre loopback, X11 real bajo Xephyr, servidor y cliente corriendo en paralelo.

Mouse y teclado compartidos

La máquina con el teclado físico captura los eventos crudos (XI2 sobre el dispositivo maestro) y los enruta al equipo vecino. El cambio ocurre al tocar el borde de pantalla que vos definís: izquierda, derecha, arriba o abajo.

Portapapeles sincronizado

Copiás en un equipo y pegás en el otro. Un loop-guard evita el rebote clásico: lo que acaba de llegar del vecino no se vuelve a difundir como si fuera un cambio local.

TLS 1.3 mutuo con TOFU

Los dos extremos presentan certificado y se validan por huella SHA-256. La confianza se fija en el primer emparejamiento y cualquier cambio posterior se rechaza como posible MITM.

Descubrimiento mDNS

El cliente puede encontrar al servidor solo en la LAN, sin que le dictes una IP. Si preferís fijarla, ponés host:puerto y listo.

Movimiento por UDP cifrado

El flujo continuo del cursor va por un canal UDP propio con clave derivada del handshake TLS. Sensible a latencia, tolerante a pérdida: sin cabeza de línea bloqueando el clic.

Multi-monitor real

La geometría del escritorio virtual se modela completa, con coordenadas negativas incluidas (en Windows los monitores a la izquierda del primario las usan). El cliente informa su resolución real al conectarse.

Panel de control de escritorio

Una app Tauri nativa muestra el ID del equipo, deja pegar el de los vecinos con su borde, y arranca o detiene el núcleo. Sin editar archivos si no querés.

Configuración en caliente

Un TOML con watcher: agregás un peer o cambiás el rol y se aplica sin reiniciar. Un TOML inválido se descarta con una advertencia en vez de tumbar el servicio.

Reconexión automática

Backoff exponencial, heartbeat con número de secuencia para medir RTT, y liberación forzada de teclas y botones que quedaron presionados al cortarse la sesión.

Corre en segundo plano

En Linux queda instalado un servicio systemd de usuario, así el núcleo sigue vivo aunque cierres la ventana. Logs en vivo con journalctl.

Cómo funciona

De tu mano al otro escritorio, en un salto

Un evento de teclado recorre seis etapas antes de aparecer en la otra máquina. Cada una es un crate independiente, con sus propias pruebas.

  1. 01

    Definís quién manda

    El equipo que tiene el mouse y el teclado físicos es el servidor; los demás son clientes y solo reciben. Se elige en la GUI o con una línea del TOML.

  2. 02

    Se emparejan por huella

    Cada instalación genera su propio certificado. Al conectarse, ambos extremos comparan la huella SHA-256 del otro y la fijan (TOFU). Desde ahí, cualquier certificado distinto se rechaza.

  3. 03

    Dibujás el escritorio

    A cada equipo vecino le asignás un borde de tu pantalla: izquierda, derecha, arriba o abajo. Eso arma el layout que usa la máquina de estados del hand-off.

  4. 04

    Movés el mouse y ya

    Al cruzar el borde, el cursor local se oculta y se confina, y los eventos empiezan a enrutarse al vecino. Volvés por el borde opuesto y el control regresa.

Ruta de un evento

< 1 ms en LAN
  • 01inputCapturaXI2 crudo sobre el dispositivo maestro
  • 02screenGeometríaescritorio virtual + bordes
  • 03coreHand-offdecide ForwardTo / ReturnLocal
  • 04protocolSerializaciónprotocolo binario de wire
  • 05networkTransporteTCP+TLS · UDP cifrado
  • 06inputInyecciónXTEST · Win32 · portal Wayland
TCP + TLS 1.3

Todo lo que no se puede perder: clics, teclas, portapapeles, autenticación, heartbeat, geometría de pantalla.

UDP cifrado

Solo el movimiento del cursor. Clave derivada del handshake TLS, número de secuencia como nonce y como filtro de frescura contra reordenamientos y replays.

Plataformas

Dónde corre hoy, y con qué rol

Cualquier plataforma soportada puede ser cliente. El rol de servidor —el equipo que capta el mouse y el teclado físicos— por ahora requiere Ubuntu con X11.

  • Ubuntu / Debian

    X11

    Servidor
    Cliente

    Camino completo y el más probado: captura con detección de borde vía XI2, inyección por XTEST.

  • Ubuntu / Debian

    Wayland

    ServidorTodavía no
    Cliente

    Recibe e inyecta por el portal RemoteDesktop. En GNOME se prefiere XTEST vía XWayland, que es más rápido que el ida y vuelta por D-Bus.

  • Windows 11

    Win32

    ServidorTodavía no
    Cliente

    Recibe e inyecta con la API nativa. Instalador .exe y .msi firmados por el pipeline de CI.

  • macOS

    ServidorTodavía no
    ClienteTodavía no

    Todavía no hay backend. Está en el roadmap; el resto del stack es independiente del sistema operativo.

Mezclá lo que tengas: un servidor Ubuntu X11 puede tener a la vez un cliente Windows a la derecha y otro Linux arriba. Los peers se enrutan en abanico desde el mismo proceso.

Instalación

Instalalo en menos de un minuto

Los instaladores los compila GitHub Actions en máquinas que ya tienen todo: no necesitás Rust, ni Visual Studio, ni ninguna dependencia de compilación.

Windows 11

Bajá el ejecutable de la última release, instalá y listo. No hace falta compilar nada.

  • IonConnect_0.1.0_x64-setup.exe
  • IonConnect_0.1.0_x64_en-US.msi
Ir a Releases

Ubuntu / Debian

Paquete .deb, o AppImage portable si preferís no instalar nada en el sistema.

terminal
sudo apt install ./ionconnect_0.1.0_amd64.deb

# o, portable:
chmod +x IonConnect_0.1.0_amd64.AppImage
./IonConnect_0.1.0_amd64.AppImage

En los dos casos, ionconnect-core se descarga de la misma release y queda en el PATH (en Linux alcanza con~/.local/bin).

Uso

Cuatro pasos y ya estás cruzando pantallas

Podés hacerlo todo desde la ventana del panel de control, o editar el TOML a mano: el archivo se recarga en caliente, sin reiniciar nada.

01

Abrí la GUI en cada equipo

Corré ionconnect-gui y copiá el «ID de este equipo» que muestra arriba.

02

En el equipo con el teclado físico

Dejá el rol en Servidor y agregá cada vecino pegando su ID y eligiendo de qué lado está.

03

En los demás equipos

Cambiá el rol a Cliente y poné la dirección ip:puerto del servidor.

04

Arrancá el núcleo

Corré ionconnect-core, primero en el servidor. Mové el mouse hacia el borde configurado y el control pasa al vecino.

Ejemplos de configuración

Un TOML parcial o de una versión anterior sigue cargando: los campos que falten toman su valor por defecto. Si guardás un TOML inválido durante la recarga en caliente, se descarta con una advertencia y sigue valiendo la configuración anterior.

servidor · config.toml
# ~/.config/ionconnect/config.toml — el equipo con el teclado físico
device_name  = "ubuntu-desk"
listen_port  = 44890
role         = "server"
log_level    = "info"

discovery_enabled = true
pairing_mode      = "auto-trust-on-first-use"

[[peers]]
device_id = "b7f3a1c2-…-9de4"   # el ID que muestra la GUI del vecino
edge      = "right"             # left | right | up | down

[[peers]]
device_id = "0a19cc84-…-51fb"
edge      = "up"
cliente · config.toml
# ~/.config/ionconnect/config.toml — el equipo que recibe
device_name = "win-lab"
role        = "client"

# host:puerto del servidor. Omitilo para descubrirlo
# solo por mDNS dentro de la LAN.
server_address = "192.168.1.40:44890"

pairing_mode = "auto-trust-on-first-use"

Correr en segundo plano (Linux)

systemd --user
# el instalador deja el servicio listo, pero sin arrancar
systemctl --user start ionconnect-core.service
systemctl --user status ionconnect-core.service
journalctl --user -u ionconnect-core.service -f

Si usás el servicio, no toques el botón «Conectar» de la GUI en esa misma máquina: los dos compiten por el mismo puerto y fallan.

Emparejar a mano

huellas
# la huella de este equipo, para pegarla del otro lado
openssl x509 -in ~/.config/ionconnect/identity.crt \
  -outform DER | sha256sum

# almacén de confianza: un SHA-256 en hex por línea,
# sin salto de línea final
cat ~/.config/ionconnect/trusted_fingerprints

Agregá la huella con un editor, no con echo: el archivo se escribe sin salto de línea final y anexar así corrompe la última entrada.

La configuración por defecto no empareja sola

El TLS acá es mutuo: los dos extremos tienen que confiar en la huella del otro. Comopairing_mode = "reject-unknown" viene por defecto y el almacén arranca vacío, dos instalaciones nuevas nunca se emparejan: el cliente queda en bucle concertificado desconocido rechazado (posible MITM). Ponéauto-trust-on-first-use en el lado que tiene que aprender, o pegá la huella a mano.

Arquitectura

Once crates, una responsabilidad cada uno

Workspace de Cargo con arquitectura limpia: las dependencias fluyen en una sola dirección y ningún crate sabe más de lo que necesita. La lógica pura —hand-off, geometría, repetición de teclas— no conoce ni X11 ni sockets.

Pruebas contra recursos reales

Handshakes TLS de verdad sobre loopback, X11 real bajo Xephyr, inotify real, y un par servidor+cliente corriendo en paralelo. Se prefiere el test de integración al mock.

Lints estrictos de fábrica

clippy::all y clippy::pedantic activos en todo el workspace, más unsafe_op_in_unsafe_fn como advertencia.

Compilación condicional por sistema

Los caminos Unix y Windows están detrás de sus cfg; agregar un backend nuevo no toca el orquestador.

Cargo.toml · workspace members
  • 01sharedTipos comunes (DeviceId, KeyModifiers)
  • 02protocolProtocolo binario de wire: mensajes, encode/decode
  • 03cryptoTLS 1.3 mutuo + confianza TOFU por huella
  • 04networkTransporte tokio: framing, heartbeat, reconexión, mDNS, UDP
  • 05inputCaptura e inyección por sistema: X11, Win32, portal Wayland
  • 06screenGeometría multi-monitor y bordes — lógica pura, sin E/S
  • 07clipboardSincronización de portapapeles con prevención de bucles
  • 08configTOML con recarga en caliente: rol, peers, puerto, emparejamiento
  • 09ipcCanal local GUI↔core autenticado por token
  • 10coreOrquestador: servidor (capta y enruta) y cliente (recibe e inyecta)
  • 11guiAplicación Tauri: el panel de control

Seguridad

Tu input nunca sale de tu red

Un programa que ve cada tecla que apretás tiene que ser aburrido de auditar. Por eso el modelo es simple: dos máquinas, un certificado cada una y ningún tercero en el medio.

handshake

cliente → hola + certificado

servidor → certificado + verifica huella

cliente → verifica huella + Authentication

servidor → ¿DeviceId en peers?

sesión abierta · clave UDP derivada

  • TLS 1.3 mutuo, no opcional

    No hay modo «sin cifrar». Los dos extremos presentan certificado y los dos validan al otro; una conexión sin identidad válida no llega a autenticarse.

  • Confianza fijada en el primer contacto

    La huella SHA-256 del certificado del vecino se guarda en ~/.config/ionconnect/trusted_fingerprints. Si mañana cambia, la conexión se rechaza como posible MITM.

  • Dos puertas, no una

    Después del handshake, el servidor rechaza a cualquier equipo cuyo DeviceId no esté en su lista de peers. Una huella confiada, por sí sola, no alcanza para recibir input.

  • El canal UDP hereda esa identidad

    Su clave sale de export_keying_material del propio TLS — sin ronda extra — y el número de secuencia sirve de nonce y de filtro: los datagramas viejos o repetidos se descartan.

Roadmap

Qué está listo y qué viene

IonConnect está funcional de punta a punta: dos instancias reales, TLS mutuo, autenticación y hand-off de mouse. Esto es lo que sigue.

Ya funciona

10
  • Protocolo binario + criptografía TLS/TOFU
  • Transporte de red (tokio) + discovery mDNS
  • Captura e inyección de entrada (X11 completo; Windows y Wayland como cliente)
  • Geometría multi-monitor y hand-off de cursor
  • Sincronización de portapapeles
  • Configuración persistente con hot-reload, rol y peers
  • IPC local GUI↔core
  • GUI Tauri: rol, peers con lado de pantalla, ID copiable
  • Binario core: capta → red → inyecta, de punta a punta
  • CI que publica instaladores nativos por plataforma

En camino

6
  • Servidor (captura) en Windows y Wayland
  • Intercambio real de geometría de pantalla al conectar
  • Backend de captura Wayland nativo (wlroots / ext-input-capture-v1)
  • Transferencia de archivos y portapapeles de imágenes
  • Ventana de emparejamiento en la GUI
  • Soporte macOS
Proponé o reclamá una

Preguntas frecuentes

Lo que suelen preguntar

¿Es lo mismo que un escritorio remoto tipo VNC o RDP?

No. En un escritorio remoto ves la pantalla de la otra máquina dentro de una ventana. Acá cada computadora sigue usando su propio monitor y sus propios programas: lo único que viaja por la red es el mouse, el teclado y el portapapeles.

¿Necesito internet?

No. Las máquinas se hablan directo dentro de tu red local. No hay cuenta, ni relay, ni servidor intermedio, ni telemetría — si desconectás el router del módem, IonConnect sigue funcionando igual.

¿Puedo poner Windows como servidor?

Todavía no. Windows y Wayland ya funcionan perfecto como clientes (reciben e inyectan input), pero la captura con detección de borde solo está implementada para X11. El servidor —el equipo con el teclado físico— tiene que ser Ubuntu con X11 por ahora.

¿Cuántos equipos puedo conectar?

Los que quieras. El servidor mantiene una conexión por peer y enruta en abanico; a cada uno le asignás el borde de pantalla que le corresponde. Un cliente Windows a la derecha y otro Linux arriba, por ejemplo.

¿Por qué el cliente dice «certificado desconocido rechazado»?

Porque la configuración por defecto es reject-unknown y el almacén de confianza arranca vacío: dos instalaciones nuevas no pueden emparejarse solas. Poné pairing_mode = "auto-trust-on-first-use" en el lado que tiene que aprender la huella del otro, o agregá la huella a mano en trusted_fingerprints.

¿Se nota el retardo al escribir?

En una LAN, no. Los eventos discretos (teclas y clics) van por TCP+TLS con prioridad sobre el movimiento, y la inyección corre desacoplada del bucle de red, así que una tecla nunca espera detrás de una ráfaga de movimiento del cursor.

¿Y si las pantallas tienen resoluciones distintas?

El cliente informa su geometría real al conectarse y el servidor reemplaza la que asumía. El hand-off funciona bien como máquina de estados; el punto exacto de reingreso puede correrse un poco si las resoluciones son muy distintas — el intercambio completo de geometría está en el roadmap.

¿Qué licencia tiene?

MIT. El código está entero en GitHub, se puede leer, forkear, auditar y usar en el trabajo sin pedir permiso.

Dejá de mirar dos teclados en el mismo escritorio

Instalalo en las dos máquinas, pegá un ID, elegí un borde. En un minuto estás cruzando pantallas con el mismo mouse.

o pegá esto en tu terminal
curl -fsSL https://raw.githubusercontent.com/millerbermeo/ion/main/install.sh \
  | bash