Módulo 5: Máquinas remotas, redes y scripting

1. Introducción: salir de tu máquina y automatizar el trabajo

Descripción

Terminaste el módulo anterior sabiendo quién eres para el sistema (whoami, permisos), qué corre en tu computadora (procesos, señales) y qué sabe tu shell de tu propio entorno (PATH, variables). Fíjate en un detalle: todo eso pasó dentro de una sola máquina, la tuya. Este módulo rompe esa frontera dos veces. Primero vas a extender tu alcance hacia otra computadora: diagnosticarla por red, entrar en ella con una llave en vez de una contraseña, moverle archivos con precisión y dejar procesos corriendo ahí aunque cierres tu laptop. Segundo, vas a dejar de escribir comandos uno por uno y vas a empezar a guardarlos en un archivo que otra persona —o tú mismo, dentro de un mes— puede ejecutar sin que estés presente para explicarlo.

Al cerrar esta lección vas a tener el mapa completo de las ocho lecciones que siguen, vas a poder explicar por qué el módulo respeta un orden muy específico —red antes que SSH, scripting al final— y vas a tener corriendo, sin gastar un centavo ni crear ninguna cuenta, al menos una de las tres formas de montar tu propio laboratorio remoto.

La razón por la que esto importa en el trabajo real es concreta: el estudio de mercado que armó el catálogo de esta guía marcó como carencia frecuente exactamente esto —gente que despliega aplicaciones a una nube sin poder explicar qué es un puerto, cómo resuelve un nombre de dominio o qué garantiza SSH—. Cuando el despliegue automático de una plataforma falla con un mensaje que no es "todo salió bien", esa persona no tiene con qué diagnosticar. Le queda apretar el botón de nuevo y esperar. Este módulo es lo que hay debajo del botón.

Conexión con el módulo: en el módulo 4 aprendiste a leer tu propia máquina —permisos, procesos, entorno—. La lección siguiente, Cómo se hablan las máquinas: IP, puertos y DNS, empieza a construir desde cero, y con calma, el modelo con el que vas a diagnosticar cualquier máquina, incluida una que no es tuya. Ningún término de red se define en esta lección: se define ahí.


De tu casa al vecindario: qué cambia en este módulo

Piensa en los cuatro módulos anteriores como aprender a moverte con soltura dentro de tu propia casa: sabes qué hay en cada cuarto (el árbol de archivos), sabes pasar cosas de un cuarto a otro sin salir a la calle (tuberías y redirección), sabes quién puede entrar por cada puerta (permisos) y sabes qué luces siguen prendidas y qué aparatos siguen andando aunque no los estés mirando (procesos y variables de entorno). Es un dominio real, y ya te sacó de apuros.

Este módulo es salir a la calle. Primero aprendes a entender cómo se identifican y se encuentran las casas del vecindario —direcciones, puertas numeradas, un directorio que traduce nombres en direcciones—, porque no puedes tocar timbre en un lugar cuya dirección no sabes leer. Después aprendes a entrar en una casa que no es tuya con una llave que solo abre esa puerta, en lugar de gritar una contraseña para que alguien adentro te escuche y decida si te cree. Ya adentro, aprendes a mover cajas completas de una casa a la otra sin cargarlas una por una, y a dejar la estufa prendida cuando te vas sin que se apague sola. Y al final, en vez de repetir de memoria los mismos pasos cada vez que visitas una casa, aprendes a dejar escrita una nota con instrucciones exactas que cualquiera —incluido tú, seis meses después— puede seguir sin que estés ahí para explicarla.

Esa nota con instrucciones es un script. Y esa es, en una frase, la distancia real entre el módulo 4 y este: dejas de ser alguien que opera su propia máquina y te conviertes en alguien que extiende su trabajo hacia otras máquinas y hacia el futuro.

Por qué el orden es red, después SSH, y scripting al final

Este módulo podría empezar directo por SSH —al final es el protagonista de buena parte de lo que sigue—. No lo hace, y hay una razón concreta detrás, no un capricho de organización.

Cuando un ssh algo@algo falla, el mensaje que recibes pertenece casi siempre a una de estas capas: no se pudo resolver el nombre (Could not resolve hostname), no hay alcance hacia esa dirección (No route to host), el puerto no responde (Connection refused, o el comando se queda colgado sin decir nada), o la autenticación falló (Permission denied). Son cuatro causas completamente distintas, con cuatro soluciones completamente distintas, y las cuatro suenan igual de confusas si nunca te explicaron qué es una dirección IP, qué es un puerto o qué hace DNS. Por eso las lecciones 2 y 3 —el modelo cliente-servidor, direcciones, puertos, DNS, y las herramientas para diagnosticar cada capa por separado— van antes que SSH. No puedes diagnosticar con criterio una conexión que no entiendes; solo puedes probar cosas al azar hasta que algo funcione, y eso no es una habilidad que se transfiera al próximo problema.

El scripting va al final por la razón contraria: no porque sea difícil, sino porque necesita todo lo anterior para tener sentido. Un script de shell es, en el fondo, la misma secuencia de comandos que ya sabes escribir a mano —con las mismas rutas del módulo 1, la misma redirección y los mismos códigos de salida del módulo 3, los mismos permisos de ejecución del módulo 4— guardada en un archivo con un poco de lógica alrededor. Si este módulo empezara por scripting, tendrías que aprender chmod +x sin haber visto permisos, o revisar $? sin haber visto códigos de salida. En cambio, cuando llegues a la lección 6, la mayoría de las piezas ya las vas a reconocer.

El mapa completo:

1. Introducción: salir de tu máquina y automatizar el trabajo        ← estás aquí
2. Cómo se hablan las máquinas: IP, puertos y DNS
3. Diagnosticar la red desde la terminal: ping, dig, curl y ss
4. Conectarse con SSH y autenticación por llaves
5. Mover archivos y sesiones que sobreviven: scp, rsync y tmux
6. Tu primer script de shell
7. Lógica y seguridad en scripts: condicionales, bucles y set -euo pipefail
8. Proyecto final: toolkit de diagnóstico remoto

Dos lecciones de modelo (2 y 3) antes de tocar ssh en la lección 4, tres lecciones de mecánica remota (4 a 6), una lección de solidez para scripts (7) y un proyecto (8) que junta todo contra un caso real: un dominio que hay que diagnosticar y una máquina remota a la que hay que conectarse para hacerlo.

Ejemplo trabajado: monta tu laboratorio a costo cero

Todo lo que viene en este módulo necesita algo del otro lado de una conexión: una máquina a la que conectarte por SSH, moverle archivos y correr comandos. No hace falta una cuenta de nube, ni una tarjeta de crédito, ni un servidor alquilado. Hay tres formas de conseguir eso mismo sin gastar nada, y con al menos una funcionando ya puedes seguir el resto del módulo.

Necesitas una sola de las tres. Si nunca tocaste una terminal de servidor, la Opción A es la de menos fricción. Si tienes una segunda computadora dando vueltas, la Opción B es la más parecida a una situación real de trabajo. Si ya usas Docker de otro curso, la Opción C es la más rápida de desarmar.

En las tres vamos a usar el comando ssh en su forma más simple, solo para comprobar que hay un servidor vivo del otro lado. Qué es SSH exactamente y qué garantiza lo vas a ver con calma en la lección 4; por ahora trátalo nada más como "una manera de pedirle a otra computadora que ejecute un comando y te devuelva el resultado".

Opción A — SSH contra tu propia máquina

Es la opción con menos pasos, porque el cliente de SSH ya viene instalado en macOS y en cualquier distribución de Linux, y el servidor solo hace falta activarlo.

En macOS:

  1. Abre el menú → Configuración del SistemaGeneralCompartir.
  2. Activa Inicio de sesión remoto (Remote Login en inglés).

Existe también una vía por línea de comandos (sudo systemsetup -setremotelogin on), pero macOS exige que la aplicación que la ejecuta tenga permiso de Acceso total al disco para esa acción específica; si la corres desde Terminal sin ese permiso, vas a recibir un error de privilegios. Por eso, para este primer contacto, la vía del menú es la que no tiene sorpresas.

En Linux (Ubuntu/Debian):

sudo apt update && sudo apt install -y openssh-server
sudo systemctl enable --now ssh

Qué esperar (puede variar un poco según tu distribución):

Created symlink /etc/systemd/system/multi-user.target.wants/ssh.service → /usr/lib/systemd/system/ssh.service.

Si usas Windows con WSL2 (módulo 1, lección 3), esto corre exactamente igual que en Linux: tu distribución Ubuntu no es distinta de un Ubuntu real para este propósito.

Prueba, en cualquiera de los dos sistemas:

whoami

Qué esperar:

mikenieva

Con ese nombre de usuario, prueba la conexión:

ssh mikenieva@localhost echo "el servidor SSH de esta máquina responde"

Qué esperar (solo la primera vez que te conectas):

The authenticity of host 'localhost (127.0.0.1)' can't be established.
ED25519 key fingerprint is SHA256:g4K9x...truncado...q2Zw.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ED25519) to the list of known hosts.
mikenieva@localhost's password:
el servidor SSH de esta máquina responde

Ese aviso de "fingerprint" y esa contraseña van a tener una explicación completa en la lección 4. Por ahora, escribe yes para confirmar y después la contraseña de tu cuenta de usuario. La última línea —tu propio texto, devuelto desde "otra" máquina que en este caso resulta ser la misma— es la confirmación de que el servidor está vivo y respondiendo.

Opción B — una segunda computadora en tu misma red

Si tienes una laptop vieja, una Raspberry Pi o cualquier otra computadora conectada al mismo Wi-Fi, repite exactamente los pasos de la Opción A, pero en esa otra máquina. La diferencia está en cómo te conectas: en lugar de localhost, vas a usar la dirección IP de esa computadora dentro de tu red local —algo con forma de 192.168.1.34—. Cómo encontrar esa dirección es, literalmente, contenido de la lección 2; por ahora guarda esta opción en el bolsillo y vuelve a ella cuando la termines. Es la opción que más se parece a una situación de trabajo real, porque hay dos máquinas físicas distintas de por medio.

Opción C — un contenedor local con Docker

Si ya tienes Docker instalado —quizás de otro curso—, esta es la opción que menos toca tu sistema operativo: el servidor entero vive dentro de un contenedor que puedes borrar con un solo comando cuando termines el módulo.

docker run -d \
  --name ssh-lab \
  -p 2222:2222 \
  -e PUID=1000 \
  -e PGID=1000 \
  -e USER_NAME=student \
  -e USER_PASSWORD=lab1234 \
  -e PASSWORD_ACCESS=true \
  lscr.io/linuxserver/openssh-server:latest

Una fila por bandera, para no dejar nada sin explicar:

BanderaQué hace
-dcorre el contenedor en segundo plano ("detached"), sin ocupar tu terminal
--name ssh-lable da un nombre legible al contenedor, para manejarlo sin memorizar su identificador
-p 2222:2222conecta el puerto 2222 de tu máquina con el puerto 2222 de adentro del contenedor. El orden es siempre host:contenedor; si lo escribes al revés, el contenedor arranca igual, pero nunca te vas a poder conectar desde afuera
-e VARIABLE=valordefine una variable de entorno dentro del contenedor —la misma idea de variable de entorno del módulo 4, aplicada a un proceso que corre adentro de otro proceso

Qué esperar:

Unable to find image 'lscr.io/linuxserver/openssh-server:latest' locally
latest: Pulling from linuxserver/openssh-server
(... progreso de descarga ...)
Status: Downloaded newer image for lscr.io/linuxserver/openssh-server:latest
3f1a9c2e8d0b4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f

Ese identificador largo es el ID del contenedor recién creado. Pruébalo igual que las otras dos opciones:

ssh -p 2222 student@localhost echo "el contenedor responde"

Misma advertencia de fingerprint, y como contraseña usas el valor que pusiste en USER_PASSWORD (lab1234 en el ejemplo). Cuando termines el módulo, docker rm -f ssh-lab borra el contenedor entero sin dejar rastro en tu sistema.


Profundización: comparar las tres opciones y adelanto del proyecto final

OpciónSoftware nuevo que instalasQué tan real es la experiencia de redCómo la desarmas al terminar
A — tu propia máquinaNinguno en macOS/LinuxParcial: es la misma máquina hablándose a sí mismaDesactivar Remote Login a mano
B — segunda computadoraNingunoCompleta: dos máquinas físicas distintasDesactivar el servicio en la otra máquina
C — contenedor DockerDocker, si no lo tienesParcial: misma máquina, pero aislada en un contenedordocker rm -f ssh-lab, un solo comando

Si nunca hiciste esto antes, empieza por la Opción A: es la que menos piezas nuevas introduce. Puedes sumar la B o la C más adelante si quieres practicar contra algo que se sienta más parecido a un servidor de verdad.

El proyecto que cierra el módulo, en la lección 8, es un pequeño kit de herramientas al que vas a llamar ops-toolkit: un script que audita el entorno de una máquina, otro que diagnostica un dominio capa por capa, y un tercero que se conecta por SSH a una máquina remota, corre los dos anteriores ahí y trae los resultados de vuelta. No hace falta que entiendas ese párrafo todavía —es apenas un adelanto de hacia dónde va este módulo, y para cuando llegues a la lección 8 cada pieza de esa frase te va a resultar conocida.


Errores comunes

Pensar que este módulo es "aprender el comando ssh". Es la trampa conceptual más común al empezar, y suena razonable: SSH es, a simple vista, un comando con dos palabras. Pero cada síntoma de conexión —Could not resolve hostname, Connection refused, Permission denied— pertenece a una capa distinta del modelo cliente-servidor, y diagnosticar de verdad significa saber en cuál capa mirar, no memorizar la sintaxis del comando. Se detecta así: si frente a un error de conexión tu primer instinto es buscar el mensaje exacto en internet en lugar de preguntarte "¿es el nombre, es la red, es el puerto, o es la autenticación?", todavía estás en modo memorización. Se corrige llegando a las lecciones 2 y 3 antes de la 4, en el orden en que están puestas.

Creer que hace falta una cuenta de nube para practicar SSH de verdad. Es un error práctico frecuente y evitable: pedir un VPS, activar un free-tier con fecha de vencimiento, o directamente posponer el módulo por "no tener un servidor". Ninguna de las tres opciones de este laboratorio necesita eso, y las tres te dan exactamente el mismo protocolo, las mismas herramientas y los mismos mensajes de error que un servidor de verdad.

En la Opción C, invertir el mapeo de puertos de Docker. Escribir -p 22:2222 en lugar de -p 2222:2222 es un error de dedo fácil de cometer y difícil de notar, porque el contenedor arranca sin quejarse. El síntoma aparece recién al intentar conectarte: ssh -p 2222 student@localhost responde Connection refused, aunque el contenedor esté corriendo. Se corrige revisando que el primer número del par sea siempre el puerto de tu máquina (el que usas para conectarte) y el segundo el puerto de adentro del contenedor.


Ejercicios

Ejercicio 1 — Elegir la opción correcta

Para cada situación, decide cuál de las tres opciones de laboratorio conviene más y justifica con lo que viste en esta lección.

  1. Alguien que nunca abrió una terminal de servidor y solo tiene su laptop de todos los días.
  2. Alguien que tiene, además de su laptop, una computadora vieja conectada al mismo Wi-Fi que ya no usa para nada.
  3. Alguien que instaló Docker hace un mes para otro curso y quiere poder deshacer el laboratorio sin dejar nada instalado de forma permanente.
Ver solución
  1. Opción A. Es la de menos piezas nuevas: no instala software adicional en macOS ni en Linux, y el único paso es activar algo que el sistema operativo ya trae. Para una primera exposición, menos fricción es mejor.
  2. Opción B. Tener una segunda máquina física disponible es exactamente el escenario que la Opción B aprovecha, y es la que da la experiencia más parecida a conectarte a un servidor real —dos computadoras distintas, no la misma hablándose a sí misma.
  3. Opción C. Ya tiene la única pieza adicional que esa opción requiere (Docker), y el contenedor se destruye por completo con docker rm -f ssh-lab, sin dejar configuración persistente en el sistema operativo —justo lo que pide el enunciado.

Por qué funciona: el criterio de esta lección no es "una opción es superior a las otras", sino qué software ya tienes disponible y qué tan real quieres que se sienta la práctica. Las tres opciones dan exactamente el mismo protocolo y los mismos mensajes de error del otro lado.

Ejercicio 2 — Cuántas causas puedes descartar sin el modelo todavía

Imagina que te saltas las lecciones 2 y 3 y vas directo a probar SSH contra la Opción B. Escribes ssh estudiante@192.168.1.50 y recibes ssh: connect to host 192.168.1.50 port 22: Connection refused. Sin el modelo de capas que enseñan las lecciones 2 y 3: ¿cuántas causas distintas se te ocurren para ese mensaje, y cuántas de ellas puedes descartar con lo que sabes hasta ahora?

Ver solución

Sin las lecciones 2 y 3, es difícil descartar ninguna: el mensaje podría deberse, entre otras cosas, a que el servidor SSH de esa máquina no está corriendo, a que hay un firewall bloqueando el puerto, a que la dirección IP que escribiste ya no es la de esa computadora (las direcciones dentro de una red local pueden cambiar), o a que las dos máquinas ni siquiera están en la misma red. Son al menos cuatro explicaciones plausibles, y sin un método para aislar cada una por separado, la única estrategia disponible es probar cambios al azar hasta que algo funcione.

Por qué funciona: ese es exactamente el problema que resuelven las lecciones 2 y 3 —dar un método de descarte por capas: ¿resuelve el nombre?, ¿hay alcance de red?, ¿el puerto está escuchando?, ¿la respuesta es la esperada?—. Connection refused en particular es información valiosa una vez que conoces el modelo: significa que sí hubo alcance de red hasta esa máquina, porque algo respondió activamente rechazando la conexión, a diferencia de un intento que se queda colgado sin ninguna respuesta. Ese matiz es imposible de aprovechar sin el vocabulario que dan las dos lecciones siguientes.

Ejercicio 3 — Confirma que ya tienes lo que hace falta

En tu propia máquina, sin tocar nada de las opciones de arriba, corre:

ssh -V

Interpreta la salida: ¿qué te dice sobre si ya tienes o no el cliente de SSH instalado, y qué harías si el resultado fuera command not found en lugar de una versión?

Ver solución

Una salida típica se ve así (la versión exacta varía según tu sistema):

OpenSSH_9.6p1, LibreSSL 3.3.6

Esa línea confirma que el cliente de SSH —el programa que usas para iniciar conexiones, distinto del servidor que activaste en la Opción A— ya viene instalado por defecto en macOS, en cualquier distribución común de Linux y dentro de una distribución WSL2. No tuviste que instalar nada para llegar hasta acá.

Si en cambio el resultado fuera zsh: command not found: ssh (o el equivalente en bash), el diagnóstico correcto no es "reinstalar el sistema operativo": es exactamente el mismo command not found que ya sabes resolver desde el módulo 4 —revisar si el programa existe en el disco y si el directorio donde vive está en tu PATH—. En la práctica, esto casi nunca ocurre en macOS, Linux o WSL2 con una instalación estándar; es más un caso de distribuciones mínimas hechas a propósito sin herramientas de red.

Por qué funciona: confirmar que el cliente ya está disponible es parte de la promesa de "costo cero" de esta lección —no solo no gastas dinero, tampoco gastas tiempo instalando el software base—. Y conectar el caso raro de falla con el módulo 4 refuerza que command not found siempre tiene la misma explicación estructural, sea cual sea el comando que falte.


Resumen y siguiente paso

Este módulo extiende todo lo que aprendiste en los cuatro anteriores más allá de tu propia máquina: vas a diagnosticar redes, conectarte a otras computadoras con SSH, mover archivos entre ellas, mantener procesos vivos aunque cierres tu laptop, y finalmente convertir comandos sueltos en scripts reutilizables. Viste por qué el orden importa —no puedes diagnosticar una conexión que no entiendes, y un script solo tiene sentido cuando ya conoces las piezas que va a encadenar— y montaste, a costo cero, al menos una de las tres formas de tener un servidor SSH esperándote del otro lado.

Antes de avanzar deberías poder:

  • Nombrar las ocho lecciones del módulo en orden y decir en una frase qué cubre cada una.
  • Explicar por qué la red va antes que SSH, y por qué el scripting va al final, sin mirar el mapa.
  • Tener al menos una de las tres opciones de laboratorio funcionando, confirmada con un ssh ...@... echo "..." que te devolvió tu propio mensaje.
  • Reconocer que un error de conexión (Connection refused, Could not resolve hostname, Permission denied) es información sobre una capa específica, aunque todavía no sepas nombrar cuál.

Lo que sigue no es todavía SSH. Es el modelo con el que vas a poder leer cualquier error de red sin adivinar: qué es una dirección IP, qué son localhost y 127.0.0.1, qué significa que un puerto esté escuchando, y qué hace DNS paso a paso cuando escribes un nombre de dominio. Con ese modelo instalado, la lección 4 —conectarte por SSH de verdad, con una llave— va a sentirse como el paso natural que sigue, no como magia nueva.


Recursos