PostgreSQL用户登录失败自动锁定的处理方案

墨墨导读:PostgreSQL使用session_exec插件实现用户密码验证失败几次后自动锁定,本文介绍一种处理方案。

一、插件session_exec安装配置篇

下载插件并编译安装。
https://github.com/okbob/session_exec

$ unzip session_exec-master.zip
$ cd session_exec-master/
$ make pg_config=/opt/pgsql/bin/pg_config
$ make pg_config=/opt/pgsql/bin/pg_config install

配置postgresql.conf。

session_preload_libraries='session_exec'
session_exec.login_name='login'

注意:上面第一个变量是设置session_preload_libraries而不是通常设置的shared_preload_libraries。
第二个变量是需要自定义实现的登录函数。

重启数据库服务。

$ sudo systemctl restart postgresql-12

二、自定义登录函数篇

创建t_login表用于存储提取自数据库日志中登录失败的信息。

create table t_login
(
login_time timestamp(3) with time zone --插入时间,
user_name text --数据库登录用户,
flag int4 --标志位,0代表过期数据,1代表正常状态数据
);

使用file_fdw外部表记录数据库日志信息。
file_fdw如果未配置过,参见下面步骤。

$ cd /opt/postgresql-12.5/contrib/file_fdw
$ make && make install

create extension file_fdw;
CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw;

建立外部表postgres_log,关联数据库日志中登录失败的信息。

CREATE FOREIGN TABLE postgres_log(
 log_time timestamp(3) with time zone,
 user_name text,
 database_name text,
 process_id integer,
 connection_from text,
 session_id text,
 session_line_num bigint,
 command_tag text,
 session_start_time timestamp with time zone,
 virtual_transaction_id text,
 transaction_id bigint,
 error_severity text,
 sql_state_code text,
 message text,
 detail text,
 hint text,
 internal_query text,
 internal_query_pos integer,
 context text,
 query text,
 query_pos integer,
 location text,
 application_name text
) SERVER pglog
OPTIONS ( program 'find /opt/pg_log_5432 -type f -name "*.csv" -mtime -1 -exec cat {} \;', format 'csv' );

注意:
1./opt/pg_log_5432需要修改为实际环境日志目录。
2. 不同PG版本csv日志格式可能有所差异,参考PG官网文档runtime-config-logging章节(http://postgres.cn/docs/12/runtime-config-logging.html)。

此时连接数据库因未创建登录函数会出现下面的警告信息。

$ psql -Upostgres
WARNING: function "login()" does not exist
psql (12.5)
Type "help" for help.

创建登录函数login。

create or replace function login() returns void as $$
declare
res text;
c1 timestamp(3) with time zone;
begin

--获取当前日志中最新时间
select login_time
from public.t_login
where flag = 0
order by login_time
desc limit 1
into c1; 

 --将最新的数据插入t_login表
insert into public.t_login
select log_time,user_name
from public.postgres_log
where command_tag='authentication'
and error_severity= 'FATAL'
and log_time > c1;

update public.t_login set flag = 1 where login_time > c1; 

--检查登录失败次数是否大于3,若大于3则锁定用户
for res in select user_name from public.t_login where flag = 1 group by user_name having count(*) >=3
loop
--锁定用户
EXECUTE format('alter user %I nologin',res);
--断开当前被锁定用户会话
EXECUTE 'select pg_catalog.pg_terminate_backend(pid) from pg_catalog.pg_stat_activity where usename=$1' using res;
raise notice 'Account % is locked!',res;
end loop;
end;
$$ language plpgsql strict security definer set search_path to 'public';

测试使用篇

创建测试用户。

create user test1 encrypted password 'XXX';

模拟test1用户登录失败,输入错误密码。

$ psql -h192.168.137.11 -Utest1 postgres
Password for user test1:
psql: error: FATAL: password authentication failed for user "test1"

通过外部表查看登录失败的日志。

select * from postgres_log where command_tag='authentication' and error_severity= 'FATAL';

可以看到1条数据,手工插入一条登录失败的信息到t_login表。

insert into t_login select log_time,user_name,0
 from postgres_log
 where command_tag='authentication'
 and error_severity= 'FATAL';

参考上面登录失败测试,接着再测试2次。

然后使用postgres用户登录数据库,观察t_login表数据。

postgres=# select * from t_login;
  login_time  | user_name | flag
-------------------------+-----------+------
 2021-02-08 06:24:47.101 | test1  | 0
 2021-02-08 06:25:16.581 | test1  | 1
 2021-02-08 06:25:18.429 | test1  | 1
(3 rows)

再测试两次失败登录,然后使用postgres用户登录数据库,看到提示该用户被锁定。

[postgres@node11 ~]$ psql
NOTICE: Account test1 is locked!
psql (12.5)
Type "help" for help.

postgres=# select * from t_login;
  login_time  | user_name | flag
-------------------------+-----------+------
 2021-02-08 06:45:38.017 | test1  | 0
 2021-02-08 06:45:58.809 | test1  | 1
 2021-02-08 06:45:58.809 | test1  | 1
 2021-02-08 06:46:08.116 | test1  | 1
 2021-02-08 06:46:11.986 | test1  | 1
(5 rows)

解锁用户。

update t_login set flag = 0 where user_name='test1' and flag=1;

总结

  • session_exec通过用户登录成功后调用login函数去实现锁定登录失败次数过多的用户。
  • 此种方式有点繁琐且会造成数据库连接变慢。
  • 不支持自动解锁,需要管理用户手工处理。

参考链接:

https://www.jb51.net/article/208018.htm

到此这篇关于PostgreSQL用户登录失败自动锁定的解决办法的文章就介绍到这了,更多相关PostgreSQL登录失败自动锁定内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Postgresql限制用户登录错误次数的实例代码

    在oracle中我们可以通过设置FAILED_LOGIN_ATTEMPTS来限制用户密码登录错误的次数,但是在postgresql中是不支持这个功能的.尽管PostgreSQL支持event trigger,可是event局限于DDL,对于登录登出事件是没办法使用event trigger的. 不过像登录新建会话触发某个事件这个需求可以通过hook实现,不过该方法比较复杂,需要修改内核代码,在客户端认证中添加逻辑,判断输入密码次数统计.这里推荐一种比较简单的方法实现类似的功能. 这里我们要使用到

  • PostgreSQL 实现登录及修改密码操作

    PostgreSQL登录 1.可通过客户端pgAdmin III直接登录 2.可通过命令行 命令:psql -h 10.10.10.10 -U user -d postgres -p 5570 -h:数据库IP -U:登录用户 -d:登录的数据库 -p:登录端口 方法:进入postgreSQL的客户端安装目录(我的安装目录:C:\Program Files\PostgreSQL\9.4\bin),执行psql命令,其中\q表示退出数据库 修改密码 直接执行以下sql即可修改密码 alter us

  • PostgreSQL用户登录失败自动锁定的处理方案

    墨墨导读:PostgreSQL使用session_exec插件实现用户密码验证失败几次后自动锁定,本文介绍一种处理方案. 一.插件session_exec安装配置篇 下载插件并编译安装. https://github.com/okbob/session_exec $ unzip session_exec-master.zip $ cd session_exec-master/ $ make pg_config=/opt/pgsql/bin/pg_config $ make pg_config=/

  • Centos7下用户登录失败N次后锁定用户禁止登陆的方法

    前言 针对linux上的用户,如果用户连续3次登录失败,就锁定该用户,几分钟后该用户再自动解锁.Linux有一个pam_tally2.so的PAM模块,来限定用户的登录失败次数,如果次数达到设置的阈值,则锁定用户. PAM的配置文件介绍 PAM配置文件有两种写法: 一种是写在/etc/pam.conf文件中,但centos6之后的系统中,这个文件就没有了. 另一种写法是,将PAM配置文件放到/etc/pam.d/目录下,其规则内容都是不包含 service 部分的,即不包含服务名称,而/etc/

  • linux尝试登录失败后锁定用户账户的两种方法

    本文主要给大家介绍了关于linux尝试登录失败后锁定用户账户的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍吧. pam_tally2模块(方法一) 用于对系统进行失败的ssh登录尝试后锁定用户帐户.此模块保留已尝试访问的计数和过多的失败尝试. 配置 使用/etc/pam.d/system-auth或etc/pam.d/password-auth配置文件来配置的登录尝试的访问 auth required pam_tally2.so deny=3 unlock_time=600 acc

  • 关于C#连接SQL Server时提示用户登录失败的解决方法

    在用C#开发windows端程序并连接SQL Server时有可能会遇到数据库登录失败的问题,报错现象如下图所示: 报错信息如下: System.Data.SqlClient.SqlException: '用户 '' 登录失败.' This exception was originally thrown at this call stack:     [External Code]     MyQQ.DataOperator.ExecSQL(string) in DataOperator.cs

  • Sql Server "用户登录失败,错误编18456"的解决过程

    目录 1.说明 2.其他错误信息 排错分析 总结 Sql Server 解决“用户登录失败,错误编号18456” 1.说明 因密码或用户名错误而使身份验证失败并导致连接尝试被拒时,类似以下内容的消息将返回到客户端:“用户‘<user_name>’登录失败. (Microsoft SQL Server,错误:18456)”. 返回到客户端的其他信息有: “用户‘<user_name>’登录失败. (.Net SqlClient 数据访问接口)” -------------------

  • oracle11g用户登录时被锁定问题的解决方法 (ora-28000 the account is locked)

    1 错误出现的现象是ora-28000 the account is locked,既用户无法登录. 2 原因:出现这种错误的原因为由于用户多次登录,无法登陆成功,超过了数据库允许登录的次数,所以导致用户被锁定,这种机制也是对数据库的一种保护,提升了数据库的安全性. 3 解决的办法如下: (1)在dos窗口中输入命令sqlplus /nolog,截图如下: (2)点击回车之后输入命令conn /as sysdba出现的结果为: (3)输入命令desc dba_profiles 截图如下: (4)

  • linux(ubuntu)用户连续N次输入错误密码进行登陆时自动锁定X分钟

    1.编辑PAM的配置文件 sudo vim /etc/pam.d/login 在第二行添加 auth required pam_tally2.so deny=3 unlock_time=5 even_deny_root root_unlock_time=10 参数介绍 even_deny_root 也限制root用户: deny 设置普通用户和root用户连续错误登陆的最大次数,超过最大次数,则锁定该用户: unlock_time 设定普通用户锁定后,多少时间后解锁,单位是秒: root_unl

  • Spring Security实现多次登录失败后账户锁定功能

    在上一次写的文章中,为大家说到了如何动态的从数据库加载用户.角色.权限信息,从而实现登录验证及授权.在实际的开发过程中,我们通常会有这样的一个需求:当用户多次登录失败的时候,我们应该将账户锁定,等待一定的时间之后才能再次进行登录操作. 一.基础知识回顾 要实现多次登录失败账户锁定的功能,我们需要先回顾一下基础知识: Spring Security 不需要我们自己实现登录验证逻辑,而是将用户.角色.权限信息以实现UserDetails和UserDetailsService接口的方式告知Spring

  • Vue2.x配置路由导航守卫实现用户登录和退出

    目录 前言 一.配置路由导航守卫 1. 全局导航守卫 2. 局部导航守卫 二.用户登录 1. axios配置 2. 用户登录代码 三.用户退出 1. 实现代码 总结 前言 之前在Vue的学习中通过路由导航守卫控制实现了用户登录模块的功能,现在再次做项目时又要通过Vue配置路由导航守卫来实现相同的功能,在此将实现过程进行记录与总结(本文基于Vue2.x进行实现) 提示:以下是本篇文章正文内容,下面案例可供参考 一.配置路由导航守卫 1. 全局导航守卫 如果项目中只有后台的情况,在Vue中配置全局导

  • 基于IO版的用户登录注册实例(Java)

    今天学的是用户登录注册功能. 4个包: itcast.cn.user包 User.java 用户类,描述用户基本信息,包括成员变量,无参构造函数,带参构造(可有可无).get和set方法 package itcast.cn.day22; /* * 用户基本描述包类 */ public class User { private int userName; private int passWord; public User(){ super(); } public User(int userName

随机推荐