From 5d2a1007f47d70b0d2e7e811c11f88f14733aa3b Mon Sep 17 00:00:00 2001 From: Alexei Boronine Date: Tue, 15 Oct 2024 11:27:58 +0300 Subject: [PATCH] Update README.md --- README.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6db2a96..c23f49b 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,21 @@ This workflow allows exposing your localhost development server to the internet. hosted on a public IP address, and a client component running on your local machine. The client establishes a tunnel to the server, and the server acts as a reverse proxy, tunneling requests back to your local machine. +## How does h2tunnel work? + +1. The client initiates a TLS connection (tunnel) to the server +2. The server takes the newly created TLS socket and tunnels an HTTP2 session through it back to the client +3. The client listens for an HTTP2 connection on the socket from which it initiated the TLS tunnel +4. The server starts accepting HTTP1 requests and converts them into HTTP2 requests before sending them to the client +5. The client receives these HTTP2 requests and converts them back into HTTP1 requests to feed them into the local server + +The reason for using HTTP2 is that it allows multiplexing: processing simultaneous HTTP requests over a single connection. +By using HTTP2 we avoid having to reinvent this wheel. + +Similarly we avoid having to reinvent authentication by using a self-signed TLS certificate + private key pair. This +pair is used by both the client and the server, and both are configured to reject any other certificate. This way, the +pair effectively becomes a shared password. + ## Usage ### Forward localhost:8000 to http://example.com @@ -27,18 +42,31 @@ openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 -days 3650 -no On your server (example.com), we will be listening for tunnel connections on port 15001, and providing an HTTP proxy on port 80. Make sure these are open in your firewall. `--mux-listen-port` can be any available port, it is necessary -to run an HTTP2 multiplexer on localhost. +to run a local HTTP2 multiplexer (always bound to 127.0.0.1). ```bash -sudo h2tunnel server --crt h2tunnel.crt --key h2tunnel.key --tunnel-listen-ip 0.0.0.0 --tunnel-listen-port 15001 --proxy-listen-port 80 --proxy-listen-ip 0.0.0.0 --mux-listen-port=15002 +sudo h2tunnel server \ + --crt h2tunnel.crt \ + --key h2tunnel.key \ + --tunnel-listen-ip 0.0.0.0 \ + --tunnel-listen-port 15001 \ + --proxy-listen-port 80 \ + --proxy-listen-ip 0.0.0.0 \ + --mux-listen-port=15002 ```` On your local machine, we will connect to the tunnel and forward a local HTTP server on port 8000. `--demux-listen-port` -can be any available port, it is necessary to run an HTTP2 demultiplexer on localhost. +can be any available port, it is necessary to run a local HTTP2 demultiplexer (always bound to 127.0.0.1). ```bash python3 -m http.server # runs on port 8000 -h2tunnel client --key h2tunnel.key --crt h2tunnel.crt --tunnel-host=example.com --tunnel-port=15001 --local-http-port=8000 --demux-listen-port=15004 +h2tunnel client \ + --key h2tunnel.key \ + --crt h2tunnel.crt \ + --tunnel-host=example.com \ + --tunnel-port=15001 \ + --local-http-port=8000 \ + --demux-listen-port=15004 ``` ### Forward localhost:8000 to https://example.com @@ -77,7 +105,7 @@ const client = new TunnelClient({ logger: (line) => console.log(line), // optional key: `-----BEGIN PRIVATE KEY----- ...`, cert: `-----BEGIN CERTIFICATE----- ...`, - demuxListenPort: 15002, + demuxListenPort: 15004, localHttpPort: 8000, tunnelHost: `mysite.example.com`, tunnelPort: 15001, @@ -90,6 +118,27 @@ client.start(); await client.stop(); ``` +```typescript +import {TunnelServer} from "h2tunnel"; + +const server = new TunnelServer({ + logger: (line) => console.log(line), // optional + tunnelListenIp: "0.0.0.0", + tunnelListenPort: 15001, + key: `-----BEGIN PRIVATE KEY----- ...`, + cert: `-----BEGIN CERTIFICATE----- ...`, + proxyListenPort: 80, + proxyListenIp: "0.0.0.0", + muxListenPort: 15002, +}); + +// Start the server +server.start(); + +// Stop the server +await server.stop(); +``` + ## Testing ```bash