Some networks only have restricted access to the internet or run MITM on the encryption to scan the traffic. In the most cases it is possible to setup a secure proxy connection to bypass this restrictions.

This guide shows how to use HUProxy to connect to a remote SSH server and setup a socks5 proxy to bypass any censorship and MITM attacks.

Requirements

The following things are required:

  • reachable from public internet
  • linux server with docker

To make the usage easier a domain or subdomain should be used instead of the IP address. This guide uses huproxy-test.boehmke.net as domain.

Important: Because HUProxy does not support any authentication or encryption it is required to setup HUProxy behind a reverse proxy that also handles the authentication via basic auth.

This guide uses Traefik as reverse proxy with automatic TLS certificate request from Let’s Encrypt.

Build HUProxy image

Currently HUProxy is not available as prebuild docker image. So the first step is to build the docker image.

First clone the HUProxy repo

git clone https://github.com/google/huproxy.git

then enter the cloned directory

cd huproxy

and as last step build the image

docker build -t local/huproxy .

Setup Server

The following docker-compose.yml shows a simple setup including SSL and basic auth:

version: "3"

volumes:
  traefik_data:

services:
  traefik:
    image: traefik:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    command:
      - --entryPoints.web.address=:80
      - --entryPoints.websecure.address=:443

      - --providers.docker
      - --providers.docker.exposedByDefault=false

      - --certificatesresolvers.letsencrypt.acme.httpChallenge.entryPoint=web
      - --certificatesresolvers.letsencrypt.acme.email=admin@example.com
      - --certificatesresolvers.letsencrypt.acme.storage=/data/acme.json

    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - traefik_data:/data/

  huproxy:
    image: local/huproxy
    restart: unless-stopped
    command: "/huproxy --listen :8086"

    labels:
      traefik.enable: "true"
      traefik.http.routers.huproxy.rule: "Host(`huproxy-test.boehmke.net`)"
      traefik.http.routers.huproxy.entrypoints: "websecure"
      traefik.http.routers.huproxy.middlewares: "huproxy-auth@docker"
      traefik.http.routers.huproxy.tls.certresolver: "letsencrypt"
      traefik.http.routers.huproxy.tls.options: "default"
      traefik.http.services.huproxy.loadbalancer.server.port: "8086"
      traefik.http.middlewares.huproxy-auth.basicauth.users: "proxy:$apr1$4rgk5ce9$LR8iGRL7hq8By5vc6/tLu1"

In this example a user proxy with the password proxy is used. To run the proxy simply start the applications with docker-compose up -d.

Setup Client

Note: this requires a working go compiler

To connect to the client the huproxyclient is needed.

To build the client clone the HUProxy repo (or reuse the one from Build HUProxy image)

git clone https://github.com/google/huproxy.git

then enter the cloned directory

cd huproxy/huproxyclient

Then build the client

# build for native system
go build -v .

# build for windows
GOOS=windows GOARCH=amd64 go build -v .

The directory now contains the build application huproxyclient (or huproxyclient.exe for windows). This application can now be used on a system with a blocked internet connection.

To connect to an SSH server at ssh.example.com run

ssh -o "ProxyCommand=./huproxyclient -auth=proxy:proxy wss://huproxy-test.boehmke.net/proxy/%h/%p" ssh.example.com

this way the connection to ssh.example.com is created via the huproxy server at huproxy-test.boehmke.net.

For an easier reuse it is also possible to add the ProxyCommand for the ~/.ssh/config