Upgrading OpenSSH Client on Mac OSX using Homebrew

Yesterday the OpenSSH project reported a client side vulnerability affecting OpenSSH versions 5.4 - 7.1. This vulnerability could allow an SSH client to leak private key information, potentially exposing users to man-in-the-middle attacks. The linked articles explain how you can disable the vulnerable feature of OpenSSH in your local configuration. This article explains how to upgrade your OpenSSH version on your machine using Homebrew.

Upgrading OpenSSH

This tutorial assumes that you already have homebrew installed on your system. If not go to http://brew.sh/ and get started.

Firstly we need to tap the homebrew-dupes library.

$ brew tap homebrew/dupes

Now we have the latest OpenSSH recipes we can go ahead and install OpenSSH which we will use instead of the system SSH.

$ brew install openssh
$ /usr/local/bin/ssh -V
OpenSSH_7.1p2, OpenSSL 1.0.2e 3 Dec 2015

Making Homebrew OpenSSH Client the default

Now that we have OpenSSH installed using Homebrew we need to make sure it is the default SSH client. By default the system SSH client is installed in /usr/bin/ssh. The issue that many are likely to face is the /usr/bin comes before /usr/local/bin in their PATH variable which is where the new SSH client will be installed. For example

$ echo $PATH
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
$ which ssh
/usr/bin/ssh
$ ssh -V
OpenSSH_6.9p1, LibreSSL 2.1.8

There are two ways to address this problem. The first and easiest is to simply delete the SSH binary in /usr/bin.

$ rm /usr/bin/ssh

While this will definitely work in allowing the homebrew version of SSH to become the default, I would not advise this as updates to OSX may inadvertantly restore the system SSH client leaving you exposed again. The second and preferred method is to rearrange the locations in the PATH variable to allow /usr/local/bin to come before /usr/bin.

We are going to use the ~/.bashrc file which gets executed everytime a new non-login shell is opened. For login shells, the system will check for ~/.profile and load it if available, otherwise it will look for ~/.bash_profile and load that if available. Luckily both of those files usually come as default with an include for the ~/.bashrc file to load it during login shells as well. If yours does not you can add the following into your profile script.

~/.profile or ~/.bash_profile

# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
fi

The following change will allow us to change the PATH variable consistently.

echo 'export PATH=/usr/local/bin:$PATH' >> ~/.bashrc

Now lets check that the $PATH variable does indeed contain our changes. We can do this either by restarting our ssh shell or by sourcing the ~/.bashrc file

$ source ~/.bashrc
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin

You can see that /usr/local/bin is listed twice, this is ok as the system will simply go through them in order looking for files. The reason we didn’t explicitly set the PATH when we modified it is because the PATH may have been modified elsewhere and we want to retain those changes.

Now we have fixed our PATH lets check that the SSH client is the one we expect

$ which ssh
/usr/local/bin/ssh
$ ssh -V
OpenSSH_7.1p2, OpenSSL 1.0.2e 3 Dec 2015

OpenSSH 7.1p2 was the version patched against the OpenSSH Client vulnerability and our system is now safe.

More information about the OpenSSH Client vulnerability