Hacking Time Machine

It’s “hack some shit up” Friday. Everybody ready?

Have a Time Capsule or Mac OS X Server configured to provide network time machine backups? Of course you do! Let’s examine the client / server interaction.

The Time Machine preference pane provides a list of available backup volumes. This list includes local volumes as well as network volumes. Mac OS X makes extensive use of multicast dns for service discovery, so let’s check there first. Get yourself a copy of Bonjour Browser, then fire it up and look under ‘local’ for things that seem interesting. Ooo there’s one called “adisk”, let’s check in there…

From http://www.dns-sd.org/ServiceTypes.html we see:

adisk          Automatic Disk Discovery
                Bob Bradley <bradley at apple.com>
                Defined TXT keys: sys, dkX

We could read a bit more about service discovery via multicast dns to learn that:

DNS-SD uses DNS TXT records to store arbitrary name/value pairs
conveying additional information about the named service. Each
name/value pair is encoded as its own constituent string within the
DNS TXT record, in the form "name=value".
...
The intention of DNS-SD TXT records is to convey a small amount of
useful additional information about a service. Ideally it SHOULD NOT
be necessary for a client to retrieve this additional information
before it can usefully establish a connection to the service. For a
well-designed TCP-based application protocol, it should be possible,
knowing only the host name and port number, to open a connection
to that listening process, and then perform version- or feature-
negotiation to determine the capabilities of the service instance.
For example, when connecting to an AppleShare server over TCP, the
client enters into a protocol exchange with the server to determine
which version of the AppleShare protocol the server implements, and
which optional features or capabilities (if any) are available.

Ok, so there’s a record there, and along with the standard parts of the record, there are two additional key / value pairs in the text record portion. The meaning of the keys and values is probably only known for sure by Time Machine and friends, but certainly some of that data looks familiar.

First there’s the IPv4 address… that’s probably provided automatically when the record is published, based on the machine’s current IP address. IPv6 address follows, again we needn’t worry about that. The port number is listed at 9, which is ‘discard’, so this is probably not used. What port *is* used, then? Well, we know that Time Machine over the network supports either AFP or SMB, so it’s going to be one of those two. Seems like AFP would be most common, just since it is the APPLE file protocol and whatnot…

Then we have the sys and dk0 items… well I dunno what waMA means (something something mac address?), but what follows certainly looks like a MAC address… and sure enough, it matches the MAC address on my Time Capsule.

Note also that the second key in the shown record is dk0, whereas the spec says the defined TXT keys are “sys, dkX”. The “X” here suggests that there might be more than one of these keys, and they are numbered starting from 0 and counting up. Let’s pick appart the dk0 entry.

dk0=adVF=0xa1,adVN=backupz,adVU=AF9AC8F1-BCF5-3E63-9EBD-CD171CF5061B
  • adVF: no idea
  • adVN: hmm… another “adV” prefix. air disk volume? air disk volume name?
  • adVU: air disk volume UUID! (I think)

Ok, now let’s have some fun. Fire up file sharing. Click the little + button to create a new share point. Select a folder / volume that has some eh… free space on it :) The name of the folder / volume as it appears in the list of share points is the AFP share point name, so we should try to use that for ‘adVN’.

Next, use diskutil to find the UUID for the volume on which your new share point resides. The argument after “info” is the path to the volume. “/” for the boot volume, “/Volumes/whatever” for something other than the boot volume.

sudo diskutil info / | grep "UUID"

Finally, find your system’s MAC address (the one that corresponds to your primary network interface).

netstat -rn | grep default | awk '{print $6}' | xargs ifconfig | grep ether

Now we should have enough information to try to create a record. Looking at the man page for dns-sd, we see the basic usage for registering a record is:

dns-sd -R name type domain port [key=value ...]

Let’s try it! We still don’t know what adVF is, so we’ll just use 0xa1 like the Time Capsule does and see what happens. In the command below, replace 00:11:22:33:44:55 with your MAC address, “Backupz” with your new share point name, and “AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE” with the UUID of the volume on which your share point resides.

sudo dns-sd -R "Back it on up" "_adisk._tcp." "local" "9" \
        "sys=waMA=00:11:22:33:44:55" \
        "dk0=adVF=0xa1,adVN=Backupz,adVU=AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE"

You should see something similar to

Registering Service Back it on up._adisk._tcp..local port 9 TXT ...

Leave that window open. Open a new terminal window.

dns-sd -B _adisk._tcp

You should see your service instance listed. cntrl-c. Get the details:

dns-sd -L "Back it on up" _adisk._tcp local

Looks good. Now go to another mac on your local network. Open the Time Machine prefpane. Click “Choose Backup Disk…”.

Cool!

Limited testing has shown that once you pick a network Time Machine disk in this fashion, the multicast dns service advertisement record is no longer needed. Apparently the Time Machine client caches the information about the location of the network disk. Also, probably a good idea to make sure that your network time machine volume is not guest-accessible…

Here’s a little script to ease the process…

#!/bin/sh
# Instructions:
# 1. Use the Sharing preference pane to configure an AFP share point that will
# be your network backup volume. Connect from another mac using Finder -->
# Connect To Server. Make sure you can log in. Note the name of the AFP volume.
# 2. Use diskutil info to get the UUID from the volume on which your AFP
# sharepoint resides.
# 3. Customize the values below.

# Customize here
servicename="Back it on up"		# the name shown in parens in the TM browser
macaddy="00:11:22:33:44:55"		# MAC address of the AFP server
volname="backupz"				# AFP sharepoint name
voluuid="6E132F57-8292-4A73-9B37-5C0F82928E85" # volume UUID 

# 4. Make sure this script is executable (chmod +x), then run it. You will be
# prompted for your password (must be admin).
# 5. Go to your other mac, use the Time Machine prefpane to select your shared
# AFP volume. The other mac needs to be on the same local network.
# 6. After selecting the volume, you can cntrl-c this script to stop it.
# 7. Enjoy your network time machine backups!

# no touchy
servicetype="_adisk._tcp."
domain="local"
port="9"
adVF="0xa1"			# magic?

# we need at least two key / value pairs, like such:
# sys=waMA=00:1F:5B:34:BC:41
# something something Mac Address, I guess...
# dk0=adVF=0x0a1,adVN=TM Test,adVU=AF9AC8F1-BCF5-3E63-9EBD-CD171CF5061B
# dkn iterates starting with dk0, then dk1... these are backup volumes
# adVF is ... something. I used trial and error to find that 0xa1 works
# adVN is volume name
# adVU is volume UUID, which you can get from diskutil info.

# dns-sd -R name type domain port [key=value ...]
sudo dns-sd -R "$servicename" "$servicetype" "$domain" "$port" \
		"sys=waMA=$macaddy" \
		"dk0=adVF=$adVF,adVN=$volname,adVU=$voluuid"

Have fun :)

About dre

I like all kinds of food.
This entry was posted in development, OS X, OS X Server, scripts. Bookmark the permalink.

3 Responses to Hacking Time Machine

Leave a Reply