Amazon RDS for PostgreSQL がパスワードをクリアテキストでログファイルにログ記録しないようにするにはどうすればよいですか?
最終更新日: 2021 年 9 月 27 日
簡単な説明
log_statement パラメータを ddl または all に設定し、CREATE ROLE/USER ...WITH PASSWORD ... ;、または ALTER ROLE/USER ...WITH PASSWORD ... ;, コマンドを実行する場合、PostgreSQLは、PostgreSQL ログにエントリを作成します。PostgreSQL はパスワードをクリアテキストで記録するため、潜在的なセキュリティリスクを引き起こす可能性があります。
現在、PostgreSQL は機密情報を識別しません。これは予期される動作であり、PostgreSQL エンジンの設計に従っています。
次の例では、パスワードを使用して CREATE ROLE ステートメントを実行し、パスワードをクリアテキストでログに表示します。
USER@postgresdb:pg> CREATE ROLE test_role WITH PASSWORD 'test123';
CREATE ROLE
Time: 0.003s
ログへの出力:
2020-04-15 14:57:29 UTC:x.x.x.x(42918):USER@pg:[13790]:LOG: statement: CREATE ROLE test_role WITH PASSWORD 'test123'
次の例では、パスワードを使用して ALTER ROLE ステートメントを実行し、パスワードをクリアテキストでログに表示します。
USER@postgresdb:pg> ALTER ROLE test_role WITH PASSWORD 'test';
You're about to run a destructive command.
Do you want to proceed? (y/n): y
Your call!
ALTER ROLE
Time: 0.004sOutput in the logs:
ログへの出力:
2020-04-15 14:59:45 UTC:x.x.x.x(42918):USER@pg:[13790]:STATEMENT: ALTER ROLE test_role SET PASSWORD 'test'
解決方法
PGAudit プラグインを使用する
pgaudit 拡張機能を使用して、PostgreSQL ログからパスワードをマスキングします。
- Amazon RDS PostgreSQL インスタンスの pgaudit をオンにします。
- お客様のパラメータグループで、pgaudit.log パラメータを設定して、ログに記録するステートメントクラスを指定します。このパラメータは、DDL、ロール、書き込み、読み取りなど、複数の値を取ることができます。
注: pgaudit.log='DDL' と log_statement='DDL' の主な違いは、pgaudit、DDL は Postgres ログに CREATE/ALTER ROLE クエリを記録しないことです。
pgaudit.log に ROLE を追加することにより、CREATE/ALTER ROLE をログ記録できます。これでパスワードがマスキングされます。
ログへの出力:
2020-07-09 13:33:50 UTC:x.x.x.x(58670):grysa@pg:[26513]:LOG:
AUDIT: SESSION,3,1,ROLE,CREATE ROLE,,,CREATE ROLE test_role WITH LOGIN
PASSWORD <REDACTED>,<not logged>
トランザクションブロック内のセッションレベルで log_statement を none に設定する
PostgreSQL がオペレーションを完全に記録するのを停止するには、トランザクションブロック内のセッションレベルで log_statement パラメータを none に設定します。
注: pgaudit.log と log_statement の両方が DDL に設定されている場合は、セッションレベルで log_statement を none に設定する必要があります。
例:
BEGIN;
SET LOCAL log_statement = 'none';
ALTER ROLE ... WITH PASSWORD ...;
COMMIT;
パスワードハッシュをローカルで作成する
パスワードハッシュをローカルで作成し、ロールまたはユーザーパスワードを作成または変更するときに当該ハッシュを使用します。
注: 作成してステートメントを実行するために使用するハッシュは、引き続きログに表示されます。これは復号できますが、クリアテキストではログ記録されません。
例:
[ec2-user@ip-x.x.x.x ~]$ username='test_1'; dbpass='test123'; echo -n "${dbpass}${username}" | md5sum | awk '{print "md5" $1}'
md574e183386ccb9039d0537aeb03c03db9
USER@postgresdb:pg> CREATE ROLE test_1 WITH PASSWORD 'md574e183386ccb9039d0537aeb03c03db9';
CREATE ROLE
Time: 0.003s
ログへの出力:
2020-04-15 15:12:08 UTC:x.x.x.x(42918):grysa@pg:[13790]:LOG: statement: CREATE ROLE test_1 WITH PASSWORD
'md574e183386ccb9039d0537aeb03c03db9'
\password コマンドを使用する
PostgreSQL を使用する場合は、PostgreSQL クライアントに組み込まれている \password 関数を使用できます。これにより、既存のロールパスワードを作成または変更するときに、新しいパスワードの入力が求められます。PostgreSQL は、パスワードのハッシュのみをログに記録します。
注: この解決策では、Postgres ログにパスワードハッシュも表示されますが、クリアテキストではログ記録されません。
次のコマンドを実行します。
pg=> CREATE ROLE test_role NOLOGIN;
CREATE ROLE
pg=> \password test_role
Enter new password:
Enter it again:
pg=> ALTER ROLE test_role LOGIN;
ALTER ROLE
pg=>
ログへの出力:
2020-04-09 12:29:29 UTC:x.x.x.x(39876):grysa@pg:[1879]:LOG: statement: CREATE ROLE test_role NOLOGIN;
2020-04-09 12:30:02 UTC:x.x.x.x(39876):grysa@pg:[1879]:LOG: statement: show password_encryption
2020-04-09 12:30:02 UTC:x.x.x.x(39876):grysa@pg:[1879]:LOG: statement: ALTER USER test_role PASSWORD 'md5175cad7c36a640b1fcfa0144056923f5'
2020-04-09 12:30:30 UTC:x.x.x.x(39876):grysa@pg:[1879]:LOG: statement: ALTER ROLE test_role LOGIN;