Today I decided to finally formalize my staging process a bit more than I used to and started setting up a new test (for starters) environment from scratch. The environment I need is not very demanding: basically, I just need W2008R2 (incl. IIS 7.5) and .Net 4.0. However, for deployment purposes I’d also like (amongst some other things which don’t really matter now) an SSH server on my boxes.
I’ve been using openssh (the one that comes with the Cygwin project) for quite some time now and, up until now, I’ve always installed it manually. The installation is pretty simple, but every time I do such an installation it takes me a few retries before I remember every step exactly, not very efficient… And, anyway, why do anything manually when you can automate it, especially when it’s as simple as this:
- Download the Cygwin installer and save it to a folder were you want to run your installation from
- Put the following lines in a windows batch file, let’s say install-ssh.bat (alongside the setup.exe)
setup.exe --quiet-mode --root C:\cygwin --site http://<the closest source to you> --packages openssh cd c:\cygwin\bin bash --login -c "/bin/ssh-host-config -y -c ntsec -u sshd_account -w <your password here>" bash --login -c "/bin/ssh-user-config -y -p <your password here>" sed -i.bak "s/#.*PasswordAuthentication.*yes/PasswordAuthentication no/" /etc/sshd_config netsh advfirewall firewall add rule name=SSH dir=in action=allow protocol=tcp localport=22 net start sshd
Now, issuing install-ssh at the command line should install openssh and start the sshd service in less then a minute…
What happened?
The first line simply runs the cygwin installer without requiring user interaction. When you run it, you’ll notice that the install wizard will show, but without you having to ‘push the buttons’ — I don’t know if there’s a way to hide the GUI as well, I didn’t mind. The command line options speak for them selves, I guess.
After the installation is done I change my working dir to the bin folder of cygwin. This isn’t important, it’s just a convenience, it allows me to call bash without the full path…
Next, we configure the ssh host with predefined options, instead of getting prompts. The options I’m using are:
- confirm all queries with yes (-y)
- instruct cygwin to use Windows’ security rules for controlling users’ access to files and other operating system facilities (-c ntsec)
- create a new local (priviledged) account ‘sshd_account’ with the specified password (-u sshd_account -w )
The ssh-user-config script is executed to generate a new private and public key pair for the current user with the specified passphrase to protect the private key. I’m fine with moving the generated private key to my deployment server in order to connect, but you don’t have to, you could even skip this command if you’re fine with username password authentication.
The sed command is related to the previous one: it simply disables password authentication by substituting the appropriate commented-out option in the sshd configuration file.
Finally, before starting the sshd service, I’m adding a firewall rule to accept incoming traffic on the default ssh port.
Connecting from a client
As mentioned above, I’m fine with moving the generated private key to my local deployment server. One reason for this (and not using some previously generate key-pair) is that it helps avoiding deploying to the wrong environment by mistake, the all have their dedicated key — no guarantee, of course. So, what I’m doing is copying the /home/user/.ssh/id_rsa file to my local depoyment server as env-user.key and connect using the following command:
ssh -i /path/to/env-user.key user@remote_host
For deployment I’m actually using a rake task that uses the SharpSsh .Net library (I’m using IronRuby).
Disclaimer
I’m not guaranteeing this will work in any given environment, but I’ve tested this on my Windows 7 and Windows 2008 R2 boxes, works like a charm for me…