Direkt zum Inhalt

Wie verwalte ich die Komplexität und den Ablauf von Passwörtern für DB-Cluster-Verbindungen von Aurora PostgreSQL-Compatible?

Lesedauer: 6 Minute
0

Ich möchte die Komplexität und den Ablauf von Passwörtern für Verbindungen zu einem Datenbank (DB)-Cluster von Amazon Aurora PostgreSQL-Compatible Edition verwalten.

Kurzbeschreibung

Um Passwörter für den DB-Cluster von Aurora PostgreSQL-Compatible zu verwalten, kannst du die folgenden Methoden verwenden:

Lösung

Verwenden eines Passwort-Überprüfungs-Hooks mit einer TLE

Um einen Passwort-Überprüfungs-Hook mit einer TLE zu verwenden, musst du die TLE zuerst im DB-Cluster von Aurora PostgreSQL-Compatible einrichten. Erstelle dann den Passwort-Überprüfungs-Hook

Hinweis: Wenn du dem Hook einen Namen gibst, kannst du user-password-check-rules nicht verwenden.

Beispiel für einen Hook-Code zur Passwortüberprüfung:

SELECT pgtle.install_extension(
  'user-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 for bad passwords
    CREATE TABLE password_check.bad_passwords (plaintext) AS
    VALUES
      ('123456'),
      ('password'),
      ('12345678'),
      ('qwerty'),
      ('123456789'),
      ('12345'),
      ('1234'),
      ('111111'),
      ('1234567'),
      ('dragon');
    -- Create table for tracking user password changes
    CREATE TABLE password_check.usertime (
      user_name text PRIMARY KEY,
      lasttime timestamp
    );
    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;
        userexists bool;
        last_password_change timestamp;
      BEGIN
        -- Check if user already exists      
        SELECT EXISTS (SELECT user_name FROM password_check.usertime WHERE user_name = username) INTO userexists;
        -- If user exists, check password age
        IF (userexists) THEN
          SELECT lasttime INTO last_password_change
          FROM password_check.usertime
          WHERE user_name = username;
          -- Check if password is older than 90 days
          IF (CURRENT_TIMESTAMP - last_password_change) > INTERVAL '90 days' THEN
            RAISE EXCEPTION 'Password has expired. It must be changed every 90 days. Last change was on %', last_password_change;
          END IF;
          -- Update timestamp for new password change
          UPDATE password_check.usertime SET lasttime = CURRENT_TIMESTAMP WHERE user_name = username;
        ELSE
          -- First time user, add to tracking table
          INSERT INTO password_check.usertime VALUES(username, CURRENT_TIMESTAMP);
        END IF;
        -- Existing password length check
        IF length(password) < 8 THEN
          RAISE EXCEPTION 'Password must be at least 8 characters long.';
        END IF;
        -- Existing common password check
        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;
        -- Existing complexity check
        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_$
);

Hinweis: Passe den Code an deine Anforderungen an. Du kannst der Tabelle bad_passwords beispielsweise weitere Passwörter hinzufügen, die Anforderung an die Passwortlänge ändern oder die Komplexität des Passworts überprüfen. 

Führe den folgenden Befehl aus, um zu überprüfen, ob ein Passwort die Längenanforderungen erfüllt:

CREATE ROLE user1 PASSWORD '123456';

Erwartete Ausgabe:

ERROR: Password must be at least 8 characters long.
CONTEXT: PL/pgSQL function password_check.passcheck_hook(text,text,pgtle.password_types,timestamptz,bool)
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)"

Hinweis: Das vorherige Beispiel zeigt einen Fehler, da das Passwort mindestens acht Zeichen lang sein muss.

Führe den folgenden Befehl aus, um zu überprüfen, ob ein Passwort zu häufig vorkommt:

CREATE ROLE user1 PASSWORD 'password';

Erwartete Ausgabe:

ERROR: Cannot use passwords from the common password dictionary
CONTEXT: PL/pgSQL function password_check.passcheck_hook(text,text,pgtle.password_types,timestamptz,bool)
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)"

Hinweis: Das vorherige Beispiel zeigt einen Fehler, weil du keine Passwörter aus dem allgemeinen Passwortwörterbuch verwenden kannst.

Gehe wie folgt vor, um zu überprüfen, ob das Passwort abgelaufen ist:

  1. Führe den folgenden Befehl aus, um zu überprüfen, wann ein(e) Benutzer:in das letzte Mal ein Passwort geändert hat:

    SELECT * FROM password_check.usertime WHERE user_name = 'user1';

    Erwartete Ausgabe:

    user_name | lasttime
    ----------+----------------------------
    user1     | 2025-10-01 18:48:07.319908
    (1 row)
  2. Führe den folgenden Befehl aus, um festzulegen, dass das letzte Mal 91 Tage lang her sein soll:

    UPDATE password_check.usertime
    SET lasttime = CURRENT_TIMESTAMP - INTERVAL '91 days'
    WHERE user_name = 'user1';

    Erwartete Ausgabe:

    UPDATE 1
  3. Führe den folgenden Befehl aus, um zu überprüfen, ob das letzte Mal 91 Tage lang her ist:

    SELECT * FROM password_check.usertime WHERE user_name = 'user1';

    Erwartete Ausgabe:

    user_name | lasttime
    ----------+----------------------------
    user1     | 2025-07-02 18:55:36.248913
    (1 row)
  4. Führe den folgenden Befehl aus, um die Funktion des Ablaufens des Passworts zu testen:

    ALTER USER user1 WITH PASSWORD 'NewTestPass786!';

    Erwartete Ausgabe:

    NOTICE: Password has expired. It must be changed every 90 days. Last change was on 2025-07-02 18:55:36.248913
    ALTER ROLE
  5. Führe den folgenden Befehl aus, um zu überprüfen, ob sich das Benutzerpasswort geändert hat und wann es das letzte Mal aktualisiert wurde:

    SELECT * FROM password_check.usertime WHERE user_name = 'user1';

    Erwartete Ausgabe:

    user_name | lasttime
    ----------+----------------------------
    user1     | 2025-10-01 19:18:42.028533
    (1 row)

Die eingeschränkte Passwortverwaltungsfunktion aktivieren

Setze den Parameter rds.restrict_password_commands auf 1, sodass nur die Datenbankbenutzer, denen du die Rolle rds_password zugewiesen hast, Passwörter verwalten können.

Gehe wie folgt vor:

  1. Erstelle eine DB-Cluster-Parametergruppe.
  2. Ordne dem DB-Cluster die DB-Cluster-Parametergruppe zu.
  3. Ändere die DB-Cluster-Parametergruppe, um die rds.restrict_password_commands auf 1 zu setzen.

Hinweis: Um die Änderung anzuwenden, musst du die primäre DB-Instance von Aurora PostgreSQL-Compatible neu starten.

Verwendung der IAM-Datenbankauthentifizierung

Verwende bei der IAM-Datenbankauthentifizierung ein Authentifizierungstoken, um eine Verbindung zum DB-Cluster herzustellen, und nicht ein Passwort.

Gehe wie folgt vor, um die IAM-Datenbankauthentifizierung zu verwenden:

  1. Aktiviere die IAM-Datenbankauthentifizierung.
  2. Erstelle eine IAM-Richtlinie für den IAM-Datenbankzugriff.
  3. Stelle als Hauptbenutzer:in oder als Benutzer:in, der/die Berechtigungen erstellen und erteilen kann, eine Verbindung zum DB-Cluster her.
  4. Erteile deinen Benutzern die Rolle rds_iam.
  5. Verwende die IAM-Authentifizierung, um eine Verbindung zum DB-Cluster herzustellen.

Eine benutzerdefinierte Passwortrichtlinie für IAM-Benutzer erstellen

Weitere Informationen findest du unter Eine Kontopasswortrichtlinie für IAM-Benutzer einrichten.

Secrets Manager verwenden

Verwende AWS Secrets Manager, um die Passwörter der Hauptbenutzer zu verwalten. Verwende IAM-Bedingungsschlüssel, um die Aurora-Verwaltung der primären Benutzerpasswörter durchzusetzen.

Weitere Informationen findest du unter Passwortverwaltung mit Amazon Aurora und AWS Secrets Manager.

Ähnliche Informationen

Grundlegendes zu PostgreSQL-Rollen und -Berechtigungen

Neu – Vertrauenswürdige Spracherweiterungen für PostgreSQL auf Amazon Aurora und Amazon RDS

AWS OFFICIALAktualisiert vor 5 Monaten