🔌 A simple tool that wraps HTTP/HTTPS proxies into a SOCKS5 proxy.
Clone or download
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci ci: drop travis, use circleci Aug 28, 2018
cmd/h2s truncate error messages Sep 6, 2018
.gitignore Initial commit Mar 14, 2018
.goreleaser.yml fix CI and release, update doc Mar 31, 2018
LICENSE Initial commit Mar 14, 2018
README.adoc feat: tls fingerprint verification Aug 28, 2018
duplex.go fix sync.WaitGroup copy Aug 28, 2018
go.mod add go.mod Aug 1, 2018
h2s.go truncate error messages Sep 6, 2018
socks5.go update docs Apr 5, 2018
upstream.go crit fix: wrong tls config detection Sep 8, 2018



GoDoc Release CircleCI Go Report Card License

h2s is a tiny CLI tool that wraps one or multiple HTTP or HTTPS proxies into a SOCKS5 proxy. It does something like polipo and privoxy do, but in a reversed way.

There are already some SOCKS to HTTP tools out there, but I can hardly find a reversed one (HTTP to SOCKS), so I decided to make one on my own.


You can view the release page for handy prebuilt binaries.

Build from Source

h2s relies on stadard libs only.

$ go get -u ekyu.moe/h2s/cmd/h2s


An example config file:

  // bind is the address h2s will listen to.
  // Note that since HTTP/HTTPS proxy support only TCP, the h2s wrapped SOCKS5
  // proxy consequently support only TCP as well.
  "bind": "",

  // upstreams are HTTP proxy upstreams.
  // h2s will do a simple round-robin load balance.
  "upstreams": [{
    // If no port is specified, 80 is assumed by default.
    "address": "proxy1.example.com",
  }, {
    "address": "proxy2.example.com:3128",

    // username and password are optional for HTTP authentication.
    "username": "Alice",
    "password": "secret here"
  }, {
    // An HTTPS proxy (HTTP over TLS) upstream.
    // You have to specify port explicitly (usually 443), and set the tls field.
    "address": "secure.proxy.example.com:443",
    "username": "Secure",
    "password": "Yeah!",

    // h2s only provides some basic TLS settings. If you are an advanced user and
    // looking for other settings, you may use stunnel(1) to handle TLS instead,
    // and simply leave a naive TCP interface to h2s.
    "tls": {
      // If empty, serverName is set to the hostname from address.
      // Most users could just leave it empty.
      "serverName": "secure.proxy.example.com",

      // If you prefer to set a fingerprint instead of providing certs, you can
      // set this to true.
      // Do not set to true unless you know what you are doing.
      "insecureSkipVerify": false,
      // Server's SHA256 fingerprint, used to verify as an alternative to providing
      // the whole server certs, should be used with insecureSkipVerify to true.
      // If both rootCA and sha256Fingerprint are provided, they will both be
      // verified.
      // An example to get fingerprint of a given cert:
      //     openssl x509 -fingerprint -sha256 -noout -in cert.cer | cut -f2 -d'=' | sed s/://g
      // or of a server with TLS enabled:
      //      openssl s_client -showcerts -connect example.com:443 < /dev/null | \
      //        openssl x509 -fingerprint -sha256 -noout | cut -f2 -d'=' | sed s/://g
      "sha256fingerprint": "22B975A1409850EF7F4522183E9C5A8955758FC899D70FE257112DA2FC430CCC",

      // rootCA is useful for self-signed certs. Be careful with it.
      // If the server has a trusted cert, you don't have to set it.
      "rootCA": "/path/to/the/ca/cert",

      // certFile and keyFile are advanced options for client authentication.
      // Most users could just leave it empty.
      "certFile": "/path/to/the/client/cert",
      "keyFile": "/path/to/the/client/key"

  // accounts is an optional array of accounts for SOCKS5 authentication
  // with no accounts, authentication is disabled
  "accounts": [{
    "username": "test server",
    "password": "test"

  // timeout optionally sets timeout value when dialing to a upstream
  // default "20s"
  "timeout": "20s",
  // retries optionally specifies the max retries count of dialing to upstreams
  // default 3.
  "retries": 3


$ h2s [-config h2s.json]