時間:2021-03-21來源:www.outletmksalestore.com作者:電腦系統城
在oracle中我們可以通過設置FAILED_LOGIN_ATTEMPTS來限制用戶密碼登錄錯誤的次數,但是在postgresql中是不支持這個功能的。盡管PostgreSQL支持event trigger,可是event局限于DDL,對于登錄登出事件是沒辦法使用event trigger的。
不過像登錄新建會話觸發某個事件這個需求可以通過hook實現,不過該方法比較復雜,需要修改內核代碼,在客戶端認證中添加邏輯,判斷輸入密碼次數統計。這里推薦一種比較簡單的方法實現類似的功能。
這里我們要使用到session_exec這個插件,使用該插件會在登錄時執行一個指定的function。
https://github.com/okbob/session_exec
下載解壓之后需要進行以下配置:
該插件有以下特點:
利用該插件我們可以寫一個簡單的函數來實現限制用戶登錄錯誤次數的功能。
1、建立外部表記錄數據庫日志信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw; CREATE FOREIGN TABLE pglog ( 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, backend_type text ) SERVER pglog OPTIONS ( program 'find $PGDATA/log -type f -name "*.csv" -mtime -1 -exec cat {} \;' , format 'csv' ); |
2、創建表t_login提取數據庫日志中的登錄信息。
1 2 3 4 5 6 |
create table t_login ( login_time timestamp (3) with time zone --插入時間, user_name text, flag int --標志位,0代表過期數據 ); |
插入登錄信息:
1 2 3 |
bill=# insert into t_login select log_time,user_name from pglog where command_tag= 'authentication' and error_severity= 'FATAL' bill-# ; INSERT 0 4 |
3、創建登錄執行的function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
create or replace function lock_user() returns void as $$ declare res text; c1 timestamp (3) with time zone; begin select login_time from t_login where flag = 0 order by login_time desc limit 1 into c1; --獲取當前日志中最新時間 insert into t_login select log_time,user_name from pglog where command_tag= 'authentication' and error_severity= 'FATAL' and log_time > c1; --將最新的數據插入t_login表 update t_login set flag = 1 where login_time > c1; for res in select user_name from t_login where flag = 1 group by user_name having count (*) >=3 --檢查登錄失敗次數是否大于3,若大于3則鎖定用戶 loop EXECUTE format( 'alter user %I nologin' ,res); --鎖定用戶 EXECUTE 'select pg_terminate_backend(pid) from pg_stat_activity where usename=$1' using res; --斷開當前被鎖定用戶會話 raise notice 'Account % is locked!' ,res; end loop; end ; $$ language plpgsql strict; |
4、編輯postgresql.conf文件,配置登錄函數
1 2 |
session_preload_libraries= 'session_exec' session_exec.login_name= 'lock_user' |
5、測試
模擬test1用戶登錄錯誤超過3次:
1 2 3 4 5 6 7 8 |
bill=# select * from t_login; login_time | user_name | flag ----------------------------+-----------+------ 2020-08-26 07:26:45.42+08 | test1 | 1 2020-08-26 07:26:50.179+08 | test1 | 1 2020-08-26 07:26:52.487+08 | test1 | 1 2020-08-26 07:26:54.537+08 | test1 | 1 (4 rows ) |
當我們在使用test1用戶登錄時則無法連接
1 2 3 4 5 6 |
pg13@cnndr4pptliot-> psql bill test1 Password for user test1: NOTICE: c1 = < NULL > psql: error: could not connect to server: FATAL: terminating connection due to administrator command CONTEXT: SQL statement "select pg_terminate_backend(pid) from pg_stat_activity where usename=$1" PL/pgSQL function lock_user() line 13 at EXECUTE |
再次登錄可以看到提示該用戶被鎖定:
1 2 3 |
pg13@cnndr4pptliot-> psql bill test1 Password for user test1: psql: error: could not connect to server: FATAL: role "test1" is not permitted to log in |
6、解鎖用戶
此時想要解鎖該用戶則需要執行:
1 2 |
bill=# alter user test1 login; ALTER ROLE |
然后需要注意還要將t_login中過期的數據修改。
1 2 |
bill=# update t_login set flag = 0; UPDATE 4 |
參考鏈接:
https://github.com/okbob/session_exec
到此這篇關于Postgresql限制用戶登錄錯誤次數的文章就介紹到這了
2022-02-25
系統城教小白如何在Centos8-stream安裝PostgreSQL132021-04-22
自定義函數實現單詞排序并運用于PostgreSQL(實現代碼)2021-04-19
MySQL命令行操作時的編碼問題詳解玩游戲的時候最怕跳出什么程序來干擾游戲,很多玩家在玩游戲過程中會遇到輸入法彈出來,影響游戲體驗,Win10玩游戲老跳出來輸入法怎么辦?按照以下的方法操作就可以解決這個問題了...
2021-02-19