Amazon RDS for PostgreSQL でパスワードポリシーを作成する方法を教えてください。
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 拡張機能を設定する
次の手順を実行します。
-
カスタムパラメータグループを作成し、Amazon RDS for PostgreSQL インスタンスに関連付けます。
注: パラメータグループを変更すると、ダウンタイムが発生します。ダウンタイムが即時発生しないようにするには、メンテナンス期間を使用してください。 -
インスタンスにログインし、次のクエリを実行して shared_preload_libraries パラメータが更新されていることを確認します。
postgres=> SHOW shared_preload_libraries;shared_preload_libraries rdsutils,pg_tle,pg_stat_statements (1 row) postgres=> -
次のクエリを実行して TLE 拡張機能を作成します。
CREATE EXTENSION pg_tle;注: pg_tle 拡張機能を設定、構成するには、データベースユーザーロールに rds_superuser ロールのアクセス許可が必要です。
-
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 テーブルにさらにパスワードを追加したり、必要なパスワードの長さを変更したり、パスワードの複雑さをチェックするための関数を変更したりできます。
次の手順を実行します。
-
次の 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 を実際のパスワードチェックのルール名に置き換えてください。
-
次のクエリを実行して拡張機能を作成します。
postgres=> CREATE EXTENSION "example-password-check-rules";注: 上記のコマンドでは、example-password-check-rules を実際のパスワードチェックのルール名に置き換えてください。
-
インスタンスに関連付けられているカスタムパラメータグループを変更し、pgtle.enable_password_check パラメータを有効にします。
-
パスワードチェックのルールをテストするには、次の例を使用してください。
例: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 認証を使用してください。なお、あるロールセットまたは特定のロールのみがパスワードを作成できるように制限する場合は、「ユーザーパスワード管理の委任と制御」を参照してください。
