这是我参与8月更文挑战的第29天,活动详情查看:8月更文挑战
总结:log_statement参数,一般设置为ddl级别以上的选项,但是该方式存在风险,任何修改用户密码的操作都将被明文记录到日志中,建议在修改用户密码前,临时关闭该参数。
在生产环境中,数据库日志记录功能必不可少。
通过设置数据库参数log_statement参数来控制数据库日志记录哪些SQL,可以选择的选项有:none, ddl, mod, and all,几个选项之间的区别如下:
none:不记录任何操作语句。
ddl:只记录所有DDL操作语句。
mod:记录所有DDL以及涉及到数据修改的语句。
all:记录所有操作语句。
例如下边这种情况就是设置数据库参数log_statement为ddl的状态:
postgres=# show log_statement;
log_statement
---------------
ddl
(1 row)
postgres=# select * from pg_file_settings where name ='log_statement';
sourcefile | sourceline | seqno | name | setting | applied | error
---------------------------------------------+------------+-------+---------------+---------+---------+-------
/postgres/data/postgresql.auto.conf | 10 | 31 | log_statement | ddl | t |
(1 row)
如果我们执行一个修改密码的操作,因为此类操作属于ddl语句范畴,因此
postgres=# alter user postgres encrypted password 'postgres';
ALTER ROLE
数据库日志记录如下:
2018-04-19 14:55:00.342 CST,"postgres","postgres",3440,"[local]",5ad83cd7.d70,3,"idle",2018-04-19 14:53:11 CST,2/7,0,LOG,00000,"statement: alter user postgres encrypted password 'postgres';",,,,,,,,,"psql"
可以看到,执行的修改密码操作被记录到了数据库日志中,而且密码以明文形式进行显示。
综上所述,建议在修改密码或者其他涉密操作之前,临时关闭该参数:
postgres=# set log_statement = 'none';
SET
postgres=# alter user postgres encrypted password 'postgres';
ALTER ROLE
该参数仅在当前会话生效,断开连接或退出登录后即失效,恢复为数据库参数设置值。
当然,这就有一个问题,就是如果有个懂行的人想干坏事,在干坏事之前先执行了set log_statement = 'none';,就会导致这些操作从日志当中无法被追踪。
所以如果是出于安全考虑,需要对这些操作进行专业而正式的审计,而不是日志记录这种辅助方法。可以采用第三方的一些插件statement,比如pgaudit。