This post is meant to document a software bug I believe I've found in Apple's Mac OS X. In short, OS X 10.10.3 fails to flush DNS TLSA records when flushing other DNS records. TLSA records can only time out based on their TTL, they will otherwise never be removed from cache. Even when manually flushing the DNS cache with these commands run as root.1
discoveryutil udnsflushcaches discoveryutil mdnsflushcache
I have been working on setting up DNSSEC and DANE on one of my test domains, https://www.synonomic.com. It works now, but when I was setting it up I noticed that after changing the TLSA record my OS X machine took a very long time to reflect the change. I ran commands like:
dig +multi _443._tcp.synonomic.com. TLSA dig @188.8.131.52 +multi _443._tcp.synonomic.com. TLSA
but I couldn't see any change on my OS X laptop. However, I could see the change reflected on both a Debian 7.8 Linux box(dig 9.8.4-rpz2+rl005.12-P1), and an OpenBSD 5.7 box(dig 9.10.1-P2) running the same commands. Something was clearly different between my laptop and these two other machines.
I assumed I needed to flush the DNS cache on my OS X laptop using the aforementioned commands, but this did not resolve the issue. I tried rebooting my laptop, but this also did not trigger a requery. I tried clearing the DNS cache and then sniffing with Wireshark to watch DNS queries. Other DNS records were requeried, but never TLSA records. Only after waiting the configured TTL of 24 hours did the TLSA record change.
At this point I wanted to verify what I suspected with another DANE enabled web site. I chose https://good.dane.verisignlabs.com/ since it has a known good DANE configuration. I also had never visited this site so I could watch the entire process from start to finish.
The first time I visited the site I sniffed with Wireshark and saw the TLSA query/response. I then flushed the DNS cache and loaded the website again. This time I saw other DNS records get requeried, but not the TLSA record. This confirmed to me that my laptop was not clearing TLSA records when clearing the DNS cache.
What about the RFC
RFC 6698 section 8.2 addresses DNS caching of TLSA records. There is nothing in this section to indicate that TLSA records should be handled differently than other DNS records. It states that TLSA records MUST NOT be cached longer than their configured TTL, which is good, and obvious. However, I don't think we should interpret this to mean that TLSA records SHOULD be cached as long as their configured TTL. I interpret this section as not introducing any new behavior for TLSA records with regards to DNS caching.
Why this Matters
This kinda sucks. Because most people setting up DANE are not going to get their TLSA records correct the first time. I didn't. Also, the default TTL at my DNS provider was 24 hours, which is a long time to wait for a timeout. We don't want early DANE adopters to get frustrated during setup and then give up.
So I'm making this blog entry to help those people in their frustrations. If someone Googles "DANE DNS cache flush TLSA Apple OS X", or something similar. I hope they find this page, and I hope this helps them move forward in their deployment of DANE.
There's a chance I've omitted something in my analysis and what I interpret as a bug is really just a consequence of my own ignorance. I don't know much about the internals of OS X's DNS caching. I just expect that when an operating system provides a command to flush its DNS cache, the command do so completely. If you have a question/problem/comment with this article please contact me at andrewm AT ischool DOT berkeley DOT edu.
I upgraded my laptop to 10.10.4 and the problem is resolved. TLSA records appear to never be cached. When I run dig now I see the TLSA queries and responses every time in Wireshark. My guess is that OS X 10.10.4 never caches TLSA records, because without even clearing the cache I see a single query/response every time.
Apple has also once again changed the command for clearing the DNS cache. The new way is to send a SIGHUP to mDNSResponder:
killall -HUP mDNSResponder
Although confusingly named, mDNSResponder is responsible for both unicast and multicast DNS. Let's see how long before Apple decides to change this method to something else.
Apple changes how their DNS is flushed with almost every release, apparently this is the way to do it in OS X 10.10(Yosemite). This is according to general Internet forum wisdom, and the man page for discoveryutil. The two commands listed here flush both the unicast DNS and multicast DNS. ↩