Postgresqlのユーザーログインエラーの回数を制限するサンプルコード
OracleではFAILED_LOGIN_ATTEMPTSを設定することでユーザーログインのエラー回数を制限できますが、postgresqlではこの機能はサポートされていません。PostgreSQLはイベントトリガーをサポートしていますが、イベントはDDLに限定されており、ログインとログアウトのイベントにイベントトリガーを使用する方法はありません。
しかし、新しいセッションにログインすることでイベントを発生させたい場合、フックを使えば可能ですが、複雑で、クライアントサイド認証にパスワードの入力回数を判断するロジックを追加するためにカーネルのコードを修正する必要があります。ここでは、よりシンプルに同様の機能を実装する方法を紹介します。
ここでは、ログイン時に指定した関数を実行するsession_execプラグインを使用しています。
ダウンロードはこちら
https://github.com/okbob/session_exec
ダウンロード、解凍後、以下の設定が必要です。
- session_execset に session_preload_libraries をセットします。
- session_exec.login_name にログイン関数の名前を指定します。
このプラグインは、以下の機能を備えています。
- 関数が存在しない場合、警告を表示します。
- 関数の実行に失敗した場合、接続を拒否します。
このプラグインを使用すると、ユーザーのログインエラーの回数を制限するための簡単な関数を書くことができます。
例
1. データベースのログ情報を記録するための外部テーブルを作成します。
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テーブルを作成します。
create table t_login
(
login_time timestamp(3) with time zone --insert time,
user_name text,
flag int -- flag bit, 0 for expired data
);
ログイン情報を挿入します。
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. ログイン時に実行される関数を作成する
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; --get the latest time in the current log
insert into t_login select log_time,user_name from pglog where command_tag='authentication' and error_severity= 'FATAL' and log_time > c1; --insert insert the latest data into the t_login table
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 --check if the number of failed login attempts is greater than 3, if greater than 3 then lock the user
loop
EXECUTE format('alter user %I nologin',res); -- lock the user
EXECUTE 'select pg_terminate_backend(pid) from pg_stat_activity where usename=$1' using res; -- break the current locked user session
raise notice 'Account % is locked!',res;
end loop;
end;
$$ language plpgsql strict;
4. 4. postgresql.conf ファイルを編集し、ログイン機能を設定します。
session_preload_libraries='session_exec'
session_exec.login_name='lock_user'
5. テスト
test1のユーザーログインエラーを3回以上再現する。
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ユーザーでログインした場合、接続できない
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
再度ログインすると、ユーザーがロックされていることが確認できます。
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. ユーザーのロックを解除する
この時点でユーザーのロックを解除したい場合は、実行が必要です。
bill=# alter user test1 login;
ALTER ROLE
それから、t_loginの有効期限切れのデータも変更する必要があることに注意してください。
bill=# update t_login set flag = 0;
UPDATE 4
参考リンクです。
https://github.com/okbob/session_exec
Postgresqlの制限ユーザーログインエラーについての記事です。Postgresql limit user login errorについては、過去の記事を検索していただくか、引き続き以下の関連記事をご覧ください。
関連
-
PostgreSQLのユーザーログイン失敗時の自動ロック解決策
-
Postgresqlへのリモートアクセスの設定方法(ファイアウォールの設定またはOFFが必要です。)
-
Postgresql データベース timescaledb timescaledb 問題 大容量データテーブルをスーパーテーブルに変換すること
-
postgresql いくつかのメソッドは、要約の重複するデータを削除する
-
postgreSQLのクエリ結果に自己インクリメントシーケンス演算が追加されました。
-
PostgreSQLにおけるsequence、serial、identityの使い方の違いについて
-
Postgresqlのシーケンススキップの問題を解決する
-
Postgresqlのデータベースにおける配列の作成と変更に関する操作
-
PostgreSqlのhash_code関数の使用法
-
PostgreSQLにおけるVACUUMコマンドの使用方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
PostgreSQLのJSONBのマッチングと交差の問題について
-
postgresql 重複データ削除 ケーススタディ
-
Postgresqlの高度なアプリケーションは、セルのアイデアをマージするの詳細
-
PostgreSQLでデータの一括インポートのパフォーマンスを向上させるn個の方法を説明します。
-
エクセルテーブルのデータをpostgresqlのデータベースにインポートする方法
-
どのように定期的にLinux上でpostgresqlのデータベースをバックアップする
-
GROUP BY句での定数使用に関するPostgreSQLの特別な制限について説明します。
-
oracle_fdwを介してOracleデータにアクセスするためのPostgreSQLの手順
-
PostgreSQLのデータベースでLIKE文の効率を確保する方法(推奨)
-
PostgreSQLで時間指定タスクを実装する4つの方法