mirror of
https://github.com/yusing/godoxy.git
synced 2025-05-19 20:32:35 +02:00
readme updates, docs moved to wiki
This commit is contained in:
parent
fab39a461f
commit
abbcbad5e9
12 changed files with 74 additions and 1130 deletions
77
README.md
77
README.md
|
@ -9,7 +9,9 @@
|
||||||
|
|
||||||
[繁體中文文檔請看此](README_CHT.md)
|
[繁體中文文檔請看此](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.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
_Join our [Discord](https://discord.gg/umReR62nRd) for help and discussions_
|
_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)
|
- [go-proxy](#go-proxy)
|
||||||
- [Table of content](#table-of-content)
|
- [Table of content](#table-of-content)
|
||||||
- [Key Points](#key-points)
|
- [Key Features](#key-features)
|
||||||
- [Getting Started](#getting-started)
|
- [Getting Started](#getting-started)
|
||||||
- [Setup](#setup)
|
- [Setup](#setup)
|
||||||
- [Commands line arguments](#commands-line-arguments)
|
|
||||||
- [Environment variables](#environment-variables)
|
|
||||||
- [Use JSON Schema in VSCode](#use-json-schema-in-vscode)
|
- [Use JSON Schema in VSCode](#use-json-schema-in-vscode)
|
||||||
- [Config File](#config-file)
|
- [Screenshots](#screenshots)
|
||||||
- [Include Files](#include-files)
|
|
||||||
- [Showcase](#showcase)
|
|
||||||
- [idlesleeper](#idlesleeper)
|
- [idlesleeper](#idlesleeper)
|
||||||
- [Build it yourself](#build-it-yourself)
|
- [Build it yourself](#build-it-yourself)
|
||||||
|
|
||||||
## Key Points
|
## Key Features
|
||||||
|
|
||||||
- Easy to use
|
- Easy to use
|
||||||
- Effortless configuration
|
- Effortless configuration
|
||||||
- Simple multi-node setup
|
- Simple multi-node setup
|
||||||
- Error messages is clear and detailed, easy troubleshooting
|
- 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 configuration for docker containers
|
||||||
- Auto hot-reload on container state / config file changes
|
- 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(s) reserve proxy
|
||||||
- [HTTP middleware support](docs/middlewares.md) _(experimental)_
|
- [HTTP middleware support](https://github.com/yusing/go-proxy/wiki/Middlewares)
|
||||||
- [Custom error pages support](docs/middlewares.md#custom-error-pages)
|
- [Custom error pages support](https://github.com/yusing/go-proxy/wiki/Middlewares#custom-error-pages)
|
||||||
- TCP and UDP port forwarding
|
- 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))
|
- **Web UI with App dashboard**
|
||||||
- Supports linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6 multi-platform
|
- Supports linux/amd64, linux/arm64
|
||||||
- Written in **[Go](https://go.dev)**
|
- Written in **[Go](https://go.dev)**
|
||||||
|
|
||||||
[🔼Back to top](#table-of-content)
|
[🔼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`
|
- A Record: `*.y.z` -> `10.0.10.1`
|
||||||
- AAAA Record: `*.y.z` -> `::ffff:a00:a01`
|
- 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
|
5. Done. You may now do some extra configuration
|
||||||
- With text editor (e.g. Visual Studio Code)
|
- With text editor (e.g. Visual Studio Code)
|
||||||
- With Web UI via `gp.y.z`
|
- With Web UI via `http://localhost:3000` or `https://gp.y.z`
|
||||||
- For more info, [See docker.md](docs/docker.md)
|
- For more info, [See Wiki]([wiki](https://github.com/yusing/go-proxy/wiki))
|
||||||
|
|
||||||
[🔼Back to top](#table-of-content)
|
[🔼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 <command>`**
|
|
||||||
|
|
||||||
### 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
|
### 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)
|
[🔼Back to top](#table-of-content)
|
||||||
|
|
||||||
### Config File
|
## Screenshots
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
### idlesleeper
|
### idlesleeper
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
[🔼Back to top](#table-of-content)
|
[🔼Back to top](#table-of-content)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
[](https://sonarcloud.io/summary/new_code?id=yusing_go-proxy)
|
[](https://sonarcloud.io/summary/new_code?id=yusing_go-proxy)
|
||||||
[](https://discord.gg/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)
|
- [VSCode 中使用 JSON Schema](#vscode-中使用-json-schema)
|
||||||
- [配置文件](#配置文件)
|
|
||||||
- [透過文件配置](#透過文件配置)
|
|
||||||
- [展示](#展示)
|
- [展示](#展示)
|
||||||
- [idlesleeper](#idlesleeper)
|
- [idlesleeper](#idlesleeper)
|
||||||
- [源碼編譯](#源碼編譯)
|
- [源碼編譯](#源碼編譯)
|
||||||
|
@ -33,14 +31,16 @@
|
||||||
- 不需花費太多時間就能輕鬆配置
|
- 不需花費太多時間就能輕鬆配置
|
||||||
- 支持多個docker節點
|
- 支持多個docker節點
|
||||||
- 除錯簡單
|
- 除錯簡單
|
||||||
- 自動配置 SSL 證書(參見[可用的 DNS 供應商](docs/dns_providers.md))
|
- 自動配置 SSL 證書(參見[可用的 DNS 供應商](https://github.com/yusing/go-proxy/wiki/Supported-DNS%E2%80%9001-Providers))
|
||||||
- 透過 Docker 容器自動配置
|
- 透過 Docker 容器自動配置
|
||||||
- 容器狀態變更時自動熱重載
|
- 容器狀態變更時自動熱重載
|
||||||
- 容器閒置時自動暫停/停止,入站時自動喚醒
|
- **idlesleeper** 容器閒置時自動暫停/停止,入站時自動喚醒 (可選, 參見 [展示](#idlesleeper))
|
||||||
- HTTP(s) 反向代理
|
- 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 端口轉發
|
- TCP/UDP 端口轉發
|
||||||
- 用於配置和監控的前端 Web 面板([截圖](https://github.com/yusing/go-proxy-frontend?tab=readme-ov-file#screenshots))
|
- Web 面板 (內置App dashboard)
|
||||||
- 支持 linux/amd64、linux/arm64、linux/arm/v7、linux/arm/v6 多平台
|
- 支持 linux/amd64、linux/arm64 平台
|
||||||
- 使用 **[Go](https://go.dev)** 編寫
|
- 使用 **[Go](https://go.dev)** 編寫
|
||||||
|
|
||||||
[🔼 返回頂部](#目錄)
|
[🔼 返回頂部](#目錄)
|
||||||
|
@ -70,20 +70,23 @@
|
||||||
|
|
||||||
5. 大功告成,你可以做一些額外的配置
|
5. 大功告成,你可以做一些額外的配置
|
||||||
- 使用文本編輯器 (推薦 Visual Studio Code [參見 VSCode 使用 schema](#vscode-中使用-json-schema))
|
- 使用文本編輯器 (推薦 Visual Studio Code [參見 VSCode 使用 schema](#vscode-中使用-json-schema))
|
||||||
- 或通過 `http://gp.y.z` 使用網頁配置編輯器
|
- 或通過 `http://localhost:3000` 使用網頁配置編輯器
|
||||||
- 詳情請參閱 [docker.md](docs/docker.md)
|
- 詳情請參閱 [docker.md](docs/docker.md)
|
||||||
|
|
||||||
[🔼 返回頂部](#目錄)
|
[🔼 返回頂部](#目錄)
|
||||||
|
|
||||||
### 命令行參數
|
### 命令行參數
|
||||||
|
|
||||||
| 參數 | 描述 | 示例 |
|
| 參數 | 描述 | 示例 |
|
||||||
| ----------- | -------------- | -------------------------- |
|
| ------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------- |
|
||||||
| 空 | 啟動代理服務器 | |
|
| 空 | 啟動代理服務器 | |
|
||||||
| `validate` | 驗證配置並退出 | |
|
| `validate` | 驗證配置並退出 | |
|
||||||
| `reload` | 強制刷新配置 | |
|
| `reload` | 強制刷新配置 | |
|
||||||
| `ls-config` | 列出配置並退出 | `go-proxy ls-config \| jq` |
|
| `ls-config` | 列出配置並退出 | `go-proxy ls-config \| jq` |
|
||||||
| `ls-route` | 列出路由並退出 | `go-proxy ls-route \| 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 <參數>` 運行**
|
**使用 `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
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
[🔼 返回頂部](#目錄)
|
[🔼 返回頂部](#目錄)
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,11 @@ services:
|
||||||
# labels:
|
# labels:
|
||||||
# - proxy.aliases=gp
|
# - proxy.aliases=gp
|
||||||
# - proxy.gp.port=3000
|
# - proxy.gp.port=3000
|
||||||
|
|
||||||
|
# Uncomment and change this if you have changed below
|
||||||
|
#
|
||||||
|
# environment:
|
||||||
|
# GOPROXY_API_ADDR: 127.0.0.1:8888
|
||||||
depends_on:
|
depends_on:
|
||||||
- app
|
- app
|
||||||
app:
|
app:
|
||||||
|
@ -18,6 +23,12 @@ services:
|
||||||
environment:
|
environment:
|
||||||
# (Optional) change this to your timezone to get correct log timestamp
|
# (Optional) change this to your timezone to get correct log timestamp
|
||||||
TZ: ETC/UTC
|
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:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
- ./config:/app/config
|
- ./config:/app/config
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
||||||
```
|
|
|
@ -1,81 +0,0 @@
|
||||||
# Supported DNS Providers
|
|
||||||
|
|
||||||
<!-- TOC -->
|
|
||||||
|
|
||||||
- [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)
|
|
321
docs/docker.md
321
docs/docker.md
|
@ -1,321 +0,0 @@
|
||||||
# Docker compose guide
|
|
||||||
|
|
||||||
## Table of content
|
|
||||||
|
|
||||||
<!-- TOC -->
|
|
||||||
|
|
||||||
- [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)**<br> _**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.<alias>.<field>` | set field for specific alias | `proxy.gitlab-ssh.scheme` | N/A | N/A |
|
|
||||||
| `proxy.#<index>.<field>` | set field for specific alias at index (starting from **1**) | `proxy.#3.port` | N/A | N/A |
|
|
||||||
| `proxy.*.<field>` | set field for all aliases | `proxy.*.set_headers` | N/A | N/A |
|
|
||||||
| `proxy.?.middlewares.<middleware>[.<field>]` | enable and set field for specific middleware | **?** here means `<alias>` / `$<index>` / `*` <ul><li>`proxy.#1.middlewares.modify_request.set_headers`</li><li>`proxy.*.middlewares.modify_response.hide_headers`</li><li>`proxy.app1.middlewares.redirect_http`</li></ul> | N/A | Middleware specific<br>See [middlewares.md](middlewares.md) for more |
|
|
||||||
|
|
||||||
### Fields
|
|
||||||
|
|
||||||
| Field | Description | Default | Allowed Values / Syntax |
|
|
||||||
| --------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| `scheme` | proxy protocol | <ul><li>`http` for numeric port</li><li>`tcp` for `x:y` port</li></ul> | `http`, `https`, `tcp`, `udp` |
|
|
||||||
| `host` | proxy host | <ul><li>Docker: docker client IP / hostname </li><li>File: `localhost`</li></ul> | 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` <br><ul><li>**x**: port for `go-proxy` to listen on.<br>**x** can be 0, which means listen on a random port</li><li>**y**: port or [_service name_](../src/common/constants.go#L55) of target container</li></ul> |
|
|
||||||
| `no_tls_verify` | whether skip tls verify **(https only)** | `false` | boolean |
|
|
||||||
| `path_patterns` | proxy path patterns **(http/s only)**<br> only requests that matched a pattern will be proxied | `/` **(proxy all requests)** | list[<sup>1</sup>](#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.<alias>.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)
|
|
|
@ -1,40 +0,0 @@
|
||||||
## Docker Socket Proxy
|
|
||||||
|
|
||||||
For docker client on other machine, set this up, then add `name: tcp://<machine_ip>: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
|
|
||||||
- <machine_private_ip>:2375:2375
|
|
||||||
```
|
|
||||||
|
|
||||||
```yml
|
|
||||||
# config.yml on go-proxy machine
|
|
||||||
autocert:
|
|
||||||
... # your config
|
|
||||||
|
|
||||||
providers:
|
|
||||||
include:
|
|
||||||
...
|
|
||||||
docker:
|
|
||||||
...
|
|
||||||
server1: tcp://<machine_ip>:2375
|
|
||||||
```
|
|
|
@ -1,438 +0,0 @@
|
||||||
# Middlewares
|
|
||||||
|
|
||||||
## Table of content
|
|
||||||
|
|
||||||
<!-- TOC -->
|
|
||||||
|
|
||||||
- [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)
|
|
||||||
|
|
||||||
<!-- TOC -->
|
|
||||||
|
|
||||||
## 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
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>404 Not Found</title>
|
|
||||||
<link type="text/css" rel="stylesheet" href="/$gperrorpage/style.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
...
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
```
|
|
||||||
|
|
||||||
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 `<statusCode>.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 `<middleware_name>@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)
|
|
|
@ -1,21 +1,28 @@
|
||||||
example: # matching `example.y.z`
|
example: # matching `example.y.z`
|
||||||
scheme: https
|
scheme: https
|
||||||
host: 10.0.0.1
|
host: 10.0.0.1
|
||||||
port: 80
|
port: 80
|
||||||
path_patterns: # Check https://pkg.go.dev/net/http#hdr-Patterns-ServeMux for syntax
|
path_patterns: # Check https://pkg.go.dev/net/http#hdr-Patterns-ServeMux for syntax
|
||||||
- GET / # accept any GET request
|
- GET / # accept any GET request
|
||||||
- POST /auth # for /auth and /auth/* accept only POST
|
- POST /auth # for /auth and /auth/* accept only POST
|
||||||
- GET /home/{$} # for exactly /home
|
- GET /home/{$} # for exactly /home
|
||||||
no_tls_verify: false
|
no_tls_verify: false
|
||||||
set_headers:
|
middlewares:
|
||||||
HEADER_A: VALUE_A, VALUE_B
|
cidr_whitelist:
|
||||||
HEADER_B: VALUE_C
|
allow:
|
||||||
hide_headers:
|
- 127.0.0.1
|
||||||
- HEADER_C
|
- 10.0.0.0/8
|
||||||
- HEADER_D
|
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
|
app1: # app1 -> localhost:8080
|
||||||
port: 8080
|
port: 8080
|
||||||
app2:
|
app2:
|
||||||
scheme: udp
|
scheme: udp
|
||||||
host: 10.0.0.2
|
host: 10.0.0.2
|
||||||
port: 2223:dns
|
port: 2223:dns
|
||||||
|
|
Before Width: | Height: | Size: 831 KiB After Width: | Height: | Size: 831 KiB |
BIN
screenshots/webui.png
Normal file
BIN
screenshots/webui.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 183 KiB |
Loading…
Add table
Reference in a new issue