About NetInvent

What we do:

Based in Melbourne Australia, NetInvent provides systems analysis, IT consultancy, software development and IT support services to a number of partners.

NetInvent provides technical support services to:

NetInvent provides software development and consultancy services to:

Configure bind9 as master/slave pair on CentOS / RHEL 5

There are plenty of HOWTO documents on this and I've discovered that nearly all of them are full of unnecessary fluff that can be both confusing and misleading. It's probably because they are reworks of older HOWTOs from the bind8 era. Configuring bind9 in master/slave is far easier and requires far fewer configuration changes than the existing HOWTOs suggest.

You need to edit the named.conf files on both systems. I'm assuming that you begin with a functioning but otherwise default configuration on both machines.

  • On the master machine, create a dns key and put it in a secure file that you can include.

    sudo dns-keygen > /etc/named-tsig-key.conf

    Then edit the output file: /etc/named-tsig-key.conf so it looks something like this:

    key ddns_key
    {
      algorithm hmac-md5;
      secret "lw8MPJFqapeAG3ehTuvDBPUhRWzX1hyz5Ov3UvIXhmGh4XkPKIcPNCsz5f8v";
    };
    

    Where the hex string is the one you just generated (not the one I've used as an example), which you should find in the file, because we just put it there.

    Fix up the permissions on the key file:

    sudo chmod og-rw /etc/named-tsig-key.conf
    sudo chown named:named /etc/named-tsig-key.conf
    
  • Include the dns key file in your named.conf on both machines:

    In your named.conf, after the logging section in named.conf add:

    include "/etc/named-tsig-key.conf";

    You can call this key file whatever you like, and put it wherever you choose (think is most secure), but I've put mine in /etc/ and named it in a way that makes sense to me.

  • Copy the key file you generated on the master to the slave machine. You will need to put it in the same place and ensure that the permissions and ownership are the same as used on the master. There are lots of ways you could copy the file, from sftp/scp to simple cut and paste from one putty session to another.
  • Add server descriptions to both machines following the include directive:
    server 123.456.789.123 {
        keys {  ddns_key;
        };
    };
    

    The address here is the address of the other machine. If you are on the master, list the address of the slave. If you are on the slave, list the address of the master.

    You need to use an IP here, don't use the server's name.

    This directive tells bind that it should use the key we generated for communication with that server.

  • Add the zones to the slave configuration:

    I'm going to assume you already know how to add zones to the master, and that they are already configured - there is no additional change required to the master. The master does not need any special configuration to serve zones to the slave. Setting up an ordinary master zone is nothing specific to the master-slave set-up, so no point going into it here, you can find info on it almost anywhere.

    There is already an example internal slave zone in the default config file in the internal view:

    //zone "my.slave.internal.zone" {
    //      type slave;
    //      file "slaves/my.slave.internal.zone.db";
    //      masters { // put master nameserver IPs here
    //      127.0.0.1;
    //    } ;
    // put slave zones in the slaves/ directory so named can update them
    

    However, if you are using your slave as a second nameserver of an authoritative pair (and this is probably the reason you want to set up master slave) you need to put your slave zones in the external view not the internal, or else your slave nameserver will not serve them to anyone else. You don't really need the zone in internal view at all on the slave, as internal look-ups on the name through localhost_resolver will do an external DNS lookup (which might end up eventually looking at our external view anyway) and then be cached - one external lookup, hardly a big overhead, and saves the complexity of adding the zone to different views.

    So for a typical zone, add something like this to the external view:

    zone "mydomain.tld" IN {
      type slave;
      file "slaves/db.mydomain.zone";
      masters { 123.456.789.122; }; // The IP of the master server
    };
    
  • So, that's all you really need to do to get master-slave working. Most of the HOWTO docs I found suggested making all kinds of pervasive changes to named.conf, particularly in the options section. When I looked at what those changes were intended to do, they either replicated default behaviour and were thus utterly pointless, or they were actually wrong and would only cause trouble.

    You can do other stuff, like enabling zone transfers to the slave on the master, but there's really no need to do that.

    All you need to get a working setup is the key declaration, a server declaration, and addition of the slave zones on the slave server (assuming the zones already exist on the master).

    All the other changes that people suggest are simply not necessary to get a working master-slave pair under CentOS / RHEL 5.X using bind9, and are as likely to result in harm rather than any benefit. The defaults of bind9 are pretty much what you want, and I don't recommend changing any of them unless you really know why you are doing it.

Basic configuration of bind9 (named) on CentOS / RHEL 5

The basics:

sudo yum bind9
sudo chkconfig named on

OK, now you've installed bind but want to know where the examples are, or how to set up the configuration files. The bind configuration samples are in:

/usr/share/doc/bind-9.x.x/sample/etc/ and /usr/share/doc/bind-9.x.x/sample/var/

Copy the default configuration files above to /etc/ and /var/named/ respectively. If you are serving several local domains. In addition, I suggest you create a named.conf.local file or something similar that contains all the zones for your system, and include it into your main configuration file.

Comment out the example zone definitions in the internal view.

If you intend to be authoritative nameserver for a zone, add it to your external view using the format show in the example zones in the internal view. You will need to create a zone description file in /var/named, which is beyond the scope of this simple explanation.

The bind executable is in /usr/sbin/named ... to test your configuration before running properly as a service, run with -g to run in the foreground and dump to stdout, -d controls debug level

You should probably also add -u named to run as the 'named' user, because otherwise you will run as the current user, which is almost certainly going to cause problems, even if you are root :)

e.g. sudo named -g -u named

You can use dns-keygen to generate DNS TSIG keys (no, it doesn't need any complex parameters, it just spits out a key to the stdout, or wherever you pipe it).

You will need to edit /etc/named.conf to replace the note about this with a real key if you have a master/slave config. Otherwise comment out that whole key section because you don't need it.

This key (if you use it) is a 'secret', you need to get it to the other machines securely (you copy that key manually into a file on the other machine). It is not a certificate. Normally the key should be kept in a file with no read permission for group or others and included into the main config file, which (allegedly) needs to be globally readable (though I suspect this is not entirely true).

To check a bind config file for errors:

named-checkconf /etc/named.conf

named-checkzone domainname.tld /var/named/db.domainname.tld.zone

Assuming that you have called your zone file db.*.zone

When you've finished configuring, sudo service named start (or restart if you already started it).

Finally, you need to open up the ports for bind9. Traditionally, bind has used port 53, and doing anything else is more likely to cause trouble, despite the 'security benefits'. Ultimately, if you are running bind as anything other than a caching nameserver, then you want people to be able to find you.

You should probably open up both UDP and TCP on port 53. While some will say that UDP is enough, there are some servers that only use TCP, so again, you're asking for trouble if you try to avoid opening it for TCP as well. I can't see any realistic benefit of not opening it for both anyway. If bind has a vulnerability, it's probably not going to be restricted to TCP connections, and returning to the point of this, a bind that other people can't see doesn't need any open ports, and one that other people do need to see should be as conformant and interoperable as possible with other nameservers; if people can't find your servers, your service is useless.

Your iptables is going to need something like the following in it...

-A INPUT -p udp -m udp --dport 53 -m state --state NEW -j ACCEPT
-A INPUT -p tcp -m tcp --dport 53 -m state --state NEW -j ACCEPT

How you add these is up to you. I maintain my iptables file manually, but many people prefer to use the iptables administration tool.

What FTP daemon to use with CentOS or RHEL 5.X

What ftp daemon to use on CentOS or RHEL? I recommend vsftpd - you can install it through yum and it's very secure.

The set-up info on the vsftpd site could be better though. In particular, there is no explanation of how vsftpd uses pam to authenticate.

Look in /etc/pam.d/vsftpd and /etc/pam/ftp or whatever you've set in the pam_service_name option e.g. ftp=/etc/pam/ftp to see how pam is set up for this service.

After editing passwords for vsftpd use something like db_load -T -t hash -f accounts.tmp accounts.db

Where you have your users and passwords in accounts.tmp, with usernames and passwords on alternate lines. You might find some contradictory instructions about on the net, but they won't work for CentOS 5.X

CentOS and RHEL Access and Permission Problems

Trying to configure mail systems and you're hitting mysterious 'access denied' or 'permission denied' issues, even though permissions allow access? This often happens when trying to get postfix and dovecot to talk to each other.

The problem is most likely SELinux. Most people cop out by disabling SELinux; and if you disable it, it might solve your problem. In some cases, SELinux appears to interfere with access even when disabled - do a full rebuild of the permissions if you seem to have this problem. Check out this guide to CentOS security for information on how to enable and disable SELinux, and how to fix your security without disabling it.

Users of Ubuntu may experience similar problems due to AppArmor. Problems are usually resolved by setting the AppArmor properties correctly.

Network Services don't work

You've installed a package, configured it, started it up and it seems to be running fine, but nothing is happening.

Did you forget to add iptables rules for the ports used by your new service? Don't forget that bind9 uses UDP as well as TCP.

Edit /etc/sysconfig/iptables and add rules to open up the necessary ports. You can also use iptables -e commands, but this stops you putting useful comments in your iptables file because iptables gets auto-generated. OTOH, don't hand edit iptables unless you are confident you aren't going to save a broken one and lock yourself out of the system. Never run system-config-securitylevel unless you want to trash your hand-edited iptables file.

Don't forget to 'service iptables restart' after making updates to the file.

Use 'netstat' to debug ports and service issues. For example, netstat -l -t -u -p -e will give a nice display of listening tcp and udp ports. Add --numeric-ports to see port numbers instead of names. The man page for netstat is fairly comprehensible, unlike some.

RHEL/CentOS/Linux Handy Hints

  • You've moved the location of an executable but the shell keeps trying to run the old one and giving you file not found error?

    Shell path caching is the problem. Use PATH=$PATH to reset the shell's path cache.

  • Use nmap to scan your own open ports for vulnerabilities, or just to check that you really have opened the ports you think you have.
  • Everything you need to know about site certificate generation can be found in this OpenSSL howto section.
  • Where did my install files go?
    rpm -ql <package>
  • Reset SQL root password (or any other user):
    use --init-file to start it up with:
    UPDATE mysql.user SET Password=PASSWORD('<new password>') WHERE User='<user>';
    FLUSH PRIVILEGES;
    Afterwards, delete the init file.
  • Some performance stats:
    • sudo yum install mysql-bench
      cd /usr/share/sql-bench
      ./test-create --user='<user>' --password='<password>'
    • uptime
    • free
    • hdparm -tT
    • top
    • iostat -x
    • vmstat
    • top

  • Choosing a disc access scheduler:
    # cat /sys/block/sda/queue/scheduler
    noop anticipatory deadline [cfq]
    # echo deadline > /sys/block/sda/queue/scheduler
    # cat /sys/block/sda/queue/scheduler
    noop anticipatory [deadline] cfq
  • bind named records not updating properly, or appear inconsistent or random but zone file looks fine:

    This usually means that somewhere you forgot to update a serial and new zone info is not propagating to slave servers. The best long-term solution is to (at least) use a script to 'wrap' edits to your zone files. The script runs sed at the end to update the serial. Other solutions involve putting all your zone info in a database and then building zone files from the db "automatically". This means you can't create a corrupt zone file by accident (nasty), and you can run as many nameservers off the db as you like, making multiple nameserver maintenance a breeze.

Syndicate content