Ssh – How to arrange for an ssh key with a passphrase to be loaded and available in ssh-agent to other processes on Windows startup

cygwindeploymentsshssh-keys

I'm setting up automated deployment of applications in a Windows environment from continuous integration (TeamCity build-agents), and using cygwin + openssh to perform the remote-execution part of that – I'm basically using ruby's capistrano with a bunch of custom tasks.

Since the build-agent is runnings as a windows service on the box, it's headless. The box doesn't sit with a user signed in, and so there's no opportunity for a user to type the key's passphrase when (for example) keychain or pageant might otherwise be loaded.

So currently, the passphrase is hard-coded in the deployment script – I mean, in a single place, so it's not scattered all over, but still, seems like there must be a more secure way of doing this.

Can anyone tell me what it is? 🙂

  • I don't really want to not use a passphrase.
  • I'd prefer to not have to manually sign in to the build-agents each time they're rebooted to do some step to give each the passphrase so the key can be loaded.

Update:

  • I chose to use passphrase'd keys because it seemed inherently more secure, until I later ran into the obstacle of how to unlock the key for a headless process. The idea was that only people that had the key's passphrase would be able to deploy. Perhaps I want one (closely controlled) passphrase-less key for the CI build-agents to use, and one passphrase'd key for humans to use?

Best Answer

SSH in a Windows environment is an unusual option. Most people would use WMI to deploy applications and manage remote systems. Jenkins-CI (formerly Hudson-CI) makes great use of WMI for this purpose, so have a look there for examples.

But, you're on SSH, so I recommend you generate SSH keys without passwords.

It'll be harder to shouldersurf or guess (unencrypted) SSH keys compared to stealing or guessing a regular password.

Combine the unencrypted SSH with IP restrictions and log monitoring, so you'll know instantly if someone stole a key and tried to log in from another host using the stolen key.

If you didn't already: Consider a design that allows your high-value hosts to connect out to your application nodes, rather than the other way around.

If your (exposed?) nodes connect via SSH to a central server for application updates, consider using ForcedCommand and ChrootDirectory to restrict how much data is available to an attacker who tries to use an application node to attack your golden host.