Configuración de Túneles SSH (Reenvío de Puertos): Guía Completa
Introducción
El tunelado SSH, también conocido como reenvío de puertos SSH, es una técnica poderosa que aprovecha el protocolo SSH seguro para crear túneles cifrados para reenviar tráfico de red entre sistemas. Este método versátil te permite acceder de forma segura a servicios que se ejecutan en redes remotas, eludir restricciones de firewall, cifrar protocolos que de otro modo serían inseguros y crear conexiones temporales similares a VPN sin requerir privilegios administrativos ni infraestructura VPN compleja.
El tunelado SSH funciona encapsulando tráfico de red arbitrario dentro de conexiones SSH, proporcionando los mismos beneficios de cifrado y autenticación que protegen tus sesiones SSH. Ya sea que necesites acceder a un servidor de bases de datos detrás de un firewall, proteger la navegación web en redes no confiables o exponer servidores de desarrollo locales temporalmente a Internet, el tunelado SSH proporciona soluciones elegantes en las que los administradores de sistemas y desarrolladores confían diariamente.
Esta guía completa cubre todos los tipos de tunelado SSH, incluyendo reenvío de puertos local, reenvío de puertos remoto, reenvío de puertos dinámico (proxy SOCKS) y escenarios avanzados de múltiples saltos. Aprenderás casos de uso prácticos, consideraciones de seguridad, técnicas de resolución de problemas y mejores prácticas para implementar túneles SSH en entornos de desarrollo, prueba y producción.
Comprendiendo los Tipos de Tunelado SSH
Reenvío de Puertos Local
El reenvío de puertos local crea un túnel desde tu máquina local hacia un destino remoto a través de un servidor SSH. El tráfico enviado a un puerto local se reenvía a través de la conexión SSH hacia un destino especificado.
Sintaxis:
ssh -L [puerto_local]:[host_destino]:[puerto_destino] [usuario]@[servidor_ssh]
Flujo:
Tu Computadora:puerto_local → Servidor SSH → host_destino:puerto_destino
Casos de Uso:
- Acceder a bases de datos remotas de forma segura
- Conectarse a servicios detrás de firewalls
- Navegación web segura a través de servidor remoto
- Acceder a recursos de red interna
Reenvío de Puertos Remoto
El reenvío de puertos remoto crea un túnel desde el servidor SSH de vuelta a tu máquina local u otro destino. El tráfico enviado a un puerto en el servidor SSH se reenvía de vuelta a través de la conexión SSH.
Sintaxis:
ssh -R [puerto_remoto]:[host_destino]:[puerto_destino] [usuario]@[servidor_ssh]
Flujo:
Servidor SSH:puerto_remoto → Tu Computadora → host_destino:puerto_destino
Casos de Uso:
- Exponer servidor de desarrollo local a Internet
- Permitir acceso remoto a servicios en tu máquina
- Crear túneles inversos a través de NAT/firewalls
- Proporcionar acceso externo temporal
Reenvío de Puertos Dinámico (Proxy SOCKS)
El reenvío de puertos dinámico crea un servidor proxy SOCKS en tu máquina local. Las aplicaciones configuradas para usar este proxy tienen su tráfico reenviado a través del servidor SSH.
Sintaxis:
ssh -D [puerto_local] [usuario]@[servidor_ssh]
Flujo:
Aplicación → Proxy SOCKS:puerto_local → Servidor SSH → Destino
Casos de Uso:
- Proteger todo el tráfico del navegador en WiFi público
- Eludir restricciones geográficas
- Enrutar múltiples aplicaciones a través del túnel
- Alternativa temporal a VPN
Prerrequisitos
Antes de configurar túneles SSH, asegúrate de tener:
- Cliente SSH instalado (OpenSSH en Linux/macOS, PuTTY en Windows)
- Acceso SSH al servidor remoto con credenciales válidas
- Conocimiento del host y puerto del servicio objetivo
- Comprensión de conceptos básicos de redes
- Permisos de firewall para los puertos requeridos (si aplica)
- Autenticación basada en claves SSH configurada (recomendado)
Verificar Instalación de SSH
# Verificar versión del cliente SSH
ssh -V
# Verificar estado del servidor SSH (en servidor remoto)
sudo systemctl status sshd
Reenvío de Puertos Local
Reenvío de Puertos Local Básico
Reenviar puerto local a servicio remoto:
# Reenviar puerto local 3307 al servidor MySQL en host remoto
ssh -L 3307:localhost:3306 [email protected]
# Ahora conectarse a MySQL localmente
mysql -h 127.0.0.1 -P 3307 -u usuario_bd -p
Explicación:
- El tráfico a
localhost:3307se reenvía a través deservidor-remoto.com - A MySQL ejecutándose en
localhost:3306(desde la perspectiva del servidor remoto) - La sesión SSH debe permanecer abierta para que el túnel funcione
Vinculación a Interfaz Específica
# Vincular solo a localhost (predeterminado)
ssh -L 127.0.0.1:3307:localhost:3306 [email protected]
# Vincular a todas las interfaces (permitir conexiones desde otras máquinas)
ssh -L 0.0.0.0:3307:localhost:3306 [email protected]
# Vincular a IP específica
ssh -L 192.168.1.100:3307:localhost:3306 [email protected]
Reenvío a Host Diferente
Reenviar a un servicio accesible desde el servidor SSH pero en un host diferente:
# Acceder al servidor de base de datos a través de host de salto
ssh -L 5432:servidor-bd.interno:5432 [email protected]
# Conectarse a PostgreSQL
psql -h localhost -p 5432 -U usuario_bd base_datos
Escenario:
host-salto.compuede acceder aservidor-bd.interno- Tu máquina no puede acceder directamente a
servidor-bd.interno - Túnel a través de
host-salto.compara alcanzar la base de datos
Múltiples Reenvíos de Puertos
Crear múltiples túneles en una sola sesión SSH:
# Reenviar múltiples servicios
ssh -L 3307:localhost:3306 \
-L 6380:localhost:6379 \
-L 8080:localhost:80 \
[email protected]
# Ahora acceder:
# MySQL en localhost:3307
# Redis en localhost:6380
# Servidor web en localhost:8080
Túnel SSH en Segundo Plano
Ejecutar túnel SSH en segundo plano:
# -f: proceso en segundo plano
# -N: no ejecutar comando remoto
ssh -f -N -L 3307:localhost:3306 [email protected]
# Verificar que el túnel está ejecutándose
ps aux | grep ssh
# Terminar túnel en segundo plano
pkill -f "ssh.*3307"
Túnel SSH Persistente con autossh
Instalar y usar autossh para reconexión automática:
# Instalar autossh
sudo apt install autossh # Ubuntu/Debian
sudo dnf install autossh # RHEL/CentOS
# Crear túnel persistente
autossh -M 0 -f -N -L 3307:localhost:3306 [email protected]
# Con opciones de reconexión
autossh -M 0 -f -N \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-L 3307:localhost:3306 [email protected]
Ejemplo Práctico: Acceso Seguro a Base de Datos
Escenario: Acceder a base de datos MySQL remota de forma segura
# Crear túnel al servidor MySQL
ssh -f -N -L 3307:localhost:3306 [email protected]
# Conectarse usando cliente MySQL local
mysql -h 127.0.0.1 -P 3307 -u admin -p
# En el cliente de base de datos
mysql> SELECT @@hostname;
# Muestra nombre del servidor remoto, confirmando que el túnel funciona
Beneficios:
- Conexión cifrada a la base de datos
- No es necesario exponer el puerto MySQL a Internet
- Puedes usar herramientas de base de datos locales con servidores remotos
Reenvío de Puertos Remoto
Reenvío de Puertos Remoto Básico
Hacer que el servicio local sea accesible desde el servidor remoto:
# Reenviar puerto 8080 en servidor remoto al puerto local 3000
ssh -R 8080:localhost:3000 [email protected]
# En el servidor remoto, acceder:
curl http://localhost:8080
# Se conecta al puerto 3000 de tu máquina local
Caso de Uso: Exponer servidor de desarrollo local para pruebas
Exponer Servicio Local a Internet
# Hacer que la aplicación web local sea accesible desde el servidor remoto
ssh -R 0.0.0.0:8080:localhost:3000 [email protected]
# Ahora accesible en:
# http://servidor-remoto.com:8080
Nota: Requiere GatewayPorts yes en /etc/ssh/sshd_config del servidor remoto
Configurar GatewayPorts en Servidor SSH
# En el servidor SSH remoto
sudo nano /etc/ssh/sshd_config
# Agregar o modificar:
GatewayPorts yes
# O para más seguridad:
GatewayPorts clientspecified
# Reiniciar servicio SSH
sudo systemctl restart sshd
Túnel Inverso a Través de Firewall
Acceder a máquina detrás de NAT/firewall:
# Desde máquina detrás de firewall
ssh -R 2222:localhost:22 [email protected]
# Desde servidor público, SSH de vuelta a máquina interna
ssh -p 2222 usuario@localhost
Escenario:
- Máquina de casa/oficina detrás de NAT
- Necesitas acceso remoto sin reenvío de puertos en el router
- Crear túnel inverso a servidor público
- Conectarse de vuelta a través del túnel
Túnel Inverso Persistente
# Usar autossh para túnel inverso persistente
autossh -M 0 -f -N \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-R 2222:localhost:22 [email protected]
Crear servicio systemd para inicio automático:
sudo nano /etc/systemd/system/tunel-inverso.service
[Unit]
Description=Túnel SSH Inverso
After=network.target
[Service]
User=usuario_tunel
ExecStart=/usr/bin/autossh -M 0 -N \
-o "ServerAliveInterval 30" \
-o "ServerAliveCountMax 3" \
-o "ExitOnForwardFailure yes" \
-R 2222:localhost:22 [email protected]
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Habilitar e iniciar:
sudo systemctl enable tunel-inverso
sudo systemctl start tunel-inverso
sudo systemctl status tunel-inverso
Reenvío de Puertos Dinámico (Proxy SOCKS)
Crear Proxy SOCKS
# Crear proxy SOCKS en puerto local 1080
ssh -D 1080 [email protected]
# Mantener túnel abierto
# Configurar aplicaciones para usar proxy SOCKS5 en localhost:1080
Configurar Navegador para Usar Proxy SOCKS
Firefox:
- Configuración → General → Configuración de Red
- Seleccionar "Configuración manual del proxy"
- Host SOCKS:
localhost, Puerto:1080 - Seleccionar "SOCKS v5"
- Marcar "Proxy DNS al usar SOCKS v5"
Chrome/Chromium (Linux):
google-chrome --proxy-server="socks5://localhost:1080"
Proxy a nivel de sistema (Linux):
export ALL_PROXY=socks5://localhost:1080
Probar Proxy SOCKS
# Verificar dirección IP antes del túnel
curl ifconfig.me
# Iniciar túnel SOCKS
ssh -D 1080 -f -N [email protected]
# Verificar IP a través del proxy
curl --socks5 localhost:1080 ifconfig.me
# Debería mostrar la IP del servidor remoto
Usar proxychains con Túnel SOCKS
# Instalar proxychains
sudo apt install proxychains
# Configurar proxychains
sudo nano /etc/proxychains.conf
# Agregar al final:
socks5 127.0.0.1 1080
# Usar con cualquier comando
proxychains curl ifconfig.me
proxychains wget http://ejemplo.com
proxychains git clone https://github.com/usuario/repo
Navegación Segura en WiFi Público
# Crear túnel a tu servidor de casa/oficina
ssh -D 1080 -f -N -C [email protected]
# Configurar navegador para usar proxy SOCKS
# Todo el tráfico ahora cifrado y enrutado a través del servidor de casa
Técnicas Avanzadas de Tunelado SSH
Tunelado SSH Multi-Salto
Saltar a través de múltiples servidores SSH:
# Método 1: ProxyJump (OpenSSH 7.3+)
ssh -J salto1.ejemplo.com,salto2.ejemplo.com [email protected]
# Método 2: ProxyCommand
ssh -o ProxyCommand="ssh -W %h:%p [email protected]" [email protected]
# Con reenvío de puertos a través de hosts de salto
ssh -J salto.ejemplo.com -L 3307:bd.interna:3306 [email protected]
Configurar en ~/.ssh/config:
nano ~/.ssh/config
Host salto
HostName salto.ejemplo.com
User usuario_salto
Host final
HostName destino-final.com
User usuario_final
ProxyJump salto
Host tunel-bd
HostName destino-final.com
User usuario_final
ProxyJump salto
LocalForward 3307 bd.interna:3306
Uso:
# Conectar a través de host de salto
ssh final
# Crear túnel de base de datos a través de host de salto
ssh tunel-bd
Reenvío X11 con Tunelado
# Reenviar X11 y crear túnel de puerto
ssh -X -L 5901:localhost:5901 [email protected]
# Ejecutar aplicaciones GUI remotamente
firefox &
Configuración Similar a VPN
Enrutar todo el tráfico a través del túnel SSH:
# Crear túnel con reenvío de IP
ssh -D 1080 -f -N -C [email protected]
# Configurar enrutamiento (requiere root)
# Enrutar todo el tráfico a través del proxy SOCKS
# Usar herramientas como redsocks o proxychains-ng
Tunelado Comprimido
# Habilitar compresión para conexiones lentas
ssh -C -D 1080 [email protected]
# Compresión útil para:
# - Conexiones de red lentas
# - Protocolos con mucho texto
# - Transferencia de datos comprimibles
Túnel con Cifrado Específico
# Usar cifrado específico para rendimiento
ssh -c [email protected] -D 1080 [email protected]
# Listar cifrados disponibles
ssh -Q cipher
Archivos de Configuración de Túneles SSH
Usar Archivo de Configuración SSH
Simplificar comandos de túnel complejos:
nano ~/.ssh/config
# Túnel de base de datos
Host tunel_bd
HostName servidor-remoto.ejemplo.com
User admin_bd
LocalForward 3307 localhost:3306
LocalForward 6380 localhost:6379
# Proxy SOCKS
Host proxy_socks
HostName servidor-proxy.ejemplo.com
User usuario_proxy
DynamicForward 1080
# Túnel inverso
Host tunel_inverso
HostName servidor-publico.ejemplo.com
User usuario_tunel
RemoteForward 8080 localhost:3000
Uso:
# Crear túnel de base de datos
ssh tunel_bd
# Crear proxy SOCKS
ssh proxy_socks
# Crear túnel inverso
ssh tunel_inverso
Opciones Persistentes
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
TCPKeepAlive yes
ExitOnForwardFailure yes
Casos de Uso de Reenvío de Puertos
Caso de Uso 1: Administración Segura de Base de Datos
# Acceder a MySQL sin exponerlo a Internet
ssh -L 3307:localhost:3306 [email protected]
# Conectar con MySQL Workbench
# Host: 127.0.0.1
# Puerto: 3307
Caso de Uso 2: Acceder a Aplicaciones Web Internas
# Acceder a aplicación corporativa interna
ssh -L 8080:app-interna.empresa.local:80 [email protected]
# Abrir navegador en http://localhost:8080
Caso de Uso 3: Pruebas de Servidor de Desarrollo
# Compartir desarrollo local con equipo remoto
ssh -R 0.0.0.0:8080:localhost:3000 [email protected]
# Equipo accede: http://servidor-demo.com:8080
Caso de Uso 4: Eludir Restricciones Geográficas
# Conectar a través de servidor en país diferente
ssh -D 1080 [email protected]
# Configurar navegador para usar proxy SOCKS
# Acceder a contenido restringido por región
Caso de Uso 5: Escritorio Remoto Seguro
# Reenviar VNC a través de SSH
ssh -L 5901:localhost:5901 [email protected]
# Conectar cliente VNC a localhost:5901
vncviewer localhost:5901
Caso de Uso 6: Git a Través de Firewall Corporativo
# Acceder a GitHub a través de firewall corporativo
ssh -D 1080 [email protected]
# Configurar Git para usar proxy SOCKS
git config --global http.proxy socks5://127.0.0.1:1080
git config --global https.proxy socks5://127.0.0.1:1080
Monitoreo y Gestión de Túneles
Listar Túneles SSH Activos
# Mostrar procesos SSH
ps aux | grep ssh
# Mostrar conexiones SSH detalladas
ss -tuln | grep ssh
netstat -tuln | grep ssh
# Mostrar puertos reenviados
lsof -i -n | grep ssh
Terminar Túnel Específico
# Encontrar proceso SSH
ps aux | grep "ssh.*3307"
# Terminar por PID
kill 12345
# O por patrón
pkill -f "ssh.*3307"
Monitorear Tráfico del Túnel
# Monitorear uso de ancho de banda
iftop -i tun0
# Monitorear conexiones a través del túnel
sudo tcpdump -i lo port 3307
# Verificar que el túnel está reenviando
nc -zv localhost 3307
Depurar Túneles
# Salida SSH detallada
ssh -v -L 3307:localhost:3306 [email protected]
# Extra detallada
ssh -vvv -L 3307:localhost:3306 [email protected]
# Verificar error específico
journalctl -u sshd | grep "forward"
Consideraciones de Seguridad
Usar Autenticación con Clave SSH
# Generar clave SSH
ssh-keygen -t ed25519 -C "clave-tunel"
# Copiar al servidor remoto
ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]
# Usar clave para túnel
ssh -i ~/.ssh/id_ed25519 -L 3307:localhost:3306 [email protected]
Restringir Reenvío de Puertos
En el servidor SSH, limitar capacidades de reenvío:
sudo nano /etc/ssh/sshd_config
# Deshabilitar todo el reenvío
AllowTcpForwarding no
# Permitir solo reenvío local
AllowTcpForwarding local
# Permitir solo reenvío remoto
AllowTcpForwarding remote
# Deshabilitar reenvío X11 si no es necesario
X11Forwarding no
# Restringir a usuarios específicos
Match User usuario_tunel
AllowTcpForwarding yes
Reiniciar SSH:
sudo systemctl restart sshd
Limitar Interfaces de Vinculación
# Vincular solo a localhost (más seguro)
ssh -L 127.0.0.1:3307:localhost:3306 [email protected]
# Evitar vincular a 0.0.0.0 a menos que sea necesario
# Esto expone el puerto a todas las interfaces de red
Usar Reglas de Firewall
# Permitir solo conexiones localhost al puerto reenviado
sudo ufw allow from 127.0.0.1 to any port 3307
# O con iptables
sudo iptables -A INPUT -p tcp --dport 3307 -s 127.0.0.1 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 3307 -j DROP
Monitorear Túneles No Autorizados
# Verificar procesos SSH inesperados
ps aux | grep ssh
# Monitorear registros de autenticación SSH
sudo tail -f /var/log/auth.log | grep sshd
# Listar todos los puertos en escucha
sudo ss -tuln
Auditar Uso de Túneles
# Habilitar registro SSH
sudo nano /etc/ssh/sshd_config
# Establecer:
LogLevel VERBOSE
# Monitorear registros
sudo journalctl -u sshd -f
Resolución de Problemas Comunes
Problema 1: Puerto Ya en Uso
Síntomas:
bind: Address already in use
channel_setup_fwd_listener_tcpip: cannot listen to port: 3307
Soluciones:
# Encontrar proceso usando el puerto
sudo lsof -i :3307
sudo ss -tulpn | grep 3307
# Terminar proceso
sudo kill -9 <PID>
# O usar puerto local diferente
ssh -L 3308:localhost:3306 [email protected]
Problema 2: Conexión Rechazada
Síntomas:
channel 2: open failed: connect failed: Connection refused
Diagnóstico:
# En el servidor remoto, verificar que el servicio está ejecutándose
sudo systemctl status mysql
sudo ss -tuln | grep 3306
# Verificar que el servicio está escuchando en la interfaz correcta
netstat -tuln | grep 3306
Soluciones:
# Iniciar servicio en servidor remoto
sudo systemctl start mysql
# Verificar que el servicio se vincula a la interfaz correcta
# Editar configuración del servicio para escuchar en 127.0.0.1 o 0.0.0.0
Problema 3: El Túnel se Desconecta
Síntomas:
- El túnel SSH se cae después de un período de inactividad
- Error "Broken pipe"
Soluciones:
# Habilitar keepalive en configuración SSH
nano ~/.ssh/config
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
# O usar en comando
ssh -o ServerAliveInterval=60 -L 3307:localhost:3306 [email protected]
# Usar autossh para reconexión automática
autossh -M 0 -o "ServerAliveInterval 30" -L 3307:localhost:3306 [email protected]
Problema 4: Permiso Denegado (Puerto < 1024)
Síntomas:
bind: Permission denied
Soluciones:
# Usar puerto >= 1024
ssh -L 8080:localhost:80 [email protected]
# O ejecutar con sudo (no recomendado)
sudo ssh -L 80:localhost:80 [email protected]
Problema 5: GatewayPorts No Funciona
Síntomas:
- El reenvío remoto solo es accesible desde localhost en el servidor remoto
Soluciones:
# En el servidor SSH
sudo nano /etc/ssh/sshd_config
# Cambiar:
GatewayPorts yes
# Reiniciar SSH
sudo systemctl restart sshd
# Verificar configuración
sudo sshd -T | grep gatewayports
Mejores Prácticas
1. Usar Archivo de Configuración SSH
Organizar túneles en ~/.ssh/config:
Host bd-prod
HostName produccion.ejemplo.com
User admin_bd
IdentityFile ~/.ssh/clave_prod
LocalForward 3307 localhost:3306
ServerAliveInterval 60
2. Implementar Mínimo Privilegio
- Crear usuarios SSH dedicados para tunelado
- Limitar permisos de reenvío
- Restringir acceso shell si solo se necesita tunelado
# En sshd_config
Match User usuario_tunel
AllowTcpForwarding yes
X11Forwarding no
PermitTunnel no
ForceCommand /bin/false
3. Documentar Configuraciones de Túneles
Mantener documentación:
- Propósito de cada túnel
- Detalles de origen y destino
- Consideraciones de seguridad
- Información de contacto para resolución de problemas
4. Monitorear Actividad de Túneles
# Crear script de monitoreo
#!/bin/bash
# verificar-tunel.sh
PUERTO_TUNEL=3307
if ! nc -z localhost $PUERTO_TUNEL; then
echo "Túnel caído, recreando..."
autossh -M 0 -f -N -L $PUERTO_TUNEL:localhost:3306 [email protected]
fi
Agregar a cron:
*/5 * * * * /usr/local/bin/verificar-tunel.sh
5. Usar Herramientas de Automatización
Para entornos de producción:
- Ansible para despliegue de túneles
- Servicios systemd para túneles persistentes
- Herramientas de monitoreo (Nagios, Zabbix) para verificación de salud de túneles
6. Asegurar Extremos de Túneles
- Mantener servidor SSH actualizado
- Usar claves SSH fuertes (ED25519, RSA 4096)
- Habilitar fail2ban para protección contra fuerza bruta
- Auditar regularmente registros de acceso SSH
Conclusión
El tunelado SSH proporciona un método versátil y seguro para reenvío de puertos y creación de vías de red cifradas sin requerir infraestructura VPN ni privilegios administrativos. Ya sea que necesites reenvío de puertos local para acceso seguro a bases de datos, reenvío de puertos remoto para exponer servicios locales o reenvío dinámico para funcionalidad de proxy SOCKS, el tunelado SSH ofrece soluciones elegantes para desafíos comunes de redes.
Aspectos clave:
- Reenvío local proporciona acceso seguro a servicios remotos
- Reenvío remoto expone servicios locales a través de servidores remotos
- Reenvío dinámico crea proxies SOCKS para enrutamiento flexible
- Archivos de configuración SSH simplifican la gestión de túneles complejos
- autossh asegura conectividad de túnel persistente
- Consideraciones de seguridad son esenciales para despliegue seguro de túneles
- Monitoreo y documentación mantienen infraestructura de túneles confiable
Dominar las técnicas de tunelado SSH mejora tu conjunto de herramientas de administración de sistemas, mejora la postura de seguridad y resuelve desafíos complejos de redes con sobrecarga mínima. Las habilidades cubiertas en esta guía se aplican en entornos de desarrollo, prueba y producción, haciendo del tunelado SSH una técnica indispensable para la gestión moderna de infraestructura.
Para escenarios avanzados, explora herramientas como sshuttle para proxy transparente, stunnel para cifrado de protocolos heredados y WireGuard para requisitos de VPN dedicados más allá de las capacidades de SSH.


