This morning I noticed that some of our network elements are using IPs that have more than one PTR associated with them. This isn’t a huge problem, but it was exposed to us because the DNS record in our monitoring system would just randomly pick a PTR when the element was rediscovered. Because these other PTRs were often just out of date cruft, having the old names show up in monitoring was confusing. I took this as a quick project to run through the IPs and resolve the duplicates. The fact that I’m now writing a blog post about it is a pretty good spoiler that it wasn’t as simple as I thought it was going to be.
I went through all the IPs in question (and then also all IPs in the same /24s as those IPs) and came up with a list of about 15 IPs that I changed. I deleted the PTRs with no matching A records, typed up a summary for my group, and was just about to hit send when I did one more check of my work and found that some of the PTRs I had deleted were back. OK. I deleted them again, and they came back again. I reloaded. I refreshed. I manually incremented zone serials. Nothing.
A quick Google showed that it is/was a known problem that the DNS snap-in cannot delete PTR records with upper-case characters in them (this page, leading to this Microsoft KB article, were the key hits). This seemed like a likely culprit. All of the records I was still having problems with did contain mixed case characters, and all the ones I had successfully deleted were all lower case. The only thing that confused me was that the KB item was specifically for Windows Server 2003. I was using the snap-in locally from Windows7, and I also had tried it directly from one of the DNS servers running Windows Server 2008, and they all had the same problem.
At this point I tried renaming the PTR to be lower case and then deleting it, but that was a spectacular failure. It renamed in the snap-in, but querying the server then showed three records instead of two, with the one I renamed showing up twice, both with the same upper case characters, even though I had renamed it with lower case. Eesh. I counted myself lucky that when I deleted the lower case version in the snap-in it put me back to where I was when I started (two PTRs, one good, one bad but undeleteable due to upper case characters).
The Solution! (almost)
Back to the Goog! This time I came across this interesting post about programmatically lower-casing all PTRs. It wasn’t directly what I needed (though I’m saving it for later review), but it did introduce the idea of using
dnscmd.exe to delete the PTRs that the snap-in won’t touch.
Since I was already logged directly into one of the DNS servers with my admin credentials, I decided to just run the command there. A little bit of experimentation and I ran the following (yes, 10.1.1.1 really was the IP):
C:\>dnscmd . /RecordDelete 1.1.10.in-addr.arpa. 1 PTR Are you sure you want to delete record? (y/n)y Command failed: ERROR_ACCESS_DENIED 5 0x5
Well crap. I relaunched CMD as an even-more-admin-ish account and got the same response. I tried deleting a PTR that didn’t have upper case characters and got the same response, so it wasn’t the same problem. I tried the following, which suggested that I was using the right syntax and it really was a permission issue:
C:\>dnscmd . /RecordDelete 10.in-addr.arpa. 1.1.1 PTR Are you sure you want to delete record? (y/n)y Command failed: DNS_ERROR_ZONE_DOES_NOT_EXIST 9601 0x2581
The Solution For Reals!
One final trip to Google and I turned up this post describing the same “what do you mean access denied, I’m an admin” experience I was having. Following the suggestion to always use an FQDN for the server, I still had the same problem. I then tried it with the IP of the server and it worked:
C:\>dnscmd 10.5.20.5 /RecordDelete 1.1.10.in-addr.arpa. 1 PTR Are you sure you want to delete record? (y/n)y Deleted PTR record(s) at 1.1.10.in-addr.arpa. Command completed successfully.
Here’s the kicker though: When I picked an IP I accidentally picked the IP from a different DNS server (oops). After a bit of experimentation I found that I could use nodename, FQDN, or IP of a different server and it would work, but if I tried to use “.”, nodename, FQDN, or IP of the local server, it would always fail with the ERROR_ACCESS_DENIED error. Fun!
So now I can delete the offending PTRs which is good, but that command also deletes the good PTR, which is not so good. Fortunately I can use
dnscmd.exe to put the good PTR right back. Here’s a full before/delete/during/recreate/after example:
C:\>dnscmd 10.5.20.5 /EnumRecords 1.1.10.in-addr.arpa. 5 Returned records: @ 3600 PTR PIX-515.example.com. 3600 PTR pix-515-2.example.com. Command completed successfully. C:\>dnscmd 10.5.20.5 /RecordDelete 1.1.10.in-addr.arpa. 5 PTR Are you sure you want to delete record? (y/n)y Deleted PTR record(s) at 1.1.10.in-addr.arpa. Command completed successfully. C:\>dnscmd 10.5.20.5 /EnumRecords 1.1.10.in-addr.arpa. 5 Returned records: Command completed successfully. C:\>dnscmd 10.5.20.5 /RecordAdd 1.1.10.in-addr.arpa. 5 PTR pix-515-2.example.com. Add PTR Record for 18.104.22.168.in-addr.arpa. at 1.1.10.in-addr.arpa. Command completed successfully. C:\>dnscmd 10.5.20.5 /EnumRecords 1.1.10.in-addr.arpa. 5 Returned records: @ 3600 PTR pix-515-2.example.com. Command completed successfully.
After running this I saw what I expected in the DNS snap-in (just one record for 10.1.1.5, pix-515-2.example.com). This would be pretty easily scriptable but it’s 13 more PTRs. Maybe next time.