
Simplify your life with an SSH config file - koide
http://nerderati.com/2011/03/simplify-your-life-with-an-ssh-config-file/
======
sneak
This overlooks ProxyCommand, the single most useful reason for using an ssh
config file.

e.g.:

    
    
        Host internal-*.example.net
            ProxyCommand ssh -T external.example.net 'nc %h %p'
    
    

Basically, specify as ProxyCommand whatever command needs to be run to give
you i/o to the remote sshd - in this case, sshing to a bastion host and
running netcat. This allows me to do, for example:

    
    
        ssh internal-dev.example.net
    

Which will (in background) ssh to the bastion host external.example.net. I can
even do port forwards to internal hosts using -L or LocalForward directives.
It's a huuuuge timesaver.

ssh even automatically replaces %h and %p in the ProxyCommand with a host and
port, though you can of course replace those tokens with static values if it
works better.

(Also, note above that one can use wildcards in Host declarations.)

~~~
olalonde
Why not directly ssh into "external.example.net"? Why is this a time saver?
I'm not sure what you use this for...

~~~
rubyrescue
i've seen this used for security, in that you can have an extra external
server you must have access to in order to get to internal servers.

~~~
olalonde
Ah ok, this make sense especially if some of your machines are on the same LAN
but don't have an external IP.

------
ef4
> Personally, I use quite a few public/private keypairs for the various
> servers and services that I use, to ensure that in the event of having one
> of my keys compromised the dammage is as restricted as possible.

If you keep all those private keys on the same machine and tend to load them
all into ssh-agent frequently, then there's little point in that. People
forget that keypairs are not like passwords -- if Github gets compromised,
nobody can do anything with the public key you gave them.

Unless you treat the keys very differently (like having a special key that you
rarely ever decrypt), there's no reason to have more than one per device.

~~~
jperras
> People forget that keypairs are not like passwords – if Github gets
> compromised, nobody can do anything with the public key you gave them.

Oh, I'm well aware of the difference between a public/private asymmetric
encryption scheme and a symmetric one.

My concerns are more along the lines of my laptop/desktop being stolen, or my
home being robbed and my backup disks/USB keys being taken, or even my
computer being seized at the US border. There are ways to mitigate those
concerns (e.g. full-disk encryption), but I'm very much a proponent of
defence-in-depth whenever possible.

I should probably clarify that in the post itself, so that readers aren't
misled as to the reasoning behind password-protecting your private keys.

~~~
apawloski
I don't think I understand you here. Are you not keeping these different keys
on the same machine?

~~~
jperras
At the time when I wrote this, I had three separate machines that I used
regularly: personal laptop, work laptop, work desktop.

~~~
harshreality
The arguments you've presented so far in favor of multiple keypairs on one
computer (different keypairs for different remote services) make no sense.

Typical ssh usage is one keypair per account per machine (or one keypair per
type, e.g. I have an rsa keypair and ecdsa keypaor). It doesn't matter if you
use the same keypair for github and ec2 instances [1]. The only way for the
key to be compromised is if your local machine is compromised. If the local
machine is compromised, you can't trust any keys stored on it unless you know
when it was compromised and you know you haven't entered the passphrase for
some of the private keys since the compromise. More than likely, you won't
know that, so you will have to treat all keys on the compromised machine as
compromised. You'll have to regenerate and redistribute N keys instead of 1.

In your parent post, you identified physical theft as your main concern.
Assuming you have a good passphrase, physical theft is a non-issue. Border
crossing seizures and court proceedings are different; in some cases they can
demand that you enter your passphrase(s), but multiple keypairs will not help
you there.

[1] caveat: of course if you use unprompted authentication forwarding, this
becomes an issue... a compromise at github for instance could allow the github
hacker to ssh into your EC2 instances using forwarded credentials, but that's
a time-limited attack and only works while you're connected to github. Private
keys never leave the machine(s) they're hosted on.

~~~
jperras
You make some good points that are making me rethink my key-per-service
approach. Though, other than the need to replace N keys when my machine(s) is
compromised, there's not that much key management overhead.

------
cmer
I now use Mosh exclusively over ssh. It's great on slow connections as well as
on fast ones. For example, I can start an ssh connection at home on my laptop,
drive to the office and resume like nothing ever happened. One of the best
discoveries of the past year for me.

<http://mosh.mit.edu/>

~~~
beagle3
I haven't heard of Mosh before, so I can't comment (I'll try it soon), but I
just watned to point out that ssh+screen (or ssh+tmux) gives you exactly the
same, and is an apt-get/yum-install/pacman-S away.

From reading about mosh, it seems to require a UDP connection, thus non-
trivial routing. I forward ssh connections through ssh tunnels (sometime
multiple layers), and it works great. Can mosh do that?

~~~
wch
It's not quite the same to use ssh + screen/tmux. mosh resumes automatically
(no need to log in again), and it also will show your keystrokes as you type
them, even if the remote machine hasn't yet received them and then sent back
to your local machine the updated text. This "buffered" text is displayed with
an underline and when your computer receives communication from the server, it
gets updated to the correct text. This makes the terminal feel a lot more
responsive, in my experience. mosh can also be installed with apt-get, at
least in Ubuntu.

~~~
beagle3
I'll try it for the predictive text ... but, what do you mean "you don't have
to login again"? I use a public key login on ssh (so login is invisible), and
you can set up your ssh command line in your config file to do so, e.g. I
often use

    
    
        ssh beagle3@remote.host -t 'screen -x || screen'
    

And it works beautifully. (I'm heavy screen user, so even if I switch to mosh,
there will be screen underneath...)

~~~
gcr
According to the manpage, `screen -DR` will detach the remote screen if it
exists and reattach your session. No need to use shell conditionals or ||.

~~~
beagle3
Ah, but I don't want it detached! I often do pair programming or pair
sysadminning through screen. Is there an equivalent that works with screen
sharing ? ( -x )

~~~
ryan-c
I have my .profile set up to auto-attach to a default screen session, which
works with -x.

<http://blog.ryanc.org/?p=5>

------
swalberg
If you add the following to your .bash_profile, you'll get command line
completion of your hosts:

    
    
      function _ssh_completion() {
        perl -ne 'print "$1 " if /^[Hh]ost (.+)$/' ~/.ssh/config
      }
      complete -W "$(_ssh_completion)" ssh

~~~
jperras
I use ZSH, which if configured properly will also do this for you. Huge
timesaver when I need to connect to a half-dozen hosts.

------
icebraining
A great option to enable for servers where you're constantly SSHing to (either
opening a shell or pushing a repo) is ControlMaster, which lets you multiplex
a single connection and cut down on the initial connection time (including
authentication).

~~~
VBprogrammer
Syntax for anyone looking for it:

    
    
      Host *
      ControlMaster auto
      ControlPath ~/.ssh/cm_socket/%r@%h:%p

~~~
icebraining
I'm an apologist of RTFMP, which is why I didn't include it ;)

~~~
SkyMarshal
It's generally appreciated anyway, since man pages don't always have examples
[1]:

 _$ > man controlmaster

No manual entry for controlmaster

$> man ssh|grep -i controlmaster

required before slave connections are accepted. Refer to the description of
ControlMaster in ssh_config(5) for details.

ControlMaster description of ControlPath and ControlMaster in ssh_config(5)
for details.

$> man ssh_config|grep -i controlmaster

ControlMaster

with ControlMaster set to “no” (the default). These sessions will try to reuse
the master instance's network connection rather than

Specify the path to the control socket used for connection sharing as
described in the ControlMaster section above or the string

When used in conjunction with ControlMaster, specifies that the master
connection should remain open in the background (waiting for_

[1]:
[http://www.reddit.com/r/fossworldproblems/comments/v7hi1/man...](http://www.reddit.com/r/fossworldproblems/comments/v7hi1/man_pages_without_examples_piss_me_off/)

------
adanto6840
I've run into a few local networks that have routers, or other network
security appliances, that are configured in such a way where my SSH connection
would get dropped after XX seconds of inactivity.

Placing the following wildcard entry in my SSH config resolved the issue for
those times when I had to use one of these networks...

    
    
      # Set Global KeepAlive to avoid timeouts
      Host *
        ServerAliveInterval 240

~~~
lostapathy
Caveat, though, is that this will force connections to break if you have a
transient network outage that SSH could otherwise cope with. Which can be
annoying if you're somewhere with a flaky connection. Putting it on the
specific hosts you need rather than globally keeps it from causing you grief
anywhere you don't need it.

~~~
beagle3
While that's true, it tries 3 times (default) before it gives up - so, setting
to 240 would require 12 minutes of no connection before disconnecting.

In any environment that I've been working in recently, if I lose connection
for more than 5 minutes, I've lost it for far longer - I might as well break
and reconnect anyway.

------
jerf
A few other useful things about SSH aliases, especially w.r.t. not just using
shell aliases:

They set you up with a layer of indirection that you can change later. Git-svn
doesn't like having the URL to the SVN server changed, but if you set up a git
alias to "svn" instead, when the SVN server moves for some reason you won't
have to do anything except change the svn alias contents. You can also share
the resulting tree between multiple people easily because they can plop in
their own "svn" alias that uses their own user instead. In general you can
safely reference the SSH alias in any number of places (beyond just shell
scripts) and know that you can trivially change the alias later without having
to change all those things.

There are many things that will use SSH, but won't accept any parameters, or
will accept only a small subset. Emacs can use SSH to access remote file
systems by opening "/ssh:username@ip:port:/file", but it will _only_ take
username, ip, and port (AFAIK). With SSH aliases, you have the full power of
SSH available to you, so you can use all these other nifty things people are
talking about. I've also been using ddd to remotely debug perl lately and that
pretty much seems to demand 'ssh host' with passwordless login and nothing
else.

------
jperras
Author here. Glad to see that this post was useful; I wrote it a while ago
when I realized that people weren't password-protecting their Github private
keys because it was "too complicated".

I've been meaning to start writing again, and my post showing up on the HN
front page is a pretty good motivator. Thanks for that, everyone :-).

------
Newky
Good article, especially the LocalForward config was new to me.

One real usage that is invaluable for me, is the fact that the config is used
for SVP also. This saves a lot of typing.

With a key based login set up, copying files to a server is a matter of

scp file dev:~/

~~~
icebraining
Usually $HOME is the default path, so you don't even need the ~/, this works
fine:

    
    
      scp file dev:

------
ftwinnovations
Great tips but this one in my opinion is pure gold
[http://blogs.perl.org/users/smylers/2011/08/ssh-
productivity...](http://blogs.perl.org/users/smylers/2011/08/ssh-productivity-
tips.html)

------
notatoad
i just switched over from using bash aliases (as described in the article) to
an SSH config file last week. The best thing for me is that it doesn't just
make ssh easier to use, it makes all the ssh family of tools easier. scp,
sshfs, rsync etc all suddenly require less typing to use.

------
liveoneggs
you can setup port forwards on-the-fly with ~C

~? shows the few things you can do over the admin channel of ssh.

    
    
      ~ $ ~?
      Supported escape sequences:
        ~.  - terminate connection (and any multiplexed sessions)
        ~B  - send a BREAK to the remote system
        ~C  - open a command line
        ~R  - Request rekey (SSH protocol 2 only)
        ~^Z - suspend ssh
        ~#  - list forwarded connections
        ~&  - background ssh (when waiting for connections to terminate)
        ~?  - this message
        ~~  - send the escape character by typing it twice
      (Note that escapes are only recognized immediately after newline.)

------
the_mitsuhiko
I wish the damn thing would support DNS. We have a bunch of servers to SSH
into and I have to use the fully qualified domain name unless I want to
hardcode all of them (and there are too many).

~~~
switch007
What damn thing? .ssh/config? 'Host foo' and the domain in the list in the
'search' option in /etc/resolv.conf works fine for me.

------
nnq
Considering the large percent Linux users frequently using SSH, I'd stick a
link to this (and to <http://www.debian-administration.org/articles/290>) in
all newbie targeted Linux tutorials... I just hate the world for letting me
live without this knowledge for close to a year since diving into Linux.

------
bonobo
Nice article. If only I had seen this last week, it would have saved me some
time. I was trying to configure multiple github accounts last week, but I
don't have enough experience with ssh.

...but now that I did manage to configure it, I wonder if it was really
necessary. Github has a nice identity control, I think it was foolish of me to
think I needed both a personal and a work account.

~~~
Tobu
Yeah, IdentityFile + IdentitiesOnly is useful for those hosts.

------
easy_rider
Here's another reason why. For specific hosts, ssh can sometimes feel terribly
slow, especially with connecting, and especially on a mac!

Host -host-name-here- GSSAPIAuthentication no GSSAPIKeyExchange no

Fixes this issue. source:
[http://hints.macworld.com/article.php?story=2011102011541796...](http://hints.macworld.com/article.php?story=20111020115417965)

------
evanm
Been doing this for some time now—getting my precious seconds back one login
at a time.

------
trotsky
no one ever uses kerberos outside of windows shops anymore?

~~~
ojiikun
A "rather large online retailer based in Seattle" is a Linux shop and started
using Kerberos for ssh to excellent results a few years back. Once properly
set up, the ability to ssh around between Linux and Windows boxen is just pure
bliss. Once you're kerberized, just click an ssh: link in a Nagios report and
boom, you're on the host.

------
grobot
I find myself wishing ~/.ssh/config had include statements, so I could mix and
match blocks which are only useful on certain networks / in certain contexts.

~~~
carlosantelo
Try my fugly script, <http://cmad.github.com/sshfu/> you can do imports for
example, and things like

inside public_place or home { host web address 192.168.10.1 gw office_fw }
otherwise { host web address 192.168.10.1 user $MY_USER }

or whatever like host .... agent yes port 8

~~~
newman314
I really wish this was an as-shipped feature with OpenSSH. Even if it is the
config file being able to have multiple Hostnames to try for a Host.

That way I can just specify two hostnames/IP addresses to try and ssh can
automagically do the right to to get to an internal machine depending if I am
at home or work.

~~~
darkarmani
On a Mac I used to use Marco Polo to detect my location and it would change my
symlinks to ~/.ssh/config. You can use Marco Polo to detect SSIDs or various
other changes.

------
lallouz
Oh man, I have been thinking about this problem for a while now. Glad to see
the start of some simple solutions to make this more bearable.

------
js2

      man ssh_config

------
mememememememe
But this is known for years. I've been using this since the second week of
using Linux.

~~~
h2s
Good old HN, where a building a website with Twitter Bootstrap on Heroku's
free tier makes you a startup founder, and learning to use one the oldest and
most basic features of one of the simplest packages in your operating system
makes you a hacker.

------
skylan_q
I was very pleased when I discovered this. I was thrilled when I discovered
that Emacs tramp mode makes use of this! :D

