SSH en Linux: guía práctica de terminal, túneles, procesos y debugging
SSH no es una herramienta: es la puerta a todo lo demás
De subir un favicon a dominar túneles, señales Unix y debugging a nivel de kernel. Una guía técnica sin rodeos para dejar de tener miedo a la terminal.
Hace unos días entré por SSH a un servidor con una misión ridícula: subir un favicon. Salí sabiendo configurar túneles inversos, interpretar exit codes y matar procesos con la señal correcta. Este artículo es todo lo que aprendí por el camino, condensado.
El momento en que todo cambia
Hay un antes y un después. Antes usaba FileZilla para subir archivos, cPanel para crear bases de datos y rezaba para que nada se rompiera. Después, entiendo por qué las cosas funcionan y puedo arreglarlas cuando fallan.
El salto no fue aprender comandos sueltos. Fue entender el modelo mental de Unix: todo es un archivo, todo comando devuelve un código, todo proceso recibe señales. Una vez que ves eso, el resto es vocabulario.
Si puedes hacerlo por SSH, puedes automatizarlo. Si puedes automatizarlo, no lo hagas a mano nunca más.
1. Por qué SSH y no FTP (la decisión que lo cambia todo)
Cuando editas código en producción, la diferencia entre FTP y SSH no es comodidad. Es riesgo.
| Tarea | FTP | SSH |
|---|---|---|
| Subir archivo | Arrastrar y esperar | scp en una línea |
| Editar código | Descargar → editar → subir | sed -i en milisegundos |
| Limpiar caché | Imposible | php artisan view:clear |
| Ver logs en vivo | Descargar y abrir | tail -f |
| Riesgo de romper producción | Alto | Cambios controlados desde terminal |
Por FTP, cada archivo que subes puede pasar por un estado intermedio donde la web todavía intenta servirlo. Por SSH puedes trabajar directamente sobre el servidor y utilizar herramientas mucho más precisas para comprobar, modificar y validar los cambios.
2. Los cimientos: los comandos que usarás cada día
Hay 10 comandos que cubren una parte enorme del trabajo diario. No memorices flags: entiende qué hace cada uno y por qué existe.
ls -la · el estándar
-l da formato largo: permisos, dueño, tamaño y fecha.
-a incluye archivos ocultos como .env, .git o
.htaccess. Sin -a no ves una parte importante del proyecto.
grep -rn "buscar" . · el rey de la búsqueda
-r busca recursivamente y -n muestra el número de línea.
Combinado con find y xargs puedes buscar rápidamente en grandes
cantidades de archivos. Es una de las primeras herramientas que conviene utilizar cuando
no sabes dónde está algo.
tail -f · el log en vivo
Abres un log, recargas la web y ves el error aparecer en tiempo real. Es una de las formas más rápidas de investigar problemas en producción sin modificar el código.
sed -i · el editor silencioso
sed -i 's|VIEJO|NUEVO|g' archivo.txt reemplaza texto directamente en un archivo
sin abrir un editor interactivo.
Es especialmente útil para cambios pequeños y controlados, aunque en producción siempre conviene hacer copia previa y comprobar el resultado.
rsync · lo que scp debería haber sido siempre
Solo transfiere las diferencias. Para una carpeta con miles de archivos donde solo han
cambiado tres, puede ahorrar muchísimo tiempo. Y con --dry-run puedes comprobar
qué haría antes de ejecutarlo.
3. El modelo mental que nadie te explica
Esta es la parte que separa a quien sabe usar comandos de quien entiende qué pasa. Si solo lees una sección de este artículo, que sea esta.
Todo es un archivo
En Unix, muchas interfaces del sistema se exponen mediante archivos y descriptores. Cada proceso comienza normalmente con tres descriptores estándar:
0→ stdin (entrada)1→ stdout (salida)2→ stderr (errores)
Por eso cmd 2> errores.txt funciona: estás redirigiendo el descriptor 2.
Y &> redirige tanto la salida estándar como los errores.
Ese detalle explica buena parte del sistema de redirecciones.
El shell expande en este orden
Cuando escribes una línea, Bash realiza diferentes fases de expansión antes de ejecutar el comando. Conocerlas evita muchos problemas con variables y comillas:
1. Brace expansion {a,b,c} → a b c
2. Tilde expansion ~ → /home/usuario
3. Parameter expansion $VAR → valor
4. Command substitution $(cmd) → salida
5. Arithmetic $((1+2)) → 3
6. Word splitting (por IFS)
7. Pathname expansion *.txt → archivos
8. Quote removal "quita" → quita
El paso de word splitting es el culpable de muchos bugs en scripts:
$VAR sin comillas puede dividirse por espacios, mientras que
"$VAR" mantiene el contenido como una única expansión.
"$VAR".
Todo comando devuelve un exit code
Los procesos comunican su estado mediante un código de salida. En términos generales, 0 significa éxito y un valor distinto de cero indica algún tipo de fallo o condición especial.
Esto es la base de operadores como && —continúa si lo anterior tuvo éxito—
y || —ejecuta la alternativa si lo anterior falló—.
Algunos códigos que aparecen con frecuencia son 1 para errores generales,
126 cuando algo no puede ejecutarse, 127 cuando no se encuentra
un comando y 130 cuando el proceso termina tras Ctrl+C.
Los procesos no se matan: reciben señales
Esta fue una de las ideas más importantes. kill no significa necesariamente
"matar": envía una señal.
Por defecto, kill PID envía SIGTERM (15), que permite al proceso
reaccionar y terminar de forma ordenada si está preparado para ello.
kill -9 envía SIGKILL. No puede ser capturada ni ignorada por el
proceso y termina inmediatamente su ejecución. Por eso puede impedir tareas de limpieza
pendientes.
kill / SIGTERM. Reserva
kill -9 para los casos en los que el proceso realmente no termina de forma normal.
4. Los trucos que separan a un usuario de un sysadmin
Túneles SSH: una VPN en una línea
SSH no solo abre terminales. También puede redirigir puertos. Esto permite crear un túnel cifrado entre tu máquina y servicios accesibles desde el servidor:
# Puerto local 8080 → puerto 80 del servidor
ssh -L 8080:localhost:80 usuario@servidor
# Acceder a MySQL solo accesible desde el servidor
ssh -L 3306:localhost:3306 usuario@servidor
# Proxy SOCKS para el tráfico compatible
ssh -D 1080 usuario@servidor
Caso real: tu base de datos MySQL solo acepta conexiones locales.
Con ssh -L 3306:localhost:3306, un cliente local puede conectarse a
localhost:3306 mientras SSH transporta esa conexión hacia el servidor.
De esta forma puedes evitar exponer directamente el puerto de la base de datos a Internet.
tmux: sobrevive a la desconexión
Si una tarea larga depende directamente de una sesión SSH, perder la conexión puede
interrumpir el proceso. tmux permite mantener una sesión de terminal persistente
aunque cierres temporalmente la conexión SSH.
tmux new -s deploy
# lanzas tu deploy de 20 minutos
# detach con:
Ctrl+b d
# cierras SSH
# vuelves a entrar y recuperas la sesión:
tmux attach -t deploy
Es una herramienta especialmente útil para procesos largos y tareas de administración.
El truco base64 para scripts complejos
Si estás en PowerShell y necesitas ejecutar un script SSH con muchas comillas anidadas, paréntesis o llaves, la combinación de shells puede resultar incómoda.
Una solución práctica es codificar el contenido del script en Base64 y reconstruirlo en el servidor.
$script = @'
cd ~/proyecto
sed -i 's|VIEJO|NUEVO|g' archivo.txt
'@
$b64 = [Convert]::ToBase64String(
[Text.Encoding]::UTF8.GetBytes($script)
)
ssh usuario@host "echo '$b64' | base64 -d | bash"
El resultado es una cadena mucho más sencilla de transportar entre PowerShell y Bash cuando las comillas empiezan a complicar la ejecución.
5. Cuando las cosas van mal: debugging real
404 o 403 en producción
curl -I https://tuweb.com/ruta permite comprobar las cabeceras HTTP
y el código de respuesta sin abrir el navegador.
- 404 → el recurso o ruta no se ha encontrado.
- 403 → el servidor ha entendido la petición pero está rechazando el acceso, normalmente por permisos, configuración o reglas de acceso.
"Edité un blade pero no se ve el cambio"
Una de las primeras comprobaciones en Laravel es la caché de vistas:
php artisan view:clear
Después puedes realizar una recarga forzada del navegador con
Ctrl+Shift+R.
"No space left on device"
El disco está lleno y diferentes servicios pueden empezar a fallar. Un diagnóstico rápido:
df -h
du -sh * | sort -h
php artisan cache:clear
Antes de borrar logs u otros archivos, identifica qué está ocupando realmente el espacio y qué puede eliminarse de forma segura.
"Address already in use"
Alguien ya está utilizando el puerto. Primero identifica el proceso:
lsof -i :8080
Después decide si realmente debe detenerse. No conviene utilizar
kill -9 automáticamente sin comprobar qué proceso es.
Cuando no hay log que explique nada
Cuando los logs de aplicación no son suficientes, herramientas como
strace permiten observar determinadas llamadas del proceso al sistema.
strace -f -e trace=openat comando
Puede resultar especialmente útil para descubrir qué archivos intenta abrir un proceso, qué recursos no encuentra o dónde se produce una llamada inesperada.
6. El arsenal avanzado (para cuando ya no tienes miedo)
~/.ssh/config: deja de escribir 30 caracteres por conexión
El archivo de configuración de SSH permite convertir conexiones largas y repetitivas en simples alias:
Host prod
HostName mi-servidor.com
User mi_usuario
Port 2222
IdentityFile ~/.ssh/id_ed25519
Host *.internal
User deploy
ProxyJump bastion
Ahora ssh prod puede utilizar toda esa configuración sin volver a escribirla
cada vez.
Con ProxyJump también puedes utilizar un servidor intermedio como bastión
para alcanzar otros sistemas sin exponerlos directamente.
journalctl: logs de systemd con filtros potentes
journalctl -u nginx -f
journalctl --since "1 hour ago"
journalctl -p err -b
Puedes seguir los logs de un servicio, limitar la búsqueda a un periodo concreto o filtrar por prioridad.
Las prioridades van desde emerg(0) hasta debug(7).
set -euo pipefail: el shebang moderno
#!/usr/bin/env bash
set -euo pipefail
-e hace que el script termine ante determinados errores.
-u considera error el uso de variables no definidas.
pipefail hace que un pipeline refleje el fallo de cualquiera de sus comandos,
no solamente el del último.
Por ejemplo:
false | true
echo $?
Sin pipefail, el resultado puede reflejar únicamente el estado del último comando.
Con pipefail, el fallo anterior puede propagarse al resultado del pipeline.
7. Las reglas que me llevo
-
Mira el prompt antes de escribir
sshoscp.PS C:\= tu PC. Si el prompt muestra que estás dentro del servidor, compruébalo antes de ejecutar comandos destructivos. -
Backup antes de editar.
cp archivo archivo.bak. Dos segundos pueden ahorrar horas. -
Después de tocar una vista Blade:
php artisan view:cleary después recarga el navegador si es necesario. -
Verifica con
grep,curly los logs. No te fíes únicamente de tu memoria. - Comillas raras entre PowerShell y Bash: utiliza una estrategia de transporte clara, como el script codificado en Base64, cuando realmente lo necesites.
-
SIGTERMantes queSIGKILL.killantes quekill -9. -
En scripts Bash:
set -euo pipefailes un buen punto de partida para evitar determinados fallos silenciosos. -
Usa
"$VAR"cuando quieras preservar una variable como una única palabra. -
Antes de un
rsync --delete, utiliza siempre--dry-runpara comprobar qué va a ocurrir. -
Deploys largos:
utiliza
tmuxo un sistema de gestión de procesos apropiado para producción.
La conclusión que nadie te cuenta
SSH no es simplemente una herramienta para abrir una terminal remota. Es una de las interfaces fundamentales para administrar sistemas Unix y automatizar operaciones sobre servidores.
Cuando aprendes SSH de verdad, no aprendes solamente un comando. Aprendes el modelo mental que después aparece detrás de Git, automatización, despliegues, backups, infraestructura como código y muchas otras herramientas.
La GUI simplifica muchas tareas, pero también puede ocultar lo que realmente está ocurriendo. La terminal obliga a enfrentarse directamente con archivos, procesos, permisos, señales, conexiones y servicios.
Aprender esto duele. Al principio te equivocas constantemente, te pierdes entre directorios, rompes cosas y no sabes cómo volver atrás.
Pero cada error te enseña algo que una interfaz gráfica puede haber ocultado durante años.
Todo lo moderno está construido alrededor de sistemas que puedes administrar desde texto. Cuando dominas la terminal, dejas de limitarte a utilizar la infraestructura: empiezas a entender cómo funciona.
Si has llegado hasta aquí leyendo, ya has dado el salto mental que separa a los dos mundos. El resto es vocabulario, práctica y muchas horas delante de una terminal.
Vic
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero en opinar!
Deja un comentario