Re: Direct SSL connection and ALPN loose ends

Heikki Linnakangas <hlinnaka@iki.fi>

From: Heikki Linnakangas <hlinnaka@iki.fi>
To: Jacob Champion <jacob.champion@enterprisedb.com>
Cc: Peter Eisentraut <peter@eisentraut.org>, Robert Haas <robertmhaas@gmail.com>, Michael Paquier <michael@paquier.xyz>, pgsql-hackers <pgsql-hackers@postgresql.org>
Date: 2024-06-24T20:30:53Z
Lists: pgsql-hackers

Attachments

On 21/06/2024 02:32, Jacob Champion wrote:
> On Thu, Jun 20, 2024 at 4:13 PM Heikki Linnakangas <hlinnaka@iki.fi> wrote:
>>> By "negotiation" I mean the server's response to the startup packet.
>>> I.e. "supported"/"not supported"/"error".
>>
>> Ok, I'm still a little confused, probably a terminology issue. The
>> server doesn't respond with "supported" or "not supported" to the
>> startup packet, that happens earlier. I think you mean the SSLRequst /
>> GSSRequest packet, which is sent *before* the startup packet?
> 
> Yes, sorry. (I'm used to referring to those as startup packets too, ha.)

Yeah I'm not sure what the right term would be.

>> Hmm, right, GSS encryption was introduced in v12, and older versions
>> respond with an error to a GSSRequest.
>>
>> We probably could make the same assumption for GSS as we did for TLS in
>> a49fbaaf, i.e. that an error means that something's wrong with the
>> server, rather than that it's just very old and doesn't support GSS. But
>> the case for that is a lot weaker case than with TLS. There are still
>> pre-v12 servers out there in the wild.
> 
> Right. Since we default to gssencmode=prefer, if you have Kerberos
> creds in your environment, I think this could potentially break
> existing software that connects to v11 servers once you upgrade libpq.

When you connect to a V11 server and attempt to perform GSSAPI 
authentication, it will respond with a V3 error that says: "unsupported 
frontend protocol 1234.5680: server supports 2.0 to 3.0". That was a 
surprise to me until I tested it just now. I thought that it would 
respond with a protocol V2 error, but it is not so. The backend sets 
FrontendProtocol to 1234.5680 before sending the error, and because it 
is >= 3, the error is sent with protocol version 3.

Given that, I think it is a good thing to fail the connection completely 
on receiving a V2 error.

Attached is a patch to fix the other issue, with falling back from SSL 
to plaintext. And some tests and comment fixes I spotted while at it.

0001: A small comment fix
0002: This is the main patch that fixes the SSL fallback issue

0003: This adds fault injection tests to exercise these early error 
codepaths. It is not ready to be merged, as it contains a hack to skip 
locking. See thread at 
https://www.postgresql.org/message-id/e1ffb822-054e-4006-ac06-50532767f75b%40iki.fi.

0004: More tests, for what happens if the server sends an error after 
responding "yes" to the SSLRequest or GSSRequest, but before performing 
the SSL/GSS handshake.

Attached is also a little stand-alone perl program that listens on a 
socket, and when you connect to it, it immediately sends a V2 or V3 
error, depending on the argument. That's useful for testing. It could be 
used as an alternative strategy to the injection points I used in the 
0003-0004 patches, but for now I just used it for manual testing.

-- 
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. Add tests for errors during SSL or GSSAPI handshake

  2. Add test for early backend startup errors

  3. Fix fallback behavior when server sends an ERROR early at startup

  4. Fix outdated comment after removal of direct SSL fallback