The notification center stuff is awesome, and a really nifty hack - I just don't understand how Mavericks improved the handling of your private key + keychain. It's been pretty slick for quite a while.
When I first wrote the article, I wasn't aware that things like /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist existed prior to Mavericks. Shouldn't detract from the value of the article though which is to add Notifications. Last Mac I had I didn't recall it automatically launching a Keychain aware ssh-agent on-demand.
Well - the detraction is I spent about 15-20 minutes re-reading through your article, googling around, checking my system, checking apple review sites - trying to figure out what, exactly, it was that Mavericks was doing differently with keychain/private key integration. Might be worth editing the (really great) article so it doesn't appear that there is something new in Mavericks specifically.
This is pretty cool, and having notifications when the agent is used is really a good security bonus. So I'm pretty sad that I can't have this (requires Apple binary) AND a decently recent version of OpenSSH:
BUT, please think twice, thrice before installing a ssh-agent binary compiled by a stranger. You're hiring that binary to really hold your keys. You have to be really sure you can trust it.
As for the OpenSSH version, Apple forks OpenSSH and then adds things like Keychain and launchd(8) support. So if you want a later version while retaining those features, you'll have to get Apple's customizations applied to a later non-Apple version or wait until Apple does it themselves. Migrating my changes into a non-Apple version simply to say you have the latest version of OpenSSH would mean that you lose keychain and launchd(8) integration.
--
Devin
1. people should compile their own binary, since there is no easy way to know if you actually made only those edits in the provided binary (don't take it personally, really)
2. it's sad that Apple forked OpenSSH, since I can't have their integrations with a recent version
Homebrew's openssh formula include a patch for Keychain support:
$ brew info openssh
openssh: stable 6.6p1
...
==> Options
--with-keychain-support
Add native OS X Keychain and Launch Daemon support to ssh-agent
--with-ldns
Build with lens support
Perhaps you could add the notification patch to Homebrew's openssh and get the best of both worlds?
What's changed is that in Mavericks (really Mountain Lion or higher) we have the Notification Center. No longer do we have to rely on 3rd party software such as Growl to get notifications. However, Apple has not yet hooked ssh-agent into the Notification Center. This blog starts off kind of slow by first introducing folks not familiar with the existing Keychain/launchd integration and then goes on to follow that up by talking about future integration with Notification Center (providing working code and binary for others to experience a Notification Center aware ssh-agent).
--
Devin
I wonder whether this really is worth the risk of replacing a system binary. Showing these notifications feels like security theater to me: the agent never hands out the key but only signs a nonce with the key, so the operation it does is not really critical.
Additionally, ssh itself already prevents you from connecting to spoofed hosts (using the known_hosts mechanism).
So in the end we are left with a useless notification (which also only shows up after the action has been done and thus the damage, if you can call it that, has already been done) and zero protection against the real issue (key theft, which any application running under your account can easily do).
the agent never hands out the key but only signs a nonce with the key, so the operation it does is not really critical
The ability to sign is the ability to assert identity. If it's known that you connect to host B and host A is compromised but low value, if you forward your agent to host A, something on host A can use your agent to connect to host B and you wouldn't know. At least with notifications, you'd know something was up. This is why I made it easy to lock and unlock the agent on demand (mentioned in my other comment). Paired with on-demand agent locking, notifications let you know when the transaction is completed and you can lock your agent again.
Additionally, ssh itself already prevents you from connecting to spoofed hosts (using the known_hosts mechanism).
Only for the first hop. An ssh session on a remote host knows of a different set of host keys than the machine that is running the agent. Unfortunately, there doesn't seem to be a way to reliably identify which of a series of hosts that your agent socket may be forwarded through is using your agent.
As for the risk of replacing a system binary, that's why I hooked it through SSH_ASKPASS.
I had this setup in Linux by using a script like [1] as SSH_ASKPASS and loading the keys into the agent with -c. I had it paired with an xscreensaver hook that locked the agent when the screensaver was activated, bound the pause key to toggle locking and unlocking the agent (also with notifications), and a panel applet that indicated if the agent was locked. This made it so I could easily unlock the agent, and be notified of its use, on demand, then immediately lock it again.
Some notes on this setup:
1) the ssh-agent protocol doesn't seem to define a way for the asking system to identify itself. This would be useful even if it was spoofable, since you can forward the agent through multiple systems. If the protocol supported identifying the host by signing something with a key that's only on that remote system (maybe the host key?), it might make knowing the identity of the asking system more robust/secure. It could also enable things like loading multiple keys into the agent and restricting which keys can be used for a given host.
2) You'd get roughly the same thing just by using -c with the default SSH_ASKPASS program, because it pops up a dialog. In that case it's only looking at the exit code of the ask-pass program, so it's not really useful for anything other than acknowledgement (you could modify it to do something with the entered password though), and so using notifications is better because they don't steal focus (and are thus easily missed/dismissed while typing -- this would be fixable if gnome hadn't removed a bunch of window manager window management customizations).
3) I had some mass ssh scripts that would continuously hit my agent, which filled the screen with notifications. I'm sure this is fixable with a more robust notification setup and better timeouts.
4) it would be cool to be able to "prime the pump" of the ssh-agent before it gets used, and it would only accept one request per hit of a key or only accept requests for some amount of time. For example, if I'm going to proxy an ssh connection through another host, I'd prime it with two requests before sshing. A panel applet that showed how many requests or time is left would be helpful here.
5) of course, all of this is dependent on the security of the machine your agent is running on, how much you feel like trusting the stuff that runs on that machine (like the X server), and the security of each machine that you're forwarding the agent to. ssh-agent is an oracle and will sign anything you give it and because of 1) above there's no way to tell who is asking. So keep those socket directories locked down and don't use a system where you don't/can't trust the admin.
6) I could only get this to work with openssh's ssh-agent, gnome-keyring's built in ssh-agent support doesn't seem to support the -c option on key addition (which I consider a serious regression for something that should have feature parity with what it is intended to replace).
I use a different method for this: I get a dialog that asks me Allow/Deny every time the key is being used. All it requires is two shell scripts. It is a modification of a method I found on GitHub. Perhaps I should put these scripts out there and share them with HN next week when I am back at the office. That way the tutorial is about 4 times shorter and all the components are open source.
22 comments
[ 5.5 ms ] story [ 49.9 ms ] threadOr if you're on linux https://github.com/gdestuynder/openssh-portable/commit/bb0e9...
Or if you use gnupg https://github.com/gdestuynder/gnupg-agent-notification/comm...
Or if you use Windows and Putty https://github.com/gdestuynder/putty-pagent-notification (binary https://github.com/gdestuynder/putty-pagent-notification/rel...)
that's all i found
cd OpenSSH-186/openssh ./configure --with-pam --with-audit=bsm make
You can see from my commits at the following URL what I had to change to add support for Notification Center.
https://github.com/devinteske/apple/tree/master/OpenSSH-186/...
Namely I changed the following:
openssh/Makefile.in openssh/ssh-agent.c openssh/ssh-agent-notify.m [new] openssh/ssh-agent-notify.h [new]
As for the OpenSSH version, Apple forks OpenSSH and then adds things like Keychain and launchd(8) support. So if you want a later version while retaining those features, you'll have to get Apple's customizations applied to a later non-Apple version or wait until Apple does it themselves. Migrating my changes into a non-Apple version simply to say you have the latest version of OpenSSH would mean that you lose keychain and launchd(8) integration. -- Devin
1. people should compile their own binary, since there is no easy way to know if you actually made only those edits in the provided binary (don't take it personally, really)
2. it's sad that Apple forked OpenSSH, since I can't have their integrations with a recent version
This article is another example of how nifty launchd is.
Additionally, ssh itself already prevents you from connecting to spoofed hosts (using the known_hosts mechanism).
So in the end we are left with a useless notification (which also only shows up after the action has been done and thus the damage, if you can call it that, has already been done) and zero protection against the real issue (key theft, which any application running under your account can easily do).
The ability to sign is the ability to assert identity. If it's known that you connect to host B and host A is compromised but low value, if you forward your agent to host A, something on host A can use your agent to connect to host B and you wouldn't know. At least with notifications, you'd know something was up. This is why I made it easy to lock and unlock the agent on demand (mentioned in my other comment). Paired with on-demand agent locking, notifications let you know when the transaction is completed and you can lock your agent again.
Additionally, ssh itself already prevents you from connecting to spoofed hosts (using the known_hosts mechanism).
Only for the first hop. An ssh session on a remote host knows of a different set of host keys than the machine that is running the agent. Unfortunately, there doesn't seem to be a way to reliably identify which of a series of hosts that your agent socket may be forwarded through is using your agent.
As for the risk of replacing a system binary, that's why I hooked it through SSH_ASKPASS.
Some notes on this setup:
1) the ssh-agent protocol doesn't seem to define a way for the asking system to identify itself. This would be useful even if it was spoofable, since you can forward the agent through multiple systems. If the protocol supported identifying the host by signing something with a key that's only on that remote system (maybe the host key?), it might make knowing the identity of the asking system more robust/secure. It could also enable things like loading multiple keys into the agent and restricting which keys can be used for a given host.
2) You'd get roughly the same thing just by using -c with the default SSH_ASKPASS program, because it pops up a dialog. In that case it's only looking at the exit code of the ask-pass program, so it's not really useful for anything other than acknowledgement (you could modify it to do something with the entered password though), and so using notifications is better because they don't steal focus (and are thus easily missed/dismissed while typing -- this would be fixable if gnome hadn't removed a bunch of window manager window management customizations).
3) I had some mass ssh scripts that would continuously hit my agent, which filled the screen with notifications. I'm sure this is fixable with a more robust notification setup and better timeouts.
4) it would be cool to be able to "prime the pump" of the ssh-agent before it gets used, and it would only accept one request per hit of a key or only accept requests for some amount of time. For example, if I'm going to proxy an ssh connection through another host, I'd prime it with two requests before sshing. A panel applet that showed how many requests or time is left would be helpful here.
5) of course, all of this is dependent on the security of the machine your agent is running on, how much you feel like trusting the stuff that runs on that machine (like the X server), and the security of each machine that you're forwarding the agent to. ssh-agent is an oracle and will sign anything you give it and because of 1) above there's no way to tell who is asking. So keep those socket directories locked down and don't use a system where you don't/can't trust the admin.
6) I could only get this to work with openssh's ssh-agent, gnome-keyring's built in ssh-agent support doesn't seem to support the -c option on key addition (which I consider a serious regression for something that should have feature parity with what it is intended to replace).
[1] https://gist.github.com/thwarted/ea392da4da0aaf8f9c19
https://github.com/TimZehta/mac-ssh-confirm
Does not require compiling, only XQuartz installation.