Passer au contenu

Comment créer une politique de mot de passe dans Amazon RDS pour PostgreSQL ?

Lecture de 6 minute(s)
0

Je souhaite créer une politique de mot de passe dans Amazon Relational Database Service (Amazon RDS) pour PostgreSQL.

Brève description

Par défaut, Amazon RDS pour PostgreSQL n’inclut pas de fonctionnalité permettant d'appliquer une politique de mot de passe. Cependant, vous pouvez utiliser les hooks PostgreSQL et les extensions TLE (Trusted Language Extensions) pour étendre les fonctionnalités de base. Pour personnaliser la façon dont PostgreSQL gère les mots de passe lorsque vous créez ou modifiez des mots de passe pour des utilisateurs ou des rôles, utilisez le hook passcheck.

Remarque : TLE prend en charge Amazon RDS pour les versions 16.1 et ultérieures de PostgreSQL, 15.2 et versions ultérieures, 14.5 et versions ultérieures, et 13.12 et versions ultérieures. Pour plus d'informations, consultez la section Exigences relatives à l'utilisation des extensions TLE (Trusted Language Extensions, extensions de langage sécurisées) pour PostgreSQL.

Résolution

Remarque : Si des erreurs surviennent lorsque vous exécutez des commandes de l'interface de la ligne de commande AWS (AWS CLI), consultez la section Résoudre des erreurs liées à l’AWS CLI. Vérifiez également que vous utilisez bien la version la plus récente de l'interface.

Créer un groupe de paramètres client et configurer l'extension TLE

Procédez comme suit :

  1. Créez un groupe de paramètres personnalisés, puis associez-le à votre instance Amazon RDS pour PostgreSQL.
    Remarque : Les modifications apportées aux groupes de paramètres entraîneront une durée d’indisponibilité. Utilisez une fenêtre de maintenance pour éviter toute indisponibilité immédiate.

  2. Configurez l'extension TLE.

  3. Connectez-vous à votre instance, exécutez la requête suivante, puis vérifiez que le paramètre shared_preload_libraries est mis à jour :

    postgres=> SHOW shared_preload_libraries;shared_preload_libraries  
    rdsutils,pg_tle,pg_stat_statements  
    (1 row)  
    postgres=>
  4. Exécutez la requête suivante pour créer l'extension TLE :

    CREATE EXTENSION pg_tle;

    Remarque : Pour configurer et configurer l'extension pg_tle, votre rôle d'utilisateur de base de données doit disposer des autorisations de rôle rds_superuser,

  5. Accordez le rôle pgtle_admin à l'utilisateur principal de votre instance Amazon RDS pour PostgreSQL. Si vous avez utilisé un utilisateur par défaut, il s'agit de l'utilisateur postgres principal :

    GRANT pgtle_admin TO example-user;

    Remarque : Remplacez example-user par l’utilisateur principal de votre instance Amazon RDS pour PostgreSQL.

Configurer le hook passcheck

Un hook passcheck PostgreSQL vérifie les mots de passe pour les opérations SQL et n'autorise pas les utilisateurs à définir des mots de passe répertoriés dans la table password_check.bad_passwords. Le hook passcheck vérifie également la longueur du mot de passe et confirme que les mots de passe contiennent des lettres majuscules et minuscules, des chiffres et des caractères spéciaux.

Remarque : Vous pouvez modifier la fonction d'un hook PostgreSQL en fonction de vos besoins spécifiques. Vous pouvez ajouter des mots de passe supplémentaires à la table bad_passwords, modifier la longueur de mot de passe requise ou modifier la fonction pour vérifier la complexité du mot de passe.

Procédez comme suit :

  1. Exécutez la commande SQL pgtle.install_extension suivante. Modifiez le code SQL en fonction de vos besoins spécifiques :

    SELECT pgtle.install_extension (  
      'example-password-check-rules',  
      '1.0',  
      'Do not let users use the 10 most commonly used passwords',  
    $_pgtle_$  
      CREATE SCHEMA password_check;  
      REVOKE ALL ON SCHEMA password_check FROM PUBLIC;  
      GRANT USAGE ON SCHEMA password_check TO PUBLIC;  
      CREATE TABLE password_check.bad_passwords (plaintext) AS  
      VALUES  
        ('123456'),  
        ('password'),  
        ('12345678'),  
        ('qwerty'),  
        ('123456789'),  
        ('12345'),  
        ('1234'),  
        ('111111'),  
        ('1234567'),  
        ('dragon');  
      CREATE UNIQUE INDEX ON password_check.bad_passwords (plaintext);  
      CREATE FUNCTION password_check.passcheck_hook(username text, password text, password_type pgtle.password_types, valid_until timestamptz, valid_null boolean)  
      RETURNS void AS $$  
        DECLARE  
          invalid bool := false;  
        BEGIN  
    
          -- Check password length  
          IF length(password) < 8 THEN  
            RAISE EXCEPTION 'Password must be at least 8 characters long.';  
          END IF;  
    
          -- Check common passwords from password from bad_passwords table  
          IF password_type = 'PASSWORD_TYPE_MD5' THEN  
            SELECT EXISTS(  
              SELECT 1  
              FROM password_check.bad_passwords bp  
              WHERE ('md5' || md5(bp.plaintext || username)) = password  
            ) INTO invalid;  
            IF invalid THEN  
              RAISE EXCEPTION 'Cannot use passwords from the common password dictionary';  
            END IF;  
          ELSIF password_type = 'PASSWORD_TYPE_PLAINTEXT' THEN  
            SELECT EXISTS(  
              SELECT 1  
              FROM password_check.bad_passwords bp  
              WHERE bp.plaintext = password  
            ) INTO invalid;  
            IF invalid THEN  
              RAISE EXCEPTION 'Cannot use passwords from the common password dictionary';  
            END IF;  
          END IF;  
    
          -- Check password contains uppercase lowercase number and special character  
          IF NOT (password ~ '[A-Z]' AND password ~ '[a-z]' AND password ~ '[0-9]' AND password ~ '[^a-zA-Z0-9]') THEN  
            RAISE EXCEPTION 'Password must contain uppercase letters, lowercase letters, numbers, and special characters';  
          END IF;  
        END  
      $$ LANGUAGE plpgsql SECURITY DEFINER;  
      GRANT EXECUTE ON FUNCTION password_check.passcheck_hook TO PUBLIC;  
      SELECT pgtle.register_feature('password_check.passcheck_hook', 'passcheck');  
    $_pgtle_$);

    Remarque : Dans la commande précédente, remplacez example-password-check-rules par le nom de vos règles de vérification de mot de passe.

  2. Exécutez la requête suivante pour créer l'extension :

    postgres=> CREATE EXTENSION "example-password-check-rules";

    Remarque : Dans la commande précédente, remplacez example-password-check-rules par le nom de vos règles de vérification de mot de passe.

  3. Modifiez le groupe de paramètres personnalisés associé à votre instance, puis activez le paramètre pgtle.enable_password_check.

  4. Pour tester vos règles de vérification de mot de passe, utilisez les exemples suivants.
    Exemple :

    postgres=> CREATE ROLE t_role PASSWORD 'password';ERROR:  Cannot use passwords from the common password dictionary  
    CONTEXT:  PL/pgSQL function password_check.passcheck_hook(text,text,pgtle.password_types,timestamp with time zone,boolean) line 25 at RAISE  
    SQL statement "SELECT password_check.passcheck_hook($1::pg_catalog.text, $2::pg_catalog.text, $3::pgtle.password_types, $4::pg_catalog.timestamptz, $5::pg_catalog.bool)"

    Remarque : L'exemple précédent indique une erreur car vous ne pouvez pas utiliser les mots de passe du dictionnaire de mots de passe communs.
    Exemple :

    postgres=> CREATE ROLE t_role PASSWORD 'pass';ERROR:  Password must be at least 8 characters long.  
    CONTEXT:  PL/pgSQL function password_check.passcheck_hook(text,text,pgtle.password_types,timestamp with time zone,boolean) line 7 at RAISE  
    SQL statement "SELECT password_check.passcheck_hook($1::pg_catalog.text, $2::pg_catalog.text, $3::pgtle.password_types, $4::pg_catalog.timestamptz, $5::pg_catalog.bool)"

    Remarque : L'exemple précédent indique une erreur car le mot de passe doit comporter au moins 8 caractères.
    Exemple :

    postgres=> CREATE ROLE t_role PASSWORD 'passwordd';ERROR:  Password must contain uppercase letters, lowercase letters, numbers, and special characters  
    CONTEXT:  PL/pgSQL function password_check.passcheck_hook(text,text,pgtle.password_types,timestamp with time zone,boolean) line 31 at RAISE  
    SQL statement "SELECT password_check.passcheck_hook($1::pg_catalog.text, $2::pg_catalog.text, $3::pgtle.password_types, $4::pg_catalog.timestamptz, $5::pg_catalog.bool)"

    Remarque : L'exemple précédent indique une erreur car le mot de passe doit contenir des lettres majuscules, des lettres minuscules, des chiffres et des caractères spéciaux.

Pour les versions d'Amazon RDS pour PostgreSQL qui ne prennent pas en charge TLE, utilisez Gestion des identités et des accès AWS (AWS IAM) pour l'authentification Amazon RDS ou Kerberos. En outre, pour limiter la création de mots de passe à un ensemble de rôles ou à un rôle spécifique, consultez la section Délégation et contrôle de la gestion des mots de passe utilisateur .

Informations connexes

Utilisation d’extensions de langage sécurisées pour PostgreSQL

Référence des hooks pour les extensions de langage sécurisées pour PostgreSQL