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.
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
$ ionconnect-core
rol=servidor puerto=44890
peer win-lab autenticado
borde derecho → hand-off
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
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.
Nada de switches, cables ni dongles. El "cable" es tu red local y el software que ya corre en las dos máquinas.
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.
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
Ahora
Funciones
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
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 LANTodo lo que no se puede perder: clics, teclas, portapapeles, autenticación, heartbeat, geometría de pantalla.
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
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
Camino completo y el más probado: captura con detección de borde vía XI2, inyección por XTEST.
Ubuntu / Debian
Wayland
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
Recibe e inyecta con la API nativa. Instalador .exe y .msi firmados por el pipeline de CI.
macOS
—
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
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.
Bajá el ejecutable de la última release, instalá y listo. No hace falta compilar nada.
Paquete .deb, o AppImage portable si preferís no instalar nada en el sistema.
sudo apt install ./ionconnect_0.1.0_amd64.deb
# o, portable:
chmod +x IonConnect_0.1.0_amd64.AppImage
./IonConnect_0.1.0_amd64.AppImageEn los dos casos, ionconnect-core se descarga de la misma release y queda en el PATH (en Linux alcanza con~/.local/bin).
Uso
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.
Corré ionconnect-gui y copiá el «ID de este equipo» que muestra arriba.
Dejá el rol en Servidor y agregá cada vecino pegando su ID y eligiendo de qué lado está.
Cambiá el rol a Cliente y poné la dirección ip:puerto del servidor.
Corré ionconnect-core, primero en el servidor. Mové el mouse hacia el borde configurado y el control pasa al vecino.
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.
# ~/.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"# ~/.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"# 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 -fSi 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.
# 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_fingerprintsAgregá 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.
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
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.
Seguridad
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
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.
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.
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.
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
IonConnect está funcional de punta a punta: dos instancias reales, TLS mutuo, autenticación y hand-off de mouse. Esto es lo que sigue.
Preguntas frecuentes
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.
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.
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.
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.
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.
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.
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.
MIT. El código está entero en GitHub, se puede leer, forkear, auditar y usar en el trabajo sin pedir permiso.
Instalalo en las dos máquinas, pegá un ID, elegí un borde. En un minuto estás cruzando pantallas con el mismo mouse.
curl -fsSL https://raw.githubusercontent.com/millerbermeo/ion/main/install.sh \
| bash