Los comandos SSH más importantes para la administración de servidores Linux cubren cuatro áreas: la conexión al servidor (ssh), la transferencia de archivos (scp y sftp), la gestión de claves criptográficas (ssh-keygenssh-copy-idssh-add) y la configuración de conexiones habituales (~/.ssh/config). Esta guía recoge todos los comandos con sus opciones más útiles, ejemplos reales de uso en producción y los atajos y trucos que hacen el trabajo diario con SSH más eficiente.

Referencia rápida: los comandos SSH más usados

ComandoFunciónEjemplo básico
sshConectar a un servidor remoto por SSHssh usuario@servidor.com
scpCopiar archivos entre local y remoto sobre SSHscp archivo.txt usuario@servidor.com:/destino/
sftpSesión interactiva de transferencia de archivos sobre SSHsftp usuario@servidor.com
ssh-keygenGenerar pares de claves SSH y gestionar claves existentesssh-keygen -t ed25519
ssh-copy-idInstalar la clave pública en un servidor remotossh-copy-id usuario@servidor.com
ssh-addAñadir claves al agente SSH para no introducir la passphrase cada vezssh-add ~/.ssh/id_ed25519
ssh-agentGestionar el agente SSH que guarda claves en memoriaeval "$(ssh-agent -s)"
ssh-keyscanObtener las claves públicas de host de un servidorssh-keyscan servidor.com

Comando ssh: conexión remota

Conexión básica

# Conexión básica con usuario y servidor:
ssh usuario@servidor.com
ssh usuario@195.234.56.78

# Conexión especificando el puerto (si el servidor no usa el 22 por defecto):
ssh -p 2222 usuario@servidor.com

# Conexión con una clave SSH específica (en lugar de la predeterminada):
ssh -i ~/.ssh/id_ed25519_produccion usuario@servidor.com

# Conexión con usuario diferente al actual del sistema local:
ssh -l usuario_remoto servidor.com
# Equivalente a:
ssh usuario_remoto@servidor.com

Ejecutar comandos remotos sin abrir sesión interactiva

# Ejecutar un solo comando y devolver el resultado localmente:
ssh usuario@servidor.com 'df -h'
ssh usuario@servidor.com 'free -m'
ssh usuario@servidor.com 'uptime'
ssh usuario@servidor.com 'cat /var/log/nginx/error.log | tail -50'

# Ejecutar un comando con sudo (el servidor debe permitir sudo sin contraseña
# o la contraseña debe ir en la sesión):
ssh usuario@servidor.com 'sudo systemctl status nginx'
ssh usuario@servidor.com 'sudo tail -100 /var/log/apache2/error.log'

# Ejecutar múltiples comandos en secuencia:
ssh usuario@servidor.com 'cd /var/www/html && ls -la && df -h'

# Ejecutar un bloque de comandos (heredoc):
ssh usuario@servidor.com << 'EOF'
echo "Iniciando despliegue..."
cd /var/www/html/mi-sitio
git pull origin main
php artisan migrate --force
php artisan config:cache
sudo systemctl reload php8.2-fpm
echo "Despliegue completado."
EOF

# Capturar la salida del comando remoto en una variable local:
ESPACIO_DISCO=$(ssh usuario@servidor.com 'df -h / | tail -1 | awk "{print \$5}"')
echo "Uso del disco en producción: $ESPACIO_DISCO"

Opciones avanzadas de conexión SSH

# Modo verbose: muestra el proceso de conexión con detalle
# Útil para diagnosticar problemas de autenticación:
ssh -v usuario@servidor.com   # Verbose básico
ssh -vv usuario@servidor.com  # Más detalle
ssh -vvv usuario@servidor.com # Máximo detalle (para diagnóstico profundo)

# Deshabilitar la verificación del host (NUNCA en producción, solo en pruebas):
ssh -o StrictHostKeyChecking=no usuario@servidor.com

# Añadir automáticamente el host a known_hosts sin preguntar:
ssh -o StrictHostKeyChecking=accept-new usuario@servidor.com

# Forzar la versión del protocolo (solo SSH-2 en 2026):
ssh -2 usuario@servidor.com

# Deshabilitar la asignación de pseudo-terminal (para comandos no interactivos):
ssh -T git@github.com

# Comprimir el tráfico SSH (útil en conexiones lentas):
ssh -C usuario@servidor.com

# Timeout de conexión (si el servidor no responde en 10 segundos, abortar):
ssh -o ConnectTimeout=10 usuario@servidor.com

# Deshabilitar el keepalive (para scripts que no necesitan sesión larga):
ssh -o ServerAliveInterval=0 usuario@servidor.com

# Configurar keepalive para sesiones largas:
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 usuario@servidor.com

SSH con salto a través de un servidor bastion (ProxyJump)

Un servidor bastion (o jump host) es un servidor intermedio de acceso seguro que se usa para llegar a servidores de una red privada que no son accesibles directamente desde internet. SSH soporta saltos nativamente con la opción -J:

# Conectar al servidor-destino a través del servidor-bastion:
ssh -J usuario@bastion.com usuario@servidor-privado.com

# Múltiples saltos en cadena:
ssh -J usuario@bastion1.com,usuario@bastion2.com usuario@servidor-final.com

# En ~/.ssh/config (más limpio para uso frecuente):
Host bastion
    HostName bastion.sys4net.com
    User admin
    IdentityFile ~/.ssh/id_ed25519

Host servidor-privado
    HostName 10.0.0.50          # IP privada del servidor destino
    User admin
    ProxyJump bastion           # Salta a través del bastion
    IdentityFile ~/.ssh/id_ed25519

# Ahora conectar es simplemente:
ssh servidor-privado

Comando scp: copiar archivos sobre SSH

SCP (Secure Copy Protocol) permite copiar archivos y directorios entre tu máquina local y el servidor remoto, o entre dos servidores remotos, usando el cifrado y la autenticación de SSH.

Copiar archivos de local a remoto

# Copiar un archivo al servidor:
scp archivo.txt usuario@servidor.com:/var/www/html/

# Copiar especificando el nombre de destino:
scp archivo.txt usuario@servidor.com:/var/www/html/nuevo-nombre.txt

# Copiar con puerto personalizado:
scp -P 2222 archivo.txt usuario@servidor.com:/var/www/html/

# Copiar usando una clave SSH específica:
scp -i ~/.ssh/id_ed25519 archivo.txt usuario@servidor.com:/destino/

# Copiar múltiples archivos:
scp archivo1.txt archivo2.txt usuario@servidor.com:/var/www/html/

# Copiar con comodines (todos los archivos PHP):
scp *.php usuario@servidor.com:/var/www/html/

# Copiar un directorio completo (opción recursiva -r):
scp -r ./mi-proyecto/ usuario@servidor.com:/var/www/html/

# Copiar con compresión (útil para archivos de texto grandes):
scp -C -r ./logs/ usuario@servidor.com:/backup/logs/

# Mostrar progreso durante la copia:
scp -v archivo-grande.zip usuario@servidor.com:/var/www/html/

Copiar archivos de remoto a local

# Descargar un archivo del servidor:
scp usuario@servidor.com:/var/log/nginx/error.log ./logs/

# Descargar con nombre diferente:
scp usuario@servidor.com:/var/log/nginx/error.log ./logs/nginx-error-$(date +%Y%m%d).log

# Descargar un directorio completo:
scp -r usuario@servidor.com:/var/www/html/backup/ ./backups/

# Descargar todos los archivos .log del servidor:
scp usuario@servidor.com:/var/log/nginx/*.log ./logs/

# Descargar preservando timestamps y permisos:
scp -p usuario@servidor.com:/var/www/html/config.php ./config.php

Copiar entre dos servidores remotos

# Copiar desde un servidor remoto a otro (pasando por tu máquina local):
# (La opción -3 fuerza la copia a través de tu máquina local)
scp -3 usuario@servidor1.com:/ruta/archivo.txt usuario@servidor2.com:/destino/

# Sin -3: SCP intenta conexión directa entre servidores (necesita tu clave en servidor1)
scp usuario@servidor1.com:/ruta/archivo.txt usuario@servidor2.com:/destino/

Comando sftp: sesión interactiva de transferencia de archivos

SFTP (SSH File Transfer Protocol) proporciona una sesión interactiva completa de gestión de archivos remotos, similar a un cliente FTP pero completamente cifrada y sin los problemas de puertos del FTP.

Abrir una sesión SFTP

# Conexión SFTP básica:
sftp usuario@servidor.com

# Con puerto personalizado:
sftp -P 2222 usuario@servidor.com

# Con clave SSH específica:
sftp -i ~/.ssh/id_ed25519 usuario@servidor.com

# El prompt cambia a: sftp>

Comandos dentro de la sesión SFTP

# === Navegación ===
pwd             # Directorio actual en el servidor (remoto)
lpwd            # Directorio actual en tu máquina (local)
ls              # Listar archivos en el directorio remoto
ls -la          # Listar con permisos y detalles
lls             # Listar archivos en el directorio local
lls -la         # Listar local con detalles
cd /ruta/       # Cambiar directorio en el servidor
cd ..           # Subir un nivel en el servidor
lcd /ruta/      # Cambiar directorio local
lcd ..          # Subir un nivel localmente

# === Descargar archivos (del servidor a local) ===
get archivo.txt                    # Descargar un archivo al directorio local actual
get archivo.txt /ruta/local/       # Descargar a una ruta específica local
get -r carpeta/                    # Descargar directorio completo (recursivo)
mget *.log                         # Descargar múltiples archivos con comodín
mget *.php /var/www/backup/        # Descargar múltiples con destino específico

# === Subir archivos (de local a servidor) ===
put archivo.txt                    # Subir un archivo al directorio remoto actual
put archivo.txt /ruta/remota/      # Subir a una ruta específica
put -r ./carpeta/                  # Subir directorio completo
mput *.css                         # Subir múltiples archivos con comodín

# === Gestión de archivos y directorios remotos ===
mkdir nueva-carpeta                # Crear directorio en el servidor
rmdir carpeta-vacia                # Eliminar directorio vacío
rename archivo.txt nuevo.txt       # Renombrar archivo en el servidor
rm archivo.txt                     # Eliminar archivo en el servidor
chmod 644 archivo.txt              # Cambiar permisos en el servidor
chown usuario archivo.txt          # Cambiar propietario en el servidor

# === Operaciones de local ===
lmkdir nueva-carpeta               # Crear directorio local
! comando                          # Ejecutar un comando local (ej: ! ls)

# === Salir de SFTP ===
bye
exit
quit

SFTP en modo batch (no interactivo)

# Ejecutar comandos SFTP desde un script sin sesión interactiva:
# Crear un archivo de comandos:
cat > /tmp/sftp-commands.txt << 'EOF'
cd /var/www/html
put index.php
put styles.css
put app.js
ls -la
bye
EOF

# Ejecutar el batch:
sftp -b /tmp/sftp-commands.txt usuario@servidor.com

# Alternativa: pasar comandos directamente con echo:
echo "get /var/log/nginx/error.log ./logs/" | sftp usuario@servidor.com

Comando ssh-keygen: gestionar claves SSH

Generar nuevas claves

# Generar clave Ed25519 (recomendado en 2026):
ssh-keygen -t ed25519 -C "descripcion-de-la-clave"
# Opciones:
# -t ed25519: algoritmo Ed25519
# -C "comentario": texto identificativo (aparece al final de la clave pública)
# El sistema pedirá:
# - Ruta donde guardar: acepta el defecto (~/.ssh/id_ed25519) o especifica otra
# - Passphrase: introduce una passphrase fuerte para proteger la clave privada

# Generar con ruta y passphrase directamente (para scripts):
ssh-keygen -t ed25519 -C "deploy-produccion" -f ~/.ssh/id_ed25519_prod -N "mi-passphrase"
# -f ruta: ruta del archivo de clave
# -N passphrase: passphrase (deja vacío con -N "" para sin passphrase)

# Generar RSA 4096 (para compatibilidad con sistemas legacy):
ssh-keygen -t rsa -b 4096 -C "servidor-legacy"

# Generar sin passphrase (para automatización, con cuidado):
ssh-keygen -t ed25519 -C "ci-cd-deploy" -f ~/.ssh/id_ed25519_cicd -N ""

Ver información de claves existentes

# Ver la huella digital (fingerprint) de una clave pública:
ssh-keygen -lf ~/.ssh/id_ed25519.pub
# Resultado: 256 SHA256:abc123... descripcion-de-la-clave (ED25519)

# Ver el fingerprint en formato antiguo MD5 (para comparar con sistemas legacy):
ssh-keygen -lf ~/.ssh/id_ed25519.pub -E md5

# Ver la clave pública desde la clave privada (si perdiste el .pub):
ssh-keygen -y -f ~/.ssh/id_ed25519
# Resultado: ssh-ed25519 AAAAC3Nza... descripcion

# Ver el fingerprint de la clave de host de un servidor remoto:
ssh-keyscan -t ed25519 servidor.com | ssh-keygen -lf -
# Compara el resultado con lo que te muestra ssh al conectar por primera vez

Modificar claves existentes

# Cambiar la passphrase de una clave existente:
ssh-keygen -p -f ~/.ssh/id_ed25519
# Pedirá la passphrase actual y luego la nueva

# Cambiar la passphrase directamente (para scripts):
ssh-keygen -p -f ~/.ssh/id_ed25519 -P "passphrase-actual" -N "nueva-passphrase"

# Cambiar el comentario de una clave:
ssh-keygen -c -C "nuevo-comentario" -f ~/.ssh/id_ed25519

# Convertir el formato de la clave (de PEM antiguo a nuevo formato OpenSSH):
ssh-keygen -p -f ~/.ssh/id_rsa -m OpenSSH

Gestionar el archivo known_hosts

# Ver todas las claves de host guardadas:
cat ~/.ssh/known_hosts

# Eliminar la entrada de un servidor específico (cuando el host cambió su clave):
ssh-keygen -R servidor.com
ssh-keygen -R 195.234.56.78

# Eliminar entradas antiguas y añadir la nueva automáticamente:
ssh-keygen -R servidor.com && ssh-keyscan servidor.com >> ~/.ssh/known_hosts

# Añadir la clave de host de un servidor al known_hosts de forma manual:
# (Útil en scripts de automatización para evitar la pregunta interactiva)
ssh-keyscan -H servidor.com >> ~/.ssh/known_hosts
# -H: guarda el hostname en formato hash (más seguro, pero menos legible)

Comando ssh-copy-id: instalar claves en servidores

# Instalar la clave pública predeterminada en un servidor:
ssh-copy-id usuario@servidor.com
# Pedirá la contraseña del usuario en el servidor una vez
# Después, la conexión será posible solo con la clave

# Instalar una clave específica:
ssh-copy-id -i ~/.ssh/id_ed25519.pub usuario@servidor.com

# Instalar en un servidor con puerto personalizado:
ssh-copy-id -p 2222 -i ~/.ssh/id_ed25519.pub usuario@servidor.com

# Si ssh-copy-id no está disponible (macOS o Windows sin OpenSSH completo):
cat ~/.ssh/id_ed25519.pub | ssh usuario@servidor.com 'mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'

# Verificar que la clave se instaló correctamente:
ssh -i ~/.ssh/id_ed25519 usuario@servidor.com 'echo "Autenticación por clave exitosa"'

El archivo ~/.ssh/config: simplifica todas tus conexiones

El archivo ~/.ssh/config permite definir configuraciones personalizadas para cada servidor o grupo de servidores, evitando tener que recordar y escribir opciones largas en cada conexión. Es una de las herramientas más útiles y menos conocidas de SSH.

Estructura básica

# ~/.ssh/config — configuración de conexiones SSH

# Configuración global (se aplica a todas las conexiones):
Host *
    ServerAliveInterval 60        # Keepalive cada 60 segundos
    ServerAliveCountMax 3         # Cerrar si no hay respuesta en 3 intentos
    AddKeysToAgent yes            # Añadir claves automáticamente al agente
    IdentityFile ~/.ssh/id_ed25519  # Clave por defecto para todas las conexiones

# Servidor de producción:
Host prod
    HostName 195.234.56.78        # IP o dominio real del servidor
    User admin                    # Usuario en el servidor
    Port 22                       # Puerto SSH
    IdentityFile ~/.ssh/id_ed25519_prod  # Clave específica para este servidor

# Servidor de staging:
Host staging
    HostName staging.sys4net.com
    User deploy
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_staging

# Servidor de base de datos (solo accesible a través del bastion):
Host db-prod
    HostName 10.0.0.100           # IP privada del servidor de base de datos
    User dbadmin
    ProxyJump bastion             # Salta a través del servidor bastion
    IdentityFile ~/.ssh/id_ed25519_prod

# Servidor bastion:
Host bastion
    HostName bastion.sys4net.com
    User admin
    IdentityFile ~/.ssh/id_ed25519_bastion

# GitHub (para Git sobre SSH):
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github

# GitLab propio:
Host gitlab.miempresa.com
    HostName gitlab.miempresa.com
    User git
    Port 22
    IdentityFile ~/.ssh/id_ed25519_gitlab

# Ahora las conexiones son simplemente:
# ssh prod          → conecta a 195.234.56.78 como admin con la clave correcta
# ssh staging       → conecta a staging.sys4net.com como deploy en puerto 2222
# ssh db-prod       → conecta a través del bastion a la base de datos
# git clone git@github.com:usuario/repo.git → usa la clave de GitHub

Opciones avanzadas del archivo config

# Control de forwarding por servidor:
Host servidor-con-agente
    HostName servidor.com
    User admin
    ForwardAgent yes              # Permite usar tu clave local desde ese servidor

Host servidor-sin-agente
    HostName otro-servidor.com
    User usuario
    ForwardAgent no               # Desactiva el forwarding (más seguro por defecto)

# Multiplexación de conexiones (reutilizar una conexión SSH existente):
Host *
    ControlMaster auto            # Crear o reutilizar conexión maestra automáticamente
    ControlPath ~/.ssh/cm_%r@%h:%p  # Dónde guardar el socket de control
    ControlPersist 10m            # Mantener la conexión activa 10 minutos después de cerrar

# Con ControlMaster, la segunda conexión al mismo servidor es instantánea:
# Primera conexión: establece el handshake completo
# Conexiones siguientes: reutilizan el canal ya cifrado (mucho más rápido)

# Configuración de algoritmos de cifrado por servidor:
Host servidor-legacy
    HostName servidor-viejo.com
    User admin
    # Permitir algoritmos más antiguos para compatibilidad con servidores legacy:
    KexAlgorithms +diffie-hellman-group14-sha1
    HostKeyAlgorithms +ssh-rsa
    PubkeyAcceptedAlgorithms +ssh-rsa

# Variables en el archivo config:
# %h: hostname del servidor
# %r: usuario remoto
# %p: puerto
# %u: usuario local
# %i: UID local

Túneles SSH: reenvío de puertos

Reenvío de puerto local (Local Port Forwarding)

# Sintaxis: ssh -L puerto_local:host_remoto:puerto_remoto usuario@servidor
# Reenvía el puerto local de tu máquina al puerto de un host accesible desde el servidor

# Acceder al phpMyAdmin del servidor de forma segura:
# (phpMyAdmin solo escucha en localhost:80 del servidor, no expuesto a internet)
ssh -L 8080:localhost:80 usuario@servidor.com
# Ahora abre http://localhost:8080/phpmyadmin en tu navegador

# Acceder a MySQL del servidor directamente desde TablePlus o DBeaver:
ssh -L 3307:localhost:3306 usuario@servidor.com
# Conecta tu cliente MySQL a: Host=127.0.0.1, Puerto=3307

# Acceder a un servidor de Redis que solo escucha en localhost:
ssh -L 6380:localhost:6379 usuario@servidor.com

# Acceder a un servidor web en la red interna del servidor:
# (el servidor puede acceder a 10.0.0.20 pero tú no directamente)
ssh -L 8090:10.0.0.20:80 usuario@servidor-bastion.com

# Túnel en background (sin terminal interactiva):
ssh -fNL 8080:localhost:80 usuario@servidor.com
# -f: va al background
# -N: no ejecuta ningún comando remoto (solo el túnel)

# Múltiples túneles en una sola conexión:
ssh -L 8080:localhost:80 -L 3307:localhost:3306 -L 6380:localhost:6379 usuario@servidor.com

Reenvío de puerto remoto (Remote Port Forwarding)

# Sintaxis: ssh -R puerto_remoto:host_local:puerto_local usuario@servidor
# Expone un puerto de tu máquina local en el servidor remoto

# Exponer tu servidor de desarrollo local (puerto 3000) en el servidor remoto (puerto 9090):
# Útil para que un cliente vea tu trabajo en progreso sin que tengas IP pública
ssh -R 9090:localhost:3000 usuario@servidor.com
# Ahora quien acceda a http://servidor.com:9090 verá tu servidor local en el puerto 3000

# Exponer en background:
ssh -fNR 9090:localhost:3000 usuario@servidor.com

# Para que el puerto remoto sea accesible desde cualquier IP (no solo localhost):
# En /etc/ssh/sshd_config del servidor: GatewayPorts yes
# Luego:
ssh -R 0.0.0.0:9090:localhost:3000 usuario@servidor.com

Proxy SOCKS dinámico

# Crear un proxy SOCKS5 dinámico que enruta todo el tráfico a través del servidor:
ssh -D 1080 usuario@servidor.com
# Configura tu navegador para usar SOCKS5 en 127.0.0.1:1080

# En background:
ssh -fND 1080 usuario@servidor.com

# Uso con curl (útil para verificar qué IP pública ve un sitio web):
curl --socks5 127.0.0.1:1080 https://ifconfig.me
# Mostrará la IP del servidor SSH, no la tuya

Multiplexación de conexiones SSH: más rápido en el trabajo diario

La multiplexación de SSH permite reutilizar una conexión SSH ya establecida para nuevas sesiones, evitando el overhead del handshake criptográfico en cada conexión. El resultado es que la segunda conexión, el scp y el sftp al mismo servidor son prácticamente instantáneos:

# Configurar multiplexación en ~/.ssh/config:
Host *
    ControlMaster auto
    ControlPath /tmp/ssh-%r@%h:%p
    ControlPersist 10m

# Con esta configuración:
ssh prod                    # Primera conexión: handshake completo (~1-2 segundos)
ssh prod                    # Segunda conexión: instantánea (reutiliza el canal)
scp archivo.txt prod:/tmp/  # También instantáneo
sftp prod                   # También instantáneo

# Ver las conexiones maestras activas:
ls /tmp/ssh-*

# Cerrar una conexión maestra específica:
ssh -O exit prod

Los atajos de escape de SSH: control avanzado de sesiones

SSH tiene un conjunto de secuencias de escape que permiten controlar la sesión sin cerrarla. El carácter de escape por defecto es la tilde (~), que debe ir al inicio de una línea después de pulsar Enter:

# Para activar los atajos de escape: pulsa Enter, luego ~ (tilde) y luego la tecla:

~.    # Cerrar la conexión SSH (útil cuando la sesión se ha colgado)
~?    # Ver todos los atajos de escape disponibles
~^Z   # Suspender la sesión SSH (vuelve al shell local; retoma con 'fg')
~#    # Ver las conexiones reenviadas activas
~&    # Poner la sesión SSH en background

# Para ejecutar en background y volver al shell local mientras el servidor trabaja:
# Dentro de la sesión SSH:
nohup comando-largo &   # Ejecuta en background con nohup
# Pulsa Enter, luego ~^Z para suspender la sesión SSH
# Ahora puedes hacer otras cosas en tu terminal local
fg  # Para volver a la sesión SSH

Comandos de administración del servidor via SSH

Una vez conectado al servidor, estos son los comandos de administración Linux más útiles en el trabajo diario:

# === Estado del sistema ===
uptime          # Carga del sistema y tiempo activo
top             # Procesos en tiempo real (q para salir)
htop            # Versión mejorada de top (si está instalado)
free -h         # Uso de memoria RAM y swap
df -h           # Espacio en disco por partición
du -sh /ruta/   # Tamaño de un directorio específico
iostat -x 1     # Estadísticas de I/O de disco

# === Logs del servidor ===
tail -f /var/log/nginx/error.log          # Seguir el log de Nginx en tiempo real
tail -100 /var/log/apache2/access.log     # Ver las últimas 100 líneas de acceso
journalctl -u nginx -f                    # Log de Nginx vía systemd en tiempo real
journalctl --since "1 hour ago"          # Logs del sistema de la última hora

# === Gestión de servicios ===
sudo systemctl status nginx               # Estado del servicio Nginx
sudo systemctl restart nginx             # Reiniciar Nginx
sudo systemctl reload nginx              # Recargar configuración sin reiniciar
sudo systemctl enable nginx              # Activar inicio automático

# === Procesos ===
ps aux | grep php                        # Ver procesos PHP activos
kill -9 PID                             # Forzar cierre de un proceso por su PID
pkill php-fpm                           # Cerrar todos los procesos php-fpm

# === Red ===
ss -tlnp                                # Puertos TCP escuchando
ss -tn | grep :443                      # Conexiones activas al puerto 443
netstat -s | grep -i "retransmit"       # Estadísticas de retransmisiones TCP

Transferencia eficiente de archivos grandes

# rsync sobre SSH: más eficiente que scp para directorios grandes
# Solo transfiere los archivos que han cambiado, no el directorio completo:
rsync -avz --progress ./directorio/ usuario@servidor.com:/var/www/html/directorio/
# -a: modo archivo (preserva permisos, timestamps, links simbólicos)
# -v: verbose (muestra qué se transfiere)
# -z: compresión durante la transferencia
# --progress: muestra la barra de progreso

# Excluir archivos o directorios de la sincronización:
rsync -avz --exclude='.git/' --exclude='node_modules/' --exclude='*.log' \
      ./proyecto/ usuario@servidor.com:/var/www/html/proyecto/

# Sincronización en modo dry-run (muestra qué haría sin hacerlo):
rsync -avzn ./directorio/ usuario@servidor.com:/var/www/html/directorio/
# -n: dry-run

# Eliminar en el destino los archivos que ya no existen en el origen:
rsync -avz --delete ./directorio/ usuario@servidor.com:/var/www/html/directorio/
# CUIDADO: --delete elimina archivos en el servidor que no están en local

# rsync como backup incremental al servidor:
rsync -avz --backup --backup-dir=/backup/$(date +%Y-%m-%d) \
      ./datos/ usuario@servidor.com:/backup/actual/

Preguntas frecuentes sobre comandos SSH

¿Cuál es la diferencia entre scp y rsync para transferir archivos?

SCP copia siempre todos los archivos especificados, independientemente de si ya existen en el destino o de si han cambiado. rsync compara origen y destino y solo transfiere las diferencias: si un archivo de 1 GB tiene un cambio de 10 KB, rsync solo transfiere esos 10 KB mientras que scp copiaría el gigabyte completo. Para transferencias únicas de archivos nuevos, scp es más sencillo. Para sincronización de directorios, actualizaciones frecuentes o archivos grandes con cambios parciales, rsync es significativamente más eficiente. En 2026, rsync sobre SSH es el estándar para despliegues y backups de código.

¿Cómo puedo mantener activa una sesión SSH que se desconecta por inactividad?

Las sesiones SSH se desconectan por inactividad cuando el servidor tiene configurado un timeout o cuando el firewall cierra las conexiones TCP inactivas. La solución es configurar el keepalive en el cliente añadiendo en ~/.ssh/configServerAliveInterval 60 y ServerAliveCountMax 3. Esto hace que el cliente envíe un paquete de keepalive al servidor cada 60 segundos, manteniendo la conexión activa. Alternativamente, usa tmux o screen en el servidor: incluso si la conexión SSH se cae, los procesos en tmux siguen ejecutándose y puedes reconectar y retomar la sesión.

¿Cómo puedo copiar archivos entre dos servidores remotos sin descargarlos primero a mi máquina?

Con SCP puedes copiar entre dos servidores remotos con scp usuario@servidor1:/origen usuario@servidor2:/destino. Por defecto, SCP intenta una conexión directa entre los servidores, lo que requiere que tu clave esté instalada en el primer servidor. Con la opción -3, la copia pasa por tu máquina local: scp -3 usuario@servidor1:/origen usuario@servidor2:/destino. Otra alternativa es conectarte al primer servidor por SSH y desde ahí usar SCP o rsync para copiar al segundo servidor.

¿Qué hace exactamente la opción -fN de SSH?

La opción -f indica a SSH que vaya al background después de la autenticación pero antes de ejecutar ningún comando. La opción -N indica que no debe ejecutar ningún comando remoto (solo establece la conexión y los túneles configurados). Combinadas (ssh -fN), permiten crear un túnel SSH en background que persiste mientras no lo cierres explícitamente. Es la forma estándar de crear túneles SSH persistentes para acceso a bases de datos, proxies, etc. Para cerrar estos túneles, busca el proceso con ps aux | grep ssh y mátalo con kill PID, o usa la multiplexación de conexiones con ssh -O exit.

¿Cómo puedo saber si una conexión SSH usa mi clave o la contraseña?

Usa la opción -v (verbose) al conectar: ssh -v usuario@servidor.com. En la salida verás líneas como "Offering public key: /home/usuario/.ssh/id_ed25519" cuando el cliente intenta la clave, y "Server accepts key" cuando el servidor la acepta. Si el servidor no acepta la clave y el cliente cae back a la contraseña, verás "Trying password authentication". También puedes forzar explícitamente el uso de la clave con -o PasswordAuthentication=no: si la conexión falla, confirma que la contraseña no se está usando.

¿Cómo puedo ejecutar un comando largo en el servidor sin que se interrumpa si se cae la conexión SSH?

Usa nohup comando & para que el comando continúe ejecutándose aunque la sesión SSH se cierre: ssh usuario@servidor.com 'nohup mi-proceso-largo > output.log 2>&1 &'. La solución más robusta es usar tmux o screen: conéctate por SSH, inicia tmux con tmux new -s mi-sesion, lanza el comando, y si la conexión cae reconecta y retoma la sesión con tmux attach -t mi-sesion. Tmux mantiene los procesos activos en el servidor independientemente de la conexión SSH.