DNS on Solaris 11
22 November 2011

One of the more, er, curious “improvements” in Solaris 11 is moving DNS client information out of resolv.conf and nsswitch.conf into SMF.

There may be a somethingadm tool buried amount the couple of thousand commands that now swamp /usr/bin, but for now the only way I can find to set my client DNS info, other than via the installer, is with svccfg.

svccfg, if you didn’t know, began as Sun’s way of making it easier for Solaris contractors to justify their daily rates. Configuration via text files had become so simple that Linux users with nano were becoming able to perform reasonably sophisticated operations, which made it more difficult for bearded, sandal-wearing Solaris admins to appear mysterious, all-knowing and guru-like. So SMF was born, hiding the configuration of Solaris and its applications behind a layer of poorly documented XML and labyrinthine commands with conflicting options, once again making it look like what we did was hard.

$ ping tap
ping: unknown host tap

Uh-oh. Looks like this zone got configured with no DNS client information. To correct that I’m going to set two nameservers, 192.168.1.26 and 192.168.1.1, and tell DNS to search localnet by default. Editing two files in /etc would obviously be a stupid way to this, so, instead, begin by enabling the DNS client service.

# svcadm enable dns/client

Adding a single DNS server is (for SMF) simple.

# svccfg -s dns/client setprop config/nameserver = 192.168.1.26

But what if you want to add more than one? Well, you’d think this might work:

# svccfg -s dns/client setprop config/nameserver = 192.168.1.26 192.168.1.1
svccfg: Unknown type "192.168.1.26".

Okay, how about

# svccfg -s dns/client setprop config/nameserver = "192.168.1.26 192.168.1.1"
svccfg: Unknown type "192.168.1.26".

The answer you’re looking for is, astonishingly,

# svccfg -s dns/client setprop config/nameserver = net_address: \
"(192.168.1.26 192.168.1.1)"

This is my issue with SMF. Unix has always been intuitive. You get a feel for how things are done, and everything makes sense. The command above is bewilderingly arbitrary. Where does the net_address come from? Why the brackets?

Now add the search domain with

# svccfg -s dns/client setprop config/search = localnet
# svccfg -s dns/client setprop config/domain = localnet

And refresh the service

# svcadm refresh dns/client
# grep -v ^# /etc/resolv.conf
domain  localnet
search  localnet
nameserver      192.168.1.26
nameserver      192.168.1.1

And find that all it’s done is create the file exactly in the way we always used to. What a pain in the arse.

We haven’t done yet though: remember that we always used to have to add dns to the hosts line of nsswitch.conf? So where’s that going to go?

$ svcs "*name*"
STATE          STIME    FMRI
disabled       13:21:37 svc:/system/name-service-cache:default
online         13:22:08 svc:/system/name-service/upgrade:default
online         13:22:14 svc:/system/name-service/switch:default
online         13:22:25 svc:/system/name-service/cache:default
online         17:55:45 svc:/milestone/name-services:default

name-service/switch looks interesting don’t you think? We’ll leave the difference between name-service/cache and name-service-cache for another day.

$ svcprop name-service/switch | wc -l
     242

So somewhere in those 242 lines of underscores and backslashes is the line we need. Using my magical sixth sense I know the property we want is called config/host. Though if I try to examine that property on my as-yet unconfigured machine, I get told

$ svcprop -p config/host name-service/switch
svcprop: Couldn't find property `config/host' for instance
`svc:/system/name-service/switch:default'.

I can still set it though, and I want it to go hosts dns mdns, just like old times. That means we have multiple arguments to pass to svccfg, so let’s use the obscure brackets syntax from earlier.

# svccfg -s name-service/switch setprop config/host = "(files dns mdns)"
svccfg: Multiple string values or string values with spaces must be quoted
with '"'.

Well, obviously. How stupid of me not to automatically assume that.

# svccfg -s name-service/switch setprop config/host = '("files dns mdns")'

Beautiful.

$ grep hosts /etc/nsswitch.conf
hosts:  files
# svcadm refresh name-service/switch
$ grep hosts /etc/nsswitch.conf
hosts:  files dns mdns
$ ping tap
tap is alive

And breathe out.

I’ve been using SMF on a regular basis since 2005, and I still regularly find it frustrating. I’ve written dozens of manifests, changed what seems like a million properties, and I still feel like a novice. Underneath, you’re almost always writing a script or editing a file, but there’s tonnes of cruft to get through to do it. Service manifests are the worst. Written a script you want to be run at boot? That’ll be an afternoon’s work then. Pain in the arse.

tags