SCP, SFTP y tunnels
SSH no solo abre shell: copia archivos y reenvia puertos TCP. Eso permite editar remotos, sincronizar artefactos y alcanzar servicios privados (Postgres, Redis, paneles admin) como si estuvieran en localhost.
SCP
Copia puntual archivo a archivo:
# Local -> remoto
scp ./app.tar.gz deploy@servidor:/var/www/
# Remoto -> local
scp deploy@servidor:/var/log/nginx/error.log ./error.log
# Directorio recursivo
scp -r ./dist/ deploy@servidor:/var/www/app/
# Con alias de config y puerto ya definidos
scp ./backup.sql prod-api:/tmp/scp usa el mismo ~/.ssh/config que ssh.
Limitacion: no reanuda bien transferencias grandes interrumpidas. Para eso, rsync sobre SSH:
rsync -avz --progress ./dist/ deploy@servidor:/var/www/app/SFTP
Sesion interactiva estilo FTP cifrado:
sftp deploy@servidorComandos habituales dentro de sftp:
ls
lcd ./local-dir
cd /var/www
put archivo.txt
get remoto.log
mkdir uploads
byeEn scripts, preferible scp/rsync o el cliente SFTP no interactivo.
Tunnel local (-L)
Expone un puerto remoto en tu maquina:
ssh -N -L 5432:127.0.0.1:5432 deploy@bastion| Flag | Significado |
|---|---|
-L local:destino:puerto | Escucha local y reenvia al destino visto desde el remoto |
-N | No abras shell; solo tunnel |
Ahora tu cliente Postgres apunta a localhost:5432 y el trafico viaja cifrado hasta el bastion, que habla con Postgres en su 127.0.0.1.
Via config:
Host db-tunnel
HostName bastion.ejemplo.com
User deploy
LocalForward 5432 127.0.0.1:5432ssh -N db-tunnelTunnel remoto (-R)
El servidor escucha y reenvia hacia tu laptop (menos frecuente; util para demos o webhooks temporales):
ssh -N -R 8080:127.0.0.1:3000 usuario@servidorQuien conecte a servidor:8080 llega a tu app local en :3000 (si GatewayPorts lo permite en el servidor).
Tunnel dinamico (-D) SOCKS
ssh -N -D 1080 deploy@bastionConfigura el navegador o ALL_PROXY=socks5://127.0.0.1:1080 para salir a internet desde la red del bastion.
Casos practicos
- Adminer / Grafana internos sin abrir el puerto al mundo:
ssh -N -L 3000:10.0.1.50:3000 bastion
# Abrir http://127.0.0.1:3000- Copiar logs de incidente:
scp prod-api:/var/log/app/error.log ./incident-$(date +%F).log- Despliegue simple de estaticos:
rsync -avz --delete ./dist/ deploy@prod-api:/var/www/app/Errores habituales
- Confundir
-L 5432:localhost:5432pensando quelocalhostes tu PC: en-L, el host del medio se resuelve desde el servidor SSH. - Dejar tunnels abiertos con servicios sensibles en
0.0.0.0local. - Usar
scprecursivo sobre node_modules o .git enormes. - Olvidar
-Ny cerrar el tunnel al hacerexitdel shell (a veces deseable; a veces no).
Buenas practicas
- Tunnels con
-Nen una terminal dedicada o servicio de usuario. - No publiques
-Ren produccion sin autenticacion adicional. - Prefiere VPN o mesh (WireGuard, Tailscale) si el acceso interno es diario y amplio.
- Audita quien tiene capacidad de abrir tunnels a datos productivos.
Ejercicio
- Monta un tunnel local a un servicio (Postgres, Redis o un HTTP interno).
- Conecta con el cliente contra
127.0.0.1. - Copia un archivo con
scpy sincroniza un directorio conrsync -avz.
Siguiente paso
Continua con Hardening del servidor.
