large refactoring, bug fixes, performance improvement

This commit is contained in:
yusing
2024-03-18 04:51:59 +00:00
parent eee6ff4f15
commit a52b1bcadd
27 changed files with 1530 additions and 419 deletions

164
README.md
View File

@@ -1,14 +1,15 @@
# go-proxy
A simple auto docker reverse proxy for home use. *Written in **Go***
A simple auto docker reverse proxy for home use. \*Written in **Go\***
In the examples domain `x.y.z` is used, replace them with your domain
## Table of content
- [Features](#features)
- [Why am I making this](#why-am-i-making-this)
- [Key Points](#key-points)
- [How to use](#how-to-use)
- [Binary] (#binary)
- [Docker] (#docker)
- [Configuration](#configuration)
- [Single Port Configuration](#single-port-configuration-example)
- [Multiple Ports Configuration](#multiple-ports-configuration-example)
@@ -20,8 +21,9 @@ In the examples domain `x.y.z` is used, replace them with your domain
- [Build it yourself](#build-it-yourself)
- [Getting SSL certs](#getting-ssl-certs)
## Features
## Key Points
- fast, nearly no performance penalty for end users when comparing to direct IP connections (See [benchmarks](#benchmarks))
- auto detect reverse proxies from docker
- additional reverse proxies from provider yaml file
- allow multiple docker / file providers by custom `config.yml` file
@@ -29,30 +31,38 @@ In the examples domain `x.y.z` is used, replace them with your domain
- path matching
- HTTP proxy
- TCP/UDP Proxy
- HTTP round robin load balance support (same subdomain and path across containers replicas)
- Auto hot-reload when container start / die / stop.
- HTTP round robin load balance support (same subdomain and path across different hosts)
- Auto hot-reload on container start / die / stop or config changes.
- Simple panel to see all reverse proxies and health (visit port [panel port] of go-proxy `https://*.y.z:[panel port]`)
![panel screenshot](screenshots/panel.png)
![panel screenshot](screenshots/panel.png)
## Why am I making this
## How to use (docker)
1. It's fun.
2. I have tried different reverse proxy services, i.e. [nginx proxy manager](https://nginxproxymanager.com/), [traefik](https://github.com/traefik/traefik), [nginx-proxy](https://github.com/nginx-proxy/nginx-proxy). I have found that `traefik` is not easy to use, and I don't want to click buttons every time I spin up a new container (`nginx proxy manager`). For `nginx-proxy` I found it buggy and quite unusable.
1. Download and extract the latest release (or clone the repository if you want to try out experimental features)
2. Copy `config.example.yml` to `config.yml` and modify the content to fit your needs
3. Do the same for `providers.example.yml`
4. See [Binary](#binary) or [docker](#docker)
## How to use
### Binary
1. (Optional) Prepare your certificates in `certs/` to enable https. See [Getting SSL Certs](#getting-ssl-certs)
- cert / chain / fullchain: ./certs/cert.crt
- private key: ./certs/priv.key
2. run the binary `bin/go-proxy`
3. enjoy
1. Download and extract the latest release
### Docker
1. Copy content from [compose.example.yml](compose.example.yml) and create your own `compose.yml`
2. Copy content from [compose.example.yml](compose.example.yml) and create your own `compose.yml`
2. Add networks to make sure it is in the same network with other containers, or make sure `proxy.<alias>.host` is reachable
3. Add networks to make sure it is in the same network with other containers, or make sure `proxy.<alias>.host` is reachable
3. (Optional) Mount your SSL certs to enable https. See [Getting SSL Certs](#getting-ssl-certs)
- cert / chain / fullchain -> /app/certs/cert.crt
- private key -> /app/certs/priv.key
4. (Optional) Mount your SSL certs. See [Getting SSL Certs](#getting-ssl-certs)
4. Start `go-proxy` with `docker compose up -d` or `make up`.
5. Start `go-proxy` with `docker compose up -d` or `make up`.
6. (Optional) If you are using ufw with vpn that drop all inbound traffic except vpn, run below to allow docker containers to connect to `go-proxy`
5. (Optional) If you are using ufw with vpn that drop all inbound traffic except vpn, run below to allow docker containers to connect to `go-proxy`
In case the network of your container is in subnet `172.16.0.0/16` (bridge),
and vpn network is under `100.64.0.0/10` (i.e. tailscale)
@@ -63,9 +73,9 @@ In the examples domain `x.y.z` is used, replace them with your domain
`docker network inspect $(docker network ls | awk '$3 == "bridge" { print $1}') | jq -r '.[] | .Name + " " + .IPAM.Config[0].Subnet' -`
7. start your docker app, and visit <container_name>.y.z
6. start your docker app, and visit <container_name>.y.z
8. check the logs with `docker compose logs` or `make logs` to see if there is any error, check panel at [panel port] for active proxies
7. check the logs with `docker compose logs` or `make logs` to see if there is any error, check panel at [panel port] for active proxies
## Known issues
@@ -88,9 +98,12 @@ However, there are some labels you can manipulate with:
- tcp/udp: is in format of `[<listeningPort>:]<targetPort>`
- when `listeningPort` is omitted (not suggested), a free port will be used automatically.
- `targetPort` must be a number, or the predefined names (see [stream.go](src/go-proxy/stream.go#L28))
- `no_tls_verify`: whether skip tls verify when scheme is https
- defaults to false
- `proxy.<alias>.path`: path matching (for http proxy only)
- defaults to empty
- `proxy.<alias>.path_mode`: mode for path handling
- defaults to empty
- allowed: \<empty>, forward, sub
- empty: remove path prefix from URL when proxying
@@ -153,7 +166,7 @@ app-db:
- proxy.app-db.scheme=tcp
# Optional (first free port will be used for listening port)
- proxy.app-db.port=20000:postgres
- proxy.app-db.port=20000:postgres
# In go-proxy
go-proxy:
@@ -189,43 +202,84 @@ A: Make sure the container is running, and \<subdomain> matches any container na
Benchmarked with `wrk` connecting `traefik/whoami`'s `/bench` endpoint
Direct connection
Remote benchmark (client running wrk and `go-proxy` server are different devices)
```shell
% wrk -t20 -c100 -d10s --latency http://homelab:4999/bench
Running 10s test @ http://homelab:4999/bench
20 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 3.74ms 1.19ms 19.94ms 81.53%
Req/Sec 1.35k 103.96 1.60k 73.60%
Latency Distribution
50% 3.46ms
75% 4.16ms
90% 4.98ms
99% 8.04ms
269696 requests in 10.01s, 32.41MB read
Requests/sec: 26950.35
Transfer/sec: 3.24MB
```
- Direct connection
With **go-proxy** reverse proxy
```shell
root@yusing-pc:~# wrk -t 10 -c 200 -d 30s --latency http://10.0.100.1/bench
Running 30s test @ http://10.0.100.1/bench
10 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.34ms 1.16ms 22.76ms 85.77%
Req/Sec 4.63k 435.14 5.47k 90.07%
Latency Distribution
50% 3.95ms
75% 4.71ms
90% 5.68ms
99% 8.61ms
1383812 requests in 30.02s, 166.28MB read
Requests/sec: 46100.87
Transfer/sec: 5.54MB
```
```shell
% wrk -t20 -c100 -d10s --latency https://whoami.mydomain.com/bench
Running 10s test @ https://whoami.6uo.me/bench
20 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.02ms 2.13ms 47.49ms 95.14%
Req/Sec 1.28k 139.15 1.47k 91.67%
Latency Distribution
50% 3.60ms
75% 4.36ms
90% 5.29ms
99% 8.83ms
253874 requests in 10.02s, 24.70MB read
Requests/sec: 25342.46
Transfer/sec: 2.47MB
```
- With reverse proxy
```shell
root@yusing-pc:~# wrk -t 10 -c 200 -d 30s --latency http://bench.6uo.me/bench
Running 30s test @ http://bench.6uo.me/bench
10 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.50ms 1.44ms 27.53ms 86.48%
Req/Sec 4.48k 375.00 5.12k 84.73%
Latency Distribution
50% 4.09ms
75% 5.06ms
90% 6.03ms
99% 9.41ms
1338996 requests in 30.01s, 160.90MB read
Requests/sec: 44616.36
Transfer/sec: 5.36MB
```
Local benchmark (client running wrk and `go-proxy` server are under same proxmox host but different LXCs)
- Direct connection
```
root@http-benchmark-client:~# wrk -t 10 -c 200 -d 10s --latency http://10.0.100.1/bench
Running 10s test @ http://10.0.100.1/bench
10 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 434.08us 539.35us 8.76ms 85.28%
Req/Sec 67.71k 6.31k 87.21k 71.20%
Latency Distribution
50% 153.00us
75% 646.00us
90% 1.18ms
99% 2.38ms
6739591 requests in 10.01s, 809.85MB read
Requests/sec: 673608.15
Transfer/sec: 80.94MB
```
- With reverse proxy
```
root@http-benchmark-client:~# wrk -t 10 -c 200 -d 10s --latency http://bench.6uo.me/bench
Running 10s test @ http://bench.6uo.me/bench
10 threads and 200 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.78ms 5.49ms 117.53ms 99.00%
Req/Sec 16.31k 2.30k 21.01k 86.69%
Latency Distribution
50% 1.12ms
75% 1.88ms
90% 2.80ms
99% 7.27ms
1634774 requests in 10.10s, 196.44MB read
Requests/sec: 161858.70
Transfer/sec: 19.45MB
```
## Memory usage