Contribute  :  Advanced Search  :  Directory  :  Forum  :  FAQ's  :  My Downloads  :  Links  :  Polls  
AFP548 Changing the world one server at a time.
Welcome to AFP548
Wednesday, February 15 2012 @ 01:54 am MST
   

Wide Area Bonjour - Part 2 Bring the Pain

ArticlesIn our first installment we discussed setting up static Wide Area Bonjour entries from which you could direct your users to other resources. In this article we'll talk about bringing this home to be what most people are looking for, which is allowing clients to dynamically register.

This does work, and you can do it. However, there are some pretty serious caveats to this. The main one being that you'll probably plow through a large bottle of your strongest alcoholic beverage. The second issue is that this probably won't do what you want it to do. More on that later though...

So read on for how to do this.

Pick your Domain

The first step in doing this is setting up the DNS domain that you want to use. Since this is going to be a dynamic domain with who knows what being put into it, it's best if you pick a subdomain. The cool kids have been using "namespace" for this. So to keep with the same examples from before, we'll set this up using namespace.afp548.com.

As long as you control the DNS server, and it's the only DNS server your clients use, you can even subdomain a domain you don't own. For example, if all of your clients used your own DNS server, you could use namespace.microsoft.com if you wanted, although I wouldn't really recommend that unless you have some time to devote to the process.

Also of note is that you can set this domain up using the Server Admin GUI if you want. Although be aware that you'll probably be leaving the GUI behind once you start into this.

Make the Records

As before, once you've created the zone in Server Admin you can manually add records inside the zone file in /var/named. Just don't mess with the include statement and you'll be fine.

You're going to need to add both the browse and the legacy browse record, similar to when you created the static entries. However, you're also going to need to add the registration and the long-lived query records as well.

_dns-llq._udp                  IN SRV 0 0 5352     server.namespace.afp548.com. ; sets up the domain for long-lived queries
_dns-update._udp             IN SRV 0 0 53         server.namespace.afp548.com. ; tells clients they can register
b._dns-sd._udp              IN PTR @   ;  "b" = browse domain
lb._dns-sd._udp             IN PTR @   ; "lb" = legacy browse domain (include domain in empty-string browses)
r._dns-sd._udp              IN PTR @   ;  "r" = registration domain
Keep in mind that if you're clients aren't all using the same DNS server, you're going to have to ensure you have some glue records between your primary domain and your subdomain. This typically entails an NS record in the primary domain pointing to the authoritative server for the subdomain. Plus an A record for the server in the primary domain.

Also, the settings in the example will require you to open up port 5352 to the WAB clients on your DNS server.

The _dns-llq._udp record allows clients to do long-lived queries. This is a fascinating way of making DNS more dynamic. When doing a long-lived query the client machine does a lookup to the DNS server. The server responds with what it knows at the time, similar to a regular DNS lookup. However, following that initial query the server will continue to alert the client when any new answers to that query become available. This doesn't require any polling by the client, instead the server just sends another packet down the same pipe that the original query came in from, even if some time has passed.

An example of this is a client browsing for _ssh._tcp registrations, or systems offering SSH connections. The client would make the appropriate PTR lookup for this. The server would respond with all of the ones that it knows of at the time. Time passes. A new system registers with the WAB server that it also does offer SSH. The DNS server then alerts the original requestor of the new system by sending it a DNS response. No additional query by the client is necessary. Pretty cool, eh?

If you want clients to automatically discover the registration domain based upon the browse domain, you'll need to add an r._dns-ds._udp record to the primary domain pointing to the subdomain. In most cases, this isn't really necessary as you'll be having your clients explicitly register in the subdomain, but you should have this regardless.

Set Up dnsextd

There is a helper app that greatly facilitates a lot of the hocus pocus that goes along with WAB. This is dnsextd. It's distributed with the ISC DNS server, but it's use is not widely understood. This includes the dnsextd man page which at no time during this exercise should you look at as it will just confuse the issues at hand.

Dnsextd acts as a proxy to named. It listens on port 53, amongst others, and receives all DNS traffic. It filters, massages and repackages this traffic as appropriate and sends it off to the regular DNS server listening on the loopback interface.

To get dnsextd to work, you're going to need to make some quick edits to its config file, /etc/dnsextd.conf. Unlike the man page, you should go ahead and read the config file. The primary change to make here is at the very end of the file. Swap out "my-dynamic-subdomain.company.com." with your registration domain. In the case of our example, this would be "namespace.afp548.com." As with other named-based config files, the trailing periods are important.

When you're down, sit on your hands for a bit and don't try to get this running yet. You need to do more changes first.

Venturing into the Wilderness

It's now time to go where few OS X DNS servers have gone before and do some mucking about with the named config file. There's two things that you need to do here. First of all named, the "traditional" DNS server needs to listen on port 5030 and ideally just on 127.0.0.1. To accomplish this you're going to have to edit /etc/named.conf and add this line:

listen-on port 5030 { 127.0.0.1; };

It's at this point that the Server Admin GUI may begin blowing away your manually entered changes. So take care from now on when doing DNS edits in Server Admin. In fact, it's probably best not to do any edits in Server Admin for DNS ever again. Just to be safe.

Secondly you're going to have to edit the zone file for the registration domain. If you're using OS X Server, this is stashed away in an include file, /etc/dns/publicView.conf.apple. Look for the specific definition of the registration zone and change the allow-update from "none;" to "any;".

Note: This is going to allow any system that wants to register its name and what services it provides in your registration domain. This may cause all kinds of sillyness depending on the level of awareness of your users. This may include false registrations, competing registrations where one system usurps the name of another, and, in the most childish of cases, very profane names and suggestions of what you can to yourself. While not necessarily a security hole, per se, it's probably best to exercise caution about whom you allow to reach this server. In most cases keeping the server behind the firewall and requiring VPN access to it will probably suit your needs.

You can lock the registrations down to user names and passwords. However, since this is not tied into directory services in any way and requires essentially hand-creating the TSIG keys that are used, we won't even discuss it here. If you have the time, or interns, on hand to keep yet another password database up to date, then read the dnsextd.conf file and the ISC BIND documentation for more direction on this. If you do go down this road, let us know and we'll post a link to your instructions.

Cross Your Fingers that Everything is in Place

With the dnsextd.conf and the appropriate named config files edited. It's time to give things a spin here. First of all you'll need to stop the DNS server from running if it is already.

serveradmin dns stop

Then start it back up.

serveradmin dns start

Use netstat to see if it's truly listening on 5030 and not on 53. If it is, you can start up dnsextd. If it's not, go back to named.conf and make sure you didn't fat finger something.

netstat -na | grep 53

Now dnsextd is a pesky little bugger. You might have to spend some quality time with launchctl getting it to load and watch the job. If you want to start it manually, you can do so via:

/usr/sbin/dnsextd -launchd

However, the daemon will stay in the foreground, so you'll have to background it or open another shell to continue working on the system. Keep in mind that you'll want to make sure launchd is doing the right thing on reboot, or else you'll be without a DNS server.

You can test your work so for by just doing a normal DNS lookup. This should hit dnsextd on port 53 which will then pass it up to named on 5030. If you don't get a response... something is wrong. If you do get a response... proceed to a client machine.

Go Forth and Register, or Whack-a-Mole With DNS

This is the more entertaining part of the process, and where the large bottle of your strongest hooch may come into play.

If, and this is typically a very large "if", everything is in place the next step will just work... If not you'll be learning a lot more about how your OS X client works.

First of all go to the Sharing Preference Pane in your System Preferences. Hit the "edit" button there, something that you've probably never noticed before. This will bring up a new sheet with some empty boxes in it. Enable both of the checkboxes, and put in some clever hostname ending in your registration domain for the hostname. For instance in our example you could use my-bottle-is-almost-dry.namespace.afp548.com.

Now, do a DNS lookup on that hostname, or use the Bonjour Browser application to see if the registration took. If it did, congratulations, you're a fine example of an admin! If it didn't it's time to play whack-a-mole with your config and your DNS caches.

The first step which typically shakes out the major issues is to have the mDNSResponder, the little bit of magic that does all of the registrations, go into debug mode. This will log all unicast mDNS, what we're trying to do with the WAB setup, to the system log.

killall -USR2 mDNSResponder

Now, start looking in the logs and see if you're using the right DNS server. If not you've most likely made a mistake in your zone files with the registration domain.

Note: In my experience the DNS resolver on OS X uses the entire collection of any manually entered DNS servers and those it picked up from DHCP at the same time. So if you're trying to do something clever and usurp someone else's DNS authority, ensure you're on a manual IP with only your own DNS server listed. Otherwise it's pot luck what you might get.

Another note: Once you've enabled registrations to happen in DNS, named will start keeping a journal file of the changes to the zone. This means that the zone file you used to know and love... it's going to reflect reality. So if you're going to make changes to the zone file you'll have to either just bail on any records you didn't put in their yourself, or you're going to have to do a rather delicate dance.

To bail on the registrations, you'll need to kill named on the server. Then kill dnsextd for fun as well, because that probably does some caching. Then looking in /var/named for your zone file ending in ..jrnl and kill that file with prejudice. Now start the whole thing back up again.

To keep the changes you'll need to freeze the zone file, so that named writes the dynamic updates back to the original zone file.

rndc -p 54 freeze

It might error on you. Ignore that. Now stop the DNS server. At this point you should be able to make whatever edits you need to the zone files. While you're doing that look to see if the include file, that references the Server Admin controlled edits has been removed. Freezing the zone file via rndc will dump back the entire zone to the main zone file in /var/named. This will most likely overwrite the include file to the Server Admin zone file in /var/named/zones. If you care, and you don't if you never intend on editing this zone file in the GUI, you can add the include back in. It's possible that if you do edit the zone in the GUI, it will add the include back in and you may have double entries... be forever vigilant!

Now, keep in mind that the client will cache some too. Since WAB is essentially gussied up DNS, the records have TTLs and all the other elements of persistence that DNS does. So... again, with prejudice, you'll need to clear that out.

First you can execute a courtesy flush of the local DS cache.

dscacheutil -flushcache

And then on to the mDNSResponder itself.

killall mDNSResponder

Now set mDNSResponder back into verbose mode if you need to.

Now For the Real Kick in the Posterior

Hopefully you have a bit of the strong stuff left in the bottle to celebrate when you've got all these pieces lined up. Have a swig and sit down. Really, you should be sitting down for this next bit.

In its current state, an OS X client will not register an RFC1918 address with a WAB server. And for those of you about to Google, an RFC1918 address is essentially any private-NAT address. So any IP that starts with 10, 172.16 or 192.168. Yes, that's correct, it won't register your IP with the WAB server unless you have a publicly routable address. Really... you read that right. Go ahead and finish the bottle.

Now, there is some serious logic behind this. In fact, for a small subset of admins out there, this may be the coolest feature of WAB yet. The client, in specific mDNSResponder, will attempt to use UPnP or Apple's own pimpy-NAT protocol to discover the external IP of the system and to then register a port mapping on your router for all of your advertised services.

It might help to explain this by walking through the process. You're on your home network working on your fancy new MacBook Air. You fire up your VPN and tunnel into the office. The VPN server gives you out a DNS server and a search domain which is WAB-enabled. mDNSResponder now kicks in and attempts to register you in the WAB domain.

First it will look at your current IPs. It sees that you're on your home LAN, which is a 10.x.x.x network. It won't register this IP, so it does a UPnP/NAT-PMP transaction with your router to determine your router's IP address. If it's able to do this, and most SOHO routers will let it, it will register that IP address with the WAB server. For each service, AFP for example, mDNSResponder will attempt to register a port mapping as well. So, your MBA which has personal file sharing turned on will likely grab port 548 on the outside of your router and ask the router to forward incoming connections to its LAN IP on port 548. The external port gets added to the WAB registration for _afp._tcp.

Now, if you have a second machine at home, also with the VPN running, the same process occurs. However, when it gets to mapping port 548 on the outside of the firewall it will get a random higher-level port instead since 548 has already been reserved by another machine. Whatever port it gets offered by the router, 5768 for example, it will have forwarded to 548 on the local system and then it will register the external IP of the router and 5768 as the port in its _afp._tcp registration.

This is quite clever actually, as it's a bit of a poor-man's Back to My Mac. Incidentally you can actually use the BtMM docs to determine if your router will do the UPnP/NAT-PMP registrations as it's the same mechanisms for both BtMM and WAB. However, since the internet is a wild and sometimes positively unwholesome place, you should exercise some caution with this as you may be inadvertently leaving well-known ports, like 22, open on your firewall and forwarded to a machine you don't realize is accessible from the Internet.

Wrapping it Up

As you can see, there are some very very cool technologies invovled in Wide Area Bonjour. It may be very applicable to your environment even. If you have your own class A subnet, or if you're a bit of a geek and you want to seamlessly connect to your home machines when you're on the road, this may be exactly what you're looking for. However, if you have more of a large-scale and structured environment, this probably isn't what you're looking for.

In that case... hopefully you at least had fun setting it up. 

Story Options

Advertising

Wide Area Bonjour - Part 2 Bring the Pain | 9 comments | Create New Account
The following comments are owned by whomever posted them. This site is not responsible for what they say.
Wide Area Bonjour - Part 2 Bring the Pain
Authored by: neilmcg on Tuesday, March 03 2009 @ 03:09 am MST
Excellent write up - the last few paragraphs are really eye opening and also a good clarification on the limitations of mDNS - shame about the 192.168.x forwarding over a VPN. I'm going to set it up and see if what happens. Thanks MacTroll for putting in the effort and time to write it up.
Wide Area Bonjour - Part 2 Bring the Pain
Authored by: Anonymous on Tuesday, March 03 2009 @ 10:19 am MST
OMG!

If this is the way ARD 4 is supposed to work, a bottle won't be enough, we'll need a revolver!
Long Live AppleTalk!
Authored by: Anonymous on Wednesday, March 04 2009 @ 08:18 pm MST
My department is split across 7 private subnets - each in a different VLAN. I can't change this. But I was hoping Apple would help by allowing Leopard's WAB to work across private subnets without any "router magic". Here's hoping that Snow Leopard will address this issue!
(btw - I am not trying to promote AppleTalk; simply pointing out that it can offer (dynamic) registrations for all our computers across multiple (private) subnets - something that mDNS can't yet match!)
(also - our current solution is to have one G3 iMac in each subnet (floor) and use a Rendezvous Proxy server to statically provide a service list to each subnet - unfortunately this is neither dynamic nor easy to maintain!)
Wide Area Bonjour - Part 2 Bring the Pain
Authored by: Anonymous on Monday, September 28 2009 @ 05:45 pm MDT
Dear Author,
dear readers,

I have used your tutorial to set up this WAB. I use a Ubuntu Vserver as DNS Server. It is in fact the authoritative DNS Server for my domain domain.com. Now I want to use bonjour.domain.com. In your example you have a line: _dns-update._udp IN SRV 0 0 53 server.namespace.afp548.com. ; tells clients they can register

You didn't mention that server subdomain anywhere before. May I just chose any subdomain (abc.namespac....) or do I need to create another zone for that domain?

Later you say to chose any fance name when setting up the mac to use that WAB (my-bottle-is-almost-dry.namespace.afp548.com). Can I really just chose anything?

My Safari shows the static website, but my Time Capsule (which is set up correctly) doesn't show, nor does anything else my macbook publishes (checked in the bonjour browser) I would be very thankful if someone could help me out.

Thanks a lot. Best regards, David
Wide Area Bonjour - Part 2 Bring the Pain
Authored by: bastronaut on Friday, November 13 2009 @ 04:19 pm MST
Has anything changed in Snow Leopard (or Server) regarding this stuff?

Has anyone else noticed that Server Admin doesn't like you to change the WAB setting? That you have to edit it yourself if you want to toggle it or change the domain name?

The description of the dynamic global hostname prefs in the Sharing pane of System Preferences seems different than it looks in Snow Leopard. Or am I just misreading?

dnsextd has apparently been included in Mac OS X since 10.4. The article seems to suggest that you need to get it elsewhere.
Stan
Authored by: Anonymous on Friday, November 04 2011 @ 03:00 pm MDT
flat ugg flat uggActual UGG boots or fake? ugg boots on sale ugg boots on sale ugg cream boots ugg cream boots You can actually tell if your Uggs are authentic by looking for the authentic sheepskin interior.