POLITICA DE COOKIES

Q2BSTUDIO.COM utiliza cookies técnicas, analíticas, de sesión y de publicidad con la finalidad de prestar un mejor servicio. No obstante, necesitamos su consentimiento explícito para poder utilizarlas. Así mismo puede cambiar la configuración de las cookies u obtener más información aquí .

Servidor SSH mínimo en Go

## Guía rápida para crear un servidor SSH mínimo en Go

Publicado el 02/09/2025

SSH es un protocolo que permite acceso remoto seguro y administración de sistemas sobre redes no confiables. Utiliza criptografía para autenticar y cifrar las conexiones entre dispositivos, lo que lo convierte en una pieza crítica de la infraestructura de internet moderna.

Como a muchos ingenieros, me ha acompañado en el día a día para abrir terminales remotas, gestionar máquinas y automatizar tareas. Aun así, durante mucho tiempo quise entender en profundidad cómo funciona SSH por dentro, más allá del uso habitual con OpenSSH.

Mi experiencia era principalmente como usuario, ejecutando comandos, configurando reenvío de puertos y ajustando el archivo sshd_config cuando hacía falta. Ese efecto casi mágico de escribir un comando y conectarte a otra máquina me llevó a investigar qué sucede tras bambalinas.

Cuando aprendo algo nuevo suelo combinar teoría y práctica: primero documentación, artículos o un curso, y después un pequeño proyecto que me obligue a afianzar conceptos con las manos en la masa. En este texto comparto cómo construí un servidor SSH minimalista como proyecto de fin de semana y qué decisiones técnicas tomé por el camino.

Si solo quieres el código, el repositorio está disponible en GitHub en JoDaUT go-ssh-server. Allí encontrarás un README con instrucciones para compilar y usar la aplicación. Además, incluyo reflexiones de ingeniería y compromisos de alcance propios de un experimento con tiempo limitado, útiles si estás estudiando o iniciándote en el desarrollo.

Por qué un servidor SSH y no un cliente. Construir un cliente también habría sido interesante, pero me atraía crear un servicio que pudiera ejecutarse en segundo plano y gestionarse con herramientas como systemd en Linux. Por eso me enfoqué en el lado servidor del protocolo y en comprender el flujo de mensajes esencial que hace posible la conexión.

Panorama de canales y solicitudes en SSH. SSH se ejecuta sobre TCP y soporta múltiples tipos de canal, cada uno con un propósito. Session es el más común y sirve para shells remotos, ejecución de comandos y subsistemas. X11 se usa para redirigir aplicaciones gráficas. forwarded-tcpip implementa el reenvío local de puertos y direct-tcpip el reenvío remoto. OpenSSH incorpora extensiones como direct-streamlocal@openssh.com y forwarded-streamlocal@openssh.com para reenviar sockets de tipo Unix.

El canal session es el que recibe solicitudes. Entre las más habituales están pty-req para solicitar un pseudo terminal, shell para iniciar una sesión interactiva, exec para ejecutar un único comando, subsystem para servicios como sftp, x11-req para reenvío X11, env para variables de entorno, window-change para cambios de tamaño de ventana, signal para enviar señales POSIX, y las notificaciones del servidor exit-status y exit-signal con el resultado o la señal de finalización.

Alcance del proyecto y enfoque técnico. El objetivo fue desarrollar un servidor SSH mínimo con soporte para dos casos de uso: ejecutar un comando remoto y abrir un shell interactivo. Con el cliente de OpenSSH puedes, por ejemplo, ejecutar ssh usuario@ip echo hola mundo para un comando único, u omitir el comando para iniciar una shell interactiva escribiendo ssh usuario@ip. El servidor debe cerrar la sesión correctamente cuando termina el comando o cuando el usuario sale del shell.

Autenticación. SSH admite autenticación por contraseña y por clave pública. Aunque parezca más simple, la contraseña exige manejar prompts interactivos, lo que complica el mínimo producto. Elegí autenticación por clave pública. Basta con generar un par de claves y proveer un archivo authorized_keys con las claves públicas permitidas. El usuario debe indicar su clave privada con ssh -i ruta_a_la_clave usuario@direccion. Importante: el cliente no envía la clave privada al servidor, sino que demuestra su posesión a través de un intercambio criptográfico utilizando la clave pública derivada.

Configuración del servidor. En lugar de replicar por completo el archivo de OpenSSH sshd_config, opté por un YAML sencillo leído al inicio con parámetros básicos como interfaz y puerto de escucha, y la lista de usuarios autorizados.

Control de acceso. Implementé un modelo basado en allowlist mediante un parámetro authorized_users en la configuración. El servidor valida que el usuario exista en el sistema consultando el archivo del sistema de cuentas, que tenga directorio home y shell por defecto, y utiliza un único archivo authorized_keys definido en la configuración. Esto implica que varias cuentas podrían autenticarse con la misma clave si la poseen.

Concurrencia. El servidor debe permitir múltiples clientes simultáneos. Aunque prescindí de un pool de hilos o planificación avanzada, la arquitectura está preparada para manejar sesiones concurrentes desde el inicio.

Pruebas. Cubrí al menos los escenarios esenciales: conexión con clave válida, rechazo de usuarios desconocidos o claves no autorizadas, ejecución de un comando único, apertura de shell interactiva y manejo de conexiones simultáneas.

Lenguaje. Implementado en Go, una elección natural para herramientas de línea de comandos, programación de sockets y servicios residentes. Go ofrece librerías sólidas de red y concurrencia, y al ser compilado, su despliegue es simple y eficiente.

Fase de codificación. Dado que solo necesitaba comandos y shell interactiva, implementé exclusivamente el canal session y las solicitudes exec, shell y pty-req. Ignoré el resto de tipos de canal para mantener el foco en el núcleo funcional.

Pasos de alto nivel. El servidor lee la configuración con usuarios permitidos, dirección y puerto, y recopila uid, gid, home y shell del usuario. Inicializa el servidor SSH y carga la clave privada de host, similar a las que OpenSSH guarda en la carpeta de configuración del sistema. Abre un listener TCP en la interfaz y puerto indicados, acepta solo canales session, maneja exec, shell y pty-req, ejecuta los comandos devolviendo la salida y, en sesiones interactivas, usa la información de pty-req para arrancar la shell con un pseudo terminal adecuado.

Retos técnicos. Hubo que gestionar correctamente stdout y stderr sin bloquear el flujo, para lo cual utilicé goroutines separadas que transmiten datos al cliente. Detecté errores al parsear claves por un formato incorrecto en authorized_keys. La gestión de PTY fue especialmente delicada, incluyendo adjuntar la shell a un pseudo terminal y el manejo de señales y modos, que quedaron parcialmente pendientes. También depuré cierres de sesión que congelaban al cliente por no cerrar canales de manera apropiada. Para ejecutar procesos como el usuario autenticado fue necesario otorgar capacidades cap_setuid y cap_setgid al binario, de lo contrario no había permisos para cambiar de identidad. En pruebas de integración noté que OpenSSH es más permisivo que la librería SSH de Go ante ciertos errores de protocolo, lo que me ayudó a alinear la implementación mejor con el estándar.

Referencias útiles. Destaco el artículo de Gopher Academy de 2015 sobre cómo construir un servidor SSH en Go y el paquete de Gliderlabs, que me sirvieron de guía en los aspectos más complejos de multiplexación y sesiones.

Código fuente. Puedes explorar el repositorio en GitHub, clonar el proyecto y usarlo como referencia para tus propios experimentos o pruebas de concepto.

Bibliografía recomendada. Cloudflare explica de forma clara qué es SSH y por qué es clave en la administración moderna. DigitalOcean ofrece una guía práctica de servidores, clientes y claves. Para los detalles formales del protocolo, las especificaciones RFC 4250, 4251, 4252, 4253 y 4254 del Internet Engineering Task Force son la base normativa.

Cómo encaja esto con Q2BSTUDIO. En nuestra empresa ayudamos a organizaciones a crear y operar soluciones seguras, escalables y mantenibles. Combinamos desarrollo de aplicaciones a medida y software a medida con prácticas de ciberseguridad, automatización y observabilidad. Si buscas un partner para diseñar un servicio robusto, un backend seguro o una plataforma que cumpla requisitos de cumplimiento, podemos ayudarte. Descubre cómo abordamos proyectos de aplicaciones a medida en nuestro servicio de software a medida y cómo fortalecemos la defensa de tus sistemas con nuestros servicios de ciberseguridad y pentesting.

Además, integramos inteligencia artificial de forma responsable y pragmática en procesos de negocio, desde ia para empresas con agentes IA hasta analítica avanzada con power bi y servicios inteligencia de negocio. También diseñamos arquitecturas en servicios cloud aws y azure para soportar cargas de trabajo críticas y maximizar la eficiencia operativa. Si tu próximo paso es automatizar flujos, escalar servicios o elevar el nivel de seguridad, en Q2BSTUDIO estarás en buenas manos.

Palabras clave: aplicaciones a medida, software a medida, inteligencia artificial, ciberseguridad, servicios cloud aws y azure, servicios inteligencia de negocio, ia para empresas, agentes IA, power bi
Fin del artículo, inicio de la diversión
Construyendo software juntos

Dando vida a tus ideas desde 2008

Diseñamos aplicaciones móviles y de escritorio innovadoras que cumplen con tus requisitos específicos y mejoran la eficiencia operativa.
Más info
Cuéntanos tu visión
Sea cual sea el alcance, podemos convertir tu idea en realidad. Envíanosla y charlemos sobre tu proyecto o una colaboración futura.
Contáctanos
artículos destacados
Live Chat
Enviado correctamente.

Gracias por confiar en Q2BStudio