PostgreSQL password security
发布时间:2020-12-13 17:36:19 所属栏目:百科 来源:网络整理
导读:一般来说数据库密码安全管理要考虑以下几个方面 : 1. 密码过期策略,决定密码的有效期,多长时间过期. PostgreSQL不支持密码过期策略,但是可以通过其他方式来实现过期提醒. 2. 密码复用策略,密码修改时需要对比以前的密码,多少次以后才可以复用,或者永不能使用
一般来说数据库密码安全管理要考虑以下几个方面 : 1. 密码过期策略,决定密码的有效期,多长时间过期.PostgreSQL不支持密码过期策略,但是可以通过其他方式来实现过期提醒.
PostgreSQL 不支持密码复用策略,但是可以通过其他方式来实现强制密码复用策略.
PostgreSQL 不支持密码长度策略,但是可以通过其他方式来实现强制密码长度策略.
PostgreSQL 不支持密码复杂度策略,但是可以通过其他方式来实现强制密码复杂度策略.
PostgreSQL 不支持密码字典过滤策略,但是可以通过其他方式来实现强制字典过滤策略.
加密存储在创建用户时使用encrypted password即可. 如果设置了password_encryption=off,同时创建用户时不加encrypted,那么密码将以明文存储. 例如 : 加密存储 : digoal=# create role u1 login encrypted password 'digoal'; CREATE ROLE digoal=# select * from pg_shadow where usename='u1'; usename | usesysid | usecreatedb | usesuper | usecatupd | userepl | passwd | valuntil | useconfig ---------+----------+-------------+----------+-----------+---------+-------------------------------------+----------+----------- u1 | 26383 | f | f | f | f | md5bdf22a6622939c7c7ab2377eaca514d5 | | (1 row) 明文存储 : digoal=# set password_encryption=off; SET digoal=# create role u2 login password 'digoal'; CREATE ROLE digoal=# select * from pg_shadow where usename='u2'; usename | usesysid | usecreatedb | usesuper | usecatupd | userepl | passwd | valuntil | useconfig ---------+----------+-------------+----------+-----------+---------+--------+----------+----------- u2 | 26387 | f | f | f | f | digoal | | (1 row)
PostgreSQL 不支持密码锁策略. 8. 密码保护策略,密码输入错误多少次后延迟认证. 可用来防止暴力破解. PostgreSQL 不支持密码保护策略. 目前PostgreSQL在密码管理这块做得较弱,以下举例通过函数来实现其中的部分安全策略 : 创建一个字典表,用于存放已经使用过的密码的md5值,以及用来进行暴力破解的密码字典的md5值. digoal=# create table pwd_dictionary(pwd text unique); CREATE TABLE 创建一个记录用户最后一次修改密码时间的表. 用于实施密码过期提醒策略. digoal=# create table user_pwd(rolename name not null unique,pwd_modify_time timestamp not null); CREATE TABLE 创建用户的函数 : digoal=# create or replace function create_role(i_rolename name,i_pwd text) returns void as $$ declare v_length int := 8; begin -- 密码长度策略 if length(i_pwd) < v_length then raise notice 'password too short,please use password long than %.',v_length; return; end if; -- 密码复杂度策略,包含数字,字母大小写. if not(i_pwd ~ '[a-z]' and i_pwd ~ '[A-Z]' and i_pwd ~ '[0-9]') then raise notice 'password too simple,please ensure password contain a-z,A-Z and 0-9.'; return; end if; -- 密码复用策略,不允许重复使用已经存在的密码. -- 密码字典策略,不允许使用密码字典中的密码. insert into pwd_dictionary(pwd) values (md5(i_pwd)); -- 插入用户表,记录用户最后一次修改密码的时间,用于密码过期策略 insert into user_pwd(rolename,pwd_modify_time) values (i_rolename,now()); -- 创建用户 execute 'create role '||i_rolename||' encrypted password '||quote_literal(i_pwd); raise notice 'create role % successed.',i_rolename; return; end; $$ language plpgsql strict; CREATE FUNCTION 创建用户密码过短,不允许创建. digoal=# select * from create_role('u4','pwd'); NOTICE: password too short,please use password long than 8. create_role ------------- (1 row) 创建用户密码过于简单,'abcdefee'); NOTICE: password too simple,A-Z and 0-9. create_role ------------- (1 row) 创建用户正常. digoal=# select * from create_role('u4','aA0ffffffff'); NOTICE: create role u4 successed. create_role ------------- (1 row) 创建用户密码与现有密码重复,不允许创建. digoal=# select * from create_role('new','aA0ffffffff'); ERROR: duplicate key value violates unique constraint "pwd_dictionary_pwd_key" DETAIL: Key (pwd)=(2b9aa88182d13d35930180b4cc791beb) already exists. CONTEXT: SQL statement "insert into pwd_dictionary(pwd) values (md5(i_pwd))" PL/pgSQL function create_role(name,text) line 17 at SQL statement 修改用户密码的函数 : digoal=# create or replace function alter_role_pwd(i_rolename name,不允许使用密码字典中的密码. insert into pwd_dictionary(pwd) values (md5(i_pwd)); -- 更新用户表,用于密码过期策略 update user_pwd set pwd_modify_time=now() where rolename=i_rolename; -- 修改用户密码 execute 'alter role '||i_rolename||' encrypted password '||quote_literal(i_pwd); raise notice 'modify role % password successed.',i_rolename; return; end; $$ language plpgsql strict; CREATE FUNCTION 使用该函数修改用户密码 digoal=# select * from alter_role_pwd('u4','new'); NOTICE: password too short,please use password long than 8. alter_role_pwd ---------------- (1 row) digoal=# select * from alter_role_pwd('u4','new22222222'); NOTICE: password too simple,A-Z and 0-9. alter_role_pwd ---------------- (1 row) digoal=# select * from alter_role_pwd('u4','new2222222z2'); NOTICE: password too simple,'new2222222z2A'); NOTICE: modify role u4 password successed. alter_role_pwd ---------------- (1 row) digoal=# select * from alter_role_pwd('u4','new2222222z2A'); ERROR: duplicate key value violates unique constraint "pwd_dictionary_pwd_key" DETAIL: Key (pwd)=(9a5c46207db775d4d98e64d427481cbc) already exists. CONTEXT: SQL statement "insert into pwd_dictionary(pwd) values (md5(i_pwd))" PL/pgSQL function alter_role_pwd(name,text) line 17 at SQL statement 密码过期提醒 : 因为密码最后一次修改时间已经更新到user_pwd表,所以结合这个可以在系统crontab中或者nagios监控软件中实施密码过期提醒. digoal=# select * from user_pwd ; rolename | pwd_modify_time ----------+---------------------------- u4 | 2013-05-25 18:21:59.376404 (1 row) [小结] 1. 为了密码安全性,在PostgreSQL 中,创建用户请使用create_role函数,不要直接使用create role 命令. 2. 修改用户密码请使用alter_role_pwd函数. 不要直接使用alter role 命令. 3. 密码过期提醒请结合nagios软件或者操作系统crontab来实现邮件提醒数据库管理员.(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |