postgresql配置session_exec 达到锁定登录失败用户目的

1 说明

由于公司的某SaaS平台要进行等保3.0评测,与之对应的postgresql数据库也要进行相关的安全设置,对其配置锁定用户是必要操作之一。
如下步骤是在postgresql12.8版本上配置session_exec的过程,如下步骤在12.8版本可以完美运行,无坑。

本文涉及的服务和服务器的基本信息

维度 说明
系统版本 Centos 7.9
postgresql版本 12.8
postgresql安装方式 源码安装
postgresql运行用户 postgres

为了避免权限错乱导致服务异常,安装后的操作基本上都是在postgres用户下操作的。

2 配置session_exec

2.1 安装postgresql

如下是我的安装步骤 可以参考 命令简单粘贴一下

yum -y install gcc gcc-c++ readline-devel zlib-devel libuuid-devel uuid uuid-devel openssl openssl-devel
useradd postgres
mv postgresql-12.8.tar.gz /home/postgres
mkdir /data/app/postgresql /data/appData/postgresql /data/logs/postgresql/postgresql -p
chown -R postgres:postgres /data/app/postgresql /data/appData/postgresql /data/logs/postgresql /home/postgres
su  - postgres
tar -xf postgresql-12.8.tar.gz
cd postgresql-12.8/
./configure --prefix=/data/app/postgresql --with-ossp-uuid --with-openssl --with-zlib
make -j4 && make install
echo -e "export PGHOME=/data/app/postgresql\nexport PATH=\$PATH:\$HOME/.local/bin:\$HOME/bin:\$PGHOME/bin" >> ~/.bashrc
source ~/.bashrc
initdb -D /data/appData/postgresql/

2.2 安装file_fdw扩展

[postgres@localhost postgresql-12.8]$ ls
aclocal.m4  config.log     configure     contrib    doc          GNUmakefile.in  INSTALL   README
config      config.status  configure.in  COPYRIGHT  GNUmakefile  HISTORY         Makefile  src
[postgres@localhost postgresql-12.8]$ cd contrib/
[postgres@localhost contrib]$ file_fdw/
[postgres@localhost file_fdw]$ make
[postgres@localhost file_fdw]$ make install

2.3 安装session_exec

这个需要去github下载然后 安装

https://github.com/okbob/session_exec 点击Code 点击Download ZIP

unzip session_exec-master.zip
cd session_exec-master/
make pg_config=/data/app/postgresql/bin/pg_config
make pg_config=/data/app/postgresql/bin/pg_config install

2.4 修改配置文件 添加session_exec

logging_collector = on # 有了就不用再添加了
log_destination = 'csvlog' # 有了就不用再添加了
session_preload_libraries='session_exec'
session_exec.login_name='login'

重启 让配置生效

session_preload_libraries参数:一个或者多个要在连接开始时预载入的共享库。
shared_preload_libraries参数:一个或者多个要在服务器启动时预载入的共享库。

2.5 创建外部表postgres_log

create extension file_fdw;

CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw;

CREATE FOREIGN TABLE public.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 /data/logs/postgresql -type f -name "*.csv" -mtime -1 -exec cat {} \;', format 'csv' );

grant SELECT on postgres_log to PUBLIC;

2.6 创建登录验证函数login

如下设置的是5次 5次登录失败就锁定用户 具体的次数可以根据需要进行设置

create or replace function public.login() returns void as $$
declare
res record;
failed_login_times int = 5;
failed_login int = 0;
begin
--获取数据库中所有可连接数据库的用户
for res in select rolname from pg_catalog.pg_roles where rolcanlogin= 't' and rolname !='postgres'
loop
  raise notice 'user: %!',res.rolname;
  --获取当前用户最近连续登录失败次数
  select count(*) 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 WHERE A.error_severity='FATAL' into  failed_login ;
  raise notice 'failed_login_times: %! failed_login: %!',failed_login_times,failed_login;
  --用户最近密码输入错误次数达到5次或以上
  if failed_login >= failed_login_times then
    --锁定用户
    EXECUTE format('alter user %I nologin',res.rolname);
    raise notice 'Account % is locked!',res.rolname;
  end if;
end loop;
end;
$$ language plpgsql strict security definer set search_path to 'public';

2.7 验证登录失败效果

修改pg_hba.conf 添加对测试用户的密码策略 然后重启pg

host    all             test1             127.0.0.1/32          md5

创建测试用户

create user test1 encrypted password 'Rootmaster@777';

前5次输入错误密码 如下

[postgres@localhost ~]$ psql -Utest1 -h127.0.0.1 -p18126 -d postgres
Password for user test1:
psql: error: FATAL:  password authentication failed for user "test1"
[postgres@localhost ~]$ psql -Utest1 -h127.0.0.1 -p18126 -d postgres
Password for user test1:
psql: error: FATAL:  password authentication failed for user "test1"
[postgres@localhost ~]$ psql -Utest1 -h127.0.0.1 -p18126 -d postgres
Password for user test1:
psql: error: FATAL:  password authentication failed for user "test1"
[postgres@localhost ~]$ psql -Utest1 -h127.0.0.1 -p18126 -d postgres
Password for user test1:
psql: error: FATAL:  password authentication failed for user "test1"
[postgres@localhost ~]$ psql -Utest1 -h127.0.0.1 -p18126 -d postgres
Password for user test1:

查询test1锁定状态 如下 可以发现已经不可登录

[postgres@localhost session_exec-master]$ psql -Upostgres -h127.0.0.1 -p18126 -d postgres
NOTICE:  user: test1!
NOTICE:  failed_login_times: 5! failed_login: 5!
NOTICE:  Account test1 is locked!
psql (12.8)
Type "help" for help.

postgres=# select rolcanlogin from pg_catalog.pg_roles where rolname='test1';
 rolcanlogin
-------------
 f
(1 row)

test1再次登录 提示如下

[postgres@localhost session_exec-master]$ psql -Utest1 -h127.0.0.1 -p18126 -d postgres
Password for user test1:
psql: error: FATAL:  role "test1" is not permitted to log in

具体的用户 解锁命令如下

[postgres@localhost ~]$ psql -Upostgres -h127.0.0.1 -p18126 -d testdb1
psql (12.8)
Type "help" for help.

testdb1=# alter user test1 login;
ALTER ROLE

你可能感兴趣的:(个人提升,postgresql,数据库,服务器)