[2352] in Kerberos_V5_Development

home help back first fref pref prev next nref lref last post

kerberos through the firewall

daemon@ATHENA.MIT.EDU (Doug MacEachern)
Fri Apr 18 16:37:42 1997

To: krbdev@MIT.EDU
Date: Fri, 18 Apr 1997 16:36:43 -0400
From: Doug MacEachern <dougm@opengroup.org>

As you know, this is a problem area for many organizations for various
reasons.  We've implemented a simple and flexible solution, which
requires (minimal) changes to the kerberos libraries.  I've included
some brief design and implementation notes below for comment.  If
anyone is interested in trying the patches against krb5-1.0 or
krb5-nt-alpha2 and the "krb5gw" program, let me know.

Regards,
-Doug

Motivation
----------

In a firewall environment, it is advantageous to use the HTTP protocol
to tunnel other protocols.  One application of this is for tunneling
the Kerberos protocol [RFC1510] (normally used on UDP port 88).  
Tunneling kerberos over TCP 80 will avoid the additional firewall
configuration normally needed to run kerberos in such an environment.

HTTP/Krb5 Protocol
------------------

This is an example of a HTTP/Krb5 protocol exchange.

Client->GW
POST http://www.foo.com/krb5gw HTTP/1.1
krb5-realm: target-realm
accept: protocol/krb5

base64 (<krb5 request>)
IP addresses of GW replicas
\n\n
GW->KDC
<Krb5 request> on port 88

KDC->GW
<Krb5 reply>

GW->Client

HTTP/1.1 200 OK
krb5-realm: target-realm
content-type: protocol/krb5
\n\n
base64(<krb5 reply>)

If a Kerberos error occurs, the following message is returned to the client:

HTTP/1.1 500 Internal Server Error
krb5-realm: target-realm
content-type: text/plain
krb5-error: <kerberos error code>
\n\n
<explanation>

Implementation Notes
--------------------

Here are some notes on this protocol:

- Need to keep HTTP protocol generic. I had a look at the HTTP/1.1
  spec and determined that we should use a HTTP POST method with the
  krb5 request in the body base64 encoded.  The reply will be returned
  from the HTTP/krb5 gateway in the message body in base64. 

- The function to modify in krb5 is lib/krb5/os/sendto_kdc.c::krb5_sento_kdc().

- There should be a new config parameter added to the krb5.conf file,
  "http-gateway = <host>".
  If this is found for a particular realm, then the http encap method
  would be used. If not, then the existing UDP protocol is used. Note
  there could be more than one http-gateway in a realm. They would all
  be listed and each one tried in order. 

- The HTTP request should include the target realm. The krb5 request
  should simply be forwarded to the HTTP gateway (even via proxies) with
  the data in the message body. There should also be a new header (an
  entity-header in HTTP/1.1 parlance). 
        "Krb5-realm : <realm-name>"
  This would be recovered by the gateway and used to locate a KDC for that realm.

- The HTTP-krb5 gateway could be implemented as a CGI program or
  server plugin. If the URL for the gateway were -
  "http://www.foo.com/krb5gw", the POST method carry the krb5
  request to this program appropriately. The request should use the
  accept header with "Accept: protocol/krb5". The response should
  reply with a content-type of "Content-type: protocol/krb5". 

- If the "http-gateway" is being used, the AS-request should be made
  with the http-gateway added to the address list. The http-gateway is
  always the host address of the system that will reissue the native
  krb5 request.  The use of HTTP proxies are transparent to the
  protocol. The modification would be in
  lib/krb5/krb/get_in_tkt.c::krb5_get_in_tkt(). 

- If the WWW-Authenticate: header contains a realm=<realm>, then this
  can be used in the request. An interesting effect of this proposal, is
  that much of the realm-to-domain mapping is done at the
  "http-gateway". This (error-prone) part of the Kerberos config is no
  longer needed at the client. 

Issues
------

1.  The client needs to discover the IP addresses of the gateway
replicas and put these addresses in its krb5 request. These addresses
could be discovered by putting them in a WWW-Authenticate response
returned by the gateway when an unauthenticated call is made.
Alternatively, they could be discovered via a GET special_URL request,
eg.  GET http://www.foo.com/bootinfo.html .  The former would probably
be better because the client would not need to know the
"bootinfo.html" name.  

2.  A krb5.conf file is needed to store HTTP/krb5 gateway addresses and
their realms.  

3.  When a client requests a krb5 ticket to an HTTP server that will
be accessed through a front end/gateway, the client should include
that gateway's address(es) in the krb5 request.  


Current working prototype notes 
-------------------------------

The `krb5_sendto_kdc' routine is now just a dispatcher who decides
which transport to use (udp or tcp), which function will carry out
the transaction and which function will find a list of potential kdc's
or HTTP gateways.  The default transport, naturally, is udp. 

One may change the transport via a new call
`krb5_sendto_kdc_transport', which takes three arguments.  

1) Transport protocol 
Currently one of UDP, HTTP or CLIENT_DEFINED.

2) Transport implementor 
Function pointer with the same prototype as krb5_sendto_kdc.
If this argument is NULL, the default transport function is used.  

The default HTTP function is `sendto_kdc_via_http'.   
A simple client who talks to the gateway using the protocol we've
outlined so far. 

The default UDP function is `sendto_kdc_via_udp'
Simply contains the body of the old krb5_sendto_kdc function.   

CLIENT_DEFINED has no defaults, as it's name implies, the client must
define all callback routines, the underlying transport may be whatever
the client chooses.

3) KDC or HTTP gateway locator
Function pointer with the same prototype as krb5_locate_kdc.
If this argument is NULL, the default location function for the given
transport is used.

The default HTTP function is `krb5_locate_http_gateway'
Looks in the kerberos configuration file "krb5.conf" for one or more
"http-gateway" tokens, containing the gateway server name(s) and optional
port number(s).

The default UDP function is `krb5_locate_kdc'
This function is already part of the kerberos API, unchanged.


Adding http-gateway addresses to AS-requests

The `krb5_get_in_tkt' function has been modified to use a new
function `krb5_http_gateway_hostlist' which finds http-gateway
addresses in krb5.conf, adding any, if found, to the request.  This
call also contains a hook so clients can determine gateway addresses
without the use of krb5 configuration files.

Transparency
------------

By default, with these modifications kerberos messages will be
transported over UDP as always.

With simple kerberos configuration file changes, existing kerberos
clients may take advantage of the Krb5/HTTP tunnel without
modification.

With the new hooks in place, kerberos clients may be written a such a
way that users behind a firewall can "download" or otherwise obtain a
kerberized client which requires no kerberos configuration 
modification or existance for that matter, in order to use the
Krb5/HTTP tunnel.   Provided TCP/80 or other TCP ports commonly used
for HTTP are accessable through the firewall, UDP 88 need not be open
for kerberos communications to take place.






home help back first fref pref prev next nref lref last post