PgBouncer is a lightweight connection pooler. When a user connects to PgBouncer, the user’s username and password is checked against userlist.txt file. If you haven’t installed PostgreSQL, see Install PostgreSQL 9.6 on Ubuntu 16.04 and reset postgres password
Disadvantage of userlist.txt
The disadvantage is whenever new user is added to PostgreSQL, the user’s username and password has to be added to userlist.txt. Password is the actual plain-text password or plain-text md5 hash.
Authenticate to PostgreSQL instead of looking for credentials in userlist.txt
There is a way to configure PgBouncer so that username and password are authenticated against PostgreSQL without completely relying on userlist.txt. There is still a limited need for userlist.txt. The general idea is to:
- Create a user called pgbouncer in PostgreSQL
- Enter pgbouncer user and password in userlist.txt
- PgBouncer can use this credential to ask PostgreSQL whether the user/password connecting to PgBouncer is actually present in PostgreSQL
Here’s how a user matt will authenticate
- User matt logs into PgBouncer with his username
- PgBouncer goes to userlist.txt and collects pgbouncer credentials and uses them to ask PostgreSQL whether matt’s credentials are OK
- If OK, PgBouncer connects matt to PostgreSQL
- If not, PgBouncer does NOT connect matt to PostgreSQL
Install PgBouncer
- Install, if not already installed, PgBouncer on the same server as PostgreSQL by typing sudo apt-get install pgbouncer
Create some users for testing
- Go to PostgreSQL and create some users
- Type psql -U postgresl
- CREATE USER pgbouncer WITH LOGIN;
- ALTER USER pgbouncer WITH PASSWORD ‘test’;
- CREATE USER matt WITH LOGIN;
- ALTER USER matt WITH PASSWORD ‘test’;
- CREATE USER hannah WITH LOGIN;
- ALTER USER hannah WITH PASSWORD ‘test’;
- Type \q to exit PostgreSQL
Create a function in PostgreSQL that will perform user lookup
Log on to PostgreSQL using psql -U postgres and type
CREATE OR REPLACE FUNCTION public.user_lookup(in i_username text, out uname text, out phash text) RETURNS record AS $$ BEGIN SELECT usename, passwd FROM pg_catalog.pg_shadow WHERE usename = i_username INTO uname, phash; RETURN; END; $$ LANGUAGE plpgsql SECURITY DEFINER; REVOKE ALL ON FUNCTION public.user_lookup(text) FROM public, pgbouncer; GRANT EXECUTE ON FUNCTION public.user_lookup(text) TO pgbouncer;
Configure PgBouncer to dynamically do user lookup
- cd /etc/pgbouncer/
- Type sudo vim userlist.txt
- Add a line like so
"pgbouncer" "test"
This credential will be used to call user_lookup function and authenticate user attempting to log on to PgBouncer.
- Type sudo vim pgbouncer.ini
- When PgBouncer is asked to connect to PostgreSQL, only connections to postgres database should be entertained. To do so, add a new line under
;bardb = host=localhost dbname=bazdb
like so:
postgres = host=localhost dbname=postgres auth_user=pgbouncer
Notice auth_user=pgbouncer. This addition tells PgBouncer to look up userlist.txt for pgbouncer’s credentials and then authenticate incoming user’s password against PostgreSQL.
- Allow all systems to connect to PgBouncer. To do so, change the following line
listen_addr = 127.0.0.1
to
listen_addr = *
- Set authentication method and query that pgbouncer user will execute against PostgreSQL
auth_type = trust auth_query = SELECT uname, phash from user_lookup($1)
- Ensure that postgres user is the one that can administer and work with PgBouncer statistics
admin_users = postgres stats_users = postgres
- Restart PgBouncer by typing sudo service pgbouncer
Test PgBouncer
- From a remote system, type psql -h <IP or hostname of PostgreSQL server> -U matt -d postgres -p 6432
- Type in the password for matt and you should have access through PgBouncer (listening on port 6432)
- Type psql -h <IP or hostname of PostgreSQL server> -U hannah -d postgres -p 6432
- Enter the password for hannah and this user should be able to access PostgreSQL through PgBouncer also
- Typing incorrect password will result in psql: ERROR: Auth failed
Note that matt and hannah are able to connect to PostgreSQL through PgBouncer without the need for userlist.txt to hold their credentials.