openssh obfuscation patch ppa deb disqus

1. Introduction to Obfuscated OpenSSH

The fact that you are on this page reading this text is evidence in itself that you most likely do not need any introduction on this topic. Nevertheless, for completeness' sake, here is some background info.

Bruce Leidl (@brl) gave a detailed description of the reasons behind his proposal to obfuscate the handshake process of ssh connection. Go over it if you have the time. It's not long and fairly easy to understand.

In short, ssh connection starts with a handshake between client and server, which is performed in clear text. The purpose of obfuscating openssh handshake is to make it more difficult for traffic analysis tools to identify this process. Consequently, blocking, interfering or eavesdropping application(s) or mechanism(s) that target ssh traffic by relying on such identification will not be triggered. More difficult, but not impossible, especially if obfuscation is performed without using a keyword (see configuration and securing below). In addition, there definitely exist other methods of identifying ssh traffic, so handshake obfuscation may not solve all your problems.

Leidl's patches did not make into upstream. Fortunately, popular demand made sure that the patches live on outside upstream. In fact, the usefulness of handshake obfuscation have become so recognized that various non-openssh ssh client/server implementations have adopted this feature (see below).

Over the years, a couple of guys have also attempted to port Leidl's patches to newer openssh versions with varying degrees of success. This project is based on Bruce Leidl's original patches against openssh-5.2p1 as well as arigo's patches against openssh-6.1p1, and intends to provide workable patches against all recent and upcoming openssh releases.

2. How to Use the Patches

Download from openssh.com a recent version (e.g. openssh-7.1p1.tar.gz) and extract the sources:

tar xvf openssh-7.1p1.tar.gz

You can download the patches as a zip archive and extract the matching patch (e.g. 7.0_7.1.diff for 7.0p1 and 7.1p1), or download only the matching patch from the github repo using copy and paste, or clone the git repo to your local machine.

Assuming that you place the patch file in the parent folder of extracted openssh sources, apply the patch:

cd openssh-7.1p1
patch -p1 < ../7.0_7.1.diff

There should not be any error at this stage. If there is, check whether you have applied the patch that matches the openssh version.

OpenSSH has building dependencies that might vary between distros and versions. The easiest way to satisfy these dependencies is to build a distro version of OpenSSH first. In Debian/Ubuntu, this can be simplified using a single line of command:

apt-get build-dep ssh

For testing purpose, configure and build using the following commands from within the openssh source folder:

./configure --prefix=/usr/local --sysconfdir=/etc/obssh
make && make install

If these is no building errors, the executable binaries will be installed under /usr/local, while the config file will be installed to /etc/obssh, and new server and client keys will be generated. This allows you to test the obfuscated openssh installation while using your distro's normal openssh version.

When you have finished testing and made sure that the obfuscated openssh works as expected, you can choose to install it to the usual locations:

make uninstall
./configure --prefix=/usr --sysconfdir=/etc/ssh
make && make install

3. Server Configuration

Edit /etc/obssh/sshd_config, make sure these options are uncommented and specified with desired values:

Port 22
ObfuscatedPort 222
ObfuscateKeyword key

Remember to set different ports for obfuscated and non-obfuscated connections. It is strongly advised to use keyword for obfuscation, but please do change the default 'key' to something else!

Then start the server in debug mode:

/usr/loca/sbin/sshd -D -ddd

4. Connecting to Obfuscated OpenSSH Server

First, test on the machine obfuscated openssh is built and installed:

/usr/local/bin/ssh -z -Z yourkey -p 222 -v localhost

This is assuming you have configured the server to listen on localhost interface in /etc/obssh/sshd_config. Remember to change the parameter of '-Z' option to the keyword specified in sshd_config. If all goes well, a connection should be established and you will be prompted to enter password for the connecting user. On both the server and client side, you should see debug messages telling you that obfuscation is enabled before handshake, and disabled after handshake.

Once local testing passes, you can try connecting from another machine using an obfuscation-aware client. On Linux and MacOS, download and build a patched openssh as detailed above. On Windows, you can use the latest version of the free (as in beer) Bitvise ssh client. Patched versions of the open source PuTTY client named PoTTY are also available.

Other clients in OpenSSH like sftp and scp, as well as non-OpenSSH clients that establish ssh connection using ssh, sftp or scp from locally installed OpenSSH package (e.g. sshuttle), are also obfuscation-aware if OpenSSH is built using these patches. Use or pass the proper -z and -Z commandline options to enable obfuscated handshake.

On Linux, you can set default obfuscation options in ~/.ssh/config to avoid having to remember settings for each server like this:

Host obssh1
    HostName 1.2.3.4
    Port 2234
    ObfuscateHandshake yes
    ObfuscateKeyword mykey

Then you can just input 'ssh obssh1' to connect to 1.2.3.4:2234 using obfuscation keyword 'mykey', equivalent to 'ssh -z -Z mykey -p 2234 1.2.3.4'.

5. Securing Server using Fail2ban

A properly configured (e.g. MaxStartups value in sshd_config) ssh server and a tool like fail2ban can protect you from most attacks though ssh connection. However, handshake failure due to wrong keyword happens before any authentication attempts were made, and fail2ban is not supposed to handle such failures. To make fail2ban pick up ssh handshake failures and ban IPs repeatedly trying to connect with wrong keywords, add the following regex to 'failregex' definition in /etc/fail2ban/filter.d/sshd.conf:

^%(__prefix_line)sMagic value check failed \(\d*\) on obfuscated handshake from <HOST> port

Remember to check proper indention as it's Python code.

6. Pre-built Binary Packages

I have built patched versions of OpenSSH as Ubuntu source and binary packages and published them on launchpad.

Use the following command to install the package corresponding to your versions of Ubuntu:

apt-add-repository ppa:zinglau/obfuscated-openssh
apt-get update
apt-get install ssh

Don't forget to edit /etc/ssh/sshd_config and restart ssh service after installation.

On Debian, after adding the ppa using "apt-add-repository ppa:zinglau/obfuscated-openssh", manually edit /etc/apt/sources.list.d/zinglau-obfuscated-openssh-VERSION.list (where VERSION is jessie, wheezy, or squeeze), and change the Debian version to an Ubuntu version based on that version of Debian. For example, change the following:

deb http://ppa.launchpad.net/zinglau/obfuscated-openssh/ubuntu jessie main

to:

deb http://ppa.launchpad.net/zinglau/obfuscated-openssh/ubuntu vivid main

If you wish or have to, you can also download the source package and build binary packages for Debian yourself by following these instructions.

7. Bugs and Issues

For serious bugs and issues, please report using github. For simple questions, just leave a comment below using Disqus.