Go HTTP tunnel is a reverse tunnel based on HTTP/2.

Go HTTP tunnel GoDoc Go Report Card Build Status Github All Releases

Go HTTP tunnel is a reverse tunnel based on HTTP/2. It enables you to share your localhost when you don't have a public IP.

Features:

  • HTTP proxy with basic authentication
  • TCP proxy
  • SNI vhost proxy
  • Client auto reconnect
  • Client management and eviction
  • Easy to use CLI

Common use cases:

  • Hosting a game server from home
  • Developing webhook integrations
  • Managing IoT devices

Installation

Build the latest version.

$ go get -u github.com/mmatczuk/go-http-tunnel/cmd/...

Alternatively download the latest release.

Running

There are two executables:

  • tunneld - the tunnel server, to be run on publicly available host like AWS or GCE
  • tunnel - the tunnel client, to be run on your local machine or in your private network

To get help on the command parameters run tunneld -h or tunnel -h.

Tunnel requires TLS certificates for both client and server.

$ openssl req -x509 -nodes -newkey rsa:2048 -sha256 -keyout client.key -out client.crt
$ openssl req -x509 -nodes -newkey rsa:2048 -sha256 -keyout server.key -out server.crt

Run client:

  • Install tunnel binary
  • Make .tunnel directory in your project directory
  • Copy client.key, client.crt to .tunnel
  • Create configuration file tunnel.yml in .tunnel
  • Start all tunnels
$ tunnel -config ./tunnel/tunnel.yml start-all

Run server:

  • Install tunneld binary
  • Make .tunneld directory
  • Copy server.key, server.crt to .tunneld
  • Start tunnel server
$ tunneld -tlsCrt .tunneld/server.crt -tlsKey .tunneld/server.key

This will run HTTP server on port 80 and HTTPS (HTTP/2) server on port 443. If you want to use HTTPS it's recommended to get a properly signed certificate to avoid security warnings.

Run Server as a Service on Ubuntu using Systemd:

  • After completing the steps above successfully, create a new file for your service (you can name it whatever you want, just replace the name below with your chosen name).
$ vim tunneld.service
  • Add the following configuration to the file
[Unit]
Description=Go-Http-Tunnel Service
After=network.target
After=network-online.target

[Service]
ExecStart=/path/to/your/tunneld -tlsCrt /path/to/your/folder/.tunneld/server.crt -tlsKey /path/to/your/folder/.tunneld/server.key
TimeoutSec=30
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
  • Save and exit this file.
  • Move this new file to /etc/systemd/system/
$ sudo mv tunneld.service /etc/systemd/system/
  • Change the file permission to allow it to run.
$ sudo chmod u+x /etc/systemd/system/tunneld.service
  • Start the new service and make sure you don't get any errors, and that your client is able to connect.
$ sudo systemctl start tunneld.service
  • You can stop the service with:
$ sudo systemctl stop tunneld.service
  • Finally, if you want the service to start automatically when the server is rebooted, you need to enable it.
$ sudo systemctl enable tunneld.service

There are many more options for systemd services, and this is by not means an exhaustive configuration file.

Configuration

The tunnel client tunnel requires configuration file, by default it will try reading tunnel.yml in your current working directory. If you want to specify other file use -config flag.

Sample configuration that exposes:

  • localhost:8080 as webui.my-tunnel-host.com
  • host in private network for ssh connections

looks like this

    server_addr: SERVER_IP:5223
    tunnels:
      webui:
        proto: http
        addr: localhost:8080
        auth: user:password
        host: webui.my-tunnel-host.com
      ssh:
        proto: tcp
        addr: 192.168.0.5:22
        remote_addr: 0.0.0.0:22
      tls:
  	    proto: sni
  	    addr: localhost:443
  	    host: tls.my-tunnel-host.com

Configuration options:

  • server_addr: server TCP address, i.e. 54.12.12.45:5223
  • tls_crt: path to client TLS certificate, default: client.crt in the config file directory
  • tls_key: path to client TLS certificate key, default: client.key in the config file directory
  • root_ca: path to trusted root certificate authority pool file, if empty any server certificate is accepted
  • tunnels / [name]
    • proto: tunnel protocol, http, tcp or sni
    • addr: forward traffic to this local port number or network address, for proto=http this can be full URL i.e. https://machine/sub/path/?plus=params, supports URL schemes http and https
    • auth: (proto=http) (optional) basic authentication credentials to enforce on tunneled requests, format user:password
    • host: (proto=http, proto=sni) hostname to request (requires reserved name and DNS CNAME)
    • remote_addr: (proto=tcp) bind the remote TCP address
  • backoff
    • interval: how long client would wait before redialing the server if connection was lost, exponential backoff initial interval, default: 500ms
    • multiplier: interval multiplier if reconnect failed, default: 1.5
    • max_interval: maximal time client would wait before redialing the server, default: 1m
    • max_time: maximal time client would try to reconnect to the server if connection was lost, set 0 to never stop trying, default: 15m

How it works

A client opens TLS connection to a server. The server accepts connections from known clients only. The client is recognized by its TLS certificate ID. The server is publicly available and proxies incoming connections to the client. Then the connection is further proxied in the client's network.

The tunnel is based HTTP/2 for speed and security. There is a single TCP connection between client and server and all the proxied connections are multiplexed using HTTP/2.

Donation

If this project help you reduce time to develop, you can give me a cup of coffee.

paypal

A GitHub star is always appreciated!

License

Copyright (C) 2017 Michał Matczuk

This project is distributed under the AGPL-3 license. See the LICENSE file for details. If you need an enterprice license contact me directly.

Owner
Michal Jan Matczuk
Mate over coffee, running over biking, reading over watching, question over answers
Michal Jan Matczuk
Comments
  • Lets Encrypt support

    Lets Encrypt support

    This PR adds support for Let's Encrypt by setting two new flags

      -letsEncrypt (bool) to enable lets encrypt autocert generation
      -letsEncryptCacheDir (string) path to store cached certificates
    

    For lets encrypt port 80 and 443 are mandatory so httpAddr and httpsAddr will ignore the port but will still be able to bind to a specific host.

  • Identify dead connections

    Identify dead connections

    I'm having issues with long lived connections:

    • the server sometimes receives connection requests from clients that are reportedly already connected, and reject them.
    • when the server restarts, some clients do not try to connect again.

    I debugged the issue and found out that once the client is connected to the server this connection is kept open waiting for a user to connect to the server. If the connection dies without notifying the client or server, they would keep listening to dead connections.

    If the server believes that a dead connection belonging to an id is open it would reject new (valid) connections from that id.

    A client may keep listening to a dead connection forever, effectively preventing the client to retry and open a fresh connection.

    My workaround was to turn on TCP keepalive for the client connection, and to let the server ping (http ping) the existing client connection when a connection request with an already connected id is received.

  • ssh tunnel connection timeout

    ssh tunnel connection timeout

    @mmatczuk I want to ssh on system(172.16.209.145) from client using this tunnel solution tool. so i am not able to do that. getting timeout error.(attached screenshot of that) added my architecture diagram screenshot and also i have added my tunnel.yml file content in that screenshot

    i am trying to execute below command from client

    ssh -p 2222 [email protected]
    

    let me know what things are wrong so i can fix it.

    tunnel_diagram (1) image

    Thanks

  • Certificate problem

    Certificate problem

    Hello I can't connect to tunneld. I have error: "msg certificate error err ptls: expecting 1 peer certificate, got 0" Both client and server are on Windows. Both have certs files and files looks ok (I also tried files from tunnel\testdata directory). Any idea what can cause the problem?

  • TCP proxy connection remains open (CLOSED_WAIT)

    TCP proxy connection remains open (CLOSED_WAIT)

    In a client TCP Proxy, when a local connection is closed the function call transfer(local, r, ...) does not return, effectively preventing the local connection to be properly closed.

    To reproduce:

    1. Create a TCP tunnel
    2. Connect to the tunnel
    3. Close the tunnel connection
    4. invoke:
    lsof -i -a -p `pidof tunnel`
    

    At least one connection marked CLOSED_WAIT is present.

    A quick and dirty solution would be to close the response reader after the local connection dies:

    From 736802f154da59e23b4f1d89baafa49a1f579815 Mon Sep 17 00:00:00 2001
    From: Riccardo Gori <[email protected]>
    Date: Tue, 14 Nov 2017 16:07:31 +0100
    Subject: [PATCH] Properly close proxy connection
    
    ---
     tcpproxy.go | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/tcpproxy.go b/tcpproxy.go
    index f7dc199..d72bb76 100644
    --- a/tcpproxy.go
    +++ b/tcpproxy.go
    @@ -104,6 +104,7 @@ func (p *TCPProxy) Proxy(w io.Writer, r io.ReadCloser, msg *proto.ControlMessage
     			"dst", msg.ForwardedBy,
     			"src", target,
     		))
    +		r.Close()
     		close(done)
     	}()
     
    -- 
    2.9.5
    
    
  • Update and lock latest go-http-tunnel dependency

    Update and lock latest go-http-tunnel dependency

    Update and explicitly set the go-http-tunnel dependency. A raw clone and dep ensure fails to build as the dependency on the project's own files fails to resolve to the latest version containing SNI protocol.

  • How to prevent just anyone joining your server.

    How to prevent just anyone joining your server.

    Hello, I have been playing around with this and it seems to be working well and easy to set up, maybe to easy. Then it occurred to me that my server isn't only allowing "known" clients to connect, but just anybody who happens to know the server IP.

    How does one restrict what clients are allowed to connect to a server?

    Thanks!

  • Https pass trough

    Https pass trough

    Would it be an idea to allow https traffic to pass trough the proxy. This way the "operator" can't see the traffic. And you could still find the host from the handshake.

  •  yaml: line 1: did not find expected key

    yaml: line 1: did not find expected key

    configuration error: failed to parse file ".tunnel/tunnel.yml": yaml: line 1: did not find expected key with config server_addr: "185.2.2.137:4443" insecure_skip_verify: true tunnels: ...

    ./tunnel -version 3d03804

  • client: max_time never set to 0

    client: max_time never set to 0

    Hi, thanks for the repo!

    I am using v1.1 release. This is what I set in the tunnel.xml:

      interval: 100ms
      multiplier: 1
      max_interval: 100ms
      max_time: 0
    

    This is what the program prints:

      interval: 100ms
      multiplier: 1
      max_interval: 100ms
      max_time: 15m0s
    

    I have to workaround it with:

      interval: 100ms
      multiplier: 1
      max_interval: 100ms
      max_time: 999999h
    

    Wonder how to set the max time to 0?

  • Add build documentation / Future release

    Add build documentation / Future release

    First off: awesome project. Really cool to see an open-source alternative to ngrok.

    I'm running into #26 on MacOS, which can be solved by building from master. Since the build process is not documented and I'm not that familiar with Go, I cannot build the app myself.

    This issue is really blocking, because I cannot use the application. When will there be a new release so I can use it?

    Cheers.

    EDIT: I added the fake ssh config from the README.md to make it work.

  • self signed certificate error

    self signed certificate error

    self signed certificate error: "http: proxy error: x509: certificate signed by unknown authority"

    my config: proto: http addr: https://192.168.1.1:443

    how to fix

  • License

    License

    Hello,

    because I think it's a very good software and, with just a few adjustments / additions (like the ones in my pull request), it can be a great library too, would it be a good idea for you to change the license to a more permissive one? It may be something like Apache License 2.0 or any other license not forcing to distribute it in open source software only, would be ok.

    At the moment I've integrated it in a software that cannot be open source at the moment, even if it will be distributed for free. The new license may highly increase the use of this software as a library.

    What do you think about it? Would it be possible?

    Thank you :)

  • Tunneld stops responding from time to time.

    Tunneld stops responding from time to time.

    I have about 30 clients connected to a tunneld server. Sometimes, when I restart one of the clients with a hard power reset, it freezes up the tunneld for all the clients.

    unfortunately, I haven't been able to isolate any logs for this but the only resolution is to restart tunneld and wait for all the clients to reconnect. Not ideal at all as sometimes I don't catch on until I get a phone call.

    Has anyone else had this issue?

  • IF YOU WOULD LIKE TO SEE THIS PROJECT MODERNIZED PLEASE UPVOTE

    IF YOU WOULD LIKE TO SEE THIS PROJECT MODERNIZED PLEASE UPVOTE

    Hello Community!

    Unfortunately this project has become a little rusty. If you would like to see this project brought back to life upvote 👍. Do not hesitate to share feature ideas in the comments. Thanks!

  • HTTP POST return 404

    HTTP POST return 404

    Hello,

    I'm running this tunnel to serve a python notebook service.

    I run the tunnel and tunneld as the Readme.md, But I find all the GET response works great,

    But the POST, PATCH request returns 404 not found, I debug this with chrome web tools, log:

    Request URL: XXX
    Request Method: POST
    Status Code: 404 Not Found
    Remote Address: 127.0.0.1:7890
    Referrer Policy: strict-origin-when-cross-origin
    
    

    tunnel client version : 75a30ab tunned version: 75a30ab

    Thanks so much!

A Stable & Secure Tunnel based on KCP with N:M multiplexing and FEC. Available for ARM, MIPS, 386 and AMD64。KCPプロトコルに基づく安全なトンネル。KCP 프로토콜을 기반으로 하는 보안 터널입니다。
A Stable & Secure Tunnel based on KCP with N:M multiplexing and FEC. Available for ARM, MIPS, 386 and AMD64。KCPプロトコルに基づく安全なトンネル。KCP 프로토콜을 기반으로 하는 보안 터널입니다。

Disclaimer: kcptun maintains a single website — github.com/xtaci/kcptun. Any websites other than github.com/xtaci/kcptun are not endorsed by xtaci. Re

Jan 9, 2023
Clash - A rule-based tunnel in Go.
Clash - A rule-based tunnel in Go.

Clash A rule-based tunnel in Go. Features Local HTTP/HTTPS/SOCKS server with authentication support VMess, Shadowsocks, Trojan, Snell protocol support

Jan 5, 2023
A rule-based tunnel in Go with experimental features
A rule-based tunnel in Go with experimental features

Experimental-Clash A rule-based tunnel in Go with experimental features. Features Local HTTP/HTTPS/SOCKS server with authentication support VMess, Sha

Dec 25, 2022
Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH.
Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH.

Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH. Single executable including both client and server. Written in Go (golang). Chisel is mainly useful for passing through firewalls, though it can also be used to provide a secure endpoint into your network.

Jan 1, 2023
Simple HTTP tunnel using SSH remote port forwarding

Simple HTTP tunnel using SSH remote port forwarding

Nov 18, 2022
HTTP tunnel over Websocket
HTTP tunnel over Websocket

WS PROXY This is a reverse HTTP proxy over websockets. The aim is to securely make call to internal APIs from outside. How does it works a WSP client

Nov 12, 2022
Simple SNI based reverse proxy

SNIProxy SNIProxy is a very simple reverse proxy server that uses TLS SNI to route to hosts (in HTTP mode it just uses the Host header). It is designe

Oct 16, 2022
Reverse proxy server to filter traffic based on JA3 fingerprint/hash

JA3RP (JA3 Reverse Proxy) Ja3RP is a basic reverse proxy server that filters traffic based on JA3 fingerprints. It can also operate as a regular HTTP

Sep 17, 2022
Toy gRPC Tunnel over CloudFlare (Proof of Concept)
Toy gRPC Tunnel over CloudFlare (Proof of Concept)

gun You know what it means. Guide Server Go to your domain in CloudFlare. In "Network" tab, turn on gRPC.

Jan 6, 2023
Cloud Native Tunnel
Cloud Native Tunnel

inlets is a Cloud Native Tunnel written in Go Expose your local endpoints to the Internet or within a remote network, without touching firewalls. Foll

Jan 4, 2022
A deployable proxy server and tunnel written in go

Tunnelify Tunnelify is a deployable proxy server and tunnel written in go Installing | Quickstart | Configuration Installing Direct download You can i

Dec 11, 2022
An anonymous, encrypted Point-to-Point (Layer 3) tunnel between two peers.

NKN-Link An anonymous, encrypted Point-to-Point (Layer 3) tunnel between two peers. NKN-Link Table of Contents Preface Description Install Setup Run P

Dec 20, 2022
Gogrok is a self hosted, easy to use alternative to ngrok. It uses SSH as a base protocol, using channels and existing functionality to tunnel requests to an endpoint.

gogrok A simple, easy to use ngrok alternative (self hosted!) The server and client can also be easily embedded into your applications, see the 'serve

Dec 3, 2022
Open Source HTTP Reverse Proxy Cache and Time Series Dashboard Accelerator
Open Source HTTP Reverse Proxy Cache and Time Series Dashboard Accelerator

Trickster is an HTTP reverse proxy/cache for http applications and a dashboard query accelerator for time series databases. Learn more below, and chec

Jan 2, 2023
gproxy is a tiny service/library for creating lets-encrypt/acme secured gRPC and http reverse proxies
gproxy is a tiny service/library for creating lets-encrypt/acme secured gRPC and http reverse proxies

gproxy is a reverse proxy service AND library for creating flexible, expression-based, lets-encrypt/acme secured gRPC/http reverse proxies GProxy as a

Sep 11, 2022
An Advanced HTTP Reverse Proxy with Dynamic Sharding Strategies
An Advanced HTTP Reverse Proxy with Dynamic Sharding Strategies

Weaver - A modern HTTP Proxy with Advanced features Description Features Installation Architecture Configuration Contributing License Description Weav

Dec 24, 2022
An Advanced HTTP Reverse Proxy with Dynamic Sharding Strategies
An Advanced HTTP Reverse Proxy with Dynamic Sharding Strategies

Weaver - A modern HTTP Proxy with Advanced features Description Features Installation Architecture Configuration Contributing License Description Weav

Jan 1, 2023
A standalone Web Server developed with the standard http library, suport reverse proxy & flexible configuration
A standalone Web Server developed with the standard http library, suport reverse proxy & flexible configuration

paddy 简介 paddy是一款单进程的独立运行的web server,基于golang的标准库net/http实现。 paddy提供以下功能: 直接配置http响应 目录文件服务器 proxy_pass代理 http反向代理 支持请求和响应插件 部署 编译 $ go build ./main/p

Oct 18, 2022
Goproxy - HTTP/HTTPS Forward and Reverse Proxy

Go HTTP(s) Forward/Reverse Proxy This is intended to provide the proxy for the goproxy frontend. It is currently a work in progress, and is not very s

Jan 4, 2022