Re: SCRAM pass-through authentication for postgres_fdw

From: Matheus Alcantara <matheusssilv97(at)gmail(dot)com>
To: Jacob Champion <jacob(dot)champion(at)enterprisedb(dot)com>
Cc: Jelte Fennema-Nio <postgres(at)jeltef(dot)nl>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: SCRAM pass-through authentication for postgres_fdw
Date: 2024-12-11 19:04:41
Message-ID: CAFY6G8ddn=i4bv4q6KGgw0U+SqeFUiavOXR9ja8S1VHyfBW-+Q@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Em qua., 4 de dez. de 2024 às 20:39, Jacob Champion
<jacob(dot)champion(at)enterprisedb(dot)com> escreveu:
>
> On Wed, Dec 4, 2024 at 3:05 PM Jelte Fennema-Nio <postgres(at)jeltef(dot)nl> wrote:
> > I only see advantages over the
> > alternative, which is copying the plaintext password around. In case
> > of compromise of the server, only the salt+verifier has to be rotated,
> > not the actual user password.
>
> Sure, I'm not saying it's worse than plaintext. But a third
> alternative might be actual pass-through SCRAM [1], where either you
> expect the two servers to share a certificate fingerprint, or
> explicitly disable channel bindings on the second authentication pass
> in order to allow the MITM. (Or, throwing spaghetti, maybe even have
> the primary server communicate the backend cert so you can verify it
> and use it in the binding?)

I'm not understanding how these options would work for this scenario.
I understand your concern about making the users copying the SCRAM
verifiers around but I don't understand how this third alternative fix
this issue. Would it be something similar to what you've implemented on
[1]?

The approach on this patch is that when the backend open the
connection with the foreign server, it will use the ClientKey stored
from the first client connection with the backend to build the final
client message that will be sent to the foreign server, which was
created/validated based on verifiers of the first backend. I can't see
how the foreign server can validate the client proof without having
the identical verifiers with the first backend.

I tested a scenario where the client open a connection with the
backend using channel binding and the backend open a connection with
the foreign server also using channel binding and everything seems to
works fine. I don't know if I missing something here, but here is how
I've tested this:

- Configure build system to use openssl
meson setup build -Dssl=openssl ...
- Start two Postgresql servers
- Configure to use ssl on both servers
ssl = on
ssl_cert_file = '/path/to/server.crt'
ssl_key_file = '/path/to/server.key'
- Changed pg_hba to use ssl on both servers
hostssl all all 127.0.0.1/32 scram-sha-256
hostssl all all ::1/128 scram-sha-256
- Performed all foreign server setup (CREATE SERVER ...)
- Connect into the backend using channel_binding=require
psql "host=127.0.0.1 dbname=local sslmode=require channel_binding=require"
- Execute a query on fdw server

I've also put a debug message before strcmp(channel_binding, b64_message)
[2] to ensure that channel binding is being used on both servers and I
got the log message on both servers logs.

Sorry if I misunderstood your message, I probably missed something here.

[1] https://www.postgresql.org/message-id/9129a012-0415-947e-a68e-59d423071525%40timescale.com
[2] src/backend/libpq/auth-scram.c#read_client_final_message

--
Matheus Alcantara
EDB: https://www.enterprisedb.com

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Nathan Bossart 2024-12-11 19:13:05 Re: Add support to TLS 1.3 cipher suites and curves lists
Previous Message Marcos Pegoraro 2024-12-11 18:45:31 Re: Document NULL