Thread: Postgres GSSAPI Encryption

Postgres GSSAPI Encryption

From
Robbie Harwood
Date:
Hello!

Today, there exists GSSAPI authentication support in Postgres.  I plan
to extend this work to include encryption as well, but wanted to get
your input on that first since you've probably thought about this
already.

From what I can tell, the auth/encryption layer is very nicely designed
for extensibility; adding an encryption mechanism should just involve
adding another option to the read/write functions in {f,b}e-secure.c,
and then creating {f,b}e-secure-gssapi.c (or similar) to populate from.

We'd I think also want a new kind of HBA entry (probably something along
the lines of `hostgss` to contrast with `hostssl`), but I'm not sure
what we'd want to do for the counterpart of `hostnossl` (`hostnogss`?
But then do we need `hostnogssnossl`?  Is this even a useful setting to
have?), so that will probably require broader discussion.

Finally, I think there are a couple different ways the protocol could
look.  I'd ideally like to opportunistically encrypt all
GSSAPI-authenticated connections and fallback to non-encrypted when the
other end doesn't support it (possibly dropping the connection if this
causes it to not match HBA), but I'm not sure if this will work with the
existing code.  A (less-nice) option could be to add a new
authentication method for gss->encryption, which feels aesthetically
misplaced.  The approach used for SSL today could probably be adopted as
a third approach, but I don't really see a gain from doing it this way
since encryption happens after authentication (opposite of SSL) in
GSSAPI.

I'm interested to hear your thoughts on this.

Thanks!

--Robbie

Re: Postgres GSSAPI Encryption

From
Stephen Frost
Date:
Robbie,

* Robbie Harwood (rharwood@redhat.com) wrote:
> Today, there exists GSSAPI authentication support in Postgres.  I plan
> to extend this work to include encryption as well, but wanted to get
> your input on that first since you've probably thought about this
> already.

Great!

> From what I can tell, the auth/encryption layer is very nicely designed
> for extensibility; adding an encryption mechanism should just involve
> adding another option to the read/write functions in {f,b}e-secure.c,
> and then creating {f,b}e-secure-gssapi.c (or similar) to populate from.

It was reworked recently thanks to Heikki.

> We'd I think also want a new kind of HBA entry (probably something along
> the lines of `hostgss` to contrast with `hostssl`), but I'm not sure
> what we'd want to do for the counterpart of `hostnossl` (`hostnogss`?
> But then do we need `hostnogssnossl`?  Is this even a useful setting to
> have?), so that will probably require broader discussion.

Are you intending to support GSSAPI encryption *without* using the
GSSAPI authentication mechanism?  If not, maybe we can come up with a
way to have an option to the GSSAPI auth mechanism that behaves the way
we want for GSSAPI encryption.  Perhaps something like:

encryption = (none | request | require)

If you need an option for it to still be able to fall-thru to the next
pg_hba line, that'd be more difficult, but is that really a sensible
use-case?

> Finally, I think there are a couple different ways the protocol could
> look.  I'd ideally like to opportunistically encrypt all
> GSSAPI-authenticated connections and fallback to non-encrypted when the
> other end doesn't support it (possibly dropping the connection if this
> causes it to not match HBA), but I'm not sure if this will work with the
> existing code.  A (less-nice) option could be to add a new
> authentication method for gss->encryption, which feels aesthetically
> misplaced.  The approach used for SSL today could probably be adopted as
> a third approach, but I don't really see a gain from doing it this way
> since encryption happens after authentication (opposite of SSL) in
> GSSAPI.

I'd definitely like to see us opportunistically encrypt all GSSAPI
authenticated connections also.  The main case to consider is how to
support migrating users who are currently using GSSAPI + SSL to GSSAPI
auth+encryption, and how to support them if they want to continue to use
GSSAPI just for user auth and use SSL for encryption.
Thanks!
    Stephen

Re: Postgres GSSAPI Encryption

From
Robbie Harwood
Date:
Stephen Frost <sfrost@snowman.net> writes:

> Robbie,
>
> * Robbie Harwood (rharwood@redhat.com) wrote:
>
>> We'd I think also want a new kind of HBA entry (probably something along
>> the lines of `hostgss` to contrast with `hostssl`), but I'm not sure
>> what we'd want to do for the counterpart of `hostnossl` (`hostnogss`?
>> But then do we need `hostnogssnossl`?  Is this even a useful setting to
>> have?), so that will probably require broader discussion.
>
> Are you intending to support GSSAPI encryption *without* using the
> GSSAPI authentication mechanism?  If not, maybe we can come up with a
> way to have an option to the GSSAPI auth mechanism that behaves the way
> we want for GSSAPI encryption.  Perhaps something like:
>
> encryption = (none | request | require)
>
> If you need an option for it to still be able to fall-thru to the next
> pg_hba line, that'd be more difficult, but is that really a sensible
> use-case?

That's a good point.  I don't see GSSAPI encryption without GSSAPI
authentication as a particularly compelling use case, so a setting like
that (with default presumably to request for backward compatibility)
seems perfect.

As for fall-through on failure, I don't really know what's reasonable
here.  My understanding of the way it works currently suggests that it
would be *expected* to fall-through based on the way other things
behave, though it's certainly less effort on my part if it does not.

>> Finally, I think there are a couple different ways the protocol could
>> look.  I'd ideally like to opportunistically encrypt all
>> GSSAPI-authenticated connections and fallback to non-encrypted when the
>> other end doesn't support it (possibly dropping the connection if this
>> causes it to not match HBA), but I'm not sure if this will work with the
>> existing code.  A (less-nice) option could be to add a new
>> authentication method for gss->encryption, which feels aesthetically
>> misplaced.  The approach used for SSL today could probably be adopted as
>> a third approach, but I don't really see a gain from doing it this way
>> since encryption happens after authentication (opposite of SSL) in
>> GSSAPI.
>
> I'd definitely like to see us opportunistically encrypt all GSSAPI
> authenticated connections also.  The main case to consider is how to
> support migrating users who are currently using GSSAPI + SSL to GSSAPI
> auth+encryption, and how to support them if they want to continue to use
> GSSAPI just for user auth and use SSL for encryption.

So if we go with the "encryption" option, we might not need a specific
entry for GSS hosts.  For the SSL encryption/GSS auth case, we'd want it
to work the way it does now where you specify "hostssl" and then "gss"
as the method.  Then for the GSS for auth and encryption, one would use
a normal "host" entry, then specify gss as the method, and then set
encryption=require.

One consequence of this would be that you can do "double encryption" by
specifying "hostssl", then "gss" with "encrypt = require".  I don't
think this is something more desirable than just one or the other, but
unless it's actually a problem (and I don't think it is) to have around,
I think the setup would work nicely.  We could also default "encrypt" to
"none" when hostssl is specified if it is a problem.

Thanks!
--Robbie

Re: Postgres GSSAPI Encryption

From
Robbie Harwood
Date:
Robbie Harwood <rharwood@redhat.com> writes:

> Stephen Frost <sfrost@snowman.net> writes:
>
>> Robbie,
>>
>> * Robbie Harwood (rharwood@redhat.com) wrote:
>>
>>> We'd I think also want a new kind of HBA entry (probably something along
>>> the lines of `hostgss` to contrast with `hostssl`), but I'm not sure
>>> what we'd want to do for the counterpart of `hostnossl` (`hostnogss`?
>>> But then do we need `hostnogssnossl`?  Is this even a useful setting to
>>> have?), so that will probably require broader discussion.
>>
>> Are you intending to support GSSAPI encryption *without* using the
>> GSSAPI authentication mechanism?  If not, maybe we can come up with a
>> way to have an option to the GSSAPI auth mechanism that behaves the way
>> we want for GSSAPI encryption.  Perhaps something like:
>>
>> encryption = (none | request | require)
>>
>> If you need an option for it to still be able to fall-thru to the next
>> pg_hba line, that'd be more difficult, but is that really a sensible
>> use-case?
>
> That's a good point.  I don't see GSSAPI encryption without GSSAPI
> authentication as a particularly compelling use case, so a setting like
> that (with default presumably to request for backward compatibility)
> seems perfect.
>
> As for fall-through on failure, I don't really know what's reasonable
> here.  My understanding of the way it works currently suggests that it
> would be *expected* to fall-through based on the way other things
> behave, though it's certainly less effort on my part if it does not.
>
>>> Finally, I think there are a couple different ways the protocol could
>>> look.  I'd ideally like to opportunistically encrypt all
>>> GSSAPI-authenticated connections and fallback to non-encrypted when the
>>> other end doesn't support it (possibly dropping the connection if this
>>> causes it to not match HBA), but I'm not sure if this will work with the
>>> existing code.  A (less-nice) option could be to add a new
>>> authentication method for gss->encryption, which feels aesthetically
>>> misplaced.  The approach used for SSL today could probably be adopted as
>>> a third approach, but I don't really see a gain from doing it this way
>>> since encryption happens after authentication (opposite of SSL) in
>>> GSSAPI.
>>
>> I'd definitely like to see us opportunistically encrypt all GSSAPI
>> authenticated connections also.  The main case to consider is how to
>> support migrating users who are currently using GSSAPI + SSL to GSSAPI
>> auth+encryption, and how to support them if they want to continue to use
>> GSSAPI just for user auth and use SSL for encryption.
>
> So if we go with the "encryption" option, we might not need a specific
> entry for GSS hosts.  For the SSL encryption/GSS auth case, we'd want it
> to work the way it does now where you specify "hostssl" and then "gss"
> as the method.  Then for the GSS for auth and encryption, one would use
> a normal "host" entry, then specify gss as the method, and then set
> encryption=require.
>
> One consequence of this would be that you can do "double encryption" by
> specifying "hostssl", then "gss" with "encrypt = require".  I don't
> think this is something more desirable than just one or the other, but
> unless it's actually a problem (and I don't think it is) to have around,
> I think the setup would work nicely.  We could also default "encrypt" to
> "none" when hostssl is specified if it is a problem.

I've coded up the GSSAPI encryption and is on my github[0].  It's
missing a number of things before merge, including proper error
handling, correct ACL behavior (by and large, it currently doesn't
respect hba.conf), and exposing configuration handles in hba.conf and
the client for the settings we've talked about above, as well as
documentation of all that.

What is here, importantly, is the fallback for old clients to new
servers and new clients to old servers.  A parameter is sent at the
start of normal connection (i.e., after SSL querying), and if the server
sees it, we encrypt; otherwise, the server will generate a failure
similar to the application_name case (and we will retry without it in
the same manner).

Thanks!
--Robbie

[0]: https://github.com/frozencemetery/postgres/

Re: Postgres GSSAPI Encryption

From
Stephen Frost
Date:
Robbie,

* Robbie Harwood (rharwood@redhat.com) wrote:
> I've coded up the GSSAPI encryption and is on my github[0].  It's
> missing a number of things before merge, including proper error
> handling, correct ACL behavior (by and large, it currently doesn't
> respect hba.conf), and exposing configuration handles in hba.conf and
> the client for the settings we've talked about above, as well as
> documentation of all that.

Neat!

We're currently focusing on stabilizing for PostgreSQL 9.5, but this
work is great and we'd like to make sure to review it for inclusion
post-9.5.  Our process is that patches are posted to the mailing list
and then an entry is created on http://commitfest.postgresql.org which
references the mailing list post.  This way, we won't forget about the
patch in a month or so, after we've branched off 9.5 and resumed
reviewing development work.

So, when you're ready for it to be reviewed for feedback, please post a
full patch against whatever current master is at the time, and register
the patch in the commitfest application.
Thanks!
    Stephen