0

I am trying to enable Kerberos authentication for our website - The idea is to have users logged into a Windows AD domain get automatic login (and initial account creation)

Before I tackle the Windows side of things, I wanted to get it work locally. So I made a test KDC/KADMIN container using git@github.com:ist-dsi/docker-kerberos.git

Thee webserver is in a local docker container with nginx and the spnego module compiled in. The KDC/KADMIN container is at 172.17.0.2 and accessible from my webserver container.

Here is my local krb.conf:

default_realm = SERVER.LOCAL

[realms]
SERVER.LOCAL = {
                kdc_ports = 88,750
                kadmind_port = 749
                kdc = 172.17.0.2:88
                admin_server = 172.17.0.2:749
        }

[domain_realms]
  .server.local = SERVER.LOCAL
  server.local = SERVER.LOCAL

and the krb.conf on the webserver container

[libdefaults]
  default_realm = SERVER.LOCAL
  default_keytab_name  = FILE:/etc/krb5.keytab
  ticket_lifetime      = 24h
  kdc_timesync         = 1
  ccache_type          = 4
  forwardable          = false
  proxiable            = false

[realms]
  LOCALHOST.LOCAL = {
    kdc_ports = 88,750
    kadmind_port = 749
    kdc = 172.17.0.2:88
    admin_server = 172.17.0.2:749
  }

[domain_realms]
  .server.local = SERVER.LOCAL
  server.local = SERVER.LOCAL

Here is the principals and keytab config (keytab is copied to the web container under /etc/krb5.keytab)

rep ~/project * rep_krb_test $ kadmin -p kadmin/admin@SERVER.LOCAL -w hunter2
Authenticating as principal kadmin/admin@SERVER.LOCAL with password.
kadmin:  list_principals
K/M@SERVER.LOCAL
kadmin/99caf4af9dc5@SERVER.LOCAL
kadmin/admin@SERVER.LOCAL
kadmin/changepw@SERVER.LOCAL
krbtgt/SERVER.LOCAL@SERVER.LOCAL
noPermissions@SERVER.LOCAL
rep_movsd@SERVER.LOCAL
kadmin:  q

rep ~/project * rep_krb_test $ ktutil
ktutil:  addent -password -p rep_movsd@SERVER.LOCAL -k 1 -f
Password for rep_movsd@SERVER.LOCAL:
ktutil:  wkt krb5.keytab
ktutil:  q

rep ~/project * rep_krb_test $ kinit -C -p rep_movsd@SERVER.LOCAL
Password for rep_movsd@SERVER.LOCAL:

rep ~/project * rep_krb_test $ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: rep_movsd@SERVER.LOCAL

Valid starting     Expires            Service principal
02/07/20 04:27:44  03/07/20 04:27:38  krbtgt/SERVER.LOCAL@SERVER.LOCAL

The relevant nginx config:

server {

  location / {
    uwsgi_pass  django;
    include     /usr/lib/proj/lib/wsgi/uwsgi_params;

    auth_gss on;
    auth_gss_realm SERVER.LOCAL;
    auth_gss_service_name HTTP;
  }
}

Finally etc/hosts has

# use alternate local IP address
127.0.0.2 server.local server

Now I try to access this with curl:

*   Trying 127.0.0.2:80...
* Connected to server.local (127.0.0.2) port 80 (#0)
* gss_init_sec_context() failed: Server krbtgt/LOCAL@SERVER.LOCAL not found in Kerberos database.
* Server auth using Negotiate with user ''
> GET / HTTP/1.1
> Host: server.local
> User-Agent: curl/7.71.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
....

As you can see it is trying to use the SPN "krbtgt/LOCAL@SERVER.LOCAL" whereas kinit has "krbtgt/SERVER.LOCAL@SERVER.LOCAL" as the SPN

How do I get this to work?

Thanks in advance..

rep_movsd
  • 6,675
  • 4
  • 30
  • 34
  • Kerberos by default resolves the hostname to an IP address and then back to a hostname. It's likely that something is causing the IP address to resolve to `local` instead of `server.local`. – bk2204 Jul 02 '20 at 01:49
  • What to I put in the hosts file to avoid this? – rep_movsd Jul 02 '20 at 08:50

1 Answers1

0

So it turns out that I needed

auth_gss_service_name HTTP/server.local;

Some other tips for issues encountered:

  1. Make sure the keytab file is readable by the web server process with user www-data or whatever user
  2. Make sure the keytab principals are in the correct order
  3. Use export KRB5_TRACE=/dev/stderr and curl to test - kerberos gives a very detailed log of what it's doing and why it fails
rep_movsd
  • 6,675
  • 4
  • 30
  • 34