Tricks to run Kerberized Zephyr through a NAT


Nick Martin

The Problem Part 1: IP Addresses encoded in packets

The main problem with Zephyr through a NAT is that the local address of the client is encoded in many of the outgoing packets. This wouldn't be so bad in straight Zephyr, as the NAT could rewrite packets, but in Kerberized (V4) Zephyr the local IP is also integrity protected.

Solution Part 1: munge_getsockname.c

The solution is to insert a stub library with LD_PRELOAD that intercepts calls to getsockname(2), which is the syscall used by both krb524init and libzephyr to determine the local address. This approach gets the internal IP substituted before it gets integrity protected by Kerberos.

Source code for the library is available here. It was inspired by tibind.c by nathan at 0x00 dot org and is in the public domain. You must run both krb524init and your zephyr client with this library in place. zhm does not need munging.

Use like so:

gcc -fPIC -shared -o munge_getsockname.so munge_getsockname.c -ldl
kinit -A
env LD_PRELOAD=./munge_getsockname.so FROMIP=10.1.2.3 TOIP=18.4.5.6 krb524init
env LD_PRELOAD=./munge_getsockname.so FROMIP=10.1.2.3 TOIP=18.4.5.6 owl

The Problem Part 2: Blocked Received Zephyrs

Another problem with Zephyr is that your client may have only talked to a subset of the zephyr servers when any zephyr server sends a UDP packet to the client. This fails because the NAT box does not have an association between the client and the hitherto unknown zephyr server.

Solution Part 2: Hardcode Zephyr servers in NAT config

The easiest solution is to hardcode the NAT to forward all packets from the zephyr servers in question to the client. Of course, this will be different depending on the NAT in question, but here is an example from a Linux iptables NAT:

iptables -t nat -A PREROUTING -p udp -i eth0 -d 18.4.5.6 -s 18.7.15.82 -j DNAT --to 10.1.2.3
iptables -t nat -A PREROUTING -p udp -i eth0 -d 18.4.5.6 -s 18.7.15.75 -j DNAT --to 10.1.2.3
iptables -t nat -A PREROUTING -p udp -i eth0 -d 18.4.5.6 -s 18.158.0.53 -j DNAT --to 10.1.2.3

This has the obvious disadvantage of only allowing one client behind the NAT to use zephyr. In theory, it wouldn't be hard to write a Linux ip_nat module for zephyr that would allow multiple clients and would not require hardcoding the addresses of zephyr servers. However, to my knowledge no one has done so, and I'm not going to do it.


Copyright 2006 Nick Martin. All rights reserved.
Last modified: Tue Nov 21 21:25:10 PST 2006