前言
最近安全问题管控的挺严格的,一项很基本的要求就是数据库的密码要设置足够复杂(例如一般会要求数字、字母、特殊字符的组合,且不少于8位)。在Oracle数据库中,我们可以通过profile中的PASSWORD_VERIFY_FUNCTION
定义一个函数,来进行管理和控制。但是在PG中默认没有这类的功能,稍微研究了一下,发现可以使用扩展passwordcheck,或者是Credcheck来实现。Credcheck这个插件是基于passwordcheck这个插件的源代码来实现的。而他们均是基于check_password_hook这个钩子来实现的。该模块主要检查密码格式,如果密码不满足模块中定义的条件,则向用户返回错误。

Credcheck
系统自带的插件passwordcheck,写的人比较多了,我这里就研究了一下新的插件Credcheck。

这个插件有个默认的模板,模板的参数如下表个所示:
检查参数 | 类型 | 描述 | 设置值 | Accepted | Not Accepted |
---|---|---|---|---|---|
username_min_length | username | 用户名的最小长度 | 4 | ✓ abcd | ✘ abc |
username_min_special | username | 最少特殊字符数 | 1 | ✓ a@bc | ✘ abcd |
username_min_digit | username | 最少位数 | 1 | ✓ a1bc | ✘ abcd |
username_min_upper | username | 最小大写数 | 2 | ✓ aBC | ✘ aBc |
username_min_lower | username | 最小小写数 | 1 | ✓ aBC | ✘ ABC |
username_min_repeat | username | 一个字符应该重复的最大次数 | 2 | ✓ aaBCa | ✘ aaaBCa |
username_contain_password | username | 用户名不应包含密码 | on | ✓ username - password | ✘ username + password |
username_contain | username | 用户名应包含这些字符之一 | a,b,c | ✓ ade | ✘ efg |
username_not_contain | username | 用户名不应包含这些字符之一 | x,y,z | ✓ ade | ✘ axf |
username_ignore_case | username | 执行上述检查时忽略大小写 | on | ✓ Ade | ✘ aXf |
password_min_length | password | 密码的最小长度 | 4 | ✓ abcd | ✘ abc |
password_min_special | password | 最少特殊字符数 | 1 | ✓ a@bc | ✘ abc |
password_min_digit | password | 密码中的最少位数 | 1 | ✓ a1bc | ✘ abc |
password_min_upper | password | 最少大写字符数 | 1 | ✓ Abc | ✘ abc |
password_min_lower | password | 最少小写字符数 | 1 | ✓ aBC | ✘ ABC |
password_min_repeat | password | 一个字符应该重复的最大次数 | 2 | ✓ aab | ✘ aaab |
password_contain_username | password | 密码不应包含密码 | on | ✓ password - username | ✘ password + username |
password_contain | password | 密码应包含这些字符 | a,b,c | ✓ ade | ✘ xfg |
password_not_contain | password | 密码不应包含这些字符 | x,y,z | ✓ abc | ✘ axf |
password_ignore_case | password | 执行上述检查时忽略大小写 | on | ✓ Abc | ✘ aXf |
测试使用
和其他插件安装方式类似,下载源代码进行编译。
1.设置pg_config和path环境变量2.make && make install3.shared_preload_libraries='credcheck'4.create extension credcheck;
查看当前的模板。
test=# select name,setting from pg_settings where name like '%credcheck%'; name | setting -------------------------------------+--------- credcheck.password_contain | credcheck.password_contain_username | on credcheck.password_ignore_case | off credcheck.password_min_digit | 0 credcheck.password_min_length | 1 credcheck.password_min_lower | 0 credcheck.password_min_repeat | 0 credcheck.password_min_special | 0 credcheck.password_min_upper | 0 credcheck.password_not_contain | credcheck.username_contain | credcheck.username_contain_password | on credcheck.username_ignore_case | off credcheck.username_min_digit | 0 credcheck.username_min_length | 1 credcheck.username_min_lower | 0 credcheck.username_min_repeat | 0 credcheck.username_min_special | 0 credcheck.username_min_upper | 0 credcheck.username_not_contain |
当前是默认的配置,我们来按照我们Oracle的VERIFY_FUNCTION的要求来配置一下,当前密码的要求如下:
密码必须在8位以上 密码必须有大写字符 密码必须有特殊字符
alter system set credcheck.password_min_length=8;alter system set credcheck.password_min_upper=1;alter system set credcheck.password_min_special=1;test=# select pg_reload_conf(); pg_reload_conf ---------------- t(1 row)
设置完成之后需要reload一下。我们创建密码试试。
1.不包含大写字符。
test=# CREATE USER test_a1 WITH PASSWORD 'aaaaa1234';ERROR: password does not contain the configured credcheck.password_min_upper characters
2.没有特殊字符
test=# CREATE USER test_a1 WITH PASSWORD 'Aaaaa1234';ERROR: password does not contain the configured credcheck.password_min_special characters
3.密码必须8位以上。
test=# CREATE USER test_a1 WITH PASSWORD 'Aaa!123'; ERROR: password length should match the configured credcheck.password_min_length
可以看到我尝试创建用户,设置的密码不符合规则都被拒绝掉了,只有符合上述规则的用户才能被创建。
test=# CREATE USER test_a1 WITH PASSWORD 'Aaa!12345';CREATE ROLE
限制
它仅仅支持纯文本密码,如果使用加密的密码,则会报错。
test=# CREATE USER user1 PASSWORD 'md55e4cc86d2d6a8b73bbefc4d5b91baa45';ERROR: password type is not a plain text
创建没有密码的用户时不会强制执行用户名检查,如果用户没有定义密码,则在重命名用户时不会强制执行用户名检查。
我们来测试一下这个限制,先把用户名这里设置一下,设置在6个字符以上。
test=# alter system set credcheck.username_min_length=6;ALTER SYSTEM
直接创建用户不输入密码,没有触发限制。
test=# CREATE USER user1;CREATE ROLE
rename用户名,也没触发限制。
test=# alter user user1 RENAME to uesr2;ALTER ROLE
这里设置密码,此处就会触发了用户名和密码的限制。
test=# ALTER USER uesr2 WITH PASSWORD 'adsfd32'; ERROR: username length should match the configured credcheck.username_min_length
后记
Credcheck这个插件可以帮助我们控制用户名和密码的强度,密码的安全加固可以用上。但是像什么密码有效期,密码多久之后可以再次重复,密码尝试多久之后就进行锁定,这些功能是没有的,它只是单纯的实现了类似Oracle中的PASSWORD_VERIFY_FUNCTION的函数功能。
参考链接:
https://github.com/MigOpsRepos/credcheck/blob/master/README.md#installation