How to Use the auth_delay Module in PostgreSQL

When working with PostgreSQL, authentication security is an important concern. One useful extension that helps mitigate brute-force attacks is the auth_delay module. This module introduces an artificial delay after failed authentication attempts, making repeated login attempts slower and less effective.

auth_delay is a PostgreSQL module that adds a delay (in milliseconds) after failed authentication attempts. This helps in slowing down attackers who try to guess passwords through repeated login attempts.

Load the Extension

First, connect to PostgreSQL and load the extension:

sudo su postgres
psql

Then run:

LOAD 'auth_delay';

Verify available parameters:

show auth_delay.milliseconds;

Output:

auth_delay.milliseconds 
-------------------------
 0
(1 row)

By default, the delay is 0, meaning no delay is applied.

Enable auth_delay via shared_preload_libraries

To properly use the module, it must be added to shared_preload_libraries.

Check current value:

show shared_preload_libraries;

Check the postgresql configuration file path

Show config_file:

You get a location like this

               config_file               
-----------------------------------------
 /etc/postgresql/18/main/postgresql.conf
(1 row)

Edit the PostgreSQL configuration file:

sudo nano /etc/postgresql/18/main/postgresql.conf

Update:

shared_preload_libraries = 'auth_delay'

Restart PostgreSQL:

sudo systemctl restart postgresql

Configure Delay Time

Set the delay duration:

ALTER SYSTEM SET auth_delay.milliseconds = 10000;

Reload configuration:

SELECT pg_reload_conf();

Verify:

show auth_delay.milliseconds;

Output:

auth_delay.milliseconds 
-------------------------
 10s
(1 row)

Now PostgreSQL will delay failed authentication attempts by 10 seconds.

Verify Authentication Method

To test auth_delay, password-based authentication must be enabled.

Check current rules:

select * from pg_hba_file_rules;

Example output:

rule_number |              file_name              | line_number | type  |   database    | user_name |  address  |                 netmask                 | auth_method | options | error 
-------------+-------------------------------------+-------------+-------+---------------+-----------+-----------+-----------------------------------------+-------------+---------+-------
           1 | /etc/postgresql/18/main/pg_hba.conf |         121 | local | {all}         | {all}     |           |                                         | peer        |         | 
           2 | /etc/postgresql/18/main/pg_hba.conf |         123 | host  | {all}         | {all}     | 127.0.0.1 | 255.255.255.255                         | trust       |         | 
           3 | /etc/postgresql/18/main/pg_hba.conf |         125 | host  | {all}         | {all}     | ::1       | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | trust       |         | 
           4 | /etc/postgresql/18/main/pg_hba.conf |         128 | local | {replication} | {all}     |           |                                         | peer        |         | 
           5 | /etc/postgresql/18/main/pg_hba.conf |         129 | host  | {replication} | {all}     | 127.0.0.1 | 255.255.255.255                         | trust       |         | 
           6 | /etc/postgresql/18/main/pg_hba.conf |         130 | host  | {replication} | {all}     | ::1       | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | trust       |         | 
(6 rows)

Here, authentication methods like peer and trust do not require passwords, so auth_delay will not be triggered.

Set Password for postgres User

Set a password:

ALTER USER postgres WITH PASSWORD 'cool';

Check the location of the pg_hba.conf file of postgres

show hba_fie;

You get a result like this

              hba_file               
-------------------------------------
 /etc/postgresql/18/main/pg_hba.conf
(1 row)

Edit pg_hba.conf:

sudo nano /etc/postgresql/18/main/pg_hba.conf

Add this line

# Database administrative login by Unix domain socket
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             postgres                                md5

Restart PostgreSQL:

sudo systemctl restart postgresql

Verify changes:

select * from pg_hba_file_rules;

Updated output:

 rule_number |              file_name              | line_number | type  |   database    | user_name  |  address  |                 netmask                 | auth_method | options | error 
-------------+-------------------------------------+-------------+-------+---------------+------------+-----------+-----------------------------------------+-------------+---------+-------
           1 | /etc/postgresql/18/main/pg_hba.conf |         119 | local | {all}         | {postgres} |           |                                         | md5         |         | 
           2 | /etc/postgresql/18/main/pg_hba.conf |         121 | local | {all}         | {all}      |           |                                         | peer        |         | 
           3 | /etc/postgresql/18/main/pg_hba.conf |         123 | host  | {all}         | {all}      | 127.0.0.1 | 255.255.255.255                         | md5         |         | 
           4 | /etc/postgresql/18/main/pg_hba.conf |         125 | host  | {all}         | {all}      | ::1       | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | trust       |         | 
           5 | /etc/postgresql/18/main/pg_hba.conf |         128 | local | {replication} | {all}      |           |                                         | peer        |         | 
           6 | /etc/postgresql/18/main/pg_hba.conf |         129 | host  | {replication} | {all}      | 127.0.0.1 | 255.255.255.255                         | trust       |         | 
           7 | /etc/postgresql/18/main/pg_hba.conf |         130 | host  | {replication} | {all}      | ::1       | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | trust       |         | 
(7 rows)

Test auth_delay

Now try connecting:

psql -U postgres

Enter a wrong password

Password for user postgres:

You will notice a delay of 10 seconds before the authentication fails.

This confirms that auth_delay is working correctly.

Understanding pre_auth_delay

PostgreSQL also provides another parameter:

\dconfig+ pre_auth_delay

Output:

Parameter       | Value | Type    | Context
-----------------+-------+---------+---------
 pre_auth_delay  | 0     | integer | sighup

Set it:

ALTER SYSTEM SET pre_auth_delay = '10s';

Reload configuration:

SELECT pg_reload_conf();

Verify:

\dconfig+ pre_auth_delay

Output:

                List of configuration parameters
   Parameter    | Value |  Type   | Context | Access privileges 
----------------+-------+---------+---------+-------------------
 pre_auth_delay | 10s   | integer | sighup  | 
(1 row)

Test pre_auth_delay

Open a new terminal and run:

psql -U postgres

Observation:

  • The password prompt itself is delayed by 10 seconds.
  • Even with the correct password, authentication completes only after 10 seconds.

auth_delay - Delays only after failed authentication

pre_auth_delay - Delays before authentication begins

The auth_delay module is a simple yet effective way to improve PostgreSQL security by slowing down brute-force attacks. By combining it with proper authentication methods like md5, you can ensure that login attempts are both secure and controlled.

Additionally, pre_auth_delay provides another layer of control by delaying all authentication attempts, regardless of success or failure.

Using these configurations wisely can significantly strengthen your database security posture without requiring complex changes.

whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, KINFRA Techno Park
Kakkanchery, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message