auth_delay 讓伺服器在報告身份驗證失敗前短暫暫停,以增加對資料庫密碼進行暴力破解的難度。需要註意的是,這對阻止拒絕服務攻擊毫無幫助,甚至可能加劇攻擊,因為在報告身份驗證失敗前等待的進程仍會占用連接。 要使用這個模塊必須要在 postgresql.conf 中配置參數 shared_prel ...
auth_delay 讓伺服器在報告身份驗證失敗前短暫暫停,以增加對資料庫密碼進行暴力破解的難度。需要註意的是,這對阻止拒絕服務攻擊毫無幫助,甚至可能加劇攻擊,因為在報告身份驗證失敗前等待的進程仍會占用連接。
要使用這個模塊必須要在 postgresql.conf
中配置參數
shared_preload_libraries = 'auth_delay'
auth_delay.milliseconds = '500'
這個代碼比較簡單,一共分為三個部分。
- hook 函數
在 libpq 中定義了一個 ClientAuthentication_hook
函數指針,代碼如下:
typedef void (*ClientAuthentication_hook_type) (Port *, int);
/*
* This hook allows plugins to get control following client authentication,
* but before the user has been informed about the results. It could be used
* to record login events, insert a delay after failed authentication, etc.
*/
ClientAuthentication_hook_type ClientAuthentication_hook = NULL;
- _PG_init 函數
void
_PG_init(void)
{
/* Define custom GUC variables */
DefineCustomIntVariable("auth_delay.milliseconds",
"Milliseconds to delay before reporting authentication failure",
NULL,
&auth_delay_milliseconds,
0,
0, INT_MAX / 1000,
PGC_SIGHUP,
GUC_UNIT_MS,
NULL,
NULL,
NULL);
/* Install Hooks */
original_client_auth_hook = ClientAuthentication_hook;
ClientAuthentication_hook = auth_delay_checks;
}
這個 _PG_init
函數會在模塊調用之前執行,這個函數主要實現的功能是定義了一個 GUC 參數 auth_delay.milliseconds
這個參數我們需要在 postgresql.conf 中進行配置,然後它將原來的鉤子函數保存在了 original_client_auth_hook
變數中,然後將我們自己的 auth_delay_checks
函數賦給了 ClientAuthentication_hook
變數,這樣我們就可以讓資料庫調用我們的函數了。
- auth_delay_checks 函數
static void
auth_delay_checks(Port *port, int status)
{
/*
* Any other plugins which use ClientAuthentication_hook.
*/
if (original_client_auth_hook)
original_client_auth_hook(port, status);
/*
* Inject a short delay if authentication failed.
*/
if (status != STATUS_OK)
{
pg_usleep(1000L * auth_delay_milliseconds);
}
}
這個函數的意思是如果原來存在有鉤子函數就先運行原來的鉤子函數,然後我們看一下驗證的狀態 status 是不是正確,如果不正確,就延時 auth_delay_milliseconds 個時間。