Simplify your life with an SSH config file
nerderati.com
nerderati.com
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.)
Host madeup
Host internal_name
ProxyCommand ssh external.example.net -W %h:22
[1] - http://manpages.debian.net/cgi-bin/man.cgi?query=ssh&apr...openssh-6.0 release notes has this:
* sshd(8): unbreak stdio forwarding when ControlPersist is in use; bz#1943
I haven't tested to see if that resolves the issue yet though (on osx which of course does not have 6.0).However, the netcat version works fine.
https://github.com/ryancdotorg/ssh-chain
It will let you do
ssh internal-dev.example.net^external.example.netThe PK/SSH HowTo: https://pagekite.net/wiki/Howto/SshOverPageKite/
2. Scripting an scp, rsync etc from the internal machine is easier now, since the ssh from the external to internal machine is handled transparently for you.
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.
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.
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.
If your computer is seized at the US border, the security of your SSH keys is the last thing you need to be worrying about: http://xkcd.com/538/
However, the other reason for segmenting keys is to do agent forwarding.
I might have a CLIENTA key and then allow ssh auth forwarding from a bastion host at CLIENTA to other CLIENTA machines. I also have a CLIENTB key and allow ssh auth forwarding from a bastion host at CLIENTB to other CLIENTB machines. (or, prod/dev at the same company, or personal/work, or whatever).
I don't want anything CLIENTA does on a subverted bastion host or other host to be able to affect CLIENTB in any way.
I also keep some keys totally offline (to manage logging servers, which are normally read-only); ideally with some better way to do 2 party control as well.
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?
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...)What is a UDP connection?
Practiaclly, this means that if your server is behind a firewall or NAT, you need to poke a hole in your firewall to be able to connect with Mosh.
It also buffers all command output server-side and doesn't send more output than the network connection allows. This means that even if you have a runaway process dumping lots of output, you can still immediately Ctrl+C it.
Is that SOP for mosh, or do you guys proxy through a mosh-only server to your actual servers, or something else?
Opening a high port in the 60000s is less risky than 22. You should probably remap ssh to something else. Or you can use ec2 security groups to limit access to certain ips.
* There is no connection session, so you can close your laptop or put it to sleep and open it up again and the connection will still be there.
* You don't have the lag of sending and then responding, it appears locally immediately
* It is much easier to get UDP around firewalls and it can't be blocked easily in the same way most VPN protocols or SSH can. I have yet to find a network where I can't get my terminal UDP packets through.
The alternative to Mosh is setting up OpenVPN[1]. It is especially worthwhile if you have a network of public servers that you administer. It is easy to setup[2] and works on Windows, Mac, Linux, BSD etc.
The best tip is to add a second interface to all your machines and setup a private VLAN across them. This way if you are experiencing a DoS attack or high traffic you can still login and administer the machine (this also applies with standard ssh - you put it in a different range of IPs and on your public machines then only have 80 and 443 open).
EC2[3], Linode[4] et al all support adding a second network interface to each machine (or to just one of the machines, which is then used as a gateway to the remainder) which can be assigned an IP address in a different range. You then setup a separate hostname to this network, or even register a separate administrative domain name (eg. company-admin.com) which you keep on a different registrar, whois record, etc.
[2] http://openvpn.net/index.php/open-source/documentation/howto...
[3] http://aws.typepad.com/aws/2012/07/multiple-ip-addresses-for...
Err, not in my world. Many hotels block udp. Amtrak's on train internet does too (they block a lot of tcp ports as well, and proxy http to stop videos).
I haven't tried recently, but most guest networks (at conferences, companies I visited, etc) did not let UDP through.
I really can't say how much mosh has improved my work life. You owe it to yourself to give it a try.
function _ssh_completion() {
perl -ne 'print "$1 " if /^[Hh]ost (.+)$/' ~/.ssh/config
}
complete -W "$(_ssh_completion)" ssh Host *
ControlMaster auto
ControlPath ~/.ssh/cm_socket/%r@%h:%p$> 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...
This fixes the UI wart where your first ssh connection to a server has to stay open for the duration of all your others (or your others all get forcibly disconnected).
It's not perfect. If the name of a server changes but you already have a control socket, it'll use the socket and connect to the old server. And it also takes it a while to pick up networking changes that break your connectivity, though I've hacked around that with a script I keep running in the background (Linux only, at the moment; requires gir1.2-networkmanager-1.0):
#!/usr/bin/python
import os
from gi.repository import GLib, NMClient
def active_connections_changed(*args):
for sock in os.listdir(os.path.expanduser('~/.ssh/sockets')):
os.unlink(os.path.join(os.path.expanduser('~/.ssh/sockets'), sock))
c = NMClient.Client.new()
c.connect('notify::active-connections', active_connections_changed)
GLib.MainLoop().run()
There's some contention with my coworkers about whether ControlPersist is actually desirable given the tradeoffs, but I personally think it's a huge improvement.Thanks!
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 240In 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.
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.
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 :-).
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:~/
scp file dev:~? 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.)...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.
Host -host-name-here- GSSAPIAuthentication no GSSAPIKeyExchange no
Fixes this issue. source: http://hints.macworld.com/article.php?story=2011102011541796...
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
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.
man ssh_config