How to setup DDNS in CentOS/RHEL Linux keeping SELinux active
If you may have a large LAN, maintaining the DNS and DHCP server on Linux can be time consuming if you edit the zones and the dhcpd.conf file by hand. As a consequence, DDNS updates for ISC dhcpd server and BIND9 have been available for a few years.
But SELinux and CentOS/RHEL the procedure explained in the hundreds of tutorials on the net about is not sufficient. Let's start with a good and short tutorial for Fedora, a very close cousin of CentOS/RHEL:
A very important step is to set the permissions, because you probably made the zone files from the root console:
chown named:named /var/named/var/named/intranet.zone
chown named:named /var/named/var/named/intranet.reverse.zone
chmod 770 /var/named/chroot/var/named
After that, set the security context for SELinux:
chcon system_u:object_r:named_zone_t intranet.reverse.zone
chcon system_u:object_r:named_zone_t intranet.zone
Now, everything should work, right? Well, you will get this error:
Mar 20 18:53:31 localhost kernel: audit(1174434811.548:82): avc: denied { write } for pid=6969 comm="named" name="named" dev=md3 ino=957224 context=root:system_r:named_t tcontext=system_u:object_r:named_zone_t tclass=dir
It seems the named process needs to write to the zone file and SELinux it does not let him. Use the swiss army knife of SELinux: tail /var/log/messages | audit2allow. You will find out that you need to allow named_t named_zone_t:dir write;.
To edit SELinux policies on CentOS you need do yum install selinux-policy-targeted-sources. This creates a the src directory in /etc/selinux/targeted.
Take the line that audit2allow spit out to you and add it to the file /etc/selinux/targeted/src/policy/domains/program/named.te. Run make load in the src/policy folder. Sweet! Now it should will work! Well... guess again, because
only the error message has changed, subtly:
Mar 20 19:19:40 localhost kernel: audit(1174436380.095:87): avc: denied { add_name } for pid=6970 comm="named" name="intranet.zone.jnl" scontext=root:system_r:named_t tcontext=system_u:object_r:named_zone_t tclass=dir
You will need some this line: allow named_t named_zone_t:dir add_name;
I'll save you the pain and give you all the lines that you need to add to named.te:
allow named_t named_zone_t:dir write;
allow named_t named_zone_t:dir add_name;
allow named_t named_zone_t:file create;
allow named_t named_zone_t:dir remove_name;
allow named_t named_zone_t:file write;
And, success!!
Mar 20 19:41:41 localhost named[7669]: client 127.0.0.1#33008: updating zone 'intranet/IN': adding an RR
Mar 20 19:41:41 localhost named[7669]: client 127.0.0.1#33008: updating zone 'intranet/IN': adding an RR
Mar 20 19:41:41 localhost dhcpd: Added new forward map from HP29674251632.intranet. to 192.168.1.252
Mar 20 19:41:41 localhost named[7575]: journal file intranet.zone.jnl does not exist, creating it
Mar 20 19:41:41 localhost named[7669]: client 127.0.0.1#33008: updating zone '1.168.192.in-addr.arpa/IN': deleting an rrset
Mar 20 19:41:41 localhost named[7669]: client 127.0.0.1#33008: updating zone '1.168.192.in-addr.arpa/IN': adding an RR
Mar 20 19:41:41 localhost named[7669]: journal file intranet.reverse.zone.jnl does not exist, creating it
Mar 20 19:41:41 localhost dhcpd: added reverse map from 252.1.168.192.in-addr.arpa. to HP29674251632.intranet.
Some Linux admins turn off SELinux just because of this extra configuration steps when you do something unusual, like Windows Domain authentication with kerberos/winbindd or , like in this case, Dynamic DNS updates. Remember that chcon, audit2allow and the targeted-sources package are your allies.
