Blog de Amazon Web Services (AWS)

Conéctese de forma segura a Amazon RDS para PostgreSQL con AWS Session Manager y autenticación de IAM

Las políticas de una empresa no suelen permitir que las instancias de bases de datos sean de acceso público, a menos que exista un requisito empresarial específico. Si bien esto protege dichos recursos del acceso público a través de Internet, también limita la forma en que los usuarios pueden conectarse a ellos desde sus ordenadores.

Con frecuencia, los administradores de bases de datos y los equipos de desarrollo intentan superar esa restricción utilizando un host bastión que puede recibir solicitudes a través de Internet y reenviarlas de forma segura a una base de datos alojada en subredes privadas.

Sin embargo, este enfoque tiene dos grandes inconvenientes:

  • Aumenta la superficie potencial de ataque para actividades maliciosas cuando un servidor está expuesto a la Internet pública
  • Añade la necesidad de almacenar y mantener las claves SSH

Además, los usuarios de las bases de datos también tienen que asumir la carga de administrar los nombres de usuario y las contraseñas para la autenticación de dichas bases de datos, lo que también aumenta la exposición a riesgos de seguridad.

En este artículo, le explicamos una solución que ofrece varias ventajas con respecto a los métodos tradicionales de conexión a bases de datos, además de mejorar la seguridad y simplificar ambos, la administración de redes y la gestión de accesos.
Describiremos los pasos necesarios para conectarse desde su máquina local a su instancia de Amazon Relational Database Service (Amazon RDS) mediante Session Manager con enrutamiento de puertos a un host remoto, una capacidad de AWS Systems Manager, y la autenticación de AWS Identity and Access Management (IAM).

Requisitos previos

Para esta publicación, utilizamos una ventana de terminal para iniciar las sesiones remotas.
Debe tener las siguientes herramientas y servicios:

Ventajas de usar la autenticación de bases de datos de IAM y Session Manager

Al aprovechar la autenticación de bases de datos de IAM, los usuarios finales pueden conectarse a su base de datos mediante entidades de IAM, en lugar de utilizar credenciales de base de datos independientes. Esto significa que usted puede gestionar el acceso a sus recursos de Amazon RDS mediante políticas de IAM y concediendo o revocando permisos a usuarios o grupos específicos según sea necesario, sin tener que modificar las cuentas de usuario o contraseñas a nivel de base de datos. Esta flexibilidad es especialmente de gran utilidad en entornos dinámicos en los que los requisitos de acceso pueden cambiar con frecuencia. Con Session Manager, un servicio de AWS totalmente gestionado y que permite administrar las instancias sin necesidad de abrir ningún puerto de entrada, puede establecer una conexión segura con su instancia de RDS sin exponerla directamente a la Internet pública.
Session Manager con enrutamiento de puertos le permite crear una conexión segura y cifrar el tráfico entre su máquina local y la instancia de RDS. Esto reduce la superficie de ataque de la base de datos y ayuda a prevenir el acceso no autorizado a ella.

Otra ventaja de usar la autenticación de IAM y Session Manager es la administración centralizada y la capacidad de auditoría que ofrecen. La autenticación de IAM le permite disponer de un sistema central de gestión de roles o usuarios de IAM, lo que permite gestionar y auditar fácilmente el acceso de los usuarios a sus bases de datos de RDS. Puede hacer un seguimiento de quién y cuándo ha accedido a la base de datos y qué acciones se han realizado.

Session Manager también le permite auditar la actividad de la sesión en su cuenta de AWS.
Este enfoque centralizado mejora la seguridad y simplifica los requisitos de conformidad.

Cómo conectarse a su instancia de RDS con Session Manager

Como práctica recomendada para la seguridad a nivel de red, recomendamos lanzar las instancias de RDS en subredes privadas y permitir el acceso solo desde las aplicaciones de la misma VPC o de una VPC diferente.

Para permitir el acceso de los usuarios a estos recursos restringidos, es necesario disponer de un host bastión a través del cual los usuarios se conecten para acceder a la base de datos. Sin embargo, conceder acceso a estos hosts bastiones a veces requiere exponerlos directamente a Internet, ya que deben estar ubicados en una subred pública, o en topologías de red complejas para que el tráfico pueda enrutarse desde las instalaciones on-premises, mediante servicios como AWS Direct Connect o una VPN.

Session Manager con enrutamiento de puertos elimina la necesidad de una conexión directa con el host bastión o con la base de datos, a la vez que mantiene intactos los aspectos de seguridad.
En el siguiente diagrama se explican los componentes que intervienen en la arquitectura y los pasos necesarios para establecer la conexión.

Los diferentes pasos del flujo de trabajo son los siguientes:

  1. Inicie una sesión de Session Manager en una de las instancias de Amazon Elastic Compute Cloud (Amazon EC2) administradas a través de Systems Manager mediante el documento AWS-StartPortForwardingSessionToRemoteHost y usando las credenciales de AWS que pertenecen a dicho usuario.
  2. El agente de SSM que se ejecuta en las instancias administradas por SSM procesa la solicitud del usuario desde Systems Manager. Esa comunicación es posible a través de los puntos de enlace de SSM configurados para tal fin.
  3. El enrutamiento de puertos está establecido y el usuario ahora puede abrir un nuevo terminal y enviar cualquier comando al host remoto a través del túnel establecido.
  4. El usuario llama con sus credenciales de IAM a Amazon RDS para obtener el token de autenticación a la base de datos.
  5. El usuario se conecta a la base de datos a través del túnel mediante el token de autenticación de la base de datos generado por Amazon RDS.

Configuración inicial

En esta sección, le guiamos a través de los pasos de configuración iniciales.

Cree el grupo de seguridad para la instancia EC2

Para crear el grupo de seguridad, complete los pasos siguientes:

  1. En la consola de Amazon EC2, seleccione Grupos de seguridad en el panel de navegación.
  2. Elija Crear grupo de seguridad.
  3. Introduzca un nombre y una descripción para su grupo de seguridad.
  4. En el campo de la VPC, introduzca su VPC.
  5. En la sección Reglas de salida, permita el acceso al puerto de PostgreSQL (5432).
  6. Para que la instancia EC2 se comunique con las interfaces de los puntos de enlace SSM, también es necesario habilitar el tráfico saliente desde el puerto 443 (HTTPS).
    En ambas reglas, añada como destino el rango de CIDR de la VPC.
  7. Elija Crear grupo de seguridad.

Cree el rol de IAM para la instancia EC2

Ahora creamos el rol de IAM para la instancia EC2:

  1. En la consola de IAM, elija Roles en el panel de navegación.
  2. Seleccione Crear rol.
  3. Seleccione el Servicio de AWS para el Tipo de entidad de confianza.
  4. Elija EC2 para el Caso de Uso.
  5. Seleccione Siguiente.
  6. En la sección Agregar permisos, seleccione la política AmazonSSMManagedInstanceCore.
  7. Elija Siguiente.
  8. Introduzca un nombre para el rol, una descripción breve y, si es necesario, añada las etiquetas necesarias. En esta publicación utilizaremos EC2-RDS-AccessRole como nombre de rol.
  9. Seleccione Crear rol.

Cree la instancia EC2 (host bastión)

Para aprovisionar la instancia EC2, complete los siguientes pasos:

  1. En la consola de Amazon EC2, elija Lanzar una instancia en el panel de navegación.
  2. Introduzca un nombre y las etiquetas necesarias para su instancia EC2.
  3. Elija la AMI de Amazon Linux más reciente.
  4. Elija un tipo de instancia (por ejemplo, una clase de instancia t3.micro).
  5. Elija Continuar sin un par de claves.
    Como utilizamos Session Manager para gestionar la conexión, no es necesario crear ni usar un par de claves existente.
  6. Para la Configuración de red, elija una de las subredes privadas configuradas en su Amazon Virtual Private Cloud (VPC).
  7. Elija Desactivar en Asignar automáticamente la IP pública.
  8. En el campo Nombre del grupo de seguridad, elija el grupo de seguridad creado anteriormente.
  9. En la sección Detalles avanzados, en el Perfil de instancia de IAM, elija el rol de IAM creado anteriormente, EC2-RDS-AccessRole.
  1. Continúe ahora con la creación de la instancia seleccionando Lanzar instancia.

Si todo se ha realizado correctamente y se han cumplido todos los requisitos, la instancia recién lanzada aparecerá en Administrador de flotas y estará lista para usarse con Systems Manager.

Autenticación de la base de datos

Para configurar la autenticación de bases de datos de IAM en su base de datos de RDS para PostgreSQL mediante funciones de IAM, siga estos pasos:

  1. Active la autenticación de base de datos de IAM en la instancia de RDS para PostgreSQL.
  2. Cree una cuenta de usuario de base de datos que se utilizará para conectarse a la instancia de base de datos mediante la autenticación de bases de datos de IAM. Asegúrese de que al usuario de la base de datos (en el ejemplo, db_user) se le conceda la función rds_iam, tal y como se muestra en el código siguiente:
    CREATE USER db_user;
    GRANT rds_iam TO db_user;

    Tenga en cuenta que, para fines de auditoría, cada identidad de usuario humano o máquina seguirá necesitando su propio usuario/rol en la base de datos.
    Para obtener más información, consulte Creación y uso de una política de IAM para el acceso a base de datos de IAM. Ahora cree una política de IAM para asignar el usuario de la base de datos creado a un usuario o rol de IAM.

  3. En la consola de IAM, en el panel de navegación izquierdo, seleccione Políticas.
  4. Seleccione Crear política.
  5. En el Editor de políticas, en la pestaña JSON, introduzca el siguiente documento JSON:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "rds-db:connect"
                ],
                "Resource": [
                    "arn:aws:rds-db:<region>:<account-id>:dbuser:<DBInstanceResourceID>/<DatabaseUser>"
                ]
            }
        ]
    }

    Asegúrese de reemplazar los siguientes elementos debidamente:

    • region – La región de AWS de la instancia de base de datos.
    • account-id – El número de cuenta de AWS de la instancia de base de datos.
    • DBInstanceResourceID – El identificador de la instancia de base de datos. Para buscar el ID del recurso de la instancia de base de datos en la consola de Amazon RDS, elija la instancia de base de datos para ver sus detalles. A continuación, elija la pestaña Configuración y el ID del recurso se mostrará en la sección Configuración.
    • DatabaseUser – La cuenta de usuario de la base de datos creada para conectarse a la instancia de base de datos mediante la autenticación de bases de datos de IAM. En nuestro ejemplo, utilizaremos db_user.
  1. Elija Revisar la política e introduzca un nombre para la política, por ejemplo, rds-db-iam.
  2. Si lo desea, puede introducir una descripción.
  3. Seleccione Crear política.
  4. Elija el nombre del usuario o rol de IAM al que quiera adjuntar dicha política.
  5. Seleccione Agregar permisos y, a continuación, Asociar políticas.
  6. Busque la política de IAM que acaba de crear y selecciónela.
  7. Seleccione Siguiente: Revisar.
  8. Asegúrese de que la política es correcta y elija Agregar permisos.
  9. Genere un token de autenticación de IAM mediante la CLI de AWS:
    aws rds generate-db-auth-token \
      --hostname <rds_hostname> \
      --port 5432 \
      --region <r egion> \
      --username db_user

    Los parámetros para generar el token de autenticación de base de datos son los siguientes:

    • rds_hostname – El nombre de host de la instancia de base de datos a la que desea conectarse (por ejemplo, rdspostgres.123456789012.eu-central-1.rds.amazonaws.com)
    • port – El número de puerto usado para conectarse a su instancia de base de datos (en nuestro ejemplo, 5432 se usa de forma predeterminada para PostgreSQL).
    • region – La región de AWS de la instancia de base de datos.
    • database_user – La cuenta de usuario de la base de datos creada para conectarse a la instancia de base de datos mediante la autenticación de bases de datos de IAM. En nuestro ejemplo, utilizaremos db_user.

Como el token de autenticación consta de varios cientos de caracteres y puede resultar engorroso en la línea de comandos, se recomienda guardarlo en una variable de entorno y usar esa variable más adelante cuando se conecte a la base de datos.

El siguiente ejemplo muestra cómo generar un token de autenticación de base de datos para el usuario de la base de datos db_user y almacenarlo en una variable de entorno PGPASSWORD. La variable PGPASSWORD se comportará de la misma manera que el parámetro de conexión por contraseña.

export RDSHOST="rdspostgres.123456789012.eu-central-1.rds.amazonaws.com"
export PGPASSWORD="$(aws rds generate-db-auth-token --hostname $RDSHOST --port 5432 --region eu-central-1 --username db_user)"

Después de generar un token de autenticación, éste es válido durante 15 minutos antes de que expire. Si intenta conectarse a la base de datos con un token caducado, se denegará la solicitud de conexión. Tenga en cuenta que el token de autenticación de la base de datos solo es necesario para establecer la conexión a la base de datos y no determina, en ningún caso, cuánto tiempo puede durar la conexión existente.

Inicie una sesión de enrutamiento de puertos

En esta sección, iniciaremos una sesión de enrutamiento de puertos de Session Manager a un host remoto mediante Systems Manager y nos conectaremos a la instancia de RDS para PostgreSQL.

  1. Abra un terminal en su ordenador y asegúrese de que sus credenciales de AWS son válidas y de que puede acceder a su cuenta de AWS.
  2. Modifique su archivo /etc/hosts para que $RDSHOST resuelva a 127.0.0.1:
    echo "127.0.0.1 $RDSHOST" >> /etc/hosts

    Tenga en cuenta que con el cambio en su archivo /etc/hosts y dicha solución, solo podrá conectarse a la instancia de la base de datos desde su equipo local.

  3. Inicie una sesión de enrutamiento de puertos de Session Manager a la base de datos de RDS mediante la instancia EC2 (host bastión) creada anteriormente. En el siguiente ejemplo, reutilizamos la variable de entorno RDSHOST creada en la sección anterior. El localPortNumber representa el puerto local del cliente al que se debe redirigir el tráfico, como por ejemplo 1053:
    aws ssm start-session \
      --region <your region> \
      --target <your EC2 instance> \
      --document-name AWS-StartPortForwardingSessionToRemoteHost \
      --parameters '{"host":["'"$RDSHOST"'"],"portNumber"=["5432"],"localPortNumber"=["1053"]}'

    Debería ver algo parecido al siguiente código:

    Starting session with SessionId: mySessionID-1234abcdefghi5678
    Port 1053 opened for sessionId mySessionID-1234abcdefghi5678
    Waiting for connections...

    Mantenga este terminal abierto.

Conéctese a su instancia de base de datos de RDS para PostgreSQL con la autenticación de IAM

Para conectarse a su instancia de base de datos de RDS para PostgreSQL mediante la sesión de enrutamiento de puertos creada en la sección anterior, debe tener instalada la herramienta de línea de comandos psql en su ordenador.

Además, cuando se conecte a la instancia de base de datos de PostgreSQL mediante SSL, será necesario descargar un certificado SSL. Para obtener más información, consulte Uso de SSL/TLS para cifrar una conexión a una instancia.

Una vez descargado el certificado en su ordenador, puede hacer referencia a él mediante el parámetro sslrootcert desde la herramienta de línea de comandos psql.

Ahora puede conectarse a su instancia de base de datos de PostgreSQL mediante TLS con psql siguiendo estos pasos:

  1. Abra un nuevo terminal en su ordenador y asegúrese de que sus credenciales de AWS son válidas y de que puede acceder a su cuenta de AWS.
  2. Conéctese ahora a su instancia de base de datos de PostgreSQL mediante SSL ejecutando el siguiente comando:
    psql --host $RDSHOST \
      --port 1053 \
      "sslmode=verify-full sslrootcert=<ssl certificate file> dbname=<db name> user=db_user"

    Los parámetros para establecer la conexión son los siguientes:

    • host – El nombre de host de la instancia de base de datos a la que desea acceder. En este ejemplo, utilizamos la variable de entorno RDSHOST establecida anteriormente.
    • port – El mismo puerto local utilizado en el comando SSM start-session, por ejemplo, el 1053.
    • sslmode – El modo SSL/TLS que se va a utilizar. Al usar sslmode=verify-full, el cliente de PostgreSQL comprueba que el nombre del certificado TLS del servidor coincida con el valor del host de la instancia de base de datos.
    • sslrootcert – La ruta completa al certificado TLS que contiene la clave pública.
    • dbname – El nombre de la base de datos a la que desea acceder.
    • user – La cuenta de usuario de la base de datos creada para conectarse a la instancia de base de datos mediante la autenticación de bases de datos de IAM. Este será el mismo usuario al que se hace referencia en la política de IAM creada anteriormente, que asigna el usuario de la base de datos a un usuario o rol de IAM. En nuestro ejemplo se denomina db_user.

Tenga en cuenta que si la verificación del certificado TLS está habilitada, el certificado TLS incluirá la URL de conexión de la instancia de base de datos como nombre común (CN) para protegerse contra los ataques de suplantación de identidad. Esta es la razón por la que, al conectarse con la herramienta de línea de comandos de psql a través de la sesión de enrutamiento de puertos, debe usar como host el punto de conexión de la instancia de base de datos de RDS, en lugar de localhost; de lo contrario, la verificación SSL fallará.

psql: error: connection to server at "localhost" (::1), port 1053 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
connection to server at "localhost" (127.0.0.1), port 1053 failed: server certificate for "rdspostgres.123456789012.eu-central-1.rds.amazonaws.com" does not match host name "localhost"

Si la conexión a su instancia de base de datos de PostgreSQL mediante la autenticación de IAM se ha realizado correctamente, debería aparecer el siguiente mensaje:

psql (14.7 (Homebrew), server 14.6)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=>

Eliminar los recursos innecesarios

Para evitar cargos no deseados en su cuenta de AWS, asegúrese de eliminar cualquier instancia EC2 que haya lanzado siguiendo los pasos anteriores. Elimine también el grupo de seguridad de la instancia EC2 y el rol de IAM creados durante los pasos iniciales de configuración.

Para terminar una instancia (consola)

  1. Abra la consola de Amazon EC2 en https://console.aws.amazon.com/ec2/.
  2. En el panel de navegación, elija Instancias.
  3. Seleccione la casilla de verificación de la instancia gestionada por SSM.
  4. Seleccione Estado de la instancia y, a continuación, Terminar instancia.
  5. Seleccione Terminar para confirmar su eliminación.

Para eliminar un grupo de seguridad (consola)

  1. Abra la consola de Amazon EC2 en https://console.aws.amazon.com/ec2/.
  2. En el panel de navegación, seleccione Security Groups.
  3. Seleccione el grupo de seguridad creado en los pasos anteriores y elija Acciones y Eliminar grupos de seguridad.
  4. Seleccione Eliminar cuando se le pida que confirme.

Para eliminar un rol de IAM (consola)

  1. Abra la consola de Amazon IAM en https://console.aws.amazon.com/iam/.
  2. En el panel de navegación, seleccione Roles y, a continuación, seleccione la casilla de verificación situada junto al nombre del rol que desea eliminar (en el ejemplo anterior, EC2-RDS-AccessRole).
  3. Seleccione Eliminar en la parte superior de la página.
  4. En el cuadro de diálogo de confirmación, introduzca el nombre del rol en el campo de entrada de texto y seleccione Eliminar.

Conclusión

En esta publicación, mostramos cómo conectarse a bases de datos de RDS mediante la autenticación de IAM y el enrutamiento de puertos de Session Manager. Esta solución, comparada con los mecanismos tradicionales de conexión a bases de datos en los que los hosts bastiones están expuestos públicamente a Internet, reduce la superficie de ataque del sistema y, al mismo tiempo, simplifica la arquitectura de la red.

También simplifica la sobrecarga operativa que supone administrar los nombres de usuario y las contraseñas de las bases de datos al garantizar un acceso seguro y controlado a los recursos de Amazon RDS mediante políticas de IAM.

Para obtener más información sobre la autenticación de bases de datos de IAM para diferentes motores de bases de datos, consulte la Autenticación de bases de datos de IAM para MariaDB, MySQL y PostgreSQL.

Para obtener más información sobre las capacidades de Systems Manager, consulte las Capacidades operativas de AWS Systems Manager.

Si tiene alguna pregunta, comentario o sugerencia, deje un comentario.


Acerca de los autores


Adria Morgado es arquitecto de la nube en Amazon Web Services. Está especializado en diseñar e implementar soluciones sólidas, escalables y seguras para clientes de grandes empresas.


Alan Oberto Jiménez es un arquitecto y desarrollador de la nube especializado en ayudar a los clientes a diseñar, desarrollar y rediseñar aplicaciones que puedan aprovechar al máximo las ventajas de la nube de AWS.

Este blog en español es una traducción de la publicación original del blog en inglés (Enlace aquí).

Traductores:
Adria Morgado | Cloud Infrastructure Architect en AWS – Múnich, Alemania
Alan Oberto Jiménez | Sr. Cloud Application Architect – Berlín, Alemania