790 likes | 981 Views
Running Secure DNS Servers Jay Beale Lead Developer, Bastille Linux Security Team Director, MandrakeSoft. Running Secure DNS Servers. Installing and configuring Unix BIND DNS server Simulating attacks and information probes for security assurance
E N D
Running Secure DNS ServersJay BealeLead Developer, Bastille LinuxSecurity Team Director, MandrakeSoft
Running Secure DNS Servers • Installing and configuring Unix BIND DNS server • Simulating attacks and information probes for security assurance • Implementing security "best practices" for DNS configuration • Advanced Methods: Chroot the Daemon, Run as Non-superuser • Split Horizon?
How Does DNS Work? • DNS provides mapping between machine names and IP addresses. • Name servers answer queries they have information for and often hunt for the rest in a recursive query. • Root Servers are the starting point in a recursive query.
Installing Unix BIND DNS server • Grab source for BIND at: ftp://ftp.isc.org/isc/bind/src/cur/bind-8/bind-src.tar.gz
Building BIND • On Solaris: # tar -xzvf bind-src.tar.gz # cd src # vi port/solaris/Makefile.set Onto configuring build process...
Configuring BIND Makefile.set (Solaris) • Append DESTINC and DESTLIB lines: 'DESTINC=/usr/local/include' 'DESTLIB=/usr/local/lib' to get the following:
Solaris Makefile.set 'CC=gcc' 'CDEBUG=-g -O2' 'DESTBIN=/usr/local/bin' 'DESTSBIN=/usr/local/sbin' 'DESTEXEC=/usr/local/sbin' 'DESTMAN=/usr/local/share/man' 'DESTHELP=/usr/local/lib' 'DESTETC=/usr/local/etc' 'DESTRUN=/usr/local/etc' 'LDS=:' 'AR=/usr/ccs/bin/ar cru' 'LEX=/usr/ccs/bin/lex' 'YACC=/usr/ccs/bin/yacc -d' 'SYSLIBS=-ll -lnsl -lsocket' 'INSTALL=/usr/ucb/install' 'MANDIR=man' 'MANROFF=man' 'CATEXT=$$N' 'PS=ps -p' 'RANLIB=/usr/ccs/bin/ranlib' 'DESTINC=/usr/local/include' 'DESTLIB=/usr/local/lib'
Compiling BIND (Solaris) # make depend # make # make install
Installing BIND on Linux • Find the location for your Linux distribution's most recent BIND package. # rpm -ivh http://path_to_package/bind-8.2.2_P7-x.rpm
Configuring BIND • BIND 8 and 9, unlike BIND4, use named.conf. • Syntax has changed, but you can use named-bootconf to convert your old named.boot to the new format. • Zone (data) files have not changed syntax.
Sample named.conf File 1/3 acl internal { 192.168.1.0/24 ; }; options { directory "/var/run/named"; listen-on {192.168.1.2 ; }; allow-recursion { internal ; }; allow-query { internal ; }; };
Sample named.conf File 2/3 zone "." { type hint; file "db.cache"; }; // bastille-linux.org maps to the 192.168.1.0/24 network zone "bastille-linux.org" { type master; file "db.bastille-linux.org"; allow-query { any ; }; };
Sample named.conf File 3/3 zone "1.168.192.in-addr.arpa" { type master; file "db.192.168.1"; allow-query { any; }; }; zone "0.0.127.in-addr.arpa" { type master; file "db.127.0.0"; allow-query { 127.0.0.1 ; }; };
Best Practice: Logging • BIND 8 adds the capability for enhanced logging. • Channel: a method (syslog priority, file, stderr or bit bucket) for logging data - Category: a type of data to log, based on hard-coded names in the BIND 8 program
BIND 8 Logging Channels 1/2 ( For syslog, format is: syslog facility; severity severity; ) • channel info_syslog { syslog daemon; severity info; }; • channel some_file { file "your_file"; severity error; };
BIND 8 Logging Channels 2/2 • channel stderr_fd { file "<stderr>"; severity critical; }; • channel null_gone { null; };
BIND 8 Logging Categories 1/3 Quoted from DNS and BIND book: • default - wildcard, maps to ALL • cname - CNAME errors • config - configuration file errors • db - database operations • eventlib - system events • insist - internal consistency check failures • lame-servers - Detection of bad delegation
BIND 8 Logging Categories 2/3 Quoted from DNS and BIND book: • load - zone loading messages • maintenance - Maintenance events (e.g. system queries) • ncache - Negative caching events • notify - Asynchronous change notifications • os - problems with the operating system • packet - decodes of packets received and sent • panic - problems that cause the shutdown of the server
BIND 8 Logging Categories 3/3 Quoted from DNS and BIND book: • parser - Parsing of the configuration file. • queries - Analogous to BIND 4's query logging • response-checks - Malformed responses, unrelated addt'l information,... • security - approved / unapproved requests • statistics - periodic reports of activities • update - dynamic update events • xfer-in / xfer-out - Zone transfers from remote/local nameserver to local/remote nameserver
Additional Logging BIND 8 has strong default logging, but we can add a security log for certain important categories. Append to named.conf: logging { channel security { file "/var/adm/bind-security" versions 4 size 10m; print-time yes; }; category insist {security;}; category os { security; }; category panic {security;}; category security {security;}; category xfer-out { security; }; category update {security; }; };
Interesting Part of the Talk • Take the role of an attacker! • DNS gives out a whole lot of useful information • Most syadmins don't think from the attacker's point of view! • Bad habits from when the Internet was a more exclusive neighborhood.
Interesting Part of the Talk • Take the role of an attacker! • DNS servers have traditionally made good cracking targets! • BIND has had a number of security vulnerabilities • BIND runs as root by default
"Profiling the Target" • Find out the target's primary nameservers: [jay@max jay]$ nslookup Default Server: ns.my.isp Address: 10.0.0.1 > set q=ns > dumb.target.jay Server: ns.my.isp Address: 10.0.0.1 Non-authoritative answer: dumb.target.jay nameserver = dumb.target.jay dumb.target.jay nameserver = ns2.dumb.target.jay Authoritative answers can be found from: dumb.target.jay internet address = 192.168.1.85
Zone Transfer of their Zone 1/2 [jay@max zone]# dig @192.168.1.85 dumb.target.jay axfr ; <<>> DiG 8.2 <<>> @192.168.1.85 dumb.target.jay axfr ; (1 server found) $ORIGIN dumb.target.jay. @ 20H IN SOA ns1 hostmaster.dumb.target.jay ( 2000111001 ; serial 5H ; refresh 1H ; retry 4d4h ; expire 1D ) ; minimum 1H IN NS dumb.target.jay. 20H IN NS ns.dumb.target.jay. 20H IN NS ns.dumbs.isp. 20H IN A 192.168.1.85 1D IN HINFO "Pentium 133" "Red Hat 6.1" 1D IN MX 10 mail
Zone Transfer of their Zone 2/2 mail 1D IN A 192.168.1.2 really 1D IN A 192.168.1.20 1D IN TXT "Admin's Trusted Workstation" 1D IN HINFO "Athlon 850" "Red Hat 6.1" rather 1D IN A 192.168.1.15 1D IN HINFO "Pentium 266" "Mandrake 7.1" serious 1D IN CNAME extra extra 1D IN A 192.168.1.80 ns 1D IN A 192.168.1.30 r_g 1D IN A 192.168.1.68 roblimo 1D IN MX 10 r_g 1D IN A 192.168.1.44 tahara 1D IN A 192.168.1.27
Reactions? Two commands and we have a full dump of their zone data! Hey, check out that TXT record! Which host appears to be the SysAdmin's workstation? Will other machines potentially trust this one more? Maybe they all trust it for rsh-based backups even?!!!!
Reactions? 2/2 Check out the HINFO records! I note the SysAdmin's trusted box, running Red Hat 6.1. I have a small kit of Red Hat 6.1 exploits -- which machine should I try them on?
Defense to Zone Transfers Should I really let everyone have this much information? Directives: • allow-transfer { }; • allow-recursion { }; • allow-query { };
Defense to Zone Transfers 2/2 Let's look at the named.conf file from before, this time with a few additions!
named.conf.restricted_axfr 1/3 acl internal { 192.168.1.0/24 ; }; acl secondaries { 192.168.1.3 ; 192.168.2.3 ; }; options { directory "/var/named/"; listen-on {192.168.1.2 ; }; allow-recursion { internal ; }; allow-query { internal ; }; allow-transfer { none; }; };
named.conf.restricted_axfr 2/3 zone "." { type hint; file "db.cache"; }; // bastille-linux.org maps to the 192.168.1.0/24 network zone "bastille-linux.org" { type master; file "db.bastille-linux.org"; allow-query { any ; }; allow-transfer { secondaries; }; };
named.conf.restricted_axfr 3/3 zone "1.168.192.in-addr.arpa" { type master; file "db.192.168.1"; allow-query { any; }; allow-transfer { secondaries; }; }; zone "0.0.127.in-addr.arpa" { type master; file "db.127.0.0"; allow-query { 127.0.0.1 ; }; // Note: no one needs to get zone transfers of this one! };
Additional Data Mining Defense Notice those allow-query lines? Those stop outside attackers from mining us for data! They also fight cache poisoning. We set default deny on queries, by specifying this in our options block.
Additional Data Mining Defense What about the allow-recursion lines? These prevent outsiders from using our nameservers to query for zones that we don't run. Again, a defense for cache poisioning.
Cache Poisoning? By taking over an authoritative nameserver, an attacker obtains the ability to put data into our nameserver's cache. He accomplish this, if he can get us to ask his nameserver for information! Remember that DNS is a distributed database. The steps we're taking here attempt to minimize this possibility.
Safe From Data Mining Yet? [jay@max jay]$ dig @localhost dumb.target.jay hinfo ; <<>> DiG 8.2 <<>> @localhost dumb.target.jay hinfo ; (1 server found) ;; res options: init recurs defnam dnsrch ;; got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUERY SECTION: ;; dumb.target.jay, type = HINFO, class = IN (continued)
Nope. ;; ANSWER SECTION: dumb.target.jay. 1D IN HINFO "Pentium 166" "Red Hat 6.1" ;; Total query time: 1 msec ;; FROM: max.fictional.attacker to SERVER: localhost 127.0.0.1 ;; WHEN: Sun Nov 12 00:17:08 2000 ;; MSG SIZE sent: 33 rcvd 69
The Simple Solution? Simple. Don't give away so much information! But how do we reconcile this with the need to keep easy online data about hosts?
Two Choices 1) Remove all HINFO and TXT records. Consider choosing less informative machine names than sysadmin, printspool, and intranet. 2) Implement Split Horizon DNS. Basically, you maintain two separate DNS servers, with two separate sets of data.
Split Horizon DNS 1/3 This is an overview: • Two DNS servers, generally separated via a firewall/packet filter. • Possibly both DNS servers are on the same machine, which restricts external hosts to the external BIND process. • Possibly both DNS servers sit on your firewall.
Split Horizon DNS 2/3 Internal DNS Server: • Only accepts requests from internal hosts. • Possesses a richer zone database. • Forwards all requests for external data to the external DNS server. • No zone transfers, unless we have other internal DNS servers.
Split Horizon DNS 3/3 External DNS Server: • Only does recursion for internal hosts, usually only for internal DNS server. • Possesses a sparser zone database. • Potentially much sparse, if used w/ NAT. • Zone transfers allowed from this host, but only to the slave servers.
Playing the Attacker Some More Cracking the DNS Server... • BIND 8.2.0 and 8.2.1 was vulnerable to a Remote Root exploit! • Huge numbers of exploitable systems, when this exploit was released. Red Hat 6.0, among many others, shipped with one of these versions.
Cracking the DNS Server The Cracker HOW-TO is available here: http://www.enteract.com/~lspitz/NXT-Howto.txtBut how does an attacker find vulnerable machines?
Finding Vulnerable DNS Servers Try this command against one of your DNS servers: dig @your_ns your_ns txt chaos version.bind Here's the output against my test system:
Grabbing the BIND Version Number ; <<>> DiG 8.2 <<>> @dumb.target.jay dumb.target.jay txt chaos version.bind ; (1 server found) ;; res options: init recurs defnam dnsrch ;; got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUERY SECTION: ;; version.bind, type = TXT, class = CHAOS ;; ANSWER SECTION: VERSION.BIND. 0S CHAOS TXT "8.2.2" (truncated)
Security through Obscurity? Security through Obscurity can be helpful, though it should never be your only defense. Against Script Kiddies, it can be extremely effective, because of their Modus Operandi. ( see http://www.securityportal.com/topnews/tighten20000720.html) We can obscure the version number through the version directive in the options section of named.conf.
named.conf Revisited We'll just add one directive to the options block: options { directory "/var/named"; listen-on {192.168.1.2 ; }; allow-recursion { internal ; }; allow-query { internal ; }; allow-transfer { none; }; version "Go away!"; };
Go Away? This is a judgment call. The script kiddies generally use scanners that pattern-match. Your goal is to not get matched. At the same time, you may want to "blend in". Suggestions: • version "9.0.0"; • version "4.9.7"; • version "8.3.0";
Other Defenses Against Cracking Well, suppose a script kiddie gets lucky and tries an attack, even though a scanner didn't pick you out? Or, worse, suppose a more capable cracker comes after you? What defenses do you have?