我想使用适用于 PostgreSQL 的 Amazon Relational Database Service (Amazon RDS) 来运行 CREATE USER 或 ALTER USER 语句。这样做时,PostgreSQL 会在日志文件中明文记录我的密码。
概述
您可以将 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.004s
日志中的输出结果:
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 for PostgreSQL 实例开启 pgaudit。
- 在您的自定义参数组中,设置 pgaudit.log 参数以指定要记录的语句类。此参数采用多个值,例如 DDL、role、write 和 read。
**注意:**pgaudit.log='DDL' 和 log_statement='DDL' 之间的主要区别在于 pgaudit,DDL 不会在 postgres 日志中记录任何 CREATE/ALTER ROLE 查询。
将 ROLE 添加到 pgaudit.log 以记录 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 日志中显示密码哈希,但不会以明文形式记录密码。
要使用 \password 函数,请运行以下命令:
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;
相关信息
Amazon RDS for PostgreSQL 数据库日志文件
使用 Amazon RDS 和 Amazon Aurora PostgreSQL 兼容版本日志: 第 1 部分
如何使用 pgaudit 扩展程序来审计运行 PostgreSQL 的 Amazon RDS 数据库实例?