Monday, September 7, 2009

Accessing a Linux File Server from OS X using AFP

I keep most of my data on a low-power Ubuntu server that sits underneath my TV.  The data isn't much good to me if I can't access it, so I've mounted the server as a network drive on OS X.  This post will show you how to do the same.

I first discovered how to set up AFP from this article on kermalicious.com.  It's slightly out-dated but feel free to go there if you want info direct from the source, especially if you run into issues with these instructions.

Step 1: Set up Netatalk on the Server

I'm using a server running Ubuntu 9.04 for these instructions.

Netatalk is the open source version of Apple's AFP (AppleTalk Filing Protocol), which provides remote filesystem access similar to NFS, Samba etc.  I've found AFP to integrate a little better with OS X.  sshfs is faster, and more secure, but I had trouble getting it to reliably automount.

First install Netatalk. It comes out-of-the-box with encrypted authentication these days, so no need to compile your own.
sudo apt-get install netatalk

Now configure AFP services by editing /etc/default/netatalk to contain only the necessary daemons (CNID_METAD and AFPD):
ATALKD_RUN=no
PAPD_RUN=no
CNID_METAD_RUN=yes
AFPD_RUN=yes
TIMELORD_RUN=no
A2BOOT_RUN=no
the rest of the defaults should be fine.

The last bit of Netatalk configuration is in /etc/netatalk/afpd.conf.  Set the last line of the file to the following:
- -transall -uamlist uams_dhx2.so -nosavepassword

This ensures that we only use Diffie-Hellman key exchange (DHX) for authentication, rather than plaintext passwords or something silly like that.

Step 2: Set up Shared Volumes

Did I say that was the last bit of configuration?  I lied, kinda.  We need to configure the volumes we wish to share via AFP - right now our server speaks AFP, but it doesn't have anything to share.  This is done by editing the file /etc/netatalk/AppleVolumes.default.

Each volume you wish to share goes on a line at the bottom of this file.  By default all users will be able to access their own home directories (~/  "Home Directory"), but you can change that to the following:
~/        "$u"        options:usedots,upriv

The "$u" will call Bob's home directory "Bob" rather than "Home Directory".  The usedots option is necessary if you want to use "invisible" dot files (such as .profile), and upriv adds support for unix privileges (but apparently has problems with OS X Tiger or older).

You can have other volumes shared - I have the following:
/home/cowling/TimeMachine TimeMachine allow:cowling options:usedots,upriv
/home/media Media allow:cowling,media options:usedots,upriv

Now restart netatalk and we should be set!
sudo /etc/init.d/netatalk restart

Step 3: Connect to the Remote Volume on OS X

This should be pretty straight-forward.  In Finder go to Go -> Connect to Server..., enter afp://servername, your username and password, and hopefully it all works!

If you want to access a volume from behind a NAT/firewall, you'll need to forward/open port 548.

If you don't want OS X putting .DS_Store files in every folder you access (you probably don't), you can turn these off for remote volumes by running the following in the OS X terminal:
defaults write com.apple.desktopservices DSDontWriteNetworkStores true

Optional: Automatic Discovery using Bonjour/Avahi

As in the last post on setting up music server, you need to set up Avahi if you want OS X to automatically detect shared volumes on your local network, and pop them up in the Finder side panel.

First install Zeroconf/Avahi if you haven't already:
sudo apt-get install avahi-daemon

Set up the AFP service by creating a file /etc/avahi/services/afpd.service containing:

<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_afpovertcp._tcp</type>
<port>548</port>
</service>
<service>
<type>_device-info._tcp</type>
<port>0</port>
<txt-record>model=Xserve</txt-record>
</service>
</service-group>


and restart avahi:
sudo /etc/init.d/avahi-daemon restart

If you have a firewall that's blocking Avahi, you'll want to open port 5353.  There's not much point forwarding this port on a NAT, since Avahi only works within a local network.

If all went well, your server will show up in the panel on the left of the Finder window. Yay, we're done!  As always, let me know if you encounter any errors with these instructions.

Have fun.

James

Monday, August 31, 2009

Setting up an Ubuntu Music Streaming Server using Firefly

If you're like me, you probably:
  • have too much music to fit on your laptop HD
  • end up storing your music on an external HD but hate carrying it around everywhere
  • want to listen to your music from your other computers
  • have access to a linux server somewhere

If you're lucky, those are the only things you have in common with me. If so, great, I'm going to show you how to serve music from a linux machine.

Now there are a few caveats before I start:
  • you'll want to have a decently fast network connection
  • it's nicer to look at your neatly-categorized music locally through iTunes cover browser interface than as a shared library
  • your library won't maintain play counts etc, and I haven't tried using ratings
  • I don't have a perfect solution for syncing an iPod/iPhone, but there are some half-baked solutions you can look into

I'm going to assume the laptop you're using is a Mac and the linux box is running Ubuntu 9.04 or greater, but most of these instructions should translate somewhat to other OS's/distros.

Oh yeah, and before you do any of this stuff, back up your music. No one wants to make a mistake and lose years of collected tracks.

Step 0: Clean up your Library

Now is a really good time to clean up your library: get rid of the old crap you don't listen to, fix your ID3 tags, add album art, replace missing songs in albums etc. I just deleted my iTunes library file and selectively added back music one album at a time when I wanted to listen to it, and have since become a bit obsessive about keeping my library organized. I lost my playlists etc, but they were all a mess anyway. You could back up this stuff if you want.

iTunes doesn't have art for a bunch of my music, so I used this widget to pull art off Amazon.

Step 1: Install Firefly

I'm assuming you have a working Ubuntu installation and you know your way around the command line.

Firefly (also known as mt-daapd) is the program that exports your library as a DAAP stream, which is Apple's protocol for iTunes media sharing. Apple have changed the protocol in recent versions of iTunes to make it incompatible with other programs, but Firefly uses a version of the protocol that works fine.

Install Firefly (mt-daapd):
sudo apt-get install mt-daapd

Now edit /etc/mt-daapd.conf to your liking. The defaults are a good start, but you'll want to change admin_pw, mp3_dir, servername and password. You can change many of these settings through the web interface once you get going. I created a new user account named "media" to store my media on the server, added myself to the "media" group, and pointed mp3_dir to /home/media/music, but do as you please. servername is whatever you want your stream to be listed as in iTunes. admin_pw is the password used to access the web configuration interface, while password is just the password people need to enter to listen to your shared library.

Now restart Firefly:
sudo /etc/init.d/mt-daapd restart

If this worked so far, you should be able to access the web configuration interface at http://servername:3689. Make sure you forward port 3689 on your router (if you're behind a NAT), and open that port on your firewall (if you have one).

Step 2: Connect to your Shared Library

Now the exciting part.

We can't connect to the stream in iTunes yet, but we can with any other program that connects to DAAP streams. I use Songbird, which I'm hoping to fully transition over to from iTunes at some stage.

Install Songbird and the Songbird Daap Client add-on. Then go to File -> New DAAP library, type in daap://servername:3689, and it should load your library in Songbird!

Wait wait, that wasn't very exciting - we haven't added any music yet! We'll get to that now.

Step 3: Move Your Music to Your Server

Your music might be neatly organized, but if you're using iTunes, all your album art is sitting in a separate database file. I used this Applescript to embed all the art back into the ID3 tags.

Now just copy your music folder across to your server, using rsync, scp, or from an external HD. (One day I'll post an article about mounting an HFS+ formatted HD in linux.)

I came across one small complication here: mp3 files have two types of ID3 tags - v1 and v2. iTunes writes tag information to the ID3v2 tag, but ignores the ID3v1 tag, which can leave bad tag data lying around to confuse other programs. I fixed this problem in bulk by stripping away the ID3v1 tags using a program called id3v2.

sudo apt-get install id3v2
id3v2 -s *.mp3
id3v2 -s *.m4a

I didn't lose any useful tag data this way. If you want to be on the safe side, you can select your mp3s in iTunes, right-click, select Convert ID3 Tags, and convert the tags to v2.3.

Step 4: Enable iTunes Sharing

Are you sure you still want to use iTunes? Okay, I still do, but bear in mind that you can only connect to your library if you're on the same subnet. There are ways around accessing libraries on different networks, but you're better off just using Songbird in this case.

iTunes doesn't just let you type in the location of a DAAP share - that would be too easy. Instead it uses Zeroconf (Bonjour) to automatically discover shared libraries on your network. What we need to do is set up the Ubuntu server to advertise Zeroconf services using Avahi. This can also be used to advertise a network drive from the server,but that's the topic of another discussion.

First install Avahi:
sudo apt-get install avahi-daemon

At the time of writing, there's a race condition between Avahi and Firefly in the current Ubuntu packages.  This sometimes prevents Firefly from loading. The bug can be fixed by applying the following patch

for 32 bit:
wget http://launchpadlibrarian.net/26549308/mt-daapd_0.9%7Er1696.dfsg-9_i386.deb
sudo dpkg -i mt-daapd_0.9%7Er1696.dfsg-9_i386.deb

or for 64 bit:
wget http://launchpadlibrarian.net/26923010/mt-daapd_0.9%7Er1696.dfsg-9ubuntu1_amd64.deb
sudo dpkg -i mt-daapd_0.9~r1696.dfsg-9ubuntu1_amd64.deb

Hopefully this bug will be fixed in Ubuntu 9.10.

Now create a file /etc/avahi/services/mt-daapd.service containing:

<?xml version="1.0" standalone='no'?>
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
<name replace-wildcards="yes">%h</name>
<service>
<type>_daap._tcp</type>
<port>3689</port>
<txt-record>txtvers=1</txt-record>
<txt-record>iTSh Version=131073</txt-record>
<txt-record>Version=196610</txt-record>
</service>
</service-group>


Restart Avahi:
sudo /etc/init.d/avahi-daemon restart

and your DAAP share should pop up in the iTunes sidebar on any of the computers in your local network.

Step 5: Listen to Some Music

Are we done? I hope so! If I've left something out, or made an error, please let me know in the comments. Bear in mind that I might not have time to help with specific problems.

James