Este script facilita la creación y gestión de conexiones de port forwarding seguras utilizando AWS Systems Manager (SSM), permitiéndote acceder a recursos privados en AWS sin necesidad de exponer puertos públicamente o mantener un host bastión dedicado.
Este repositorio contiene varios documentos para ayudarte a entender y utilizar el AWS SSM Port Forwarding Manager:
- README.md (este archivo) - Visión general y uso básico
- GUIA_INSTALACION.md - Instrucciones detalladas de instalación para Linux, Windows y macOS
- EXPLICACION_CODIGO.md - Explicación técnica del funcionamiento interno del script
- PERMISOS_IAM.md - Guía completa de permisos AWS IAM y consideraciones de seguridad
- Descripción
- Requisitos previos
- Instalación
- Uso del script
- Flujo de trabajo típico
- Explicación detallada de funcionalidades
- Seguridad
- Solución de problemas
- Preguntas frecuentes
AWS SSM Port Forwarding Manager es una herramienta que simplifica el proceso de establecer túneles seguros a recursos privados en AWS (como bases de datos RDS, instancias EC2 en subredes privadas, etc.) utilizando el servicio AWS Systems Manager Session Manager.
La herramienta permite:
- Crear y guardar configuraciones de conexión
- Gestionar perfiles de AWS y sesiones de SSO
- Seleccionar instancias intermediarias con el agente SSM instalado
- Establecer túneles seguros a hosts remotos
- Almacenar las configuraciones de forma encriptada
Para utilizar este script necesitas:
- Python 3.6 o superior instalado en tu sistema
- AWS CLI configurado con credenciales válidas
- Plugin de Session Manager para AWS CLI instalado
- Al menos una instancia EC2 con el agente SSM instalado y configurado
- Permisos IAM adecuados para usar SSM Session Manager
-
Verifica la versión de Python:
python3 --version
-
Verifica que AWS CLI está instalado:
aws --version
-
Verifica que el plugin de Session Manager está instalado:
session-manager-plugin --version
-
Verifica que tienes instancias gestionadas por SSM:
aws ssm describe-instance-information
-
Instala las dependencias necesarias:
pip install boto3 inquirer tabulate cryptography
-
Descarga el script:
# Clona el repositorio o copia el script directamente chmod +x ssm_port_forwarder.py
-
Verifica la instalación:
./ssm_port_forwarder.py --help
La forma más sencilla de usar el script es en modo interactivo:
./ssm_port_forwarder.py
Esto mostrará un menú con las siguientes opciones:
- Crear nueva conexión
- Listar conexiones guardadas
- Conectar usando una conexión guardada
- Eliminar conexión
- Salir
También puedes usar el script con argumentos de línea de comandos:
# Crear una nueva conexión
./ssm_port_forwarder.py --new
# Listar conexiones guardadas
./ssm_port_forwarder.py --list
# Conectar usando una conexión guardada
./ssm_port_forwarder.py --connect "nombre_conexion"
# Eliminar una conexión guardada
./ssm_port_forwarder.py --delete "nombre_conexion"
Al crear una nueva conexión, el script te guiará a través de los siguientes pasos:
- Nombre de la conexión: Asigna un nombre descriptivo a la conexión
- Selección de perfil AWS: Elige el perfil AWS a utilizar
- Autenticación SSO (si es necesario): El script verificará si necesitas iniciar sesión con SSO
- Selección de instancia intermediaria: Elige una instancia EC2 con el agente SSM instalado
- Configuración del host remoto:
- Dirección IP o nombre del host remoto
- Puerto remoto al que quieres conectarte
- Puerto local que quieres usar para la conexión
Al iniciar una conexión:
- El script establece un túnel seguro a través de SSM
- El puerto local especificado se abre en tu máquina
- Todo el tráfico a ese puerto local se reenvía al puerto remoto del host destino
- La sesión permanece activa hasta que presiones Ctrl+C
Una vez establecida la conexión, puedes usar cualquier cliente para conectarte al servicio remoto a través de localhost:puerto_local
. Por ejemplo:
- Para una base de datos MySQL/PostgreSQL: Usa tu cliente SQL favorito
- Para un servidor web: Abre tu navegador y visita
http://localhost:puerto_local
El script detecta automáticamente los perfiles AWS configurados en tu sistema, buscando en:
~/.aws/credentials
~/.aws/config
Esto te permite seleccionar fácilmente el perfil adecuado para cada conexión.
Si utilizas AWS SSO, el script:
- Verifica si tu sesión SSO está activa
- Si la sesión ha expirado, inicia automáticamente el proceso de login
- Continúa con la operación una vez que la autenticación es exitosa
El script muestra una lista de todas las instancias gestionadas por SSM que están en estado "Online", mostrando:
- Nombre de la instancia (tag "Name")
- ID de la instancia
- Dirección IP
El script proporciona funcionalidades para gestionar la contraseña de encriptación:
- Cambio de contraseña: Puedes cambiar la contraseña en cualquier momento usando la opción "Change password" en el menú o el parámetro
--change-password
en la línea de comandos. - Confirmación de contraseña: Al crear o cambiar una contraseña, se solicita confirmación para evitar errores.
- Validación de contraseña: No se permiten contraseñas vacías.
- Límite de intentos: Se permiten hasta 3 intentos para ingresar la contraseña correcta.
El script utiliza el siguiente comando de AWS CLI para establecer el port forwarding:
aws ssm start-session \
--profile <perfil> \
--target <id-instancia> \
--document-name AWS-StartPortForwardingSessionToRemoteHost \
--parameters '{"portNumber":["<puerto-remoto>"],"localPortNumber":["<puerto-local>"],"host":["<host-remoto>"]}'
- Credenciales AWS: El script no almacena tus credenciales AWS, utiliza los perfiles configurados en tu sistema
- Contraseña de encriptación: La contraseña para encriptar las conexiones no se guarda, solo se usa un salt para la derivación de la clave
- Conexiones seguras: Todo el tráfico va a través de AWS SSM, que utiliza TLS para encriptar las comunicaciones
- Sin puertos expuestos: No es necesario abrir puertos en firewalls o grupos de seguridad
- Usa una contraseña fuerte para encriptar el archivo de conexiones
- Asegúrate de que tus instancias EC2 tengan solo los permisos mínimos necesarios
- Considera usar roles IAM temporales para acceder a AWS
- Cierra las sesiones de port forwarding cuando no las necesites
Problema: El script no muestra ninguna instancia al crear una conexión.
Solución:
- Verifica que tienes permisos para listar instancias SSM:
aws ssm describe-instance-information --profile tu_perfil
- Asegúrate de que las instancias tienen el agente SSM instalado y están en estado "Online"
- Verifica que estás usando la región correcta en tu perfil AWS
Problema: Aparecen errores relacionados con credenciales o permisos.
Solución:
- Verifica que tu perfil AWS está correctamente configurado:
aws sts get-caller-identity --profile tu_perfil
- Si usas SSO, asegúrate de que tu sesión no ha expirado:
aws sso login --profile tu_perfil
- Verifica que tienes los permisos IAM necesarios para usar SSM Session Manager
Problema: El túnel SSM se establece correctamente pero no puedes conectarte al servicio remoto.
Solución:
- Verifica que el host remoto es accesible desde la instancia intermediaria:
aws ssm start-session --target tu_instancia_id # Una vez conectado a la instancia: ping host_remoto telnet host_remoto puerto
- Asegúrate de que los grupos de seguridad o firewalls permiten el tráfico desde la instancia intermediaria al host remoto
- Verifica que estás usando el puerto correcto para el servicio remoto
No, AWS SSM Session Manager siempre requiere una instancia EC2 (u otro recurso) con el agente SSM instalado como intermediario. No es posible establecer un túnel directo a servicios como RDS sin pasar por una instancia EC2.
Como mínimo, necesitas:
ssm:StartSession
ssm:TerminateSession
ssm:ResumeSession
ec2:DescribeInstances
(para listar instancias)ssm:DescribeInstanceInformation
Sí, puedes usar herramientas como screen
, tmux
o nohup
para mantener el script ejecutándose en segundo plano:
# Usando screen
screen -S ssm-tunnel
./ssm_port_forwarder.py --connect "mi_conexion"
# Presiona Ctrl+A, D para desconectar la sesión
# Para volver: screen -r ssm-tunnel
# Usando nohup
nohup ./ssm_port_forwarder.py --connect "mi_conexion" > tunnel.log 2>&1
# Para terminar: encuentra el PID y usa kill
Sí, este método es seguro ya que:
- No expone puertos públicamente
- Utiliza la infraestructura segura de AWS SSM
- Todo el tráfico está encriptado con TLS
- No requiere almacenar credenciales adicionales
Sin embargo, siempre debes seguir las políticas de seguridad de tu organización y usar este método solo cuando sea necesario.
Sí, puedes ejecutar múltiples instancias del script para establecer diferentes túneles simultáneamente. Asegúrate de usar diferentes puertos locales para cada conexión.
Las conexiones se guardan en un archivo JSON encriptado (~/.ssm-port-forwarder/connections.enc
) utilizando:
- Una contraseña que proporcionas la primera vez (con confirmación)
- Encriptación Fernet (implementación de AES-128 en CBC mode con PKCS7 padding)
- Derivación de clave segura con PBKDF2
- Sistema de protección con límite de 3 intentos de contraseña incorrecta