概述:使用session_exec+file_fdw插件,实现当有用户成功连接数据库后,锁定数据库中最近连续输入错误密码5次或以上的用户。(自动锁定用户后,需要手动解锁)
编译session_exec插件
$ unzip session_exec-master.zip
$ cd ./session_exec-master/
$ which pg_config
/u01/pg13/pg/bin/pg_config
$ make pg_config=/u01/pg13/pg/bin/pg_config
$ make pg_config=/u01/pg13/pg/bin/pg_config install
复制
修改数据库配置
设置数据库日志输出格式为CSV,设置日志记录数据库连接信息
$ tail -5 $PGDATA/postgresql.conf
logging_collector=on
log_destination='csvlog'
log_connections = on
session_preload_libraries='session_exec'
session_exec.login_name='public.login'
$ pg_ctl reload
server signaled
复制
注:
session_preload_libraries参数:一个或者多个要在连接开始时预载入的共享库。
shared_preload_libraries参数:一个或者多个要在服务器启动时预载入的共享库。
创建一个外部表:postgres_log
外部表数据为一天内的CSV日志文件内容
postgres=# create extension file_fdw;
CREATE EXTENSION
postgres=# CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw;
CREATE SERVER
postgres=# CREATE FOREIGN TABLE public.postgres_log(
postgres(# log_time timestamp(3) with time zone,
postgres(# user_name text,
postgres(# database_name text,
postgres(# process_id integer,
postgres(# connection_from text,
postgres(# session_id text,
postgres(# session_line_num bigint,
postgres(# command_tag text,
postgres(# session_start_time timestamp with time zone,
postgres(# virtual_transaction_id text,
postgres(# transaction_id bigint,
postgres(# error_severity text,
postgres(# sql_state_code text,
postgres(# message text,
postgres(# detail text,
postgres(# hint text,
postgres(# internal_query text,
postgres(# internal_query_pos integer,
postgres(# context text,
postgres(# query text,
postgres(# query_pos integer,
postgres(# location text,
postgres(# application_name text,
postgres(# backend_type text
postgres(# ) SERVER pglog
postgres-# OPTIONS ( program 'find /u01/pg13/pgsource/pgdata/log -type f -name "*.csv" -mtime -1 -exec cat {} \;', format 'csv' );
CREATE FOREIGN TABLE
postgres=# grant SELECT on postgres_log to PUBLIC ;
GRANT
postgres=# select log_time,user_name,error_severity,message,detail from public.postgres_log where command_tag = 'authentication' order by log_time desc limit 10 offset 0;
log_time | user_name | error_severity | message | detail
----------------------------+-----------+----------------+------------------------------------------------------------------------------+--------------------------------------------------------------------------------------
----------
2021-09-07 05:57:41.24+08 | test | FATAL | password authentication failed for user "test" | Connection matched pg_hba.conf line 100: "host all all 0.0.0.0/0 scram
-sha-256"
2021-09-07 05:57:23.412+08 | postgres | LOG | connection authorized: user=postgres database=postgres application_name=psql |
2021-09-07 05:55:43.124+08 | test | FATAL | password authentication failed for user "test" | Connection matched pg_hba.conf line 100: "host all all 0.0.0.0/0 md5"
2021-09-07 05:45:15.064+08 | test5 | FATAL | password authentication failed for user "test5" | Role "test5" does not exist.
+
| | | | Connection matched pg_hba.conf line 100: "host all all 0.0.0.0/0 md5"
2021-09-07 05:45:12.308+08 | test5 | FATAL | password authentication failed for user "test5" | Role "test5" does not exist.
+
| | | | Connection matched pg_hba.conf line 100: "host all all 0.0.0.0/0 md5"
2021-09-07 05:43:06.076+08 | test | LOG | connection authorized: user=test database=db1 application_name=psql |
2021-09-07 05:42:51.308+08 | test | LOG | connection authorized: user=test database=postgres application_name=psql |
2021-09-07 05:42:42.994+08 | test | FATAL | password authentication failed for user "test" | Connection matched pg_hba.conf line 100: "host all all 0.0.0.0/0 md5"
2021-09-07 05:42:25.626+08 | postgres | LOG | connection authorized: user=postgres database=postgres application_name=psql |
2021-09-07 05:41:32.74+08 | test | FATAL | password authentication failed for user "test" | Connection matched pg_hba.conf line 100: "host all all 0.0.0.0/0 md5"
(10 rows) +
复制
创建存储过程public.login()
postgres=# create or replace function public.login() returns void as $$
postgres$# declare
postgres$# res record;
postgres$# failed_login_times int = 5;
postgres$# failed_login int = 0;
postgres$# begin
postgres$# --获取数据库中所有可连接数据库的用户
postgres$# for res in select rolname from pg_catalog.pg_roles where rolcanlogin= 't' and rolname !='postgres'
postgres$# loop
postgres$# raise notice 'user: %!',res.rolname;
postgres$# --获取当前用户最近连续登录失败次数
postgres$# select count(*)
postgres$# from (select log_time,user_name,error_severity,message,detail from public.postgres_log where command_tag = 'authentication' and user_name = res.rolname and (detail is null or detail not like 'Role % does not exist.%') order by log_time desc limit failed_login_times) A
postgres$# WHERE A.error_severity='FATAL'
postgres$# into failed_login ;
postgres$# raise notice 'failed_login_times: %! failed_login: %!',failed_login_times,failed_login;
postgres$# --用户最近密码输入错误次数达到5次或以上
postgres$# if failed_login >= failed_login_times then
postgres$# --锁定用户
postgres$# EXECUTE format('alter user %I nologin',res.rolname);
postgres$# raise notice 'Account % is locked!',res.rolname;
postgres$# end if;
postgres$# end loop;
postgres$# end;
postgres$# $$ language plpgsql strict security definer set search_path to 'public';
CREATE FUNCTION
复制
密码错误次数测试
$ psql -U test -d postgres -h 192.168.2.154
Password for user test:(输入错误的密码)
psql: error: FATAL: password authentication failed for user "test"
$ psql -U test -d postgres -h 192.168.2.154
Password for user test:(输入错误的密码)
psql: error: FATAL: password authentication failed for user "test"
$ psql -U test -d postgres -h 192.168.2.154
Password for user test:
psql: error: FATAL: password authentication failed for user "test"
$ psql -U test -d postgres -h 192.168.2.154
Password for user test:(输入错误的密码)
psql: error: FATAL: password authentication failed for user "test"
$ psql -U test -d postgres -h 192.168.2.154
Password for user test:(输入错误的密码)
psql: error: FATAL: password authentication failed for user "test"
$ psql -U test -d postgres -h 192.168.2.154
Password for user test:(输入错误的密码)
psql: error: FATAL: password authentication failed for user "test"
$ psql
NOTICE: user: test1!
NOTICE: failed_login_times: 5! failed_login: 4!
NOTICE: user: test2!
NOTICE: failed_login_times: 5! failed_login: 0!
NOTICE: user: test!
NOTICE: failed_login_times: 5! failed_login: 5!
NOTICE: Account test is locked!
psql (13.3)
Type "help" for help.
postgres=# \q
$ psql -U test -d postgres -h 192.168.2.154
Password for user test:(输入正确的密码)
psql: error: FATAL: role "test" is not permitted to log in
$ psql -U test -d postgres -h 192.168.2.154
Password for user test:(输入错误的密码)
psql: error: FATAL: password authentication failed for user "test"
$
$ psql
NOTICE: user: test1!
NOTICE: failed_login_times: 5! failed_login: 4!
NOTICE: user: test2!
NOTICE: failed_login_times: 5! failed_login: 0!
psql (13.3)
Type "help" for help.
postgres=# alter user test login;
ALTER ROLE
postgres=# \q
$ psql -U test -d postgres -h 192.168.2.154
Password for user test:
NOTICE: user: test1!
NOTICE: failed_login_times: 5! failed_login: 4!
NOTICE: user: test2!
NOTICE: failed_login_times: 5! failed_login: 0!
NOTICE: user: test!
NOTICE: failed_login_times: 5! failed_login: 3!
psql (13.3)
Type "help" for help.
postgres=> \q
复制
结论
数据库有用户正常连接到数据库时,就会运行public.login()函数,锁定数据库中连续五次或以上密码输入错误的用户。
最后修改时间:2021-09-23 09:10:10
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
文章被以下合辑收录
评论
一个人真正的成熟,是能接受自己的不完美。与其一味沉浸在后悔中,不如坦然接受。学会卸下心中沉重的包袱,我们才能昂首大步向前。
1年前

评论
按照文档操作,但是报错 ,我使用的GP版本是9.4
1年前

评论
相关阅读
外国CTO也感兴趣的开源数据库项目——openHalo
小满未满、
1767次阅读
2025-04-21 16:58:09
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
381次阅读
2025-04-15 14:48:05
转发有奖 | PostgreSQL 16 PGCM高级认证课程直播班招生中!
墨天轮小教习
193次阅读
2025-04-14 15:58:34
中国PostgreSQL培训认证体系新增PGAI应用工程师方向
开源软件联盟PostgreSQL分会
186次阅读
2025-05-06 10:21:13
华象新闻 | PostgreSQL 18 Beta 1、17.5、16.9、15.13、14.18、13.21 发布
严少安
149次阅读
2025-05-09 11:34:10
PG生态赢得资本市场青睐:Databricks收购Neon,Supabase融资两亿美元,微软财报点名PG
老冯云数
147次阅读
2025-05-07 10:06:22
SQL 优化之 OR 子句改写
xiongcc
141次阅读
2025-04-21 00:08:06
告别老旧mysql_fdw,升级正当时
NickYoung
125次阅读
2025-04-29 11:15:18
PostgreSQL中文社区亮相于第八届数字中国峰会
PostgreSQL中文社区
110次阅读
2025-05-07 10:06:20
PostgreSQL的dblink扩展模块使用方法
szrsu
106次阅读
2025-04-24 17:39:30