Installing and upgrading BIND - some challenges and options
In a test environment, building and installing BIND is pretty simple - you just download and unpack the source code tarball, run the configure script (with the options of your choice, or just using the defaults) and then use make install to compile and install everything into the default directories. See Getting Started with BIND for some simple instructions on installing and configuring BIND.
But in a production environment, you will very likely have other constraints, including:
- There is already a version of BIND installed and running - you don't want to overwrite it until you're ready.
- It's often desirable to maintain the option of switching back to the previous version in case of unanticipated problems post-upgrade.
- You may be required to build BIND on another machine because your production environment doesn't have compilers installed.
- You may be building BIND centrally for distribution to many production machines that are widely dispersed.
Whatever your constraints or options are, you will need to develop your own administrative processes appropriate to your environment, but documented below are some ideas to get you started.
The default BIND build and installation
By default BIND will install in /usr/local and place files in these subdirectories of it:
- sbin - named and all the system administrative tools associated with BIND such as rndc, dnssec-keygen, named-checkconf etc..
- bin - tools for non-admin users - you'll find dig, host and nsupdate here
- lib - object code libraries
- share - (and various subdirectories) BIND's man pages
- include - C header files
In addition, BIND compiled with no change to the default directories will expect to use the following directories (relative to /)
- /etc - configuration files (such as named.conf, rndc.conf)
- /var/run - run-time files created and used by named
Building BIND for distribution/independent installation
In the simple case, you'll be building BIND on a machine with the same operating system version, hardware architecture, and version/location of other dependent packages (such as OpenSSL) as will be found in the target production environments. If you are doing anything other than this, then it's possible to use compiler and other options to make things work out, but the details are too specific for a generic article - we recommend reading the README file distributed with all versions of BIND, running configure --help for documentation on what other options are available, and checking your compiler reference manual for compiler/architecture options that might be needed.
So assuming that you're building on a compatible machine, or directly on your production host, then to make life easy for yourself you can put all the files associated with the new build under one directory - ideally one that identifies clearly what it contains. But as noted above, you may still want BIND to use the default run-time directories once you are running it in production. The example below shows the commands used to build BIND 9.9.6 using this method to place the installable files into /usr/local/bind-9.9.6/ but at the same time retain the default use of /etc and /var by the new binaries.
The example assumes that you've downloaded the source code to directory /home/builds and unpacked it there. There are two additional options (--enable-threads and --with-openssl) added to enable multi-threading and to enable the use of OpenSSL. (OpenSSL is required if you want to use DNSSEC.)
/home/builds/bind-9.9.6# ./configure --prefix=/usr/local/bind-9.9.6 --sysconfdir=/etc --localstatedir=/var --enable-threads --with-openssl (then wait for the configure step to complete) /home/builds/bind-9.9.6# make (and then, assuming that the make completed successfully): /home/builds/bind-9.9.6# make install
BIND is built - so now what?
Assuming that you're happy that the new build is performing as you'd expect - then apart from the process of getting the files to the target production machine(s), here are your options:
1. Run the new binaries directory from the new directories (which may be different from the current directory that BIND is running from).
(Not recommended - but sometimes useful for testing purposes)
- You will need to update any scripts that you use to manage or monitor named to use the new path.
- You will need to update $PATH (for all users).
- The man pages won't be updated.
2. Replace the existing binaries with the new versions (you can script this).
- A good system here is to maintain multiple versions of BIND but set up for each a script that copies the files from the 'build' directory structure into the production directory structure.
- You will need to stop BIND before the copy and then restart it afterwards.
- You won't need to update any scripts or $PATH variables.
- Don't forget (if you don't already have this as part of your structure) to back-up the currently installed and running version of BIND.
- It's easy to switch between versions, although it will require a stop and start of BIND each time.
3. Instead of moving files around, use links instead from the default install location to the BIND files in the new location (you can script this).
- This is very similar to option 2 above, except that instead of scripting to copy the files across, you script to create links instead.
- You will need to stop BIND before recreating the links to point to the new version, and then restart it afterwards.
- You won't need to update and scripts or $PATH variables.
- You may need to do an initial back-up of the currently-installed and running version of BIND first, and then convert the installation to one that is using links rather than the files directly.
- It will be easy to switch between versions, although it will require a stop and start of BIND each time.
Here are some sample script commands to link the new build:
for i in /usr/local/bind-9.9.6/sbin/*; do ln -f -s $i /usr/local/sbin; done for i in /usr/local/bind-9.9.6/bin/*; do ln -f -s $i /usr/local/bin; done
You shouldn't need to link the other files, but for updated man pages:
for Mandir in /usr/local/bind-9.9.6/share/man/* ; do \ Chapter=$( echo $Mandir | cut -f7 -d/ ) ; for Man in $Mandir/* ; do \ ln -f -s $Man /usr/local/man/$Chapter ; done ; done
Note that "Chapter" is the seventh field as delimited by "/".