From Segfault
Jump to: navigation, search


To get the OpenSSH version: cvs get openssh
mv openssh openssh_portable-cvs

Or, via Git:

git clone 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
autoheader && autoconf
./configure --prefix=/opt/openssh --with-pam --with-tcp-wrappers --with-Werror

sudo make install


We could make some changes[1] to the server and to the client configuration.


Protocol                        2
HostKey                         /etc/ssh/ssh_host_ed25519_key
HostKey                         /etc/ssh/ssh_host_rsa_key

PermitRootLogin                 without-password
PasswordAuthentication          no
ChallengeResponseAuthentication no

Ciphers               ,,,aes256-ctr,aes192-ctr,aes128-ctr
MACs                  ,,,,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,
KexAlgorithms         ,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
      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


On the client side, similar changes may be needed:

Host *  
       Protocol                2
       Ciphers       ,,,aes256-ctr,aes192-ctr,aes128-ctr
       MACs          ,,,,hmac-sha2-512,hmac-sha2-256,hmac-ripemd160,

       TCPKeepAlive            yes
       ServerAliveInterval     20
       IdentitiesOnly[5]       yes
       HashKnownHosts          yes
       ForwardX11              no
#      VisualHostKey           yes
#      ProxyCommand            /usr/bin/nc -X connect -x %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



 autossh -M 0 -f -N

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
       PasswordAuthentication  no
       TCPKeepAlive    yes
       LogLevel        ERROR
       User            alice
       IdentityFile    ~/.ssh/ssh-key
       LocalForward    1234 localhost:80

With systemd having won the system service management init war, let's create a service file[6] so autossh is started during bootup:

$ cat /etc/systemd/system/autossh@example.service
Description=autossh: %I
Documentation=file:///usr/share/doc/autossh/README.service man:autossh(1)

ExecStart=/usr/bin/autossh $OPTIONS


Create a configuration file:

$ cat /etc/autossh/example.conf 

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                                       # 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


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
     -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!


As gnome-keyring cannot handle ECDSA[10] or Ed25519[11] keys yet[12][13], we might have to use something else.[14][15]


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]
Name=SSH Key Agent (keychain)
Exec=keychain –quiet –agents ssh

$ cat ~/.config/autostart/gnome-keyring-gpg.desktop
[Desktop Entry]
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/


We could also use ssh-agent with some systemd trickery:[16]



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
# Host 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.[17]

Remove a known hostkey:

$ ssh-keygen -R                               # Repeat for the host's IP address as needed
# Host 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
# SSH-2.0-OpenSSH_6.7p1 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 -
# SSH-2.0-OpenSSH_6.7p1
> 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 -O-
Hello, world!


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

But our xauth(1) is located somewhere else:

 $ which xauth 

The trick is tp specify the correct location in ssh_config(5):

 XAuthLocation           /opt/X11/bin/xauth