diff --git a/README.md b/README.md index 2b20305..7d38c58 100755 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ [繁體中文文檔請看此](README_CHT.md) -A lightweight, easy-to-use, and [performant](docs/benchmark_result.md) reverse proxy with a web UI. +A lightweight, easy-to-use, and [performant](https://github.com/yusing/go-proxy/wiki/Benchmarks) reverse proxy with a Web UI and dashboard. + +![Screenshot](screenshots/webui.png) _Join our [Discord](https://discord.gg/umReR62nRd) for help and discussions_ @@ -19,34 +21,30 @@ _Join our [Discord](https://discord.gg/umReR62nRd) for help and discussions_ - [go-proxy](#go-proxy) - [Table of content](#table-of-content) - - [Key Points](#key-points) + - [Key Features](#key-features) - [Getting Started](#getting-started) - [Setup](#setup) - - [Commands line arguments](#commands-line-arguments) - - [Environment variables](#environment-variables) - [Use JSON Schema in VSCode](#use-json-schema-in-vscode) - - [Config File](#config-file) - - [Include Files](#include-files) - - [Showcase](#showcase) + - [Screenshots](#screenshots) - [idlesleeper](#idlesleeper) - [Build it yourself](#build-it-yourself) -## Key Points +## Key Features - Easy to use - Effortless configuration - Simple multi-node setup - Error messages is clear and detailed, easy troubleshooting -- Auto SSL cert management (See [Supported DNS Challenge Providers](docs/dns_providers.md)) +- Auto SSL cert management (See [Supported DNS-01 Challenge Providers](https://github.com/yusing/go-proxy/wiki/Supported-DNS%E2%80%9001-Providers)) - Auto configuration for docker containers - Auto hot-reload on container state / config file changes -- **idlesleeper**: stop containers on idle, wake it up on traffic _(optional, see [showcase](#idlesleeper))_ +- **idlesleeper**: stop containers on idle, wake it up on traffic _(optional, see [screenshots](#idlesleeper))_ - HTTP(s) reserve proxy -- [HTTP middleware support](docs/middlewares.md) _(experimental)_ -- [Custom error pages support](docs/middlewares.md#custom-error-pages) +- [HTTP middleware support](https://github.com/yusing/go-proxy/wiki/Middlewares) +- [Custom error pages support](https://github.com/yusing/go-proxy/wiki/Middlewares#custom-error-pages) - TCP and UDP port forwarding -- Web UI for configuration and monitoring (See [screenshots](https://github.com/yusing/go-proxy-frontend?tab=readme-ov-file#screenshots)) -- Supports linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6 multi-platform +- **Web UI with App dashboard** +- Supports linux/amd64, linux/arm64 - Written in **[Go](https://go.dev)** [🔼Back to top](#table-of-content) @@ -72,37 +70,15 @@ _Join our [Discord](https://discord.gg/umReR62nRd) for help and discussions_ - A Record: `*.y.z` -> `10.0.10.1` - AAAA Record: `*.y.z` -> `::ffff:a00:a01` -4. Setup `docker-socket-proxy` other docker nodes _(if any)_ (see [example](docs/docker_socket_proxy.md)) and then them inside `config.yml` +4. Setup `docker-socket-proxy` other docker nodes _(if any)_ (see [Multi docker nodes setup](https://github.com/yusing/go-proxy/wiki/Configurations#multi-docker-nodes-setup)) and then them inside `config.yml` 5. Done. You may now do some extra configuration - With text editor (e.g. Visual Studio Code) - - With Web UI via `gp.y.z` - - For more info, [See docker.md](docs/docker.md) + - With Web UI via `http://localhost:3000` or `https://gp.y.z` + - For more info, [See Wiki]([wiki](https://github.com/yusing/go-proxy/wiki)) [🔼Back to top](#table-of-content) - -### Commands line arguments - -| Argument | Description | Example | -| ----------------- | ---------------------------------------------------- | -------------------------------- | -| empty | start proxy server | | -| `validate` | validate config and exit | | -| `reload` | trigger a force reload of config | | -| `ls-config` | list config and exit | `go-proxy ls-config \| jq` | -| `ls-route` | list proxy entries and exit | `go-proxy ls-route \| jq` | -| `debug-ls-mtrace` | list middleware trace **(works only in debug mode)** | `go-proxy debug-ls-mtrace \| jq` | - -**run with `docker exec go-proxy /app/go-proxy `** - -### Environment variables - -| Environment Variable | Description | Default | Values | -| ------------------------------ | ------------------------------------------- | ---------------- | ------------- | -| `GOPROXY_NO_SCHEMA_VALIDATION` | disable schema validation | `false` | boolean | -| `GOPROXY_DEBUG` | enable debug behaviors | `false` | boolean | -| `GOPROXY_HTTP_ADDR` | http server listening address | `:80` | `[host]:port` | -| `GOPROXY_HTTPS_ADDR` | https server listening address (if enabled) | `:443` | `[host]:port` | -| `GOPROXY_API_ADDR` | api server listening address | `127.0.0.1:8888` | `[host]:port` | +| ### Use JSON Schema in VSCode @@ -110,27 +86,12 @@ Copy [`.vscode/settings.example.json`](.vscode/settings.example.json) to `.vscod [🔼Back to top](#table-of-content) -### Config File - -See [config.example.yml](config.example.yml) - -[🔼Back to top](#table-of-content) - -### Include Files - -These are files that include standalone proxy entries - -See [Fields](docs/docker.md#fields) - -See [providers.example.yml](providers.example.yml) for examples - -[🔼Back to top](#table-of-content) - -## Showcase +## Screenshots ### idlesleeper -![idlesleeper](showcase/idlesleeper.webp) +![idlesleeper](screenshots/idlesleeper.webp) + [🔼Back to top](#table-of-content) diff --git a/README_CHT.md b/README_CHT.md index 882c7c0..3bebe4d 100644 --- a/README_CHT.md +++ b/README_CHT.md @@ -7,7 +7,7 @@ [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=yusing_go-proxy&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=yusing_go-proxy) [![](https://dcbadge.limes.pink/api/server/umReR62nRd)](https://discord.gg/umReR62nRd) -一個輕量化、易用且[高效](docs/benchmark_result.md)的反向代理和端口轉發工具 +一個輕量化、易用且[高效]([docs/benchmark_result.md](https://github.com/yusing/go-proxy/wiki/Benchmarks)))的反向代理和端口轉發工具 ## 目錄 @@ -21,8 +21,6 @@ - [命令行參數](#命令行參數) - [環境變量](#環境變量) - [VSCode 中使用 JSON Schema](#vscode-中使用-json-schema) - - [配置文件](#配置文件) - - [透過文件配置](#透過文件配置) - [展示](#展示) - [idlesleeper](#idlesleeper) - [源碼編譯](#源碼編譯) @@ -33,14 +31,16 @@ - 不需花費太多時間就能輕鬆配置 - 支持多個docker節點 - 除錯簡單 -- 自動配置 SSL 證書(參見[可用的 DNS 供應商](docs/dns_providers.md)) +- 自動配置 SSL 證書(參見[可用的 DNS 供應商](https://github.com/yusing/go-proxy/wiki/Supported-DNS%E2%80%9001-Providers)) - 透過 Docker 容器自動配置 - 容器狀態變更時自動熱重載 -- 容器閒置時自動暫停/停止,入站時自動喚醒 +- **idlesleeper** 容器閒置時自動暫停/停止,入站時自動喚醒 (可選, 參見 [展示](#idlesleeper)) - HTTP(s) 反向代理 +- [HTTP middleware](https://github.com/yusing/go-proxy/wiki/Middlewares) +- [自訂 error pages](https://github.com/yusing/go-proxy/wiki/Middlewares#custom-error-pages) - TCP/UDP 端口轉發 -- 用於配置和監控的前端 Web 面板([截圖](https://github.com/yusing/go-proxy-frontend?tab=readme-ov-file#screenshots)) -- 支持 linux/amd64、linux/arm64、linux/arm/v7、linux/arm/v6 多平台 +- Web 面板 (內置App dashboard) +- 支持 linux/amd64、linux/arm64 平台 - 使用 **[Go](https://go.dev)** 編寫 [🔼 返回頂部](#目錄) @@ -70,20 +70,23 @@ 5. 大功告成,你可以做一些額外的配置 - 使用文本編輯器 (推薦 Visual Studio Code [參見 VSCode 使用 schema](#vscode-中使用-json-schema)) - - 或通過 `http://gp.y.z` 使用網頁配置編輯器 + - 或通過 `http://localhost:3000` 使用網頁配置編輯器 - 詳情請參閱 [docker.md](docs/docker.md) [🔼 返回頂部](#目錄) ### 命令行參數 -| 參數 | 描述 | 示例 | -| ----------- | -------------- | -------------------------- | -| 空 | 啟動代理服務器 | | -| `validate` | 驗證配置並退出 | | -| `reload` | 強制刷新配置 | | -| `ls-config` | 列出配置並退出 | `go-proxy ls-config \| jq` | -| `ls-route` | 列出路由並退出 | `go-proxy ls-route \| jq` | +| 參數 | 描述 | 示例 | +| ------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------- | +| 空 | 啟動代理服務器 | | +| `validate` | 驗證配置並退出 | | +| `reload` | 強制刷新配置 | | +| `ls-config` | 列出配置並退出 | `go-proxy ls-config \| jq` | +| `ls-route` | 列出路由並退出 | `go-proxy ls-route \| jq` | +| `go-proxy ls-route \| jq` | +| `ls-icons` | 列出 [dashboard-icons](https://github.com/walkxcode/dashboard-icons/tree/main) 並退出 | `go-proxy ls-icons \| grep adguard` | +| `debug-ls-mtrace` | 列出middleware追蹤 **(僅限於 debug 模式)** | `go-proxy debug-ls-mtrace \| jq` | **使用 `docker exec go-proxy /app/go-proxy <參數>` 運行** @@ -103,25 +106,12 @@ [🔼 返回頂部](#目錄) -### 配置文件 - -參見 [config.example.yml](config.example.yml) - -[🔼 返回頂部](#目錄) - -### 透過文件配置 - -參見 [Fields](docs/docker.md#fields) - -參見範例 [providers.example.yml](providers.example.yml) - -[🔼 返回頂部](#目錄) ## 展示 ### idlesleeper -![idlesleeper](showcase/idlesleeper.webp) +![idlesleeper](screenshots/idlesleeper.webp) [🔼 返回頂部](#目錄) diff --git a/compose.example.yml b/compose.example.yml index 3d12e8b..a32deb7 100755 --- a/compose.example.yml +++ b/compose.example.yml @@ -8,6 +8,11 @@ services: # labels: # - proxy.aliases=gp # - proxy.gp.port=3000 + + # Uncomment and change this if you have changed below + # + # environment: + # GOPROXY_API_ADDR: 127.0.0.1:8888 depends_on: - app app: @@ -18,6 +23,12 @@ services: environment: # (Optional) change this to your timezone to get correct log timestamp TZ: ETC/UTC + + # Change these if you need + # + # GOPROXY_HTTP_ADDR: :80 + # GOPROXY_HTTPS_ADDR: :443 + # GOPROXY_API_ADDR: 127.0.0.1:8888 volumes: - /var/run/docker.sock:/var/run/docker.sock - ./config:/app/config diff --git a/docs/add_dns_provider.md b/docs/add_dns_provider.md deleted file mode 100644 index 31734e1..0000000 --- a/docs/add_dns_provider.md +++ /dev/null @@ -1,41 +0,0 @@ -# Adding provider support - -## **CloudDNS** as an example - -1. Fork this repo, modify [autocert.go](../src/go-proxy/autocert.go#L305) - - ```go - var providersGenMap = map[string]ProviderGenerator{ - "cloudflare": providerGenerator(cloudflare.NewDefaultConfig, cloudflare.NewDNSProviderConfig), - // add here, e.g. - "clouddns": providerGenerator(clouddns.NewDefaultConfig, clouddns.NewDNSProviderConfig), - } - ``` - -2. Go to [https://go-acme.github.io/lego/dns/clouddns](https://go-acme.github.io/lego/dns/clouddns/) and check for required config - -3. Build `go-proxy` with `make build` - -4. Set required config in `config.yml` `autocert` -> `options` section - - ```shell - # From https://go-acme.github.io/lego/dns/clouddns/ - CLOUDDNS_CLIENT_ID=bLsdFAks23429841238feb177a572aX \ - CLOUDDNS_EMAIL=you@example.com \ - CLOUDDNS_PASSWORD=b9841238feb177a84330f \ - lego --email you@example.com --dns clouddns --domains my.example.org run - ``` - - Should turn into: - - ```yaml - autocert: - ... - options: - client_id: bLsdFAks23429841238feb177a572aX - email: you@example.com - password: b9841238feb177a84330f - ``` - -5. Run with `GOPROXY_NO_SCHEMA_VALIDATION=1` and test if it works -6. Commit and create pull request diff --git a/docs/benchmark_result.md b/docs/benchmark_result.md deleted file mode 100644 index b34df2a..0000000 --- a/docs/benchmark_result.md +++ /dev/null @@ -1,104 +0,0 @@ -# Benchmarks - -Benchmarked with `wrk` and `traefik/whoami`'s `/bench` endpoint - -## Remote benchmark - -- Direct connection - - ```shell - root@yusing-pc:~# wrk -t 10 -c 200 -d 10s -H "Host: bench.6uo.me" --latency http://10.0.100.3:8003/bench - Running 10s test @ http://10.0.100.3:8003/bench - 10 threads and 200 connections - Thread Stats Avg Stdev Max +/- Stdev - Latency 94.75ms 199.92ms 1.68s 91.27% - Req/Sec 4.24k 1.79k 18.79k 72.13% - Latency Distribution - 50% 1.14ms - 75% 120.23ms - 90% 245.63ms - 99% 1.03s - 423444 requests in 10.10s, 50.88MB read - Socket errors: connect 0, read 0, write 0, timeout 29 - Requests/sec: 41926.32 - Transfer/sec: 5.04MB - ``` - -- With reverse proxy - - ```shell - root@yusing-pc:~# wrk -t 10 -c 200 -d 10s -H "Host: bench.6uo.me" --latency http://10.0.1.7/bench - Running 10s test @ http://10.0.1.7/bench - 10 threads and 200 connections - Thread Stats Avg Stdev Max +/- Stdev - Latency 79.35ms 169.79ms 1.69s 92.55% - Req/Sec 4.27k 1.90k 19.61k 75.81% - Latency Distribution - 50% 1.12ms - 75% 105.66ms - 90% 200.22ms - 99% 814.59ms - 409836 requests in 10.10s, 49.25MB read - Socket errors: connect 0, read 0, write 0, timeout 18 - Requests/sec: 40581.61 - Transfer/sec: 4.88MB - ``` - -## Local benchmark (client running wrk and `go-proxy` server are under same proxmox host but different LXCs) - -- Direct connection - - ```shell - 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 `go-proxy` reverse proxy - - ```shell - root@http-benchmark-client:~# wrk -t 10 -c 200 -d 10s -H "Host: bench.6uo.me" --latency http://10.0.1.7/bench - Running 10s test @ http://10.0.1.7/bench - 10 threads and 200 connections - Thread Stats Avg Stdev Max +/- Stdev - Latency 1.23ms 0.96ms 11.43ms 72.09% - Req/Sec 17.48k 1.76k 21.48k 70.20% - Latency Distribution - 50% 0.98ms - 75% 1.76ms - 90% 2.54ms - 99% 4.24ms - 1739079 requests in 10.01s, 208.97MB read - Requests/sec: 173779.44 - Transfer/sec: 20.88MB - ``` - -- With `traefik-v3` - - ```shell - root@traefik-benchmark:~# wrk -t10 -c200 -d10s -H "Host: benchmark.whoami" --latency http://127.0.0.1:8000/bench - Running 10s test @ http://127.0.0.1:8000/bench - 10 threads and 200 connections - Thread Stats Avg Stdev Max +/- Stdev - Latency 2.81ms 10.36ms 180.26ms 98.57% - Req/Sec 11.35k 1.74k 13.76k 85.54% - Latency Distribution - 50% 1.59ms - 75% 2.27ms - 90% 3.17ms - 99% 37.91ms - 1125723 requests in 10.01s, 109.50MB read - Requests/sec: 112499.59 - Transfer/sec: 10.94MB - ``` \ No newline at end of file diff --git a/docs/dns_providers.md b/docs/dns_providers.md deleted file mode 100644 index 40be2a9..0000000 --- a/docs/dns_providers.md +++ /dev/null @@ -1,81 +0,0 @@ -# Supported DNS Providers - - - -- [Supported DNS Providers](#supported-dns-providers) - - [Cloudflare](#cloudflare) - - [CloudDNS](#clouddns) - - [DuckDNS](#duckdns) - - [OVHCloud](#ovhcloud) - - [Implement other DNS providers](#implement-other-dns-providers) - -## Cloudflare - -```yaml -autocert: - provider: cloudflare - options: - auth_token: -``` - -`auth_token` your zone API token - -Follow [this guide](https://cloudkul.com/blog/automcatic-renew-and-generate-ssl-on-your-website-using-lego-client/) to create a new token with `Zone.DNS` read and edit permissions - -## CloudDNS - -```yaml -autocert: - provider: clouddns - options: - client_id: - email: - password: -``` - -## DuckDNS - -```yaml -autocert: - provider: duckdns - options: - token: -``` - -Tested by [earvingad](https://github.com/earvingad) - -## OVHCloud - -```yaml -autocert: - provider: ovh - options: - api_endpoint: - application_key: - application_secret: - consumer_key: - oauth2_config: - client_id: - client_secret: -``` - -_Note, `application_key` and `oauth2_config` **CANNOT** be used together_ - -- `api_endpoint`: Endpoint URL, or one of - - `ovh-eu`, - - `ovh-ca`, - - `ovh-us`, - - `kimsufi-eu`, - - `kimsufi-ca`, - - `soyoustart-eu`, - - `soyoustart-ca` -- `application_secret` -- `application_key` -- `consumer_key` -- `oauth2_config`: Client ID and Client Secret - - `client_id` - - `client_secret` - -## Implement other DNS providers - -See [add_dns_provider.md](docs/add_dns_provider.md) diff --git a/docs/docker.md b/docs/docker.md deleted file mode 100644 index e113992..0000000 --- a/docs/docker.md +++ /dev/null @@ -1,321 +0,0 @@ -# Docker compose guide - -## Table of content - - - -- [Docker compose guide](#docker-compose-guide) - - [Table of content](#table-of-content) - - [Suggestions](#suggestions) - - [Additional setup](#additional-setup) - - [Labels](#labels) - - [Syntax](#syntax) - - [Fields](#fields) - - [Key-value mapping example](#key-value-mapping-example) - - [List example](#list-example) - - [Troubleshooting](#troubleshooting) - - [Docker compose examples](#docker-compose-examples) - - [Services URLs for above examples](#services-urls-for-above-examples) - -## Suggestions - -In order for labels to work correctly in `compose.yml`: - -1. `key: value` mapping is suggested for label, instead of `- key=value` -2. you need to add `|` in the end for multiline strings. - -Example - -```yaml -services: - app: - ... - container_name: app - labels: - proxy.app.middlewares.modify_request.set_headers: | - X-Custom-Header1: value1, value2 - X-Custom-Header2: value3 - proxy.app.middlewares.modify_request.hide_headers: | - X-Custom-Header4 - X-Custom-Header5 - X-Custom-Header6 -``` - -## Additional setup - -1. Enable HTTPs _(optional)_ - - Mount a folder to store obtained certs or to load existing cert - - ```yaml - services: - go-proxy: - ... - volumes: - - ./certs:/app/certs - ``` - - To use **autocert**, complete that section in `config.yml`, e.g. - - ```yaml - autocert: - email: john.doe@x.y.z # ACME Email - domains: # a list of domains for cert registration - - y.z - - *.y.z - provider: cloudflare - options: - auth_token: c1234565789-abcdefghijklmnopqrst # your zone API token - ``` - - To use **existing certificate**, set path for cert and key in `config.yml`, e.g. - - ```yaml - autocert: - provider: local - cert_path: /app/certs/cert.crt - key_path: /app/certs/priv.key - ``` - -2. Modify `compose.yml` to fit your needs - -3. Run `docker compose up -d` to start the container - -4. Navigate to Web panel `http://gp.yourdomain.com` or use **Visual Studio Code (provides schema check)** to edit proxy config - -[🔼Back to top](#table-of-content) - -## Labels - -**Parts surrounded by `[]` are optional** - -### Syntax - -| Label | Description | Example | Default | Accepted values | -| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | ------------------------------------------------------------------------- | -| `proxy.aliases` | comma separated aliases for subdomain and label matching | `gitlab,gitlab-reg,gitlab-ssh` | `container_name` | any | -| `proxy.exclude` | to be excluded from `go-proxy` | | false | boolean | -| `proxy.idle_timeout` | time for idle (no traffic) before put it into sleep **(http/s only)**
_**NOTE: idlewatcher will only be enabled containers that has non-empty `idle_timeout`**_ | `1h` | empty or `0` **(disabled)** | `number[unit]...`, e.g. `1m30s` | -| `proxy.wake_timeout` | time to wait for target site to be ready | | `30s` | `number[unit]...` | -| `proxy.stop_method` | method to stop after `idle_timeout` | | `stop` | `stop`, `pause`, `kill` | -| `proxy.stop_timeout` | time to wait for stop command | | `10s` | `number[unit]...` | -| `proxy.stop_signal` | signal sent to container for `stop` and `kill` methods | | docker's default | `SIGINT`, `SIGTERM`, `SIGHUP`, `SIGQUIT` and those without **SIG** prefix | -| `proxy..` | set field for specific alias | `proxy.gitlab-ssh.scheme` | N/A | N/A | -| `proxy.#.` | set field for specific alias at index (starting from **1**) | `proxy.#3.port` | N/A | N/A | -| `proxy.*.` | set field for all aliases | `proxy.*.set_headers` | N/A | N/A | -| `proxy.?.middlewares.[.]` | enable and set field for specific middleware | **?** here means `` / `$` / `*`
  • `proxy.#1.middlewares.modify_request.set_headers`
  • `proxy.*.middlewares.modify_response.hide_headers`
  • `proxy.app1.middlewares.redirect_http`
| N/A | Middleware specific
See [middlewares.md](middlewares.md) for more | - -### Fields - -| Field | Description | Default | Allowed Values / Syntax | -| --------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `scheme` | proxy protocol |
  • `http` for numeric port
  • `tcp` for `x:y` port
| `http`, `https`, `tcp`, `udp` | -| `host` | proxy host |
  • Docker: docker client IP / hostname
  • File: `localhost`
| IP address, hostname | -| `port` | proxy port **(http/s)** | first port returned from docker | number in range of `1 - 65535` | -| `port` | proxy port **(tcp/udp)** | `0:first_port` | `x:y`
  • **x**: port for `go-proxy` to listen on.
    **x** can be 0, which means listen on a random port
  • **y**: port or [_service name_](../src/common/constants.go#L55) of target container
| -| `no_tls_verify` | whether skip tls verify **(https only)** | `false` | boolean | -| `path_patterns` | proxy path patterns **(http/s only)**
only requests that matched a pattern will be proxied | `/` **(proxy all requests)** | list[1](#list-example) of ([path patterns](https://pkg.go.dev/net/http#hdr-Patterns-ServeMux)) | - - -[🔼Back to top](#table-of-content) - -#### Key-value mapping example - -Docker Compose - -```yaml -services: - nginx: - ... - labels: - proxy.nginx.middlewares.modify_request.set_headers: | # remember to add the '|' - X-Custom-Header1: value1, value2 - X-Custom-Header2: value3, value4 -``` - -File Provider - -```yaml -service_a: - host: service_a.internal - middlewares: - modify_request: - set_headers: - X-Custom-Header1: value1, value2 - X-Custom-Header2: value3 -``` - -[🔼Back to top](#table-of-content) - -#### List example - -Docker Compose - -```yaml -services: - nginx: - ... - labels: - proxy.nginx.path_patterns: | # remember to add the '|' - GET / - POST /auth - proxy.nginx.middlewares.modify_request.hide_headers: | # remember to add the '|' - X-Custom-Header1 - X-Custom-Header2 -``` - -Include file - -```yaml -service_a: - host: service_a.internal - path_patterns: - GET / - POST /auth - middlewares: - modify_request: - hide_headers: - - X-Custom-Header1 - - X-Custom-Header2 -``` - -[🔼Back to top](#table-of-content) - -## Troubleshooting - -- Container not showing up in proxies list - - Please check that either `ports` or label `proxy..port` is declared, e.g. - - ```yaml - services: - nginx-1: # Option 1 - ... - ports: - - 80 - nginx-2: # Option 2 - ... - container_name: nginx-2 - network_mode: host - labels: - proxy.nginx-2.port: 80 - ``` - -- Firewall issues - - If you are using `ufw` with vpn that drop all inbound traffic except vpn, run below: - - `sudo ufw allow from 172.16.0.0/16 to 100.64.0.0/10` - - Explaination: - - Docker network is usually `172.16.0.0/16` - - Tailscale is used as an example, `100.64.0.0/10` will be the CIDR - - You can also list CIDRs of all docker bridge networks by: - - `docker network inspect $(docker network ls | awk '$3 == "bridge" { print $1}') | jq -r '.[] | .Name + " " + .IPAM.Config[0].Subnet' -` - -[🔼Back to top](#table-of-content) - -## Docker compose examples - -More examples in [here](examples/) - -```yaml -volumes: - adg-work: - adg-conf: - mc-data: - palworld: - nginx: -services: - adg: - image: adguard/adguardhome - restart: unless-stopped - labels: - - proxy.aliases=adg,adg-dns,adg-setup - - proxy.#1.port=80 - - proxy.#2.scheme=udp - - proxy.#2.port=20000:dns - - proxy.#3.port=3000 - volumes: - - adg-work:/opt/adguardhome/work - - adg-conf:/opt/adguardhome/conf - ports: - - 80 - - 3000 - - 53/udp - mc: - image: itzg/minecraft-server - tty: true - stdin_open: true - container_name: mc - restart: unless-stopped - ports: - - 25565 - labels: - - proxy.mc.port=20001:25565 - environment: - - EULA=TRUE - volumes: - - mc-data:/data - palworld: - image: thijsvanloef/palworld-server-docker:latest - restart: unless-stopped - container_name: pal - stop_grace_period: 30s - ports: - - 8211/udp - - 27015/udp - labels: - - proxy.aliases=pal1,pal2 - - proxy.*.scheme=udp - - proxy.#1.port=20002:8211 - - proxy.#2.port=20003:27015 - environment: ... - volumes: - - palworld:/palworld - nginx: - image: nginx - container_name: nginx - volumes: - - nginx:/usr/share/nginx/html - ports: - - 80 - labels: - proxy.idle_timeout: 1m - go-proxy: - image: ghcr.io/yusing/go-proxy:latest - container_name: go-proxy - restart: always - network_mode: host - volumes: - - ./config:/app/config - - /var/run/docker.sock:/var/run/docker.sock - go-proxy-frontend: - image: ghcr.io/yusing/go-proxy-frontend:latest - container_name: go-proxy-frontend - restart: unless-stopped - network_mode: host - labels: - - proxy.aliases=gp - - proxy.gp.port=3000 - depends_on: - - go-proxy -``` - -[🔼Back to top](#table-of-content) - -### Services URLs for above examples - -- `gp.yourdomain.com`: go-proxy web panel -- `adg-setup.yourdomain.com`: adguard setup (first time setup) -- `adg.yourdomain.com`: adguard dashboard -- `nginx.yourdomain.com`: nginx -- `yourdomain.com:2000`: adguard dns (udp) -- `yourdomain.com:20001`: minecraft server -- `yourdomain.com:20002`: palworld server - -[🔼Back to top](#table-of-content) diff --git a/docs/docker_socket_proxy.md b/docs/docker_socket_proxy.md deleted file mode 100644 index 0331851..0000000 --- a/docs/docker_socket_proxy.md +++ /dev/null @@ -1,40 +0,0 @@ -## Docker Socket Proxy - -For docker client on other machine, set this up, then add `name: tcp://:2375` to `config.yml` under `docker` section - -```yml -# compose.yml on remote machine (e.g. server1) -docker-proxy: - container_name: docker-proxy - image: tecnativa/docker-socket-proxy - privileged: true - environment: - - ALLOW_START=1 - - ALLOW_STOP=1 - - ALLOW_RESTARTS=1 - - CONTAINERS=1 - - EVENTS=1 - - PING=1 - - POST=1 - - VERSION=1 - volumes: - - /var/run/docker.sock:/var/run/docker.sock - restart: always - ports: - - 2375:2375 - # or more secure - - :2375:2375 -``` - -```yml -# config.yml on go-proxy machine -autocert: - ... # your config - -providers: - include: - ... - docker: - ... - server1: tcp://:2375 -``` diff --git a/docs/middlewares.md b/docs/middlewares.md deleted file mode 100644 index 0241708..0000000 --- a/docs/middlewares.md +++ /dev/null @@ -1,438 +0,0 @@ -# Middlewares - -## Table of content - - - -- [Middlewares](#middlewares) - - [Table of content](#table-of-content) - - [Available middlewares](#available-middlewares) - - [Redirect http](#redirect-http) - - [Custom error pages](#custom-error-pages) - - [Real IP](#real-ip) - - [Custom](#custom) - - [Cloudflare](#cloudflare) - - [CIDR Whitelist](#cidr-whitelist) - - [Modify request or response](#modify-request-or-response) - - [Set headers](#set-headers) - - [Add headers](#add-headers) - - [Hide headers](#hide-headers) - - [X-Forwarded-\* Headers](#x-forwarded--headers) - - [Hide X-Forwarded-\*](#hide-x-forwarded-) - - [Set X-Forwarded-\*](#set-x-forwarded-) - - [Forward Authorization header (experimental)](#forward-authorization-header-experimental) - - [Middleware Compose](#middleware-compose) - - [Examples](#examples) - - [Authentik (untested, experimental)](#authentik-untested-experimental) - - - -## Available middlewares - -### Redirect http - -Redirect http requests to https - -```yaml -# docker labels -proxy.app1.middlewares.redirect_http: - -# include file -app1: - middlewares: - redirect_http: -``` - -nginx equivalent: -```nginx -server { - listen 80; - server_name domain.tld; - return 301 https://$host$request_uri; -} -``` - -[🔼Back to top](#table-of-content) - -### Custom error pages - -To enable custom error pages, mount a folder containing your `html`, `js`, `css` files to `/app/error_pages` of _go-proxy_ container **(subfolders are ignored, please place all files in root directory)** - -Any path under `error_pages` directory (e.g. `href` tag), should starts with `/$gperrorpage/` - -Example: -```html - - - 404 Not Found - - - - ... - - -``` - -Hot-reloading is **supported**, you can **edit**, **rename** or **delete** files **without restarting**. Changes will be reflected after page reload - -Error page will be served if: - -- route does not exist or domain does not match any of `match_domains` - -or - -- status code is not in range of 200 to 300, and -- content type is `text/html`, `application/xhtml+xml` or `text/plain` - -Error page will be served: - -- from file `.html` if exists -- otherwise from `404.html` -- if they don't exist, original response will be served - -```yaml -# docker labels -proxy.app1.middlewares.custom_error_page: - -# include file -app1: - middlewares: - custom_error_page: -``` - -nginx equivalent: -```nginx -location / { - try_files $uri $uri/ /error_pages/404.html =404; -} -``` - -[🔼Back to top](#table-of-content) - -### Real IP - -Check https://nginx.org/en/docs/http/ngx_http_realip_module.html for explaination of options - -#### Custom - -```yaml -# docker labels -proxy.app1.middlewares.real_ip.header: X-Real-IP -proxy.app1.middlewares.real_ip.from: | - 127.0.0.1 - 192.168.0.0/16 - 10.0.0.0/8 -proxy.app1.middlewares.real_ip.recursive: true - -# include file -app1: - middlewares: - real_ip: - header: X-Real-IP - from: - - 127.0.0.1 - - 192.168.0.0/16 - - 10.0.0.0/8 - recursive: true -``` - -nginx equivalent: -```nginx -location / { - set_real_ip_from 127.0.0.1; - set_real_ip_from 192.168.0.0/16; - set_real_ip_from 10.0.0.0/8; - - real_ip_header X-Real-IP; - real_ip_recursive on; -} -``` - -[🔼Back to top](#table-of-content) - -#### Cloudflare - -This is a preset for Cloudflare - -- `header`: `CF-Connecting-IP` -- `from`: CIDR List of Cloudflare IPs from (updated every hour) - - https://www.cloudflare.com/ips-v4 - - https://www.cloudflare.com/ips-v6 -- `recursive`: true - -```yaml -# docker labels -proxy.app1.middlewares.cloudflare_real_ip: - -# include file -app1: - middlewares: - cloudflare_real_ip: -``` - -[🔼Back to top](#table-of-content) - -### CIDR Whitelist - -```yaml -# docker labels -proxy.app1.middlewares.cidr_whitelist.allow: | - 10.0.0.0/8 - 192.168.0.0/16 -# optional (default: 403) -proxy.app1.middlewares.cidr_whitelist.status_code: 403 -# optional (default: "IP not allowed") -proxy.app1.middlewares.cidr_whitelist.message: "IP not allowed" - -# include file -app1: - middlewares: - whitelist: - cidr: - - 10.0.0.0/8 - - 192.168.0.0/16 - status_code: 403 # default - message: "IP not allowed" # default -``` - -### Modify request or response - -```yaml -# docker labels -proxy.app1.middlewares.modify_request.field: -proxy.app1.middlewares.modify_response.field: - -# include file -app1: - middlewares: - modify_request: - field: - modify_response: - field: -``` - -#### Set headers - -```yaml -# docker labels -proxy.app1.middlewares.modify_request.set_headers: | - X-Custom-Header1: value1, value2 - X-Custom-Header2: value3 - -# include file -app1: - middlewares: - modify_request: - set_headers: - X-Custom-Header1: value1, value2 - X-Custom-Header2: value3 -``` - -nginx equivalent: -```nginx -location / { - add_header X-Custom-Header1 value1, value2; - add_header X-Custom-Header2 value3; -} -``` - -[🔼Back to top](#table-of-content) - -#### Add headers - -```yaml -# docker labels -proxy.app1.middlewares.modify_request.add_headers: | - X-Custom-Header1: value1, value2 - X-Custom-Header2: value3 - -# include file -app1: - middlewares: - modify_request: - add_headers: - X-Custom-Header1: value1, value2 - X-Custom-Header2: value3 -``` - -nginx equivalent: -```nginx -location / { - more_set_headers "X-Custom-Header1: value1, value2"; - more_set_headers "X-Custom-Header2: value3"; -} -``` - -[🔼Back to top](#table-of-content) - -#### Hide headers - -```yaml -# docker labels -proxy.app1.middlewares.modify_request.hide_headers: | - X-Custom-Header1 - X-Custom-Header2 - -# include file -app1: - middlewares: - modify_request: - hide_headers: - - X-Custom-Header1 - - X-Custom-Header2 -``` - -nginx equivalent: -```nginx -location / { - more_clear_headers "X-Custom-Header1"; - more_clear_headers "X-Custom-Header2"; -} -``` - -[🔼Back to top](#table-of-content) - -### X-Forwarded-* Headers - -#### Hide X-Forwarded-* - -Remove `Forwarded` and `X-Forwarded-*` headers before request - -```yaml -# docker labels -proxy.app1.middlewares.modify_request.hide_x_forwarded: - -# include file -app1: - middlewares: - modify_request: - hide_x_forwarded: -``` - -#### Set X-Forwarded-* - -Replace existing `X-Forwarded-*` headers with `go-proxy` provided headers - -```yaml -# docker labels -proxy.app1.middlewares.modify_request.set_x_forwarded: - -# include file -app1: - middlewares: - modify_request: - set_x_forwarded: -``` - -[🔼Back to top](#table-of-content) - -### Forward Authorization header (experimental) - -Fields: -- `address`: authentication provider URL _(required)_ -- `trust_forward_header`: whether to trust `X-Forwarded-*` headers from upstream proxies _(default: `false`)_ -- `auth_response_headers`: list of headers to copy from auth response _(default: empty)_ -- `add_auth_cookies_to_response`: list of cookies to add to response _(default: empty)_ - -```yaml -# docker labels -proxy.app1.middlewares.forward_auth.address: https://auth.example.com -proxy.app1.middlewares.forward_auth.trust_forward_header: true -proxy.app1.middlewares.forward_auth.auth_response_headers: | - X-Auth-Token - X-Auth-User -proxy.app1.middlewares.forward_auth.add_auth_cookies_to_response: | - uid - session_id - -# include file -app1: - middlewares: - forward_authorization: - address: https://auth.example.com - trust_forward_header: true - auth_response_headers: - - X-Auth-Token - - X-Auth-User - add_auth_cookies_to_response: - - uid - - session_id -``` - -Traefik equivalent: -```yaml -# docker labels -traefik.http.middlewares.authentik.forwardauth.address: https://auth.example.com -traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: true -traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: X-Auth-Token, X-Auth-User -traefik.http.middlewares.authentik.forwardauth.addAuthCookiesToResponse: uid, session_id - -# standalone -http: - middlewares: - forwardAuth: - address: https://auth.example.com - trustForwardHeader: true - authResponseHeaders: - - X-Auth-Token - - X-Auth-User - addAuthCookiesToResponse: - - uid - - session_id -``` - -[🔼Back to top](#table-of-content) - -## Middleware Compose - -Middleware compose is a way to create reusable middlewares in file(s), just like docker compose. - -Files will be loaded from `config/middlewares` - -You may use them with `@file` - -See [example](../internal/net/http/middleware/test_data/middleware_compose.yml) - -[🔼Back to top](#table-of-content) - -## Examples - -### Authentik (untested, experimental) - -```yaml -# docker compose -services: - ... - server: - ... - container_name: authentik - labels: - proxy.authentik.middlewares.redirect_http: - proxy.authentik.middlewares.set_x_forwarded: - proxy.authentik.middlewares.modify_request.add_headers: | - Strict-Transport-Security: "max-age=63072000" always - - whoami: - image: containous/whoami - container_name: whoami - ports: - - 80 - labels: - proxy.#1.middlewares.forward_auth.address: https://your_authentik_forward_address - proxy.#1.middlewares.forward_auth.trustForwardHeader: true - proxy.#1.middlewares.forward_auth.authResponseHeaders: | - X-authentik-username - X-authentik-groups - X-authentik-email - X-authentik-name - X-authentik-uid - X-authentik-jwt - X-authentik-meta-jwks - X-authentik-meta-outpost - X-authentik-meta-provider - X-authentik-meta-app - X-authentik-meta-version - restart: unless-stopped -``` - -[🔼Back to top](#table-of-content) \ No newline at end of file diff --git a/providers.example.yml b/providers.example.yml index 7feb571..63f1743 100644 --- a/providers.example.yml +++ b/providers.example.yml @@ -1,21 +1,28 @@ example: # matching `example.y.z` - scheme: https - host: 10.0.0.1 - port: 80 - path_patterns: # Check https://pkg.go.dev/net/http#hdr-Patterns-ServeMux for syntax - - GET / # accept any GET request - - POST /auth # for /auth and /auth/* accept only POST - - GET /home/{$} # for exactly /home - no_tls_verify: false - set_headers: - HEADER_A: VALUE_A, VALUE_B - HEADER_B: VALUE_C - hide_headers: - - HEADER_C - - HEADER_D + scheme: https + host: 10.0.0.1 + port: 80 + path_patterns: # Check https://pkg.go.dev/net/http#hdr-Patterns-ServeMux for syntax + - GET / # accept any GET request + - POST /auth # for /auth and /auth/* accept only POST + - GET /home/{$} # for exactly /home + no_tls_verify: false + middlewares: + cidr_whitelist: + allow: + - 127.0.0.1 + - 10.0.0.0/8 + status_code: 403 + message: "IP not allowed" + homepage: + name: Example App + icon: png/example.png + description: An example app + category: example + app1: # app1 -> localhost:8080 - port: 8080 + port: 8080 app2: - scheme: udp - host: 10.0.0.2 - port: 2223:dns + scheme: udp + host: 10.0.0.2 + port: 2223:dns diff --git a/showcase/idlesleeper.webp b/screenshots/idlesleeper.webp similarity index 100% rename from showcase/idlesleeper.webp rename to screenshots/idlesleeper.webp diff --git a/screenshots/webui.png b/screenshots/webui.png new file mode 100644 index 0000000..ca3d771 Binary files /dev/null and b/screenshots/webui.png differ