La manera más habitual que he observado para conectarse a instancias de EC2 ha sido por medio del manejo de llaves para SSH, usando un bastion host y abriendo una serie de puertos para lograr tener ese acceso. Pero ¿sabías que existe otra manera de hacerlo que es segura, auditable y sin hacer nada de lo anterior? Hablamos de AWS System Manager Session Manager.
Debemos empezar diciendo que Session Manager es un componente totalmente administrado por AWS y que nos permite administrar instancias de EC2, edge devices, servidores on-premises y máquinas virtuales por medio de un shell que ejecuta en un browser o bien por el AWS CLI.
Los principales beneficios que nos aporta este servicio son:
- Control de Acceso Centralizado usando políticas de IAM.
Los administradores tienen ahora un punto central para otorgar y revocar permisos hacia los nodos que administran. Y al hacer uso de políticas de IAM se puede establecer que grupos o usuarios acceden a ciertos nodos.
¿Cuantas veces no hemos encontrado que una llave de SSH está distribuida a personas que no deberían tener acceso a un equipo?
O del control administrativo que deben tener los encargados para poder determinar que usuario tiene acceso a un grupo de equipos. Cuando hablamos de decenas o centenas de instancias y dispositivos; esto se vuelve una tarea casi imposible.
- No tenemos que abrir puertos, gestionar llaves de SSH o el bastion host
Tener puertos de entrada de SSH o de RDP en los nodos que gestionamos aumenta sustancialmente el riesgo de que los mismos sean comprometidos. Al emplear Session Manager podemos cerrar esos puertos, no tener que gestionar las llaves y tampoco el bastion host.
Lo anterior nos ayuda a mejorar nuestra postura de seguridad y nos libera de las labores de mantenimiento del bastion host como actualizaciones del OS, paquetería, entre otros.
Cabe indicar que la sesión es una conexión entre el cliente y el nodo remoto por medio de un tráfico encriptado por medio de TLS 1.2; y además es posible usar una llave de AWS KMS para encriptar los datos más allá de la encriptación por omisión de TLS.
- Soporte para Windows, Linux y macOS.
Podemos usar Session Manager en cualquiera de esto sistemas operativos con la misma herramienta.
- Auditoria y Bitácoras de Actividad
Este es una de las mayores ventajas que tiene Session Manager pues permite cumplir requerimientos operativos y de seguridad en la organización.
Puedo citar que se integra con Cloud Trail y todas las llamadas a los API de Session Manager quedan registradas para el análisis y registro adecuado. También se puede registrar los datos del log de sesión en S3 cuando se desean hacer labores de depuración y resolución de problemas. Y con CloudWatch Logs podemos tener el monitoreo y registro de log de sesión.
Por último, se puede integrar con EventBridge y SNS para crear reglas como por ejemplo: notificar si un usuario inicia una sesión.
¿Cómo configuramos Session Manager?
Instalar el Agente de SSM
El primer paso es instalar el agente de SSM en los nodos que vamos a gestionar. Aunque debo aclarar que en muchos de los AMI de AWS ya está preinstalado el agente: por ejemplo en Amazon Linux 2, macOS, SUSE, Ubuntu y Windows Servers. La lista actualizada la pueden ver en este enlace.
Para este ejercicio empleare un Amazon Linux 2; en donde verificamos que este corriendo el agente por medio del comando:
sudo systemctl status amazon-ssm-agent
El resultado debe indicarnos que está activado.
Verificar o Crear el role de IAM
Por omisión System Manager no tiene permiso para realizar ninguna acción sobre las instancias de EC2. Por tanto debemos otorgar ese permiso por medio de un instance profile que asociamos a la instancia o instancias a gestionar.
En nuestro ejemplo; crearemos un nuevo role de IAM con los permisos mínimos que necesitamos. La política es la que se anexa y debemos indicar el ARN de nuestra llave de KMS en caso de que deseemos utilizar encriptación con KMS; sino la necesitamos podemos suprimir ese parte. Debemos notar también los permisos hacia CloudWatch y S3.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:UpdateInstanceInformation",
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": "arn:aws:s3:::MI_BUCKET/*"
},
{
"Effect": "Allow",
"Action": [
"s3:GetEncryptionConfiguration"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"kms:Decrypt"
],
"Resource": "arn:aws:kms:us-east-1:XXX:key/XXX"
}
]
}
En mi caso le colocamos el nombre SessionManagerPermissions a esta nueva política y una vez creada procedemos a definir un nuevo rol indicando como caso de uso EC2.
Luego le asociamos la política recién creada al mismo. A este rol le denominare SessionManagerRole.
Asociar Rol a Instancia
Ahora debemos asociar este rol a la instancia sobre la cual haremos la prueba; como se aprecia en la siguiente imagen.
Configurar Session Manager
El siguiente paso es ir a la consola de System Manager y ahí al apartado de Session Manager que esta debajo del segmento de Node Management.
En este lugar damos click a Configure Preferences y podemos establecer el timeout, duración máxima de una sesión, encriptación de KMS y bitácoras para CloudWatch y S3. En mi caso selecciono la llave de KMS y un log group de CloudWatch creado previamente.
Esto genera un tipo de documento que se llama SSM-SessionManagerRunShell. Esto lo podemos encontrar en el apartado de Documents de System Manager y podemos definir múltiples documentos adicionales; pero este es el que se emplea por omisión y su contenido refleja la configuración que realizamos por medio de la consola.
{
"schemaVersion": "1.0",
"description": "Document to hold regional settings for Session Manager",
"sessionType": "Standard_Stream",
"inputs": {
"s3BucketName": "MI_BUCKET",
"s3KeyPrefix": "",
"s3EncryptionEnabled": true,
"cloudWatchLogGroupName": "/aws/sessionmanager/log",
"cloudWatchEncryptionEnabled": false,
"idleSessionTimeout": "20",
"maxSessionDuration": "",
"cloudWatchStreamingEnabled": true,
"kmsKeyId": "XXXX",
"runAsEnabled": false,
"runAsDefaultUser": "",
"shellProfile": {
"windows": "",
"linux": ""
}
}
}
¿Cómo nos conectamos?
Hecho lo anterior, vamos a conectarnos por medio de la consola de EC2, como se ilustra de seguido.
Al dar connect observamos que tenemos ingreso a la instancia
Ahora, si queremos usar el AWS CLI primero debemos instalar el Session Maanager plugin y que se descarga del sitio de AWS.
Una vez instalado, podemos conectarnos usando el AWS CLI; con el comando (el último parámetro es el instance id)
aws ssm start-session --target i-023add916cd6d8bb2
y ya tenemos acceso a la instancia.
Observen que eso nos da un identificador de sesión y este lo podemos observar en la consola de session manager; para ver las sesiones activas y el historial de las mismas.
Adicionalmente, si revisamos en CloudWatch podremos ver la totalidad de comandos que se ejecutaron en esa sesión en particular.
Es importante que se tome en cuenta que Session Manager guarda todos los comandos y si no queremos que se guarde información sensible como credenciales se puede hacer uso del comando:
stty -echo; read passwd; stty echo;
Permisos
La pregunta que puede surgir ahora es:
¿Cómo puedo limitar el acceso a sólo cierta instancias? o ¿a ciertos usuarios?
Esto se hace por medio de una política que asociamos al usuario o a un grupo y que nos permite controlar múltiples escenarios; por ejemplo si deseamos limitar el acceso a ciertas instancias:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": [
"arn:aws:ec2:us-east-1:123456:instance/i-instanciaA",
"arn:aws:ec2:us-east-1:123456:instance/i-instanciaB",
"arn:aws:ec2:us-east-1:123456:instance/i-instanciaC"
]
},
{
"Effect": "Allow",
"Action": [
"ssm:TerminateSession",
"ssm:ResumeSession"
],
"Resource": [
"arn:aws:ssm:*:*:session/${aws:username}-*"
]
}
]
}
También podemos permitir que se emplee sólo el AWS CLI para establecer las sesiones o bien por medio de EC2 Console; entre muchas opciones que podemos hacer por medio de estas políticas de IAM.
Otras Opciones
Además de lo anterior, con Session Manager podemos hacer otras cosas, como por ejemplo hacer un ‘port-forwarding’ y que puede ser interesante en varios escenarios.
Podemos encontrar varios documentos de ejemplo en System Manager->Documents filtrando por ‘Session Documents’
Conclusión
Este es una breve introducción a Session Manager, el cual es la alternativa idónea y recomendada para conectarnos a nuestras instancias en AWS; de una manera simple, segura y centralizada; eliminado los riesgos inherentes a tener los puertos administrativos abiertos o compartiendo las llaves de SSH.
Espero que este artículo les haya sido de utilidad.
Comentarios