Re: Experiments with Postgres and SSL

Heikki Linnakangas <hlinnaka@iki.fi>

From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Matthias van de Meent <boekewurm+postgres@gmail.com>
Cc: PostgreSQL-development <pgsql-hackers@postgresql.org>, Greg Stark <stark@mit.edu>, Andrey Borodin <amborodin86@gmail.com>, Jacob Champion <jchampion@timescale.com>, Vladimir Sitnikov <sitnikov.vladimir@gmail.com>, Michael Paquier <michael@paquier.xyz>
Date: 2024-02-22T17:02:51Z
Lists: pgsql-hackers
On 22/02/2024 01:43, Matthias van de Meent wrote:
> On Wed, 10 Jan 2024 at 09:31, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
>> 4. The number of combinations of sslmode, gssencmode and sslnegotiation
>> settings is scary. And we have very few tests for them.
> 
> Yeah, it's not great. We could easily automate this better though. I
> mean, can't we run the tests using a "cube" configuration, i.e. test
> every combination of parameters? We would use a mapping function of
> (psql connection parameter values -> expectations), which would be
> along the lines of the attached pl testfile. I feel it's a bit more
> approachable than the lists of manual option configurations, and makes
> it a bit easier to program the logic of which connection security
> option we should have used to connect.
> The attached file would be a drop-in replacement; it's tested to work
> with SSL only - without GSS - because I've been having issues getting
> GSS working on my machine.

+1 testing all combinations. I don't think the 'mapper' function 
approach in your version is much better than the original though. Maybe 
it would be better with just one 'mapper' function that contains all the 
rules, along the lines of: (This isn't valid perl, just pseudo-code)

sub expected_outcome
{
     my ($user, $sslmode, $negotiation, $gssmode) = @_;

     my @possible_outcomes = { 'plain', 'ssl', 'gss' }

     delete $possible_outcomes{'plain'} if $sslmode eq 'require';
     delete $possible_outcomes{'ssl'} if $sslmode eq 'disable';

     delete $possible_outcomes{'plain'} if $user eq 'ssluser';
     delete $possible_outcomes{'plain'} if $user eq 'ssluser';

     if $sslmode eq 'allow' {
	# move 'plain' before 'ssl' in the list
     }
     if $sslmode eq 'prefer' {
	# move 'ssl' before 'plain' in the list
     }

     # more rules here


     # If there are no outcomes left in $possible_outcomes, return 'fail'
     # If there's exactly one outcome left, return that.
     # If there's more, return the first one.
}


Or maybe a table that lists all the combinations and the expected 
outcome. Something lieke this:

         	nossluser	nogssuser	ssluser	gssuser		
sslmode=require	fail		...
sslmode=prefer	plain
sslmode=disable	plain


The problem is that there are more than two dimensions. So maybe an 
exhaustive list like this:

user		sslmode		gssmode		outcome

nossluser	require		disable		fail
nossluser	prefer		disable		plain
nossluser	disable		disable		plain
ssluser		require		disable		ssl
...


I'm just throwing around ideas here, can you experiment with different 
approaches and see what looks best?

>> ALPN
> 
> Does the TLS ALPN spec allow protocol versions in the protocol tag? It
> would be very useful to detect clients with new capabilities at the
> first connection, rather than having to wait for one round trip, and
> would allow one avenue for changing the protocol version.

Looking at the list of registered ALPN tags [0], I can see "http/0.9"; 
"http/1.0" and "http/1.1". I think we'd want to changing the major 
protocol version in a way that would introduce a new roundtrip, though.

-- 
Heikki Linnakangas
Neon (https://neon.tech)




Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Enhance libpq encryption negotiation tests with new GUC

  2. With gssencmode='require', check credential cache before connecting

  3. Add tests for libpq gssencmode and sslmode options

  4. Move Kerberos module

  5. Give nicer error message when connecting to a v10 server requiring SCRAM.