This post is an addition to Using maven behind a proxy.

TLDR: Jump to the end

Problem description

When you are in a corporate network, you might be behind an authenticating http proxy server. Every connection to the outside world needs to go through that proxy. Direct SSH connections are not allowed. Indications that you are in such a situation: timeouts when trying to git clone a repository with an SSH url. If you are lucky, the firewall is configured to immediately reject the connection attempt and answers with a ICMP destination unreachable message. Otherwise the SYNC packet just times out.

Sure, you could use https and use the normal https_proxy environment settings. That would work. But if you use 2FA, you’d need to create a access token. With SSH, you can use your SSH key.

Solution 1 (no proxy)

To workaround the firewall, github provides SSH access on port 443 as well. This is described at Using SSH over the HTTPS port. With that you need to configure your ~/.ssh/config to use host “ssh.github.com” and port 443 instead of github.com:

Host github.com
  Hostname ssh.github.com
  Port 443

But that solution doesn’t consider yet a http proxy.

Solution 2 (proxy without auth)

The blog post Getting started with git behind a company proxy comes already close to the solution, we need. Additionally we need to configure a “ProxyCommand”, so that ssh doesn’t directly open the connection, but through the proxy. The complete file ~/.ssh/config will look like this:

Host github.com
  Hostname ssh.github.com
  Port 443
  ProxyCommand nc -X connect -x 192.168.x.y:8080 %h %p

It uses netcat. Please be aware to use the package netcat-openbsd under Debian, as only this variant supports proxies. The other package netcat-traditional does not support proxies.

With this configuration, we get one step further: Now we try to use the proxy server, but it responds with “407 Proxy Authentication Required”. Looking at the manual page, there is a option to specify the “proxy_username”:

Host github.com
  Hostname ssh.github.com
  Port 443
  ProxyCommand nc -X connect -x 192.168.x.y:8080 -P proxyuser %h %p

Now it uses “proxyuser” to authenticate. Since this user requires a password (it is anyway http basic authentication), netcat will prompt for it. This means, every time, you execute some remote git command, you’ll need to enter the proxy password. Not very convenient. This can still be improved.

Solution 3 (proxy with auth, using ncat)

netcat from OpenBSD doesn’t seem to have an option to specify the password. But there is another netcat variant, this time from nmap, the network scanner. The proxy settings are described in the proxying chapter of Ncat User’s Guide: Proxying. Note that this tool is available in Debian as package ncat.

The complete file ~/.ssh/config looks now:

Host github.com
  Hostname ssh.github.com
  Port 443
  ProxyCommand ncat --proxy-type http --proxy 192.168.x.y:8080 --proxy-auth proxyuser:password %h %p

You can use additionally the ssh option “IdentityFile” to use a specific ssh key if you want.

Solution 4 (proxy with auth, using socat)

There seems to be still one more option, which I didn’t try: Instead of “ncat”, you might be able to use socat. This is described here: https://gist.github.com/rbenaley/1111823 and with that command, the file ~/.ssh/config looks this way:

Host github.com
  Hostname ssh.github.com
  Port 443
  ProxyCommand socat - PROXY:192.168.x.y:%h:%p,proxyport=8080,proxyauth=proxyuser:password

One point to note with these solutions: Since you specify the proxy password here directly, it ends up in the command line and in the process list. This means, that every user on the same machine can see the password, e.g. via ps. Also note, that in case of basic authentication, the proxy password can be sniffed on the network, since the proxy connection is unencrypted and the http basic authentication is just a base64 encoded.

Final solution

In short, this needs to be done:

  1. Install ncat: sudo apt install ncat

  2. Create ~/.ssh/config with the following content:

     Host github.com
       Hostname ssh.github.com
       Port 443
       ProxyCommand ncat --proxy-type http --proxy 192.168.x.y:8080 --proxy-auth proxyuser:password %h %p
    
  3. Use git: git clone git@github.com:organization/repo.git