スキップしてコンテンツを表示

Amazon RDS for PostgreSQL でパスワードポリシーを作成する方法を教えてください。

所要時間3分
0

Amazon Relational Database Service (Amazon RDS) for PostgreSQL でパスワードポリシーを作成しようとしています。

簡単な説明

デフォルトでは、Amazon RDS for PostgreSQL にはパスワードポリシーを適用する機能はありません。ただし、PostgreSQL フックと Trusted Language Extensions (TLE) 拡張機能を使用すると、コア機能を拡張できます。ユーザーまたはロールのパスワードを作成または変更する際の、PostgreSQL のパスワード処理方法をカスタマイズするには、パスチェックフックを使用します。

**注:**TLE は、バージョン 16.1 以降、15.2 以降、14.5 以降、13.12 以降の Amazon RDS for PostgreSQL をサポートしています。詳細については、「PostgreSQL 用の Trusted Language Extensions を使用するための要件」を参照してください。

解決策

注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI で発生したエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。

カスタマーパラメータグループを作成し、TLE 拡張機能を設定する

次の手順を実行します。

  1. カスタムパラメータグループを作成し、Amazon RDS for PostgreSQL インスタンスに関連付けます。
    注: パラメータグループを変更すると、ダウンタイムが発生します。ダウンタイムが即時発生しないようにするには、メンテナンス期間を使用してください。

  2. TLE 拡張機能を設定します

  3. インスタンスにログインし、次のクエリを実行して shared_preload_libraries パラメータが更新されていることを確認します。

    postgres=> SHOW shared_preload_libraries;shared_preload_libraries  
    rdsutils,pg_tle,pg_stat_statements  
    (1 row)  
    postgres=>
  4. 次のクエリを実行して TLE 拡張機能を作成します。

    CREATE EXTENSION pg_tle;

    注: pg_tle 拡張機能を設定、構成するには、データベースユーザーロールに rds_superuser ロールのアクセス許可が必要です。

  5. pgtle_admin ロールを Amazon RDS for PostgreSQL インスタンスのプライマリユーザーに付与します。デフォルトユーザーを使用した場合は、そのユーザーがプライマリ postgres ユーザーになります。

    GRANT pgtle_admin TO example-user;

    注: example-user を Amazon RDS for PostgreSQL インスタンスのプライマリユーザーに置き換えます。

パスチェックフックを設定する

PostgreSQL パスチェックフックは SQL 操作のパスワードをチェックし、ユーザーが password_check.bad_passwords テーブルに含まれるパスワードを設定することを禁止します。パスチェックフックはパスワードの長さおよび、そのパスワードに大文字と小文字、数字、特殊文字が含まれていることを確認します。

注: PostgreSQL フックの関数は、特定のニーズに合わせて変更できます。bad_passwords テーブルにさらにパスワードを追加したり、必要なパスワードの長さを変更したり、パスワードの複雑さをチェックするための関数を変更したりできます。

次の手順を実行します。

  1. 次の SQL コマンド pgtle.install_extension を実行します。特定のニーズに合わせて SQL コードを変更します。

    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_$);

    注: 上記のコマンドでは、example-password-check-rules を実際のパスワードチェックのルール名に置き換えてください。

  2. 次のクエリを実行して拡張機能を作成します。

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

    注: 上記のコマンドでは、example-password-check-rules を実際のパスワードチェックのルール名に置き換えてください。

  3. インスタンスに関連付けられているカスタムパラメータグループを変更し、pgtle.enable_password_check パラメータを有効にします。

  4. パスワードチェックのルールをテストするには、次の例を使用してください。
    例:

    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)"

    注: 上記の例は、一般パスワード辞書のパスワードを使用できないため、エラーが発生したことを示しています。
    例:

    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)"

    注: 上記の例は、パスワードは 8 文字以上でなければならないため、エラーが発生したことを示しています。
    例:

    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)"

    注: 上記の例は、パスワードには大文字、小文字、数字、特殊文字が含まれている必要があるため、エラーが発生したことを示しています。

TLE をサポートしていない Amazon RDS for PostgreSQL のバージョンでは、AWS Identity and Access Management (IAM) for Amazon RDS または Kerberos 認証を使用してください。なお、あるロールセットまたは特定のロールのみがパスワードを作成できるように制限する場合は、「ユーザーパスワード管理の委任と制御」を参照してください。

関連情報

Trusted Language Extensions for PostgreSQL の使用方法

Trusted Language Extensions for PostgreSQL のフックに関するリファレンス

コメントはありません

関連するコンテンツ