The Path to Kerberos over Port 443

While Kerberos’ reputation as a Single Sign On solution is quite strong, its adoption outside the corporate VPN has been limited. One reason is that many host providers block port 88 traffic in the firewalls. What would it take to make Kerberos a viable solution in a web-only constrained situation?

Kerberos communicates over port 88 in order to secure tickets that will be used for authentication and (to a limited degree) authorization on other servers.  This communication is done using the Kerberos wire protocols.  First the user requests a ticket granting ticket (TGT).  Later, the user will use that TGT to get a ticket specific to the service they are trying to talk to.

The connection to get the TGT is a two way street.  There are multiple messages and back and forth as both sides performs steps necessary to prove to the other that they are indeed,  who they claim to be.  This cannot be done over straight HTTP without serious reworking,  but it can be done using a techonology called websockets.  With websockets,  the connection between client and server remains open, and HTTP becomes a tunneling protocol for TCP.

Thus, the two things we need to do to get a TGT are:

  1.  Place the Key Distribution Center (KDC)  behind a websockets Proxy.
  2. Create a modified version of the kinit program that can talk websockets,  or build a client side proxy.

There are other approaches, of course.  FreeIPA can request a TGT on the server on behalf of the user.  The user could download this TGT, and a Browser plugin could even stick it into the Kerberos Credentials Cache.  But this bypasses the Kerberos ideal of the users password never crossing the wire.

We could write the kinit code into the browser itself, using either a native extension or Javascript,  but it is a complicated enough of a protocol that forking from the C code would be a hefty maintenance effort.

The second step is trickier:  getting the service ticket.  This action is performed for the user automatically when visiting a web site that is protected by, for example, mod_auth_krb.  The web server responds to a request with a 401 and enough information that the browser knows to try Kerberos…by way of two wrapper libraries called SASL and GSSAPI in turn.  Unfortunately,  this is a pipeline that is pretty much welded shut:  without modifying  either the browser or the Kerberos libraries,  there is no way to automatically request and inject a service ticket on behalf of the user.

It would be possible for the user to do it explicitly, though.  That might be an OK stop-gap measure.  Again, a custom client of some sort could fetch the service ticket and push it into the Kerberos credential cache.

I think the most straight forward path would be to :

  • Extend the Kerberos libraries to be able to talk Web Sockets as a tunnel for the Kerberos wire protocol.
  • Allow a krb5.conf option that will specify that the KDC is reachable via websockets.  This would be something along the lines of an krb5.conf line

kdc = wss://kerberos.younglogic.com/kdc

  • This value should also be available as a SRV record out of DNS:

NAME: _kerberos._wss

TYPE: SRV:

VALUE:wss://kerberos.younglogic.com/kdc

As a simple proof of concept,  a websocket proxy can run on the client, listening on localhost:88 and talking via Websockets to the KDC.  Then the krb5.conf file can point to the local proxy instead of the KDC Websocket proxy.

Websockets is a simple enough protocol that writing it into the Kerberos code base should not be prohibitive.  If desired,  it could be done as a separate shared object for the general consumption of the system.

It is not necessary to run the TGT fetching code over wss,  the SSL version of web sockets, as the handshake already sets up encryption.  But there is no drawback to running the whole thing over SSL and it will mask any KDC traffice that is not encrypted.

An additional advantage is that now kpasswd can be run on the same port as the rest of the KDC based services, just on a different URL.

Since Websockets is supported by all the major browsers,  making browser plugins to communicate with the KDC is viable.

There might well be other issues of scale:  protecting against DOS attacks and the like, but there is a path forward to a secure WebSSO.

9 thoughts on “The Path to Kerberos over Port 443

  1. Heimdal already implements talking to the KDC over HTTP, but this will be incompatible, right?

  2. Markus. Yes, you are right. We are working on doing just that. Specifically, we are looking to get MS-KKDCP support into MIT Kerberos.

  3. MS-KKDCP support in MIT Kerberos and Heimdal would be very useful indeed!

    One thing I have not yet understood about MS-KKDCP is how the client is meant to discover the server URL. The Microsoft spec only says “The KKDCP client is configured with the URL of the KKDCP server”, which is not very helpful.

    With the normal KDC protocol, there is the DNS SRV record for _kerberos._tcp.realm.com pointing at the domain name of the kdc of REALM.COM. Is there already an equivalent discovery convention defined for the KKDCP protocol? If not, I think that is definitely needed.

    A sys-admin with thousands of hererogeneous clients surely would *much* prefer to just have announce their KKDCP server via DNS for their realm once and for all, rather than having to explain to every owner of a client computer in what config file they have to manually add the KKDCP URL. Zero client-side configuration is very important, but often forgotten by the invendors of new authentication protocols.

  4. There are a couple options. One is to do a SRV record for HTTP separate from TCP, and the other is to use the TCP record like this:

    http://hurl
    vs
    tcp://url

    We are doing that for the config file, but it might break things as the DNS level. I’m leaning toward a third SRV record for HTTP, but would like some input.

  5. I think that needs some discussion and writing up of a specification, and ideally should involve the authors of both MS-KKDCP and whatever service-discovery protocol is to be used, e.g. RFC 2782 for DNS SRV.

    Reading the SRV record spec at https://tools.ietf.org/html/rfc2782, the Target field of a SRV record MUST contain the domain name of a target hostname, with an A or AAAA address record. RFC 2782 was really mainly written with UDP and TCP in mind and currently appears to have no provisions for providing URLs rather than just hostnames and port numbers as targets.

    That is a shame, because if you use HTTPS or HTTP, you really want to be able to specify not just a domain name and port number, but also a path. If the path part of the URL is constrained to remain empty, you could not reuse an existing HTTPS server and associated SSL certificate to install a KKDCP server, and would have to obtain an extra SSL certificate for each KKDCP server.

Leave a Reply

Your email address will not be published. Required fields are marked *