[vpn-help] Apple OSX >= 10.4 DNS resolver, very disappointing ...
Matthew Grooms
mgrooms at shrew.net
Wed Dec 19 00:37:42 CST 2012
All,
As most of you are probably aware, I have been working hard to improve
the OSX port lately and have run into some very interesting challenges.
If your not particularly interested in OSX, you should skip this email
as its mostly a rather long rant about how Apple screwed the pooch WRT
DNS resolution and why OSX will be 2nd class citizen for remote access
products until they fix some things under the hood. I usually don't go
out of my way to write about this kind of topic, but I thought it would
be a good exercise for myself and perhaps a decent read for others that
have some interest in the topic. Now, on to the brain dump ...
Back in the OSX Tiger days, Apple introduced a new method to configure
adapter settings ( like DNS ) which leverages information stored in the
configd dynamic store. The store is a nexus for several components that
are interested in the same configuration data. For example: There are
GUI config components that publish IP/DNS settings to the dynamic store
and there are service components, like the DNS resolver, that read
settings from the dynamic store. On the command line, the configuration
information in the dynamic store can be modified or queried using the
scutil program.
So what does this have to do with the VPN Client? Well, on *nix like
systems, the Shrew Soft client assigns IP address info using a tried and
true unix staple, ioctl(). DNS settings are written out to a file named
/etc/resolv.conf. Route table manipulation is handled by sending and
receiving messages via a special socket and protocol family named
PF_ROUTE on BSD and PF_NETLINK on Linux. Since OSX had grafted a fair
amount of code from the BSD family onto the Mach kernel, configuration
used to be pretty similar to a BSD system. But with the introduction of
Tiger, all this changed to look a lot more like a Windows system. You
write a bunch of information into the registry ( or configd on OSX ) and
the system does stuff with it. For example, in Windows you have a
registry section that correlates to an adapters IPv4 configuration. It
holds information like the IP address, Netmask, DNS settings, etc. You
plug the information in, enable the adapter, and it's configured. With
OSX it's pretty much the same thing, but unfortunately the system DNS
resolver doesn't honor one of the fundamental aspects of TCP/IP, the
route table.
To configure an adapter via the command line on OSX, you specify some
information related to an adapter IP config. For example, in a shell you
could do something like this ...
>scutil
open
d.init
d.add DomainName shrew.prv
d.add ServerAddresses * x.x.x.x
set State:/Network/Service/tap0/DNS
d.init
d.add InterfaceName tap0
d.add Addresses * y.y.y.y
d.add SubnetMasks * 255.255.255.0
d.add Router z.z.z.z
d.add OverridePrimary # 1
set State:/Network/Service/tap0/IPv4
close
Awesome, the adapter is configured and we have DNS settings. But how do
I make the DNS settings active? Well, you make the adapter override the
primary adapter by including the "OverridePrimary # 1" in the second
section of the configuration. The catch is, it won't work unless you
also specify a Router x.x.x.x which becomes the new default gateway for
the system. So to get a new DNS server, you have to change the way in
which all IP packets ( that don't follow a more specific route ) leave
the host.
Great. No problem, we can just change the DNS settings associated with
the Primary adapter ( like your Ethernet or Wifi ) and then restore the
old settings when we shut down the VPN tunnel. Nope. Even if there is an
entry in the route table that says the DNS server should be reached via
another adapter, the packet is always sent out the Primary adapter.
Apparently at Apple, DNS over UDP is not part of the TCP/IP protocol
suite, it's a layer 2 protocol that just happens to contain UDP and IP
headers. Interesting.
Lets try another approach. Maybe we can just change the priority of the
DNS servers used by the system resolver. Not possible. If your adapter
isn't primary, your DNS server simply won't get used except under one
special condition. The behavior is achieved by specifying a list of DNS
suffixes that should be serviced by your adapters name server. For
example ...
>scutil
open
d.init
d.add DomainName shrew.prv
d.add SupplementalMatchDomains shrew.prv
d.add ServerAddresses * x.x.x.x
set State:/Network/Service/tap0/DNS
d.init
d.add InterfaceName tap0
d.add Addresses * y.y.y.y
d.add SubnetMasks * 255.255.255.0
set State:/Network/Service/tap0/IPv4
close
Now, any request that matches *.shrew.prv will be forwarded to the DNS
server associated with your adapter. Great for forward DNS lookups as
long as you have an exact list of all domains that would be significant
to your VPN connection, but what about reverse lookups? Nah, your out of
luck.
My conclusion: The system DNS resolver in OSX is flawed by design. All
you have to do is google 'OSX 10.4 DNS' and you will find thousands of
posts by people with multi-homed hosts trying to figure out how to work
around the shortcomings of Apples OS. Lots of folks who need to use a
private DNS server for internal use or development resort to installing
a local instance of bind ( the defacto DNS server on *nix ) and forcing
all queries to localhost. Way to go apple.
In any case, the Shrew Soft client is more or less ported to OSX. How
useful it will be to users is another story. I tried to get help from
the Apple network developers mailing list, but there was no response ...
http://lists.apple.com/archives/macnetworkprog/2012/Dec/msg00006.html
All the information in this email was learned from reading the scarce
documentation and by trial and error. I would love it if someone would
show me light and disclose how this should really be done, but I'm not
going to hold my breath.
-Matthew
More information about the vpn-help
mailing list