We prefer to run our infrastructure on open platforms. For our DNS infrastructure we have chosen to run it on top of Red Hat Enterprise Linux version 5.x. Since we have deployed DNSSEC, we have run into a number of problems, and to save you the trouble of having to run into and solve these on your own, here’s a short breakdown:

IPv6

Since we operate a modern cutting-edge network, all our services have native IPv6 support. Security is of equal importance for us so we usually operate a two-tiered model where we have an ACL on both the switch as well as on the host-based firewall (so if there is an issue with one of the two, the other will hopefully still function). We did the same for IPv6 which means that we have an ACL on the switches behind which DNS servers sit and we used ip6tables on the servers themselves.

Unfortunately, this caused us some major headaches. First of all, IPv6 filtering is broken in Linux kernels ≤ 2.6.20. Red Hat uses kernel 2.6.18 for Enterprise Linux 5.x. This means that it is not possible to create stateful firewall rules (for TCP connections).

It is possible to work around this issue using some creative rule-writing skills. Unfortunately this triggered problem number 2: if you enable ip6tables this has disastrous effects on the MTU for IPv6. We only noticed this because we suddenly saw problems on our resolvers (that do DNSSEC validation). Suddenly, validations started failing because the resolver was unable to retrieve DNSKEY sets. When we traced back in our administration what had changed on the resolver, we noticed that the problems coincided with the enabling of ip6tables. Some further analysis by inspecting packet traces shows the cause: first of all, the MTU for IPv6 decreased from around 4K to around 1300 bytes (near to the minimum IPv6 MTU). This meant that not all DNSKEY answers would fit into a single packet. No problem, you would say, the packets will be fragmented. Well, as it turns out yes and no. Packets are indeed fragmented by the sender after path MTU discovery, but our receiving host failed to reassemble the fragments.

The only way to prevent these problems is to not use ip6tables. This would also be our advice to anyone running Red Hat Enterprise Linux 5.x, at least if you are using the server for DNS operations. Don’t use ip6tables, instead you should rely on the firewalling capabilities of your switches and other network infrastructure.

Update: from a number of e-mail exchanges with readers of this blog I have heard that everybody seems to be seeing different results. Some have no problems while others report that using ip6tables means that checks like the DNS-OARC Reply-Size Tester completely fail. So your mileage may vary but expect problems if you use ip6tables on your DNSSEC server system (resolver or authoritative).

Packaged BIND 9.3

A second problem we ran into more recently is the packaged version of BIND that comes with Red Hat Enterprise Linux 5.x. The version that comes packaged with the OS is a 9.3 variant of BIND with specific Red Hat patches applied to it. As an ordinary DNS server, this suffices, but if you want to serve out signed zones you run into the problem that it doesn’t support NSEC3.

The only solution is to take a Fedora package of a newer version and rebuild it. We have taken the latest BIND 9.7 release, which we found using rpmfind.net. This package requires some extra patching; here’s how you do it.

3. Instead, unpack it in a separate directory using rpm2cpio and cpio by using the following commands:
# cat bind-9.7.1-2.P2.fc13.src.rpm | rpm2cpio | cpio -i
15269 blocks

4. You will end up with a directory that contains all the files in the cpio archive. Now use the following commands to manually ‘install’ the source RPM:
# mv bind.spec /usr/src/redhat/SPECS/bind-9.7.1-2.P2.spec
# mv * /usr/src/redhat/SOURCES

5. Now you need to add a patch to the mix. The autoconf packages that come with RHEL 5.x are too old to support all the macros that are in the BIND 9.7 configuration scripts. This can easily be resolved by adding the following patch (download it here):
diff -u unpatched/configure.in patched/configure.in
--- unpatched/configure.in 2010-07-05 14:02:20.000000000 +0200
+++ patched/configure.in 2010-07-05 14:03:48.000000000 +0200
@@ -282,7 +282,8 @@
AC_C_INLINE
AC_C_VOLATILE
AC_CHECK_FUNC(sysctlbyname, AC_DEFINE(HAVE_SYSCTLBYNAME))
-AC_C_FLEXIBLE_ARRAY_MEMBER
+# RvR: this breaks things on RHEL5
+#AC_C_FLEXIBLE_ARRAY_MEMBER

#
# Older versions of HP/UX don't define seteuid() and setegid()

6. To add the patch, copy it to the /usr/src/redhat/SOURCES directory (we’ll assume you call it “bind97-ac.patch”) and edit the bind-9.7.1-2.P2.spec file in /usr/src/redhat/SPECS.

7. In the spec file, add the following line to the list of patches:
Patch300:bind97-ac.patch

8. Then add the following line in the %prep section:
%patch300 -p1 -b .97ac

9. You’re done. You can now build the RPMs (the package builds multiple RPMs) with the following commands:
# cd /usr/src/redhat/SPECS
# rpmbuild -bb ./bind-9.7.1-2.P2.spec

Once you have the RPMs, you can install the relevant ones just like you would install the regular package from Red Hat.

6 Comments to “Red-Hatted Trouble… IPv6 and BIND 9.7 on RHEL 5.x”

I have been in the same position and using your procedure with CentOS 5 to get a current copy of BIND. I’m curious now that RHEL6 is GA, have you done any testing with it? If so have you found any issues with the included BIND and do the issues with ip6tables still seem to be present.

I was able to follow to the tee the procedures above when building bind-9.7.1-2.P2. It worked great. Now I have the need to upgrade to bind-9.7.3 using the fedora src rpm. I followed the steps but it bombs out at: