On Mon, 2020-10-19 at 13:06 -0400, Jason Keltz wrote:
On 10/19/2020 12:53 PM, Simo Sorce wrote:
> On Mon, 2020-10-19 at 12:40 -0400, Jason Keltz wrote:
> > On 10/19/2020 10:55 AM, Simo Sorce wrote:
> >
> > > On Mon, 2020-10-19 at 10:14 -0400, Jason Keltz wrote:
> > > > On 10/19/2020 8:59 AM, Simo Sorce wrote:
> > > >
> > > > > On Fri, 2020-10-16 at 16:39 -0400, Jason Keltz wrote:
> > > > > > Hi.
> > > > > >
> > > > > > I've been trying to get gssproxy working with httpd and
mod_auth_gssapi
> > > > > > on CentOS 7.8. Albeit, I'm not using the httpd from
CentOS, but a later
> > > > > > 2.4.39.
> > > > > >
> > > > > > I setup the httpd keytab. I setup mod_auth_gssapi and was
able to
> > > > > > access my page with Kerberos auth no problem at all.
> > > > > >
> > > > > > Next, I wanted to get things working with gssproxy.
> > > > > >
> > > > > > I created /etc/gssproxy/80-httpd.conf
> > > > > >
> > > > > > [service/HTTP]
> > > > > > mechs = krb5
> > > > > > cred_store =
keytab:/xconf/httpd/keytab/httpd-www-svc.keytab
> > > > > > cred_store =
ccache:/var/lib/gssproxy/clients/krb5cc_%U
> > > > > > euid = www
> > > > > >
> > > > > > My web user is "www".
> > > > > >
> > > > > > My keytab file is in the given location. I change
permission to 600,
> > > > > > owned by root.
> > > > > >
> > > > > > I added to the Service section of
/etc/systemd/system/httpd.service:
> > > > > >
> > > > > > Environment=GSS_USE_PROXY=yes
> > > > > >
> > > > > > I restart httpd and gssproxy.
> > > > > >
> > > > > > My test protected page is under a .htaccess as follows:
> > > > > >
> > > > > > AuthType GSSAPI
> > > > > > AuthName "GSSAPI Login"
> > > > > > GssapiBasicAuth On
> > > > > > GssapiLocalName on
> > > > > > Require valid-user
> > > > > >
> > > > > > When I visit the page and I don't have a ticket, I get
prompted for my
> > > > > > username and password. Access is denied.
> > > > > >
> > > > > > When I visit my page Apache outputs:
> > > > > >
> > > > > > [Thu Oct 15 15:04:12.311614 2020] [auth_gssapi:error] [pid
28584:tid
> > > > > > 13995355614
> > > > > > 1824] [client 130.63.97.125:57910] GSS ERROR
gss_acquire_cred[_from]()
> > > > > > failed to
> > > > > > get server creds: [Unspecified GSS failure. Minor
code may provide
> > > > > > more inform
> > > > > > ation (Keytab FILE:/etc/krb5.keytab is nonexistent or
empty)]
> > > > > >
> > > > > > ... so I know that it's not really using gssproxy
because if it was, it
> > > > > > wouldn't be looking at /etc/krb5.keytab.
> > > > > >
> > > > > > I enabled debugging on gssproxy, level 3, but when I access
the page,
> > > > > > gssproxy doesn't log anything. This is printed when I
start gssproxy
> > > > > > and doesn't change:
> > > > > >
> > > > > > [2020/10/15 23:23:26]: Service: HTTP, Keytab:
> > > > > > /xconf/httpd/keytab/httpd-www-svc.keytab, Enctype: 23
> > > > > > [2020/10/15 23:23:26]: Service: nfs-server, Keytab:
/etc/krb5.keytab,
> > > > > > Enctype: 17
> > > > > > [2020/10/15 23:23:26]: Service: nfs-client, Keytab:
/etc/krb5.keytab,
> > > > > > Enctype: 17
> > > > > > [2020/10/15 23:23:26]: Debug Enabled (level: 3)
> > > > > > [2020/10/15 23:23:26]: Problem with kernel communication!
NFS server
> > > > > > will not work
> > > > > > [2020/10/15 23:23:26]: Failed to get peer's SELinux
context (92:Protocol
> > > > > > not available)
> > > > > > [2020/10/15 23:23:26]: Client connected (fd =
10)[2020/10/15 23:23:26]:
> > > > > > (pid = 24902) (uid = 0) (gid = 0)[2
> > > > > >
> > > > > > I assume the "Problem with kernel communication"
error is just because
> > > > > > there is no nfs-server running here, but the gssproxy file
exists.
> > > > > >
> > > > > > Of course if I go back and insert into the .htaccess:
> > > > > >
> > > > > > GssapiCredStore
keytab:/xconf/httpd/keytab/httpd-www-svc.keytab
> > > > > >
> > > > > > ... and I make the file readable by "www" then it
works, but that, of
> > > > > > course isn't using gssproxy either.
> > > > > >
> > > > > > I read a bug report on Redhat about there being an issue
with using
> > > > > > "GssapiLocalName on" so I removed that and it
didn't make a difference.
> > > > > >
> > > > > > So what is the magic bit that I'm missing to tell httpd
to actually use
> > > > > > gssproxy? I thought the only thing was the
USE_GSS_PROXY=yes
> > > > > >
> > > > > > Does the application itself need to be aware of gssproxy,
or is that
> > > > > > hidden from the application?
> > > > > >
> > > > > > I even tried adding to the httpd.service:
> > > > > >
> > > > > > Environment=KRB5_TRACE=/tmp/log
> > > > > >
> > > > > > ... hoping this would give me *something* but the file
didn't even get
> > > > > > created.
> > > > > >
> > > > > > Any feedback that you can provide would be helpful.
> > > > > Hi Jason,
> > > > > I assume you have a custom install of gssproxy as well here.
> > > > >
> > > > > So 2 questions.
> > > > > 1) what libkrb5 version do you have installed ?
> > > > > 2) Have you configured gssproxy as a GSSAPI mechanism ?
> > > > >
> > > > > See man 8 gssproxy-mech for more info on how to do (2).
> > > > Hi Simo,
> > > >
> > > > Thanks for your message.
> > > >
> > > > I'm actually just using the OS provided gssproxy. I don't
have a custom
> > > > install of that.
> > > >
> > > > In terms of libkrb5, in /usr/lib64 I see:
> > > >
> > > > lrwxrwxrwx 1 root root 14 May 6 12:22 /usr/lib64/libkrb5.so
->
> > > > libkrb5.so.3.3
> > > > lrwxrwxrwx 1 root root 14 May 6 12:22 /usr/lib64/libkrb5.so.3
->
> > > > libkrb5.so.3.3
> > > > -rwxr-xr-x 1 root root 967760 Mar 31 2020 /usr/lib64/libkrb5.so.3.3
> > > > lrwxrwxrwx 1 root root 21 May 6 12:22
/usr/lib64/libkrb5support.so
> > > > -> libkrb5support.so.0.1
> > > > lrwxrwxrwx 1 root root 21 May 6 12:22
> > > > /usr/lib64/libkrb5support.so.0 -> libkrb5support.so.0.1
> > > > -rwxr-xr-x 1 root root 67104 Mar 31 2020
/usr/lib64/libkrb5support.so.0.1
> > > >
> > > > I see /etc/gss/mech.d/gssproxy.conf containing:
> > > >
> > > > # GSS-API mechanism plugins
> > > > #
> > > > # Mechanism Name Object Identifier Shared
Library
> > > > Path Other Options
> > > > gssproxy_v1 2.16.840.1.113730.3.8.15.1
> > > > /usr/lib64/gssproxy/proxymech.so <interposer>
> > > >
> > > > ... which is just the default setup, but I don't see any reason
why it
> > > > wouldn't work at this point.
> > > Ah, sorry, I just realized this is for password based authentication.
> > >
> > > Unfortunately hand-over for that operation is not supported in the
> > > gssproxy version you are using.
> > >
> > > In fact it is something I am working on upstream krb5 now, to provide a
> > > proper interface via gss_acquire_cred_from() that will allow me to
> > > change proxy to allow password based validation to be performed via the
> > > proxy.
> > >
> > > So I am afraid what you are experiencing is expected at this time, for
> > > password based authentication apache needs direct access to a key it
> > > can use.
> > Hi Simo,
> >
> > This is unfortunate. I've spent a lot time trying to make this work.
> > However, it's good to know that it was just something I wasn't doing
right.
> >
> > What could a regular user do with the keytab file if they got a hold of
> > it - run a web server which purports to be the web server?
> They can:
> - impersonate any user to the server
> - impersonate the server
> - acquire tickets and contact other services using the server's
> identity.
>
> Definitely not recommended to hand untrusted users a keytab.
>
> However you do not need to use the server's key for password
> verification.
>
> You could use a key specifically used for password verification only,
> and not used for any other purposes.
> You should make sure such key cannot acquire credentials either, by
> properly marking the principal in the KDC, to protect separate service
> with lax configuration on principal mappings.
>
> So you could create a principal like:
> HTTP/password.verification.only(a)YOUR.REALM
> And extract a key for that principal in the keytab you then use in
> mod_auth_gssapi authentication.
>
> In this case you must *not* set an acceptor name, so that whatever is
> in the keytab will be used.
>
> You will keep gssproxy current configuration to protect the actual
> service key instead for when users present valid GSSAPI credentials and
> do normal negotiation.
I apologize in advance because I'm new to all of this.
I've already done exactly that as part of my original setup - I created
"httpd-www-svc" in Kerberos. I extracted the SPN for
HTTP/httpd-www-svc(a)MY.REALM to a separate file. That's the file I was
trying to use with gssproxy to allow Apache to access without it needing
to be readable by "www".
I'm not sure how to configure the KDC to protect the service. I assume
it's by adding an entry to /etc/krb5.conf?
Given you speak about SPN I am going to assume this is a realm served
by Active Directory.
If that's the case you should be fine because by default AD does not
allow AS requests with SPNs (it requires you to use the UPN for that),
however a clever user could extract the key and figure out what is the
UPN to reassemble a keytab, so all you need to do is to configure the
account so that it cannot login anywhere (but can still perform
authentication).
If the KDC is an MIT KDC you'd have to disable TIX on the principal
(IIRC) via kadmin.
But then you said "You will keep gssproxy current configuration
to
protect the actual service key instead for when users present valid
GSSAPI crendeitalss and do normal negotiation.". That part I'm not sure
about. If you have time, can you possibly give more description, and
possibly an example configuration?
I am assuming you wan to allow users to login transparently and not be
asked for a password if they do have a kerberos ticket.
To do that you need to provide mod_auth_gssapi with a keytab that
contains keys for HTTP/actual.fqdn.of.the.server@REALM
If you do this you'll have single-sign-on experience.
You want to keep that keytab private, let's call it keytab-P
If you are the only person with access to the web server user, then all
you need to do is to just make sure only the webserver user can read
keytab-P, and you do not need gss-proxy at all.
However if you are using gss-proxy I assume that this is some sort of
shared account so you want to use gss-proxy to keep the keytab-P secret
from other users and accessible only from root.
In this case keytab-P is your keytab:/xconf/httpd/keytab/httpd-www-
svc.keytab which you'll keep segregated from the www user.
At this point SSO works, but password authentication doesn't work.
To fix that you create a new completely arbitrarily named principal,
say: PASSWORD-CHECK/invented-name@REALM and extract a keytab with a key
for this principal, let's call this keytab-K
Put keytab-K in a place where apache can read it, and give ownership to
apache.
Just add GssapiCredStore keytab:/path/to/keytab-K to your apache
configuration and now BasicAuth has a key to use for password checks.
Basically you end up using to distinct keytabs.
Normally, because GSS-Proxy interposes, there is no confusion of which
keytab is used, and if some odd configuration makes mod_auth_gssapi
"not" work through gssprosy it will simply fail to authenticate with
its keytab-K because users don't get tickets for a non-HTTP-randomly-
named service when they connect to your server.
There is a chance to try to attack the server if a malicious user gain
access to keytab-K and can force a fallback from gss-proxy auth to
local GSSAPI auth. To mitigate that you can set also the environment
variable:
GSSPROXY_BEHAVIOR=REMOTE_FIRST
Note that unfortunately you can't use GSSPROXY_BEHAVIOR=REMOTE_ONLY
which would be better, because in that case the shim that intercept
gss_acuire_cred_with_password() will cause an error to be returned :-/
This is as far as I can go with this workaround, it is not perfect and
may cause you some heartburn if you have issues, as it is a rather
complex and nuanced setup. But it should work.
HTH,
Simo.
--
Simo Sorce
RHEL Crypto Team
Red Hat, Inc