OpenSSH
Installation
To get the OpenSSH version:
CVSROOT=anoncvs@anoncvs.mindrot.org:/cvs cvs get openssh mv openssh openssh_portable-cvs
Or, via Git:
git clone git://anongit.mindrot.org/openssh.git openssh-git
Install prerequisites & build:
apt-get install autoconf libpam0g-dev libwrap0-dev # Debian yum install autoconf tcp_wrappers-devel pam-devel # Fedora
cd openssh_portable-cvs aclocal && autoheader && autoconf ./configure --prefix=/opt/openssh --with-pam --with-tcp-wrappers --with-Werror make sudo make install
Configuration
We could make some changes[1] to the server and to the client configuration.
Server
Protocol 2 HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_rsa_key PermitRootLogin without-password PasswordAuthentication no ChallengeResponseAuthentication no Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
To support older clients[2][3], add the following:
MACs [...],hmac-sha1 KexAlgorithms [...],diffie-hellman-group-exchange-sha1
To set certain configuration options for trusted clients, use the Match directive:
Match Address 10.10.0.0/24 PasswordAuthentication yes
As we enabled diffie-hellman-group-exchange key exchange algorithms, we should also generate stronger moduli:
ssh-keygen -G moduli.candidates -b 4096 # Takes about 6 min on a i7-3632QM, output was ~200 MB ssh-keygen -f moduli.candidates -T moduli # Takes about 2 hrs on a i7-3632QM sudo mv moduli.tested /etc/ssh/moduli && sudo chown root:root /etc/ssh/moduli rm moduli
To re-generate the host keys (skipping ECDSA again[4]):
ssh-keygen -t ed25519 -N "" -f ssh_host_ed25519_key ssh-keygen -t rsa -b 4096 -N "" -f ssh_host_rsa_key
Client
On the client side, similar changes may be needed:
Host * Protocol 2 Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-ripemd160-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,umac-128@openssh.com KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256 TCPKeepAlive yes ServerAliveInterval 20 IdentitiesOnly[5] yes HashKnownHosts yes ForwardX11 no # VisualHostKey yes # ProxyCommand /usr/bin/nc -X connect -x 10.36.6.86:8080 %h %p # EscapeChar none
Again, if the SSH client doesn't understand current algorithms[2][3], enable:
MACs [...],hmac-sha1 KexAlgorithms [...],diffie-hellman-group-exchange-sha1
Usage
autossh
autossh -M 0 -f -N ssh.example.com
We're using -M 0
to disable autossh's monitoring capabilities and the use TCPKeepAlive feature from OpenSSH to monitor the connection:
$ cat ~/.ssh/config Host ssh.example.com PasswordAuthentication no TCPKeepAlive yes LogLevel ERROR User alice IdentityFile ~/.ssh/ssh-key LocalForward 1234 localhost:80
With systemd having won the init war, let's create a service file[6] so autossh
is started during bootup:
$ cat /etc/systemd/system/autossh@example.service [Unit] Description=autossh: %I Documentation=file:///usr/share/doc/autossh/README.service man:autossh(1) After=network.target [Service] User=nagios Environment="AUTOSSH_GATETIME=0" EnvironmentFile=/etc/autossh/%i.conf ExecStart=/usr/bin/autossh $OPTIONS [Install] WantedBy=multi-user.target
Create a configuration file:
$ cat /etc/autossh/example.conf
OPTIONS=-M 0 -N ssh.example.com
Start and enable with:
systemctl start autossh@example && systemctl enable autossh@example
Agent Forwarding
This will forward the local authentication agent connection to the remote host, to be used for a later connection. This has the advantage that the SSH key for the remote host does not need to be copied to the intermediate system.
On the server side, AllowAgentForwarding
has to be enabled (default for many installations).
Note: there are security concerns though.[7][8]
$ ssh-add -c ~/.ssh/remotehost-key # Use "-c" to have key usage confirmed[9] Enter passphrase for ~/.ssh/remotehost-key: $ ssh -A jump.example.com # ForwardAgent=yes jump$ ssh-add -l 4096 1e:60:9d:99:f6:20:c5:d3:23:f6:57:1c:e9:f4:15:9c ~/.ssh/remotehost-key (RSA) jump$ ls -l ~/.ssh/remotehost-key ls: cannot access ~/.ssh/remotehost-key: No such file or directory jump$ ssh -v remotehost [...] debug1: Offering public key: ~/.ssh/remotehost-key debug1: Server accepts key: pkalg ssh-rsa blen 535 remotehost$
Escapes
According to ssh(1), several escape characters are supported:
~. Disconnect. ~^Z Background ssh. ~# List forwarded connections. ~& Background ssh at logout when waiting for forwarded connection / X11 sessions to terminate. ~? Display a list of escape characters. ~B Send a BREAK to the remote system ~C Open command line. Currently this allows the addition of port forwardings using the -L, -R and -D options (see above). It also allows the cancellation of existing remote port-forwardings using -KR[bind_address:]port. !command allows the user to execute a local command if the PermitLocalCommand option is enabled in ssh_config(5). Basic help is available, using the -h option. ~R Request rekeying of the connection
Listing and modifying existing forwarded connections seem to be very interesting. Let's see how this goes.
$ ssh -L 1234:localhost:80 malice malice% ~# The following connections are open: #2 client-session (t4 r0 i0/0 o0/0 fd 8/9 cc -1)
Hm, this isn't too descriptive :-\ Let's open another port forward:
malice% ~C ssh> -h Commands: -L[bind_address:]port:host:hostport Request local forward -R[bind_address:]port:host:hostport Request remote forward -D[bind_address:]port Request dynamic forward -KR[bind_address:]port Cancel remote forward ssh> -L1235:localhost:80 Forwarding port. malice% ~C
And it worked:
$ wget http://localhost:1235 -qO- Hello, world!
gnome-keyring
As gnome-keyring cannot handle ECDSA[10] or Ed25519[11] keys yet[12][13], we might have to use something else.[14][15]
While most of these issues have been resolved one might still want to disable Gnome Keyring and use the alternatives below. However, Gnome Keyring appears to rewrite the SSH_AUTH_SOCK
environment variable. To prevent this, here's how to disable Gnome Keyring once and for all:[16][17]
cp /etc/xdg/autostart/gnome-keyring-ssh.desktop ~/.config/autostart/ echo Hidden=true >> ~/.config/autostart/gnome-keyring-ssh.desktop
Add the following to your login scripts, e.g. ~/.profile
:
export GSM_SKIP_SSH_AGENT_WORKAROUND=1
keychain
Install keychain:
sudo apt-get install keychain
Disable gnome-keyring
:
sudo mv /etc/xdg/autostart/gnome-keyring-ssh.{desktop,disabled}
Create startup items:
$ cat ~/.config/autostart/gnome-keyring-ssh.desktop [Desktop Entry] Type=Application Name=SSH Key Agent (keychain) Exec=keychain –quiet –agents ssh $ cat ~/.config/autostart/gnome-keyring-gpg.desktop [Desktop Entry] Type=Application Name=GPG Key Agent (keychain) Exec=keychain –quiet –agents gpg
Logout and login again, then tell your shell to pick-up the keychain environment variables:
echo 'eval $(keychain --eval --quiet)' >> ~/.bashrc
Adding and removing keys:
$ ssh-add .ssh/ed25519-key Enter passphrase for .ssh/ed25519-key: Identity added: .ssh/ed25519-key (.ssh/ed25519-key) $ ssh-add -l 256 11:43:de:1a:39:c8:96:71:d3:54:75:1c:3d:15:41:ac .ssh/ed25519-key (ED25519) $ ssh-add -d .ssh/ed25519-key Identity removed: .ssh/ed25519-key (.ssh/ed25519-key.pub)
ssh-agent
We could also use ssh-agent
with some systemd
trickery:[18]
TBD
known_hosts
List all known fingerprints (length in bits, MD5 fingerprint, hashed hostkey, type)
$ ssh-keygen -l -f ~/.ssh/known_hosts | tail -2 256 37:8c:a0:67:78:53:4b:da:d7:38:fe:14:10:d1:90:aa |1|h6o4y26eF7Vtc/ypRvdrrvxshQ (ED25519) 2048 c5:50:3a:b4:fa:b5:2d:6f:2e:9e:ea:15:de:cf:25:21 |1|sG5je3ToIqDIIyPLG0sqKrU5tM (RSA)
Note: for some OpenSSH versions, one has to specify -E md5
to show the fingerprints as an MD5 sum, otherwise it may display SHA256 fingerprints.
Display the fingerprint of the hostkey of a known host. The -f known_hosts_file
switch is optional here and ~/.ssh/known_hosts
is assumed:
$ ssh-keygen -l -F login.example.org # Host login.example.org found: line 12 type ED25519 256 37:8c:a0:67:78:53:4b:da:d7:38:fe:14:10:d1:90:aa |1|h6o4y26eF7Vtc/ypRvdrrvxshQ (ED25519)
Note: because HashKnownHosts
is most likely set in ssh_config
, all entries are hashed and thus will not reveal any hostnames. Only known hostnames can be queried.[19]
Remove a known hostkey:
$ ssh-keygen -R login.example.org # Repeat for the host's IP address as needed # Host login.example.org found: line 12 type RSA ~/.ssh/known_hosts updated. Original contents retained as ~/.ssh/known_hosts.old
Display the hostkey of a known host, not stored in known_hosts_file
:
$ ssh-keyscan -t ed25519 login.example.org
# login.example.org SSH-2.0-OpenSSH_6.7p1
login.example.org ssh-ed25519 AAAAC3NzCa1lDZI1NT5EAAAAILMG6q9z8HuoBWehII1/aOBgom5piBip635juE50v+QP
Find all hosts from the file ssh_hosts
which have new or different key from a sorted known_hosts
file:
$ ssh-keyscan -t ed25519 ssh_hosts | sort -u - ~/.ssh/known_hosts | diff known_hosts.sorted - # login.example.org SSH-2.0-OpenSSH_6.7p1 76a77 > login.example.org ssh-ed25519 AAAAC3NzCa1lDZI1NT5EAAAAILMG6q9z8HuoBWehII1/aOBgom5piBip635juE50v+QP
Port Forwarding
Forward a remote port to a local one. For example, only the remote site may be connected to an internal webserver:
local$ ssh -L 1234:box.intra:80 webserver local$ wget http://localhost:1234 -qO - Hello, I'm an intranet webserver!
Forward a local port to a remote site. For example, the remote site may not have access to the internet:
local$ ssh -R 1234:localhost:8080 box box$ http_proxy=localhost:1234 wget http://example.org -O- Hello, world!
UDP port forwarding:[20]
local$ ssh -L 1234:localhost:1234 server server$ mkfifo /tmp/fifo server$ nc -l -p 1234 < /tmp/fifo | nc -u dns.local 53 > /tmp/fifo
On the local machine again:
local$ mkfifo /tmp/fifo local$ sudo nc -l -u -p 53 < /tmp/fifo | nc localhost 1234 > /tmp/fifo
Now we can use DNS over UDP:
local$ dig www.kame.net @127.0.0.1
Or, with socat:
server$ socat tcp4-listen:1234,reuseaddr,fork UDP:dns.local:53 local$ sudo socat -T15 udp4-recvfrom:53,reuseaddr,fork tcp:localhost:1234
xauth
SSH connections sometimes complain about:
Warning: untrusted X11 forwarding setup failed: xauth key data not generated Warning: No xauth data; using fake authentication data for X11 forwarding.
Somehow xauth(1)
is involved:
$ strings `which ssh` | grep -i bin/xauth /usr/X11R6/bin/xauth
But our xauth(1)
is located somewhere else:
$ which xauth /opt/X11/bin/xauth
The trick is tp specify the correct location in ssh_config(5)
:
XAuthLocation /opt/X11/bin/xauth
lsh-authorize
Only slightly related to OpenSSH, but here is how to convert an OpenSSH public key[21] to one that lsh understands:
ssh-conv < openssh-key.pub > lsh-key.pub lsh-authorize lsh-key.pub
With that, a new public will be installed and public key authentication should succeed:
$ find .lsh/ -type f .lsh/authorized_keys_sha1/b39ce18ccd66629e8f9a0976d69400135425a3c6
Links
- Tests
- openssh.git (Portable OpenSSH)
- ssh-agent and GNU Screen (Janurary 2004)
- High Performance SSH/SCP - HPN-SSH
- Mosh (mobile shell)
- Dropbear[22]
- duraconf - A collection of hardened configuration files for SSL/TLS services
- Bug 641082 - Can't handle ECDSA keys (gnome-keyring, 2011-01-31)
- RSA vs. DSA for SSH authentication keys (2011-07-08)
- Improving the security of your SSH private key files (2013-05-24)
- stronger encryption for SSH keys (2013-07-21)
- new openssh key format and bcrypt pbkdf (2013-12-21)
- Scripting with SSH
- sshuttle: where transparent proxy meets VPN meets ssh
References
- ↑ Secure Secure Shell
- ↑ 2.0 2.1 Can't import private ed25519 key
- ↑ 3.0 3.1 support new SHA256-based HMAC transport integrity modes
- ↑ How to design an elliptic-curve signature system
- ↑ Too many authentication failures for *username*
- ↑ systemd: Writing unit files
- ↑ SSH Agent Forwarding Is a Bug
- ↑ #120: SSH Agent Forwarding (Mobile Shell)
- ↑ Short Tip: Use SSH agent forwarding on remote servers
- ↑
Can't handle ECDSA keys - ↑
Can't handle ED25519 keys - ↑ gnome-keyring doesn't support ecdsa or ed25519 keys
- ↑ gnome-keyring doesn't work with ecdsa keys
- ↑ Use Funtoo's Keychain Instead of GNOME Keyring
- ↑ SSH with ed25519 (curve25519) + GNOME-KeyRing
- ↑ Disable keyring daemon components
- ↑ Down the SSH_AUTH_SOCK Rabbit Hole: A GNOME Adventure
- ↑ Using ssh-agent and ED25519 Keys on GNOME
- ↑ Is it possible to find out the hosts in the known_hosts file?
- ↑ Performing UDP tunneling through an SSH connection
- ↑ Converting OpenSSH public keys
- ↑ Ed25519 support commited with: Add Ed25519 support (2020-03-11)