IPTABLES AND BIND
Disclaimer
As always we do not warrant this information for any particular use and assume no liability. We offer it as information that may or may not help you in your quest to solve a problem. Your mileage may vary. This document describes how to modify security levels of your environment and we cannot stress strongly enough that you must take all necessary precautions to prevent a system compromise. This is beyond the scope of this article.
DNS External Access is not Working
You may have used an RPM, or built BIND yourself on your CentOS, Fedora, Debian, Ubuntu, SuSE environment and internal queries work fine but external queries and zone transfers fail.
It does not matter if you're running "split horizon" DNS (where internal/external views exist). Many people get so far, search the net and ultimately give up because they don't realize there is probably a software-based (kernel-based) firewall running on their *NIX system: IPTABLES or IP6TABLES.
For the purpose of this discussion it is expected that you are loged in as the superuser "root" and are at the '#' prompt.
To see if IPTables is configured to be running check your runlevel startup scripts (the quick way is with chkconfig):
#chkconfig
Then review the output to see if iptables and ip6tables is set to run on any specific runlevel. If it is try turning it off with:
#/etc/init.d/iptables stop
and
#/etc/init.d/ip6tables stop
Now perform your DNS lookup or zone request on your remote server and see if it works. If it does but did not previously then it was the iptables firewall blocking you. You may ask why not just leave it off? Well, it may be protecting other vulnerabilities on your system.
Before continuing let's restart your IPTables command:
#/etc/init.d/iptables start
and
#/etc/init.d/ip6tables start
You can see which rules are in the system by running the iptables list command:
#iptables --list
You can add the following "rules" to your iptables for both the INPUT and OUTPUT rulesets.
INPUT: Processing DNS Queries and Zone Transfer Requests
Standard DNS queries are typically handled on port 53 as UDP (fire and forget) requests. However, zone transfers need to be handled more reliably and so requires the TCP protocol. Therefore we need to create an INPUT rule for both UDP and TCP. These rules should be placed before the final reject all rules. In this case they are inserted at the beginning of the INPUT ruleset:
iptables -I INPUT 1 -p tcp -m tcp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -I INPUT 2 -p udp -m udp --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
OUTPUT: SENDING RESPONSES BACK TO CLIENT OR REMOTE NAMESERVER
IPTables also blocks outgoing traffic (including responses), so in order for NAMED/BIND to respond and send an answer back we have to tell IPTABLES it's also acceptable to allow the response traffic. In this case these rules are appended to the end of the OUTPUT rule as typically the OUTPUT ruleset is blank.
iptables -A OUTPUT -p tcp -m tcp --sport 53:65535 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p udp -m udp --sport 53:65535 --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
The rules should produce no errors and should take effect immediately.
You should now be able to do remote DNS queries from any external address to your nameserver. Too, zone transfers should work as well. If you want to be more secure you will want to confine zone (TCP) transfers to specific hosts. I left these rules as open to any originating host because you're just trying to get it working to begin with. Once it works you can begin experimenting with tightening the IPTables rules.
- Engineering





