Re: Kerberos delegation support in libpq and postgres_fdw

From: Stephen Frost <sfrost(at)snowman(dot)net>
To: Jacob Champion <pchampion(at)vmware(dot)com>
Cc: "pgsql-hackers(at)lists(dot)postgresql(dot)org" <pgsql-hackers(at)lists(dot)postgresql(dot)org>, "magnus(at)hagander(dot)net" <magnus(at)hagander(dot)net>, "peter(dot)eisentraut(at)enterprisedb(dot)com" <peter(dot)eisentraut(at)enterprisedb(dot)com>, "tgl(at)sss(dot)pgh(dot)pa(dot)us" <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Subject: Re: Kerberos delegation support in libpq and postgres_fdw
Date: 2022-04-06 19:27:03
Message-ID: 20220406192703.GY10577@tamriel.snowman.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Greetinsg,

* Jacob Champion (pchampion(at)vmware(dot)com) wrote:
> On Fri, 2022-03-11 at 19:39 -0500, Stephen Frost wrote:
> > On Fri, Mar 11, 2022 at 18:55 Jacob Champion <pchampion(at)vmware(dot)com> wrote:
> > > [5] says we have to free the proxy credential with GSS_Release_cred();
> > > I don't see that happening anywhere, but I may have missed it.
> >
> > I’m not sure that it’s really necessary or worthwhile to do that at
> > process end since … the process is about to end. I suppose we could
> > provide a function that a user could call to ask for it to be
> > released sooner if we really wanted..?
>
> Do we have to keep the credential handle around once we've stored it
> into the MEMORY: cache, though? Just seems like a leak that someone
> will have to plug eventually, even if it doesn't really impact things
> now.

We don't, so I've fixed that in the attached. Not sure it's that big a
deal but I don't think it hurts anything either.

> > > It seems like there should be significant security implications to
> > > allowing delegation across the board. Especially since one postgres_fdw
> > > might delegate to another server, and then another... Should this be
> > > opt-in, maybe via a connection parameter?
> >
> > This is already opt-in- at kinit time a user can decide if they’d
> > like a proxy-able ticket or not. I don’t know that we really need to
> > have our own option for it … tho I’m not really against adding such
> > an option either.
>
> I don't really have experience with the use case. Is it normal for
> kinit users to have to decide once, globally, whether they want
> everything they interact with to be able to proxy their credentials? It
> just seems like you'd want more fine-grained control over who gets to
> masquerade as you.

Yes, that's pretty typical for kinit users- they usually go with
whatever the org policy is. Now, you're not wrong about wanting more
fine-grained control, which is what's known as 'constrained delegation'.
That's something that Kerberos in general supports these days though
it's more complicated and requires additional code to do. That's
something that I think we could certainly add later on.

> > > Similarly, it feels a little strange that the server would allow the
> > > client to unilaterally force the use of a delegated credential. I think
> > > that should be opt-in on the server side too, unless there's some
> > > context I'm missing around why that's safe.
> >
> > Perhaps you could explain what isn’t safe about accepting a delegated
> > credential from a client..? I am not away of a risk to accepting
> > such a delegated credential.
>
> My initial impression is that this is effectively modifying the USER
> MAPPING that the admin has set up. I'd be worried about an open
> credential proxy being used to bypass firewall or HBA restrictions, for
> instance -- you might not be able to connect as an admin from your
> machine, but you might be able to connect by bouncing through a proxy.
> (What damage you can do is going to be limited by what the server
> extensions can do, of course.)

I'm not sure that I really see the concern here. Also, in order for
this to work, the user mapping would have to be created with "password
required = false". Maybe that's something we revisit later, but it
seems like a good way to allow an admin to have control over this.

> Another danger might be disclosure/compromise of middlebox secrets? Is
> it possible for someone who has one half of the credentials to snoop on
> a gssenc connection between the proxy Postgres and the backend
> Postgres?

A compromised middlebox would, of course, be an issue- for any kind of
delegated credentials (which certainly goes for cleartext passwords
being passed along, and that's currently the only thing we support..).
One nice thing about GSSAPI is that the client and the server validate
each other, so it wouldn't just be 'any' middle-box but would have to be
one that was actually a trusted system in the infrastructure which has
somehow been compromised and was still trusted.

> > Even so, I’m not against adding an option… but exactly how would that
> > option be configured? Server level? On the HBA line? role level..?
>
> In the OPTIONS for CREATE SERVER, maybe? At least for the FDW case.

I'm a bit confused on this. The option to allow or not allow delegated
credentials couldn't be something that's in the CREATE SERVER for FDWs
as it applies to more than just FDWs but also dblink and anything else
where we reach out from PG to contact some other system.

> > > If I'm reading it right, we're resetting the default credential in the
> > > MEMORY cache, so if you're a libpq client doing your own GSSAPI work,
> > > I'm guessing you might not be happy with this behavior.
> >
> > This is just done on the server side and not the client side..?
>
> Yeah, I misread the patch, sorry.

No worries.

> > > Also, we're
> > > globally ignoring whatever ccache was set by an administrator. Can't
> > > two postgres_fdw connections from the same backend process require
> > > different settings?
> >
> > Settings..? Perhaps, but delegated credentials aren’t really
> > settings, so not really sure what you’re suggesting here.
>
> I mean that one backend server might require delegated credentials, and
> another might require whatever the admin has already set up in the
> ccache, and the user might want to use tables from both servers in the
> same session.

That an admin might have a credential cache that's picked up and used
for connections from a regular user backend to another system strikes me
as an altogether concerning idea. Even so, in such a case, the admin
would have had to set up the user mapping with 'password required =
false' or it wouldn't have worked for a non-superuser anyway, so I'm not
sure that I'm too worried about this case.

> > > I notice that gss_store_cred_into() has a companion,
> > > gss_acquire_cred_from(). Is it possible to use that to pull out our
> > > delegated credential explicitly by name, instead of stomping on the
> > > global setup?
> >
> > Not really sure what is meant here by global setup..? Feeling like
> > this is a follow on confusion from maybe mixing server vs client
> > libpq?
>
> By my reading, the gss_store_cred_into() call followed by
> the setenv("KRB5CCNAME", ...) is effectively performing global
> configuration for the process. Any KRB5CCNAME already set up by the
> server admin is going to be ignored from that point onward. Is that
> accurate?

The process, yes, but I guess I disagree on that being 'global'- it's
just for that PG backend process.

Attached is an updated patch which adds the gss_release_creds call, a
function in libpq to allow checking if the libpq connection was made
using GSS, changes to dblink to have it check for password-or-gss when
connecting to a remote system, and tests for dblink and postgres_fdw to
make sure that this all works correctly.

Thoughts?

Thanks!

Stephen

Attachment Content-Type Size
v4-0001-kerberos-delegation.patch text/x-diff 25.2 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2022-04-06 19:27:34 Re: shared-memory based stats collector - v70
Previous Message Jacob Champion 2022-04-06 19:16:43 Re: [PATCH] Expose port->authn_id to extensions and triggers