DNS source port randomisation
By Rick Moen
[RM note: This article is excerpted from the middle of a mailing list discussion, two weeks after the now-infamous DNS security bug emerged, and hours after security consulting firm Matasano Security's blog "Matasano Chargen" accidentally revealed full details of how to exploit the hole.]
This article is written particularly for the benefit of the majority of you who do not run your own DNS nameservers -- because everyone has a horse in this race, not just sysadmins:
When your app (say, a Web browser or e-mail client) needs to communicate with a remote host, it invokes the system DNS service. On Linux boxes, that's a small library (disturbingly, derived from horrible, ancient, BIND8 spaghetti code) built into the system C library called the resolver. The resolver, which is each TCP/IP system's DNS client piece, has (on Linux) /etc/resolv.conf as its (main) configuration file. (Also relevant is /etc/nsswitch.conf, but we won't get into that.)
For the 98% of you who get your IP addresses, nameservice details, routing, and so on via DHCP, that resolv.conf file gets overwritten frequently, each time your DHCP lease is renewed, FYI. Please do have a look at your /etc/resolv.conf. It's really simple. My server's own resolv.conf:
search linuxmafia.com deirdre.org nameserver 126.96.36.199 nameserver 188.8.131.52 nameserver 184.108.40.206
The first line says "If the silly human gives a less-than-fully-specified hostname, try 'linuxmafia.com' as the domain suffix, and then also 'deirdre.org', before giving up." The remaining three lines give the IPs of three DNS servers where the resolver client can deliver queries. The first two are (excellently run!) nameservers at my upstream link, Raw Bandwidth Communications. The third is my own nameserver.
You folks on DHCP get all such lines from your DHCP server. (There are also ways to configure your DHCP client to modify this behaviour.) If you control your own DHCP server, e.g., as part of a "firewall" appliance, then you can determine what configuration data gets passed out with the DHCP IP leases.
Anyhow, your resolver library lobs a query off to one of the DNS nameservers listed in resolv.conf. What does the nameserver do? It's like asking a research librarian: either he/she knows, or knows whom to ask. "Knowing" is the model called authoritative DNS service: that's where your query happens to go to one of the nameservers that are the recognised, worldwide authorities for what DNS data that domain is serving at this moment. "Knowing whom to ask" is called recursive-resolver service, where your query reaches a nameserver that is not authoritative for the queried domain, but happens to have the requested data in its cache of data that others have asked for in the recent past ("I know a guy, who knows a guy...."), and that the accompanying "use by date" stamp (the "time to live" value) suggests that data are still good.
It's been known for a long, long time that recursive-resolver service is technically difficult, and has huge security pitfalls. Among the worst hazards is a malicious party "poisoning" the cache data of a recursive-resolver server your local resolver library queries. Such caches can be poisoned only via queries from resolvers (DNS clients) on the servers' lists of IPs permitted to send them recursive queries. Remember when you signed up with your ISP and they gave you a small list of IPs that you can use as nameservers? (Maybe you don't, because you're using 100% DHCP. In that case, you're getting those IPs with your lease.) Those are nameservers your ISP is exposing to a huge number of users for recursive service -- at minimum, all of its customers, and some ISPs leave their public nameservers open to recursive queries from anywhere at all.
So, lesson #1: one of the easiest ways to reduce your security exposure to all DNS security issues is to avoid using (most) ISP nameservers for your general DNS needs. You can do that by setting up your own recursive-resolver nameserver package. The thing hardly anyone knows except sysadmins is that doing so is dead-simple. You pretty much just install the package and it works great by default. No tweaking, no futzing around. You just have to make sure resolv.conf points to it. It costs you a bit of RAM, and that's about it. Anyone can and should consider doing that -- yes, even on laptops.
Picking a Local, Caching, Recursive-Resolver Nameserver
In an ideal world, I'd have tested candidates and be able to give you simple, foolproof instructions and recommendations. But alas, I haven't even kicked the tires of most -- which illustrates why progress in this area has been slow: too many sysadmins making do with BIND9. The good news is that all you really do with DNS servers in this category is start them and point /etc/resolv.conf at them.
The following, in no special order, seem worth trying:
- BIND9: The only one yr. humble servant has used extensively. Maddeningly slow, bloated, overfeatured monolithic binary (optionally doing all other conceivable types of nameservice, as well). Cryptic and brittle (but "standard", for better or worse) configuration and zonefile formats.
- Unbound: By design, excellent in all areas where BIND9 is lackluster. The only obvious problem is that it's brand-new -- which, in security-sensitive code is a point of concern.
- PowerDNS Recursor: Dedicated recursor component (newly made available separately) of the respected do-it-all PowerDNS package. Probably requires a SQL database for back-end storage. Fast. PowerDNS as a whole -- but I'm not sure how much of this applies to the separely packaged recursor -- is somewhat bloated, has an over-large tree of required libraries and other dependencies), and has a fair (but not stellar) reputation for security.
- dnscache: Dan Bernstein's caching recursive-resolver, part of the djbdns suite, and the first to randomise source ports as a security precaution. Eccentric style of coding and operation. (Let me just leave it at that.) Unsurpassed security history. Said to be a bit of a challenge to set up, and at present you must immediately patch it to compensate for Dan not having maintained it since 2001. Has problems resolving some domains (such as Akamai), and in general is by design a bit underfeatured, which accounts in part for both its superb security history and its problem areas.
- MaraDNS: Lightweight, fast, and well-maintained. Like BIND9, does all conceivable DNS roles, but without the bloat. Excellent security.
Basically, ISP nameservers are (in general) Typhoid Marys. Don't use them! The fact that I'm still relying in part on Raw Bandwidth's reflects the high esteem in which I hold Mike Durkin's operation, there, but that does not generalise to other ISPs.
A lot of people including Dan Bernstein pointed out, starting many years ago, that recursive queries are dangerously easy to forge (I mean, to forge a faked response loaded with bogus data that is then accepted as having come from the real nameserver the resolver actually asked). Recursive queries have a (sort of) unique transaction ID number, called a query ID (QID) -- but that's just a 16-bit number, which is rather too few, making forged responses much more likely to succeed than if QIDs were, say, 32-bit integers.
Since it's not practical to switch to longer QIDs, the only other logical way to make it more difficult to convincingly forge responses to recursive queries is to make the queries originate on a random TCP or UDP port, rather than the standard DNS port 53. Guess what? Most nameservers prior to the patches released on July 8, 2008 did the very, very dumb thing, and always sent out their queries from port 53. The nameserver you use today probably does, too. That's very, very bad, because, as the "Matasano Chargen" guy and German mathematician Halvar Flake have pointed out, the bad guys have recently figured out -- or are right about to figure out -- how to easily poison the caches of vulnerable recursive-resolver nameservers. And nothing increases that vulnerability as much as always sending out recursive queries from the same port.
(The Matasano Chargen piece also talks about a second part of the problem: nameservers willing to accept "out of bailiwick" recursive response data: extra "oh, by the way" data thrown in along with the requested response that is about a different domain entirely. Fortunately, most modern nameservers are relatively good about that -- though some concern remains -- and it's not addressed by the July 8 patches.)
Something a lot of people don't think much about is that your libc DNS code is a "stub" (limited) recursive-resolver of a sort: it originates DNS queries with the recursive bit set, which is the "if you don't know, please ask some other nameserver that does" signal. Aren't they also potentially attackable by the sort of forgery that the Matasano Chargen guy discusses? Yes, but "stub" resolvers don't cache their received data, so it's not much of a threat. (The "poison" gets flushed immediately.) Oddly enough, the desktop software components aren't the problem, this time. It's the working nameservers out on people's (and ISPs') server machines.
And people's "firewall" boxes are going to be a big problem. Two reasons:
- Many firewall appliances have built-in recursive-resolver nameservers. Guess how many of those are likely to get patched? Right, almost none. (Fortunately, probably most of them are non-caching.)
- Let's say you follow my advice and run a caching recursive-resolver nameserver on your local machine -- and that you operate behind a "firewall" gateway appliance that connects your DSL or cable link to upstream, and that does NAT / port address translation (as they pretty much all do) so you can get by with a single IP. You're wary and so patch your systems to get the July 8 patches -- so that your resolver is originating its queries from a random port, instead of always sending them from port 53.
Good, right? Except, then, the firewall appliance's network address translation/port address translation (NAT/PAT) algorithm kicks in, and rewrites the outbound traffic. The originating port was random, so the firewall's rewritten version of that same packet should likewise have a random source port, right? Because all $40 cheap plastic appliances have excellent random number generators, right? Oops. Sorry, your originating port assignment probably doesn't end up being quite so random, any more. See: http://www.circleid.com/posts/87143_dns_not_a_guessing_game/ Basically, a typical firewall box makes a rather efficient de-randomiser.
Testing your nameserver's randomness of source port selection
$ dig [nameserver IP or hostname] porttest.dns-oarc.net in txt
The result string will include a editorial comment like "GOOD", "FAIR", or "POOR" about randomness quality.
Or use this Web facility: https://www.dns-oarc.net/oarc/services/dnsentropy
You really do want to attend to this now. It's not Somebody Else's Problem.
Rick has run freely-redistributable Unixen since 1992, having been roped
in by first 386BSD, then Linux. Having found that either one
sucked less, he blew
away his last non-Unix box (OS/2 Warp) in 1996. He specialises in clue
acquisition and delivery (documentation & training), system
administration, security, WAN/LAN design and administration, and
support. He helped plan the LINC Expo (which evolved into the first
LinuxWorld Conference and Expo, in San Jose), Windows Refund Day, and
several other rabble-rousing Linux community events in the San Francisco
Bay Area. He's written and edited for IDG/LinuxWorld, SSC, and the
USENIX Association; and spoken at LinuxWorld Conference and Expo and
numerous user groups.
His first computer was his dad's slide rule, followed by visitor access
to a card-walloping IBM mainframe at Stanford (1969). A glutton for
punishment, he then moved on (during high school, 1970s) to early HP
timeshared systems, People's Computer Company's PDP8s, and various
of those they'll-never-fly-Orville microcomputers at the storied
Homebrew Computer Club -- then more Big Blue computing horrors at
college alleviated by bits of primeval BSD during UC Berkeley summer
sessions, and so on. He's thus better qualified than most, to know just
how much better off we are now.
When not playing Silicon Valley dot-com roulette, he enjoys
long-distance bicycling, helping run science fiction conventions, and
concentrating on becoming an uncarved block.
His first computer was his dad's slide rule, followed by visitor access to a card-walloping IBM mainframe at Stanford (1969). A glutton for punishment, he then moved on (during high school, 1970s) to early HP timeshared systems, People's Computer Company's PDP8s, and various of those they'll-never-fly-Orville microcomputers at the storied Homebrew Computer Club -- then more Big Blue computing horrors at college alleviated by bits of primeval BSD during UC Berkeley summer sessions, and so on. He's thus better qualified than most, to know just how much better off we are now.
When not playing Silicon Valley dot-com roulette, he enjoys long-distance bicycling, helping run science fiction conventions, and concentrating on becoming an uncarved block.