SSH tunnels for the common man (and woman)

Thanks to the fine folks at TUAW, I’ve been alerted to an interesting start to a series at Apple Matters called Using SSH: Secure Tunnels for the Common Man. There’s a nice bit of explanation on the need for and the basic concepts behind SSH tunneling.

Of course I’d be remiss to not mention Meerkat, Code Sorcery Workshop’s next application, built specifically to address the need for easy and feature-rich management of SSH tunnels. Even for folks like me who know the Terminal commands for SSH and the concepts behind rather arcane uses such as dynamic forwarding as a SOCKS proxy, it’s very useful to have menu bar access, Growl integration, Bonjour capability, and other Mac-like features for a classic UNIX tool like SSH.

However, I think that even with a tool like Meerkat, it’s important to have some sort of forum or knowledge base for various uses of SSH, which is something that I hope to start when Meerkat launches. It’s tricky because part of an SSH tunnel is inherently personal (e.g., your account details), but the basic concept can be shared for other people — whether it’s tunneling to your home iTunes collection, accessing your colocated Mac server securely via screen sharing, or securely browsing the web while on guest networks.

Anyway, give the article a look. I look forward to the upcoming installments — SSH is a dark art to many and it’s good to shed some light on it!

Comments (5)

Feature requests versus the “right way” to do it

One of the challenges of developing Mac software, particularly for an audience that is generally more technical than the average user, is that your users compare your application to others that are out there on the basis of how they utilize the rich set of technologies available on Mac OS X. And I’m not just talking competitors here, but any Mac application. This can be both a blessing and a curse, as it can inform you of and inspire you to add great new features, but can also cast a seemingly bad light on your own product if you are unable or unwilling to implement certain functionality. Users often don’t care why you might not want to or can’t implement features which are, in your own estimation, not the “right” way of doing something — at least not right now. Other apps are doing it, why can’t you?

I’m hoping to provide some insight into my thought process on making these judgement calls and talk about a specific issue that I’ve been working on in this department. I’ll get a bit technical, but I’ll try to explain along the way for the non-programmers in the room. And I’ll mention a couple of other apps by name that handle the same issue in different ways. I don’t mean to call out or embarrass anyone, and all the apps that I mention are ones that I use (and love) on a daily basis, but I want to show what other developers are doing. Lastly, I have an overriding goal here to be a somewhat exhaustive resource for this particular issue for other programmers to find, too.

What’s up, dock?

A big feature request that’s been hanging around for some time for Pukka is the ability to run without a dock icon. For a utility with a small footprint like Pukka, this makes a lot of sense for a number of reasons:

  • As of Pukka 1.6, a status bar menu provides omnipresence for all of the app’s “background features” — looking up bookmarks and visiting your links online.
  • Pukka is not visible when you are not using its “foreground features” — posting bookmarks — anyway. Some users would like to not have to think about it by seeing it in the dock and task switcher.
  • Pukka has long supported a “quit after posting” feature which quits the app entirely after a post is made. Since you can call Pukka via your RSS reader or the browser bookmarklet and since it’s lightweight and starts quickly, Pukka can come and go only when you need it. People who like an uncluttered dock really appreciate this, though some people would rather have Pukka running all of the time, but still not in the dock. After all, lingering invisibly in the background is faster than starting up on demand.
  • “All the other apps are doing it!” :-) Apps that I use that have a user-configurable dockless mode include Twitterrific, MenuCalendarClock, Knox, BluePhoneElite, SSHKeychain, and iShowU. There are many more that do as well.

I should make a distinction here between applications like Lighthouse, Macaroni, and Growl (which I also use) which always run dockless, since these apps have alternate interfaces — typically robust status bar menus or preference panes — that allow use of the application. I’m talking about applications that let you choose on a whim whether you’d like to run without a dock icon or not — defaulting, of course, like normal applications, to running with a dock icon.

Users who are used to dockless apps know the downsides — no application switching, the app doesn’t show up in the Force Quit menu, and sometimes there are window focus issues — and are willing to accept them as limitations in Mac OS X. But there are some issues on the developer side that make this feature more difficult than one might think at first pass.

How do you work this thing?

The only real way* to make an application run dockless is to change a setting in a file inside of its application bundle — though a variation on this exists, as I’ll describe in a little bit.

* I do know about TransformProcessType, a Carbon call, which can go from dockless mode to having a dock icon, but this has to happen too early in the launch process to read a user’s preference setting, plus it’s only a one-way transition.

A Mac application is actually a folder named <application name>.app containing a number of files and folders, one of which is called Info.plist. This property list file contains entries such as the application’s name, version, copyright info, and other info used by the system to query what the application is all about.

If you add an entry to an application’s Info.plist called LSUIElement and set its value to a string containing the number one, relaunching the application will make it go dockless. There are even applications like Dockless and Dock Dodger that will do this for you for a given application. Most of the applications that I mention above use this method to go dockless.

However, I’ve long preferred not to do this for a couple reasons:

  • It’s bad form for an application to modify itself — though I realize it’s not the end of the world.
  • If the user is not an admin or if the application is located someplace like a network-mounted share, the user will not be able to — and shouldn’t be able to — modify the app bundle that is shared by other users or even other computers.
  • Lastly — and this is the big one — Apple introduced code signing in Leopard and, according to the documentation, it’s only a matter of time before this method of altering the Info.plist will render the application unusable.

With code signing and Info.plist modification on the fly, the writing is on the wall:

A seal, which is a collection of checksums or hashes of the various parts of the program, such as the identifier, the Info.plist, the main executable, the resource files, and so on. The seal can be used to detect alterations to the code and to the program identifier. #

Various components of the application bundle (such as the Info.plist file, if there is one) are also signed. #

Your code must be immutable once signed. After signing, do not attempt to change executable code (including symbol tables), the Info.plist, or your program’s resource files. Do all that before signing. If you make modifications after signing, the signature may be invalid. #

And according to Apple, you should be signing code now. Not doing so can interfere with the keychain user experience, Parental Controls, firewall, and other integrated systems in Leopard that rely on code signing.

So, where does that leave us?

When I talked to Marko Karppinen, whose company makes the excellent Knox security application, at last summer’s C4 in Chicago, he let me in on how he accomplished a user-specified dockless setting in that application.

If you look at the application bundle, it contains another copy of the application within a subfolder of the app bundle itself — sort of a Russian Doll. But if you look closer, you’ll see that all of the components of this “inside” application are actually symbolic links to the parent application’s version, except for the Info.plist file. And — you guessed it — the internal Info.plist has the LSUIElement set. For the curious, here is a shell script that I came up with to be used as an Xcode build phase to accomplish this.

I’m actually using this method successfully with Meerkat, my next application (which is currently in private beta) and it’s working ok for now. On launch, the application checks to see if if the user’s preference setting matches the setting of the version being launched and if not, it launches the other one. Pretty sweet, right?

It is, except for one thing in Pukka’s case — Apple Event targeting. Besides being launched normally, Pukka can be launched by a number of external forces, including:

  • AppleScripts that interact with Pukka
  • Posted information from RSS readers like NetNewsWire using its author’s External Weblog Editor Interface
  • Pukka’s bookmarklet, which actually uses a custom pukka:// protocol to pass information
  • Opening http:// and https:// URLs with Pukka like you would with an alternate web browser
  • Opening a supported file, such as a .webloc on the desktop, a Pukka license file, or one of the Spotlight files that Pukka generates for easy access to your bookmarks via system searching

On launch, not only do I have to figure out if the right version is running, but if not, I have to pass whatever information actually launched the application to a new process. I’ve actually managed to accomplish this for everything but AppleScript, but it’s still non-ideal. It comes down to the fact that it’s just generally bad practice to have more than one copy of the same application on the same hard drive because Mac OS X’s Launch Services can get confused as to which one it should be targeting.

On top of that, since Pukka uses Sparkle for auto-updating, some issues needed to be resolved in order to update the outer, docked application and not the internal, dockless one, even if the internal one is the one running the update. Overwhelmed yet?

Now what?

So right now, I’m at a loss as to how to proceed. Apple doesn’t provide a tried-and-true way to let the user toggle an application’s dock mode and although many applications implement this, it seems to me that no way is fool-proof nor future-proof. The last thing I’d want is to release the feature but have to revoke it later from paying customers because it’s untenable.

Cocoa developers, anything obvious that I’m missing? Have you tackled these challenges? Are you thinking about adding the same feature to your application?

Comments (9)

Meerkat use case: iTunes at home, music anywhere

I thought I’d take a moment to outline a sample use case for Meerkat, one that goes outside the normal scenarios that most people think of when (or if) they think of SSH tunneling. Since Meerkat supports app triggers and Bonjour, it goes above and beyond plain old SSH and can really be used in some innovative ways.

Suppose that you have a large iTunes music collection on your home Mac that you either don’t want or can’t fit on your work Mac or your laptop because of its size. If you enable iTunes sharing on this home Mac, as well as SSH (under System Preferences -> Sharing -> Remote Login), you can use Meerkat to connect to this music collection from any other Mac running Meerkat and iTunes.

Just setup a tunnel in Meerkat using an account with the IP address, username, and password of your home Mac.

Meerkat-based iTunes sharing thumbnail

Meerkat-based iTunes sharing (click for larger screenshot)

You would pick port 3689, since this is what iTunes uses for music sharing, and an arbitrary port on the local Mac (doesn’t matter what). It only takes a few seconds to setup a tunnel like this.

Because of the app trigger, whenever you start iTunes on the Mac running Meerkat, Meerkat will automatically connect to your home Mac securely and, because of Bonjour, your home iTunes collection will show up right in iTunes’ source list, just like a Mac on the local network. You just select the collection and stream the music, just like if your home Mac was with you at work or next to your laptop at the coffee shop. It couldn’t be easier!

Plus, Meerkat responds automatically to sleep and wake of your Mac as well as network change events such as outages or a change of location. Just set it and forget it!

After Meerkat is released, I hope to maintain a list of scenarios like these. If you have any further ideas, feel free to post them below, and if you’re interested in being considered for the upcoming private beta, just leave a comment!

Comments (3)

Meerkat preview: Setup Assistant

Continuing in my set of blog posts previewing my upcoming application, Meerkat, I’d like to take a moment to show off another handy feature of this SSH tunneling utility.

I often find that when I’m setting up an SSH tunnel, even though I know my way around the tool pretty well, I have to consult the man page to figure out what flags to use and which direction to setup the hosts. It can get confusing.

That’s why in Meerkat, I’ve created a setup assistant which helps guide you through quickly setting up a tunnel. While you can use the normal interface, particularly when you’re editing an existing tunnel or are very used to the process, the setup assistant walks you through the basics quickly.

Meerkat Setup Assistant thumbnail

I’m hoping that this feature will help people more easily setup SSH tunnels with Meerkat. Stay tuned for more preview details soon!

Comments off

And for my next app… Meerkat!

I’m happy to announce that I’m very near the beta stages of my next application — introducing Meerkat! In this post, I’ll cover a couple of the major features of this new utility, but stay tuned for more info in future posts!

Meerkat is an SSH tunnel manager designed for the developer or systems administrator with the need for multiple tunnels and advanced, automated management.

Meerkat thumbnail

Meerkat (click for larger screenshot)

Meerkat allows you to easily set up SSH accounts and associated tunnels and activate and deactivate them via the main window, the dock, or the status bar.

Meerkat's dock menu

Meerkat dock menu

Meerkat integrates with Growl to notify you of background tunnel management.

Meerkat's Growl notifications

Meerkat Growl notification

One of Meerkat’s signature features is application triggers. Meerkat can automatically bring up or tear down tunnels in response to applications that you launch and quit.

Meerkat application trigger thumbnail

Meerkat application trigger (click for larger screenshot)

On top of this, Meerkat can optionally advertise your tunnel endpoints over the LAN via Bonjour, Mac OS X’s convenient networking protocol. A great, practical use of this is connecting to your home computer’s iTunes collection and having it show up in your local iTunes, no matter what kind of firewall you may be behind (providing it allows SSH, a secure, encrypted protocol).

Another use for Meerkat’s Bonjour feature is to securely provide access to a remote database server to a local office for development purposes. The possibilities are endless — Leopard’s Finder uses Bonjour to see VNC servers, Safari recognizes web servers on the LAN using Bonjour, and Terminal uses Bonjour to find SFTP servers. And you can define custom Bonjour protocols to meet your own needs.

Meerkat Bonjour customization

Meerkat Bonjour customization

That’s all for the Meerkat preview for now! If you’d like to be considered for the Meerkat beta, just leave a comment below. (Unless you put it in the body of the comment, your email address is only viewable to me.)

Happy holidays everyone!

Comments (25)