Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Accès sécurisé à un RDS privé via Amazon EC2 Instance Connect Endpoint

By Richard KangJun 29, 20237 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

aws security best practices

Pour se connecter à des ressources AWS privées, par exemple exécuter des commandes psql sur une base RDS Postgres, on passe généralement par un bastion. Mais les bastions coûtent cher et sont difficiles à gérer. Je vous montre ici comment procéder de façon économique, pratique et sécurisée avec Amazon EC2 Instance Connect.

Les bonnes pratiques de sécurité AWS recommandent que la base de données ne soit accessible que sur une plage d'adresses IP privées, afin de garantir l'isolation réseau. Autrement dit, mieux vaut héberger votre base de données, RDS notamment, dans un sous-réseau privé.

L'une des façons d'accéder à des ressources privées consiste à passer par un bastion.

Mais les bastions ont un coût : ils tournent souvent 24h/24 et 7j/7 pour ne servir qu'à un accès ponctuel, et ils imposent la gestion d'une instance dédiée, avec ses correctifs de sécurité réguliers et ses règles d'exception dans le pare-feu réseau. Mal gérés, ils peuvent même élargir la surface d'attaque de votre système — pensez à une clé SSH à longue durée de vie, partagée à l'avance avec un partenaire commercial pour accéder au bastion, qui devient un véritable risque cyber.

La nouvelle fonctionnalité Amazon EC2 Instance Connect Endpoint, annoncée le 13 juin 2023, offre un mécanisme supplémentaire pour accéder aux workloads d'un sous-réseau privé sans avoir à maintenir de bastion.

Sommaire

· Sommaire

· Vue d'ensemble

· Pas à pas

· Prérequis

· Créer un Security Group pour l'EC2 Instance Connect Endpoint

· Créer l'EC2 Instance Connect Endpoint

· Configurer la politique IAM pour la connexion

· Container DevOps : se connecter au RDS privé

· Se connecter au RDS via l'EC2 Instance Connect Endpoint

· Dépannage

· InvalidParameter avec aws ec2-instance-connect open-tunnel

· Conclusion

Vue d'ensemble

aws security best practices

Architecture globale d'EC2 Instance Connect se connectant à un RDS dans un sous-réseau privé

  1. Les utilisateurs se connectent depuis Internet au service EC2 Instance Connect Endpoint via l'AWS CLI aws ec2-instance-connect open-tunnel ;
  2. Les connexions EIC sont soumises aux permissions IAM, et éventuellement journalisées ;
  3. Les connexions issues de l'EC2 Instance Connect Endpoint doivent être autorisées en entrée par le Security Group du workload ;
  4. L'EC2 Instance Connect Endpoint se connectera au RDS via des IP privées.

Pas à pas

Prérequis

  1. Pour démontrer la connectivité sans Internet, vérifiez que la table de routage du sous-réseau du RDS ne comporte aucune route vers une Internet Gateway.
  2. Notez le Security Group du RDS, par exemple sg-012345.
  3. Notez le VPC du RDS, par exemple vpc-012345.

Nous créerons l'EC2 Instance Connect Endpoint dans le même VPC, comme illustré dans le schéma ci-dessus. 4. Notez les sous-réseaux privés où le RDS est hébergé, par exemple subnet-0abc101 et subnet-0abc102.

Nous créerons l'EC2 Instance Connect Endpoint dans l'un de ces sous-réseaux. 5. Notez les IP privées du RDS, par exemple 10.0.128.61

Nous nous connecterons depuis Internet à l'EC2 Instance Connect via l'AWS CLI ; or, depuis la version 2.12.1 de l'AWS CLI, la commande open-tunnel n'accepte que des adresses IP pour ouvrir un tunnel.

L'IP privée de l'instance RDS se trouve dans Network interfaces du dashboard EC2, en filtrant par Description=RDSNetworkInterface.

Si plusieurs entrées remontent, affinez par VPC.

Sélectionnez la Network Interface concernée : l'adresse IPv4 privée figure dans le panneau IP addresses.

ec2 security group

Recherchez l'IP privée de RDSNetworkInterface

Une fois en possession des informations sur les ressources AWS privées auxquelles nous voulons accéder via l'EC2 Instance Connect Endpoint, créons d'abord un Security Group dédié, puis l'EC2 Instance Connect Endpoint lui-même.

Créer un Security Group pour l'EC2 Instance Connect Endpoint

Nous allons créer un Security Group autonome pour l'EC2 Instance Connect Endpoint. Ce Security Group n'a aucune règle d'entrée, mais une seule règle de sortie permettant de se connecter au RDS associé au Security Group du RDS.

  • Rendez-vous sur Create security group dans la console EC2 via ce lien https://console.aws.amazon.com/ec2/v2/home#CreateSecurityGroup.
  • Renseignez un Security group name et une Description explicites.
  • Sélectionnez le VPC du RDS. Dans cet exemple, ce sera vpc-012345
  • Laissez les Inbound rules vides
  • Dans les Outbound rules, configurez une règle sortante avec les paramètres suivants :

a. Type : Customer TCP

b. Plage de ports : port de connectivité RDS, par exemple 5432 pour Postgresql

c. Destination : sélectionnez le Security Group du RDS. Dans cet exemple, c'est sg-012345

d. Description : Connexion sortante de l'EC2 Instance Connect Endpoint vers le RDS

  • Cliquez sur Create Security Group en bas à droite de la page
  • Un Security Group autonome sera créé, par exemple sg-0abcde

ec2-instance-connect

Créez un nouveau Security Group pour l'EC2 Instance Connect Endpoint

Créer l'EC2 Instance Connect Endpoint

  1. Rendez-vous sur la page Create endpoint du VPC via ce lien https://console.aws.amazon.com/vpc/home#CreateVpcEndpoint
  2. Renseignez un nom d'endpoint explicite
  3. Dans Service Category, sélectionnez EC2 Instance Connect Endpoint
  4. Dans la liste des VPC, sélectionnez celui du RDS. Dans cet exemple, sélectionnez vpc-012345
  5. Dans Security groups, sélectionnez le Security Group créé pour l'EC2 Instance Connect Endpoint. Dans cet exemple, c'est sg-0abcde
  6. Sélectionnez l'un des sous-réseaux où le RDS est hébergé. Dans cet exemple, ce sera soit subnet-0abc101, soit subnet-0abc102
  7. Cliquez sur Create endpoint

aws

Créez l'EC2 Instance Connect Endpoint et utilisez le Security Group dédié

Configurer la politique IAM pour la connexion

L'EC2 Instance Connect Endpoint est créé et la connectivité en place via le Security Group associé : place à la création d'un utilisateur IAM doté du moindre privilège pour utiliser cette connexion.

  1. Rendez-vous sur Create Policy dans la console IAM via ce lien https://console.aws.amazon.com/iamv2/home#/policies/create?step=addPermissions
  2. Basculez sur l'éditeur de politique JSON et saisissez la politique ci-dessous. Remplacez la ressource EC2 Instance Connect Endpoint par l'ARN correspondant, et remplacez les variables entre chevrons par les valeurs propres à votre environnement :
{
"Version": "2012-10-17",
"Statement": [\
{\
"Effect": "Allow",\
"Action": "ec2-instance-connect:OpenTunnel",\
"Resource": "arn:aws:ec2:<AWS Region>:<AWS Account>:instance-connect-endpoint/eice-<EICE ID>",\
"Condition": {\
"NumericEquals": {\
"ec2-instance-connect:remotePort": "5432"\
},\
"IpAddress": {\
"ec2-instance-connect:privateIpAddress": [\
"<CIDR of subnet-0abc101>",\
"<CIDR of subnet-0abc102>"\
]\
}\
}\
},\
{\
"Sid": "Describe",\
"Action": [\
"ec2:DescribeInstances",\
"ec2:DescribeInstanceConnectEndpoints"\
],\
"Effect": "Allow",\
"Resource": "*"\
}\
]
}

Container DevOps : se connecter au RDS privé

Maintenant que nous disposons de l'EC2 Instance Connect et de la politique de moindre privilège associée à l'utilisateur IAM, place au test de la connexion.

Nous allons nous connecter via un client Postgres lancé depuis une image de conteneur Postgres, dans une logique Container DevOps.

Le Container DevOps apporte fiabilité, reproductibilité et sécurité :

  • Fiabilité grâce à une image de conteneur empaquetée avec les bonnes versions d'outils, dépendances et paramètres, gage de cohérence.
  • Reproductibilité grâce à la même image de conteneur utilisée dans le pipeline CICD : la moindre erreur peut être rejouée à l'identique dans l'environnement de débogage DevOps.
  • Sécurité grâce à l'analyse de sécurité des images de conteneur et à l'analyse de tout script d'automatisation avec SCAT, avant utilisation au sein de l'équipe DevOps et dans l'automatisation CICD.

Se connecter au RDS via l'EC2 Instance Connect Endpoint

  1. Utilisez le profil AWS de l'utilisateur IAM auquel la politique créée plus haut est rattachée
  2. Lancez un client Postgres depuis Docker pour vous connecter au RDS privé avec la commande docker run -it — rm — network=bridge postgres psql -h host.docker.internal -U <db user>
  3. Saisissez le mot de passe du db user
  4. Si tout se passe bien, le prompt postgres s'affiche
% docker run -it --rm --network=bridge postgres psql -h host.docker.internal -U postgres
Password for user postgres:
psql (15.3 (Debian 15.3-1.pgdg120+1), server 14.7)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, compression: off)
Type "help" for help.
postgres=>

Dépannage

InvalidParameter avec aws ec2-instance-connect open-tunnel

J'ai rencontré l'erreur suivante en exécutant aws ec2-instance-connect open-tunnel

% aws ec2-instance-connect open-tunnel --instance-connect-endpoint-id <EIC ID> --private-ip-address <RDS Endpoint DNS> --local-port 5432 --remote-port 5432
Listening for connections on port 5432.
[1] Accepted new tcp connection, opening websocket tunnel.
2023-06-20 23:32:09,666 - awscli.customizations.ec2instanceconnect.websocket - ERROR - {"ErrorCode":"InvalidParameter","Message":"The specified PrivateIpAddress is not valid. Specify a valid IPv4 PrivateIpAddress and retry your request."}
AWS_ERROR_HTTP_WEBSOCKET_UPGRADE_FAILURE: Failed to upgrade HTTP connection to Websocket.

Cette erreur vient de l'implémentation WebSocket utilisée par l'AWS CLI, qui exige une IP privée. Résolvez l'endpoint RDS vers son IP interne et passez celle-ci en paramètre --private-ip-address de aws ec2-instance-connect open-tunnel.

EC2 Instance Connect est une bien meilleure façon de se connecter à des ressources privées comme RDS. En tant que service managé, il renforce la sécurité, réduit les coûts et allège la charge de gestion.

Et surtout, il est simple à utiliser !