PostgreSQLのユーザーログイン失敗時の自動ロック解決策
MoMo:PostgreSQLではsession_execプラグインを使用して、パスワードの確認に数回失敗すると自動的にユーザーをロックするようになっていますが、この記事ではその対処法を紹介しています。
I. プラグイン 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'
注:上記の最初の変数は、通常設定されるshared_preload_librariesの代わりに、session_preload_librariesを設定します。
2つ目の変数は、カスタム実装が必要なログイン関数です。
データベースサービスを再起動します。
$ sudo systemctl restart postgresql-12
第2回 カスタムログイン機能編
データベースのログから抽出したログインの失敗を保存するために、t_loginテーブルを作成します。
create table t_login
(
login_time timestamp(3) with time zone --insert time,
user_name text -- database login user,
flag int4 -- flag bit, 0 for expired data, 1 for normal status data
);
データベースのログ情報を記録するために、外部テーブル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. 1. /opt/pg_log_5432 を実際の環境ログディレクトリに変更する必要があります。
2. csvログのフォーマットはPGのバージョンによって異なる場合があります。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
--get the latest time in the current log
select login_time
from public.t_login
where flag = 0
order by login_time
desc limit 1
into c1;
--insert the latest data into the t_login table
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;
--check if the number of failed logins is greater than 3, if greater than 3 then lock the user
for res in select user_name from public.t_login where flag = 1 group by user_name having count(*) >=3
loop
-- Lock the user
EXECUTE format('alter user %I nologin',res);
--open the current locked user session
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)
さらに2回ログインに失敗した後、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のログイン失敗自動ロック内容については、スクリプトハウスの過去記事を検索するか、引き続き以下の関連記事を閲覧してください。
関連
-
PostgreSQLのURL解決方法
-
単語をソートするカスタム関数とそれをPostgreSQLで使用する(実装コード)
-
PostgreSQLで文字列が対象の文字列を含むかどうかを判断する様々な方法
-
どのように定期的にLinux上でpostgresqlのデータベースをバックアップする
-
Postgresql データベース timescaledb timescaledb 問題 大容量データテーブルをスーパーテーブルに変換すること
-
Postgresqlのデータベース権限まとめ
-
PostgreSQLがバキュームテーブルの情報を収集する必要があることを発見する方法
-
Postgresqlのデータは、2つのフィールドを追加し、一意の操作を統合する
-
postgreSQLのクエリ結果に自己インクリメントシーケンス演算が追加されました。
-
PostgreSQLにおけるsequence、serial、identityの使い方の違いについて
最新
-
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における時間処理のコツ(推奨)
-
Postgresqlへのリモートアクセスの設定方法(ファイアウォールの設定またはOFFが必要です。)
-
postgresql いくつかのメソッドは、要約の重複するデータを削除する
-
Postgresqlの操作でSQL文の実行効率を表示する
-
GROUP BY句での定数使用に関するPostgreSQLの特別な制限について説明します。
-
pgAdmin for postgreSQLでサーバーのデータをバックアップする方法
-
PostgreSQLの自己インクリメント構文使用上の注意点
-
Postgresqlのセルフインクリメントidをキーにした場合の重複問題の解決
-
PostgreSQLで時間指定タスクを実装する4つの方法
-
PostgreSQLにおけるVACUUMコマンドの使用方法