We are going to set up a DHCP failover with dynamic DNS.
This article is part of the Homelab Project with KVM, Katello and Puppet series.
Homelab
We have two CentOS 7 (minimal) servers installed which we want to configure as follows:
admin1.hl.local (10.11.1.2) – will be configured as a DHCP master server
admin2.hl.local (10.11.1.3) – will be configured as a DHCP slave server
Both servers have SELinux set to enforcing mode.
See the image below to identify the homelab part this article applies to.
Software
Software used in this article:
- CentOS 7
- DHCP 4.2
Configure Master DHCP Server
Installation and Firewall
Install packages and ensure that the service is enabled:
[admin1]# yum install dhcp [admin1]# systemctl enable dhcpd
Configure firewall to allow DHCP traffic (we use iptables):
[admin1]# iptables -A INPUT -p udp -m state --state NEW -m udp --dport 67 -j ACCEPT
Allow DHCP peer communication from admin2:
[admin1]# -A INPUT -s 10.11.1.3/32 -p tcp -m state --state NEW -m tcp --dport 647 -j ACCEPT
Master dhcpd.conf Configuration
Open the file /etc/dhcp/dhcpd.conf
and configure as per below.
Note that the parameter mclt (Maximum Client Lead Time) must be defined on the master server but must not be defined on the slave server. The parameter split is another parameter that should be defined on the primary and omitted from the configuration on the secondary. It is worth noting that the communication between failover nodes is neither encrypted nor authenticated.
failover peer "failover-dhcp" { primary; # This defines the master address 10.11.1.2; port 647; peer address 10.11.1.3; peer port 647; max-response-delay 60; max-unacked-updates 10; mclt 3600; split 128; # 128 is balanced; use 255 if primary is 100% responsible until failure load balance max seconds 3; } authoritative; allow booting; allow bootp; next-server 10.11.1.4; # Katello TFTP filename "pxelinux.0"; default-lease-time 86400; # 1 day max-lease-time 86400; # 1 day ddns-update-style interim; update-static-leases on; one-lease-per-client on; # We generated the rndc-key when setting up DNS servers key "rndc-key" { algorithm hmac-md5; secret "T0+1uWvaiKLkhWutTNhsGvLw7m4CXbjHr+3CrDwQP5ZMNHeRSvghg2XxQvT3uGVwNle9oMvBEcjB+4GEPDK1Qg=="; }; # We created zones when setting up DNS servers zone 1.11.10.in-addr.arpa { primary 10.11.1.2; key "rndc-key"; } zone hl.local { primary 10.11.1.2; key "rndc-key"; } subnet 10.11.1.0 netmask 255.255.255.0 { option subnet-mask 255.255.255.0; option broadcast-address 10.11.1.255; option routers 10.11.1.1; option domain-name-servers dns1.hl.local, dns2.hl.local; option domain-search "hl.local"; pool { failover peer "failover-dhcp"; range 10.11.1.40 10.11.1.59; } } # DHCP leases for PXE boot host ldap1 { hardware ethernet 00:22:FF:00:00:11; fixed-address 10.11.1.11; option host-name "ldap1"; } host ldap2 { hardware ethernet 00:22:FF:00:00:12; fixed-address 10.11.1.12; option host-name "ldap2"; } host monitoring { hardware ethernet 00:22:FF:00:00:13; fixed-address 10.11.1.13; option host-name "monitoring"; } host syslog { hardware ethernet 00:22:FF:00:00:14; fixed-address 10.11.1.14; option host-name "syslog"; } host storage1 { hardware ethernet 00:22:FF:00:00:15; fixed-address 10.11.1.15; option host-name "storage1"; } host storage2 { hardware ethernet 00:22:FF:00:00:16; fixed-address 10.11.1.16; option host-name "storage2"; } host db1 { hardware ethernet 00:22:FF:00:00:17; fixed-address 10.11.1.17; option host-name "db1"; } host db2 { hardware ethernet 00:22:FF:00:00:18; fixed-address 10.11.1.18; option host-name "db2"; } host proxy1 { hardware ethernet 00:22:FF:00:00:19; fixed-address 10.11.1.19; option host-name "proxy1"; } host proxy2 { hardware ethernet 00:22:FF:00:00:20; fixed-address 10.11.1.20; option host-name "proxy2"; } host web1 { hardware ethernet 00:22:FF:00:00:21; fixed-address 10.11.1.21; option host-name "web1"; } host web2 { hardware ethernet 00:22:FF:00:00:22; fixed-address 10.11.1.22; option host-name "web2"; } host backup { hardware ethernet 00:22:FF:00:00:23; fixed-address 10.11.1.23; option host-name "backup"; }
Harden file permissions because of the plaintext rndc-key:
[admin1]# chmod 0600 /etc/dhcp/dhcpd.conf
Test the configuration file:
[admin1]# dhcpd -t -cf /etc/dhcp/dhcpd.conf
Restart the service:
[admin1]# systemctl restart dhcpd
Check leases:
[admin1]# tail /var/lib/dhcpd/dhcpd.leases
Configure Slave DHCP Server
Installation and Firewall
This part is the same as for the master server.
Install packages and ensure that the service is enabled:
[admin2]# yum install dhcp [admin2]# systemctl enable dhcpd
Configure firewall to allow DHCP traffic (we use iptables):
[admin2]# iptables -A INPUT -p udp -m state --state NEW -m udp --dport 67 -j ACCEPT
Allow DHCP peer communication from admin1:
[admin2]# -A INPUT -s 10.11.1.2/32 -p tcp -m state --state NEW -m tcp --dport 647 -j ACCEPT
Slave dhcpd.conf Configuration
Open the file /etc/dhcp/dhcpd.conf
and configure the following:
failover peer "failover-dhcp" { secondary; # This defines the slave address 10.11.1.3; port 647; peer address 10.11.1.2; peer port 647; max-response-delay 60; max-unacked-updates 10; load balance max seconds 3; } authoritative; allow booting; allow bootp; next-server 10.11.1.4; # Katello TFTP filename "pxelinux.0"; default-lease-time 86400; # 1 day max-lease-time 86400; # 1 day ddns-update-style interim; update-static-leases on; one-lease-per-client on; # We generated the rndc-key when setting up DNS servers key "rndc-key" { algorithm hmac-md5; secret "T0+1uWvaiKLkhWutTNhsGvLw7m4CXbjHr+3CrDwQP5ZMNHeRSvghg2XxQvT3uGVwNle9oMvBEcjB+4GEPDK1Qg=="; }; # We created zones when setting up DNS servers zone 1.11.10.in-addr.arpa { primary 10.11.1.2; key "rndc-key"; } zone hl.local { primary 10.11.1.2; key "rndc-key"; } subnet 10.11.1.0 netmask 255.255.255.0 { option subnet-mask 255.255.255.0; option broadcast-address 10.11.1.255; option routers 10.11.1.1; option domain-name-servers dns1.hl.local, dns2.hl.local; option domain-search "hl.local"; pool { failover peer "failover-dhcp"; range 10.11.1.40 10.11.1.59; } } # DHCP leases for PXE boot host ldap1 { hardware ethernet 00:22:FF:00:00:11; fixed-address 10.11.1.11; option host-name "ldap1"; } host ldap2 { hardware ethernet 00:22:FF:00:00:12; fixed-address 10.11.1.12; option host-name "ldap2"; } host monitoring { hardware ethernet 00:22:FF:00:00:13; fixed-address 10.11.1.13; option host-name "monitoring"; } host syslog { hardware ethernet 00:22:FF:00:00:14; fixed-address 10.11.1.14; option host-name "syslog"; } host storage1 { hardware ethernet 00:22:FF:00:00:15; fixed-address 10.11.1.15; option host-name "storage1"; } host storage2 { hardware ethernet 00:22:FF:00:00:16; fixed-address 10.11.1.16; option host-name "storage2"; } host db1 { hardware ethernet 00:22:FF:00:00:17; fixed-address 10.11.1.17; option host-name "db1"; } host db2 { hardware ethernet 00:22:FF:00:00:18; fixed-address 10.11.1.18; option host-name "db2"; } host proxy1 { hardware ethernet 00:22:FF:00:00:19; fixed-address 10.11.1.19; option host-name "proxy1"; } host proxy2 { hardware ethernet 00:22:FF:00:00:20; fixed-address 10.11.1.20; option host-name "proxy2"; } host web1 { hardware ethernet 00:22:FF:00:00:21; fixed-address 10.11.1.21; option host-name "web1"; } host web2 { hardware ethernet 00:22:FF:00:00:22; fixed-address 10.11.1.22; option host-name "web2"; } host backup { hardware ethernet 00:22:FF:00:00:23; fixed-address 10.11.1.23; option host-name "backup"; }
Harden file permissions because of the plaintext rndc-key:
[admin2]# chmod 0600 /etc/dhcp/dhcpd.conf
Restart the service:
[admin2]# systemctl restart dhcpd
One thing to note in dhcpd.conf:
Setting FQDN in (option host-name) while (option domain-name) and (option-domain-name-servers) are set will cause your DNS to create records with duplicate tlds, meaning it will create something like storage1.hl.local.hl.local.
Just set option host-name to “storage” instead of “storage1.hl.local” and you should be fine.
Thanks, yes, I’ve just checked my config, and will update the article.
Perfect
works fine with me
Hi
Don’t you need to install foreman proxy on DHCP server? How your katello is communicating with this DHCP server?
I don’t, because I use PXE boot with static DHCP leases based on MAC address.
I provide Katello with a MAC address when provisioning a new VM and DHCP server issues a static lease.
Hi Tomas,
I really like your tutorial, however, I cannot make it working.
named.conf
include “/etc/named.rfc1912.zones”;
include “/etc/named.root.key”;
include “/etc/rndc.key”;
# Allow rndc management
controls {
inet 127.0.0.1 port 953 allow { 127.0.0.1; } keys { “rndc-key”; };
};
# Limit access to local network
acl “acjo_infra” {
127.0.0.0/8;
10.123.116.0/24;
10.10.72.0/24;
};
options {
listen-on port 53 { 127.0.0.1; 10.123.116.2; }; ## netserv1
listen-on-v6 { none; };
directory “/var/named”;
dump-file “/var/named/data/cache_dump.db”;
statistics-file “/var/named/data/named_stats.txt”;
memstatistics-file “/var/named/data/named_mem_stats.txt”;
tcp-clients 50;
# Disable built-in server information zones
version none;
hostname none;
server-id none;
recursion yes;
recursive-clients 50;
allow-recursion { acjo_infra; };
allow-query {
acjo_infra;
};
allow-transfer {
localhost;
10.123.116.3;
};
auth-nxdomain no;
notify no;
dnssec-enable yes;
dnssec-validation auto;
#dnssec-lookaside auto;
bindkeys-file “/etc/named.iscdlv.key”;
managed-keys-directory “/var/named/dynamic”;
pid-file “/run/named/named.pid”;
session-keyfile “/run/named/session.key”;
};
# Specifications of what to log, and where the log messages are sent
logging {
channel common_log {
file “/var/log/named/named.log”;
print-category yes;
print-severity yes;
print-time yes;
};
category lame-servers {
null;
};
category query-errors {
common_log;
};
category security {
common_log;
};
category client {
common_log;
};
category queries {
common_log;
};
category general {
common_log;
};
category default {
common_log;
};
};
zone “.” IN {
type hint;
file “named.ca”;
};
# Internal zone definitions
zone “acj.net” {
type master;
file “data/db.acj.net”;
allow-update { key rndc-key; };
notify yes;
};
zone “116.123.10.in-addr.arpa” {
type master;
file “data/db.116.123.10”;
allow-update { key rndc-key; };
notify yes;
};
DNS Server DIG – OK
[root@netserv1 ~]# dig google.com
; <> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <> google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<nslookup google.com
DNS request timed out.
timeout was 2 seconds.
Server: UnKnown
Address: 10.123.116.2
DNS request timed out.
timeout was 2 seconds.
DNS request timed out.
timeout was 2 seconds.
Any thoughts will be much appreciated
The error message suggests a firewall issue. Are your servers configured to allow inbound/outbound DNS traffic on both TCP and UDP ports?
Thanks, Thomas,
I just completely disabled the SELinux and, checked the firewall.
Now it’s working.
Thanks
That’s fine. Try setting SELinux to permissive mode and check the audit log to see if anything gets blocked. You can enable firewall logging to see if any traffic gets blocked.
Great Tomas,
I really liked this tutorial and you gave me some new ideas for lessons for my students.
But I have a question for you.
Doing tests I noticed that if the master primary DDNS is offline, the secondary DDNS correctly supplies the IP addresses trough dhcp service, but for it is not possible to update the primary DDNS server (…is offline.).
There is a possible configuration that allows the dhcp service on secondary to dynamically update “on board” DNS table with the new entries, and when the primary goes back online, the secondary transfers the modified table with the new entries dhcp?
Thanks in advance for your help.
Dario M.