pgbouncer and scram-sha-256 setup - postgresql

I was able to get SCRAM-SHA-256 authentication to work with pgpool, but I haven't been able to find a good example how to set this up in pgbouncer. I'm trying to use auth_query. In postgres, the user that pgbouncer will connect as has the password encrypted and stored in SCRAM-SHA-256. But I don't know how to create the entries in userlist.txt. This is supposed to be the format:
SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>
What exactly are the storedkey and serverkey and how do I generate those? Which tools can I use to create this? In pgpool, I can use pg_enc but I don't see anything for pgbouncer.

You don't construct the SCRAM hashed password yourself, you get it by querying the pg_authid table in the PostgreSQL database:
SELECT rolpassword
FROM pg_authid
WHERE rolname = 'pgbouncer';
However, as the documentation says:
The passwords or secrets stored in the authentication file serve two purposes. First, they are used to verify the passwords of incoming client connections, if a password-based authentication method is configured. Second, they are used as the passwords for outgoing connections to the backend server, if the backend server requires password-based authentication (unless the password is specified directly in the database's connection string). The latter works if the password is stored in plain text or MD5-hashed. SCRAM secrets can only be used for logging into a server if the client authentication also uses SCRAM, the PgBouncer database definition does not specify a user name, and the SCRAM secrets are identical in PgBouncer and the PostgreSQL server (same salt and iterations, not merely the same password). This is due to an inherent security property of SCRAM: The stored SCRAM secret cannot by itself be used for deriving login credentials.
So if that user is used as auth_user, you cannot use a SCRAM hashed password for that user, but you have to use the clear text password.

Related

with scram-sha-256 is password encrypted during authentication

With the scram-sha-256 protocol, does Postgres server encrypt the client's password when initializing the connection so that authentication is secure and the password cannot be read?
It is even better than encrypted, it is salted and hashed. Not only can an eavesdropper not readily reverse it back to the raw password, the server can't either. A weakness though is that if you connect to a malicious server, it can simply insist on not using scram, and the default client will silently comply.

Why Is Knex.js Failing on Password Authentication When My Database Has No Password?

I'm trying to connect to my database using Knex like so:
const client = knex({
client: 'postgresql',
connection: {
host: '127.0.0.1',
user: 'me',
database: 'my_db'
}
});
client('some_table').then(console.log);
When I created the database (using createdb my_db at the command line) I set no password. At the command line I can run psql -d my_db and it works just fine.
However, when I try to use Knex, I get an error:
Unhandled rejection error: password authentication failed for user "me"
This happens whether I set a null password, an empty string ('') password, or leave the field off of the configuration entirely.
Can anyone explain why Knex insists on failing password authentication ... when there is no password (and when I can connect without one at the command line just fine)?
PostgreSQL does not permit login based on the presence/absence of a password. Rather, all login authentication is handled via pg_hba.conf. In your particular case--creating the me user without a password (or using null or '', as you would describe it)--the absence of the password doesn't necessarily allow your user to log in. In fact, setting no password will not allow that user to log in unless pg_hba.conf was set to some password-less setting (i.e., peer or trust).
If you want password-less login for the me user (I assume for testing/development purposes, as having password-less login is not good security practice in production), you could simply set trust-level authentication in pg_hba.conf:
#conn_origin database user ip_mask auth_method
host all me 0.0.0.0/0 trust
The more secure method of implementing password-less authentication would be to use a .pgpass file or set the PGPASSWORD environment variable. Seeing that you are trying to use knex.js, you may be better off with tweaking pg_hba.conf as above. Again, I don't know what your intentions are, but please be safe out there ;)
Disclosure: I work for EnterpriseDB (EDB)

postgres uses a database password or a user password

I imported a postgres database in my local postgres server.
I had to connect to the database (to allows django to retrive data) using the file called setup.local.
There is required to specify: DB_HOST=localhost, DB_NAME, DB_USER, DB_PASSWORD.
DB_HOST is localhost without any doubt. The DB_name is the one I choose importing (psql imported_db < downloaded_DB)
DB_USER is my_name (or I can change the owner ALTER DATABASE imported_db OWNER TO other_name).
The wire thing, for me, is that I have to use the user (either the my_name or other_name) password and not the database password (even if the variable name is DB_PASSWORD).
So the question:
does a psql database have a password or just the roles/users have ones and use them to access the database?
Andrea
Passwords are set for USER and ROLE only. A user may access multiple databases, according to the GRANTs for the ROLE.
See also:
https://www.postgresql.org/docs/10/static/ddl-priv.html
https://www.postgresql.org/docs/10/static/client-authentication.html
https://www.postgresql.org/docs/10/static/user-manag.html
DB_HOST=localhost is a key here. Look into the pg_hba.conf you will find ident against localhost connections most probably.
https://www.postgresql.org/docs/current/static/auth-methods.html#AUTH-IDENT
When ident is specified for a local (non-TCP/IP) connection, peer
authentication (see Section 20.3.6) will be used instead.
https://www.postgresql.org/docs/current/static/auth-methods.html#AUTH-PEER
The peer authentication method works by obtaining the client's
operating system user name from the kernel and using it as the allowed
database user name (with optional user name mapping). This method is
only supported on local connections.

Postgres unencrypted keyword is no longer supported

When executing this postgres command:
EXECUTE 'CREATE USER myuser WITH UNENCRYPTED PASSWORD ''my+password''';
I see the error:
RoundhousE encountered an error.
Npgsql.PostgresException (0x80004005): 0A000: UNENCRYPTED PASSWORD is no longer supported
Is there a workaround for this, or will the password need to be manually encrypted and supplied without the UNENCRYPTED keyword?
No. All you have to do is to omit the UNENCRYPTED.
You can supply both encrypted and unencrypted passwords that way, and PostgreSQL can tell the difference automatically.
PostgreSQL 10+ no longer support user creation with UNENCRYPTED password,
create it with ENCRYPTED:
CREATE USER myuser WITH ENCRYPTED PASSWORD ''my+password''

Change PostgreSQL password encryption from MD5 to SHA

Is there a way to change the PostgreSQL password encryption method from MD5 to SHA?
If Yes, can you please tell me how?
I am using PostgreSQL 9.5
Pg 10
With PostgreSQL 10, you can set password_encryption to scram-sha-256. From the docs
When a password is specified in CREATE ROLE or ALTER ROLE without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted. The default value is md5, which stores the password as an MD5 hash. Setting this to plain stores it in plaintext. on and off are also accepted, as aliases for md5 and plain, respectively. Setting this parameter to scram-sha-256 will encrypt the password with SCRAM-SHA-256.
See this post for information about iterations using scram-sha-256
Pg 9.x
This can not be done without actually modifying the source.