ssh

“secure shell”, which is not a shell but is a useful way that we log in to the back-end of things


SSH, the secure shell, is the Swiss army knife of the internet. It lets you shunt data from one place to another with little fuss. There are similar tools which are even less fuss, but they are gaping security holes and should not be used. That is why it is weird that it is named after almost the one thing that it is not: a shell. But other pedants have complained about that, I am sure.

I am writing from the perspective of someone using ssh as a client, not maintaining a server.

Suspending ssh

Use the escape character. Per default this is Enter ~. Immediately after typing is, Ctrl-Z will suspend an ssh client.

Extra security

One should probably secure ssh but shutting down unneccessrily weak crypto options, and disabling unneeded ports and so on. If you want to be extra sensible secure it to modern cryptography standards, such as elliptic ciphers, and smart defaults which are suspected to be less vulnerable to the more quotidian NSA attacks. (With these settings you’re still screwed when cheap quantum factorization becomes a thing, though, but let us set that aside for now.)

tl;dr

ssh-keygen -t ed25519 -o -a 100
ssh-keygen -t rsa -b 4096 -o -a 100

SSH identities

It is fiddly to have multiple identities for the same host - in particular if you are using git this needs to be managed at the configuration level by host aliases. A guide to that is here. See also the lengthy stackoverflow discussion.

Key encryption

If you don't want someone to steal your private key you can encrypt it. Doing this even if you have filesystem encryption would be wise if you were in a hostile environment such as a server, or use features such as ssh agent forwarding (long story) or are just generally paranoid.

Constantly decrypting the key with a password is annoying; for this you use ssh-agent, which is slightly subtle and complicated

Want to start ssh-agent on startup, but not if it’s already running? See Joseph M. Reagle’s solution:

SSH_ENV="$HOME/.ssh/environment"

function start_agent {
    echo "Initialising new SSH agent…"
    /usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
    echo succeeded
    chmod 600 "${SSH_ENV}"
    . "${SSH_ENV}" > /dev/null
    /usr/bin/ssh-add;
}

# Source SSH settings, if applicable

if [ -f "${SSH_ENV}" ]; then
    . "${SSH_ENV}" > /dev/null
    #ps ${SSH_AGENT_PID} doesn’t work under cywgin
    ps -ef | grep ${SSH_AGENT_PID} | \
        grep ssh-agent$ > /dev/null || {
            start_agent;
    }
else
    start_agent;
fi

I am unclear as to how much of this can be avoided for a modern setup.

ssh-agent on macOS

How does ssh-agent work with the macOS keychain? Should it be permitted to do is, or is that inviting hostile actors in?

Things are weird for macOS because you can store things in ssh-agent, or osx keychain, or some weird hybrid options that make my eyes cross. Apple’s Explanation is sorta clear but it got confused and changed over time. Github has an opinion on it. Old macOS SSH behaviour for the vexed. The best and most current summary seems to be Awesome macOS CLI:

Prior to macOS Sierra, ssh would present a dialog asking for your passphrase and would offer the option to store it into the keychain. This UI was deprecated some time ago and has been removed.

Instead, a new UseKeychain option was introduced in macOS Sierra allowing users to specify whether they would like for the passphrase to be stored in the keychain. This option was enabled by default on macOS Sierra, which caused all passphrases to be stored in the keychain.

This was not the intended default behavior, so this has been changed in macOS 10.12.2. …

ssh-add -K /path/to/private_key

Then add to ~/.ssh/config:

Host server.example.com
    IdentityFile /path/to/private_key
    UseKeychain yes

SSH as VPN

sshuttle (manual) is a VPN-workalike built on SSH. As far as I can tell it’s easy for both the client and server to set up VPN this way, so I’m not sure why it is not more common. Possibly because setting up SSH shells on various servers is in itself easy to make insecure for the server? Anyway, you have a login, you might as well use it.

Installation options:

pip install shuttle
brew install sshuttle
# etc

Run:

sshuttle --dns -r username@sshserver 0/0

Terminal multiplexers

screen, tmux etc.

Amazing handy for remote admin.

See terminal multiplexers.

Over https

The classic is corkscrew, which injects SSH control over, e.g. hostile web-only firewalls at the airport.

Tunnels

sshtunnelmanager (macos) assembles the right commands arguments for you to make tunnels without having to check the manual every time.

ProxyJump is a 2 step proxy for easing double tunnelling.

ssh -J your.jump.host remote.internal.host

or

scp -o 'ProxyJump your.jump.host' \
  myfile.txt remote.internal.host:/my/dir

Alternatives/extensions

dropbear ssh is a minimal ssh implementation.

mosh ("mobile shell") is also not a shell. It is a terminal with ssh-style tunneling for intermittent connections, including predictive editing and graceful packet loss.

How is mosh better than tmux + ssh, though? I need a Venn diagram of features here.

“Enterprise” ssh? teleport claims to offer that.

To mention

  • ssh-copy-id is a magical command to deploy your keys to remote servers.