support '0' listening port, readme update, showcase added

This commit is contained in:
yusing 2024-09-23 04:09:56 +08:00
parent 090b73d287
commit 3b597eea29
9 changed files with 271 additions and 241 deletions

View file

@ -24,22 +24,23 @@ A lightweight, easy-to-use, and [performant](docs/benchmark_result.md) reverse p
- [Use JSON Schema in VSCode](#use-json-schema-in-vscode) - [Use JSON Schema in VSCode](#use-json-schema-in-vscode)
- [Config File](#config-file) - [Config File](#config-file)
- [Provider File](#provider-file) - [Provider File](#provider-file)
- [Known issues](#known-issues) - [Showcase](#showcase)
- [idlesleeper](#idlesleeper)
- [Build it yourself](#build-it-yourself) - [Build it yourself](#build-it-yourself)
## Key Points ## Key Points
- Easy to use - Easy to use
- Effortless configuration - Effortless configuration
- Error messages is clear and detailed, easy troubleshooting - Error messages is clear and detailed, easy troubleshooting
- Auto certificate obtaining and renewal (See [Supported DNS Challenge Providers](docs/dns_providers.md)) - Auto certificate obtaining and renewal (See [Supported DNS Challenge Providers](docs/dns_providers.md))
- 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
- Stop containers on idle, wake it up on traffic _(optional)_ - Stop containers on idle, wake it up on traffic _(optional, see [showcase](#idlesleeper))_
- HTTP(s) reserve proxy - HTTP(s) reserve proxy
- 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 for configuration and monitoring (See [screenshots](https://github.com/yusing/go-proxy-frontend?tab=readme-ov-file#screenshots))
- Written in **[Go](https://go.dev)** - Written in **[Go](https://go.dev)**
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)
@ -49,16 +50,16 @@ A lightweight, easy-to-use, and [performant](docs/benchmark_result.md) reverse p
1. Setup DNS Records, e.g. 1. Setup DNS Records, e.g.
- 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`
2. Setup `go-proxy` [See here](docs/docker.md) 2. Setup `go-proxy` [See here](docs/docker.md)
3. Setup `docker-socket-proxy` (see [example](docs/docker_socket_proxy.md) other machine that is running docker (if any) 3. Setup `docker-socket-proxy` (see [example](docs/docker_socket_proxy.md) other machine that is running docker (if any)
4. Configure `go-proxy` 4. Configure `go-proxy`
- with text editor (e.g. Visual Studio Code) - with text editor (e.g. Visual Studio Code)
- or with web config editor via `http://gp.y.z` - or with web config editor via `http://gp.y.z`
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)
@ -97,21 +98,21 @@ See [config.example.yml](config.example.yml) for more
```yaml ```yaml
# autocert configuration # autocert configuration
autocert: autocert:
email: # ACME Email email: # ACME Email
domains: # a list of domains for cert registration domains: # a list of domains for cert registration
provider: # DNS Challenge provider provider: # DNS Challenge provider
options: # provider specific options options: # provider specific options
- ... - ...
# reverse proxy providers configuration # reverse proxy providers configuration
providers: providers:
include: include:
- providers.yml - providers.yml
- other_file_1.yml - other_file_1.yml
- ... - ...
docker: docker:
local: $DOCKER_HOST local: $DOCKER_HOST
remote-1: tcp://10.0.2.1:2375 remote-1: tcp://10.0.2.1:2375
remote-2: ssh://root:1234@10.0.2.2 remote-2: ssh://root:1234@10.0.2.2
``` ```
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)
@ -124,9 +125,11 @@ See [providers.example.yml](providers.example.yml) for examples
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)
## Known issues ## Showcase
- `autocert` config is not hot-reloadable ### idlesleeper
![idlesleeper](showcase/idlesleeper.webp)
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)

View file

@ -22,22 +22,23 @@
- [VSCode 中使用 JSON Schema](#vscode-中使用-json-schema) - [VSCode 中使用 JSON Schema](#vscode-中使用-json-schema)
- [配置文件](#配置文件) - [配置文件](#配置文件)
- [透過文件配置](#透過文件配置) - [透過文件配置](#透過文件配置)
- [已知問題](#已知問題) - [展示](#展示)
- [idlesleeper](#idlesleeper)
- [源碼編譯](#源碼編譯) - [源碼編譯](#源碼編譯)
## 重點 ## 重點
- 易用 - 易用
- 不需花費太多時間就能輕鬆配置 - 不需花費太多時間就能輕鬆配置
- 除錯簡單 - 除錯簡單
- 自動處理 HTTPS 證書(參見[可用的 DNS 供應商](docs/dns_providers.md) - 自動處理 HTTPS 證書(參見[可用的 DNS 供應商](docs/dns_providers.md)
- 透過 Docker 容器自動配置 - 透過 Docker 容器自動配置
- 容器狀態變更時自動熱重載 - 容器狀態變更時自動熱重載
- 容器閒置時自動暫停/停止,入站時自動喚醒 - 容器閒置時自動暫停/停止,入站時自動喚醒
- HTTP(s)反向代理 - HTTP(s)反向代理
- TCP/UDP 端口轉發 - TCP/UDP 端口轉發
- 用於配置和監控的前端 Web 面板([截圖](https://github.com/yusing/go-proxy-frontend?tab=readme-ov-file#screenshots) - 用於配置和監控的前端 Web 面板([截圖](https://github.com/yusing/go-proxy-frontend?tab=readme-ov-file#screenshots)
- 使用 **[Go](https://go.dev)** 編寫 - 使用 **[Go](https://go.dev)** 編寫
[🔼 返回頂部](#目錄) [🔼 返回頂部](#目錄)
@ -47,14 +48,14 @@
1. 設置 DNS 記錄,例如: 1. 設置 DNS 記錄,例如:
- A 記錄: `*.y.z` -> `10.0.10.1` - A 記錄: `*.y.z` -> `10.0.10.1`
- AAAA 記錄: `*.y.z` -> `::ffff:a00:a01` - AAAA 記錄: `*.y.z` -> `::ffff:a00:a01`
2. 安裝 `go-proxy` [參見這裡](docs/docker.md) 2. 安裝 `go-proxy` [參見這裡](docs/docker.md)
3. 配置 `go-proxy` 3. 配置 `go-proxy`
- 使用文本編輯器 (推薦 Visual Studio Code [參見 VSCode 使用 schema](#vscode-中使用-json-schema)) - 使用文本編輯器 (推薦 Visual Studio Code [參見 VSCode 使用 schema](#vscode-中使用-json-schema))
- 或通過 `http://gp.y.z` 使用網頁配置編輯器 - 或通過 `http://gp.y.z` 使用網頁配置編輯器
[🔼 返回頂部](#目錄) [🔼 返回頂部](#目錄)
@ -93,21 +94,21 @@
```yaml ```yaml
# autocert 配置 # autocert 配置
autocert: autocert:
email: # ACME 電子郵件 email: # ACME 電子郵件
domains: # 域名列表 domains: # 域名列表
provider: # DNS 供應商 provider: # DNS 供應商
options: # 供應商個別配置 options: # 供應商個別配置
- ... - ...
# 配置文件 / docker # 配置文件 / docker
providers: providers:
include: include:
- providers.yml - providers.yml
- other_file_1.yml - other_file_1.yml
- ... - ...
docker: docker:
local: $DOCKER_HOST local: $DOCKER_HOST
remote-1: tcp://10.0.2.1:2375 remote-1: tcp://10.0.2.1:2375
remote-2: ssh://root:1234@10.0.2.2 remote-2: ssh://root:1234@10.0.2.2
``` ```
[🔼 返回頂部](#目錄) [🔼 返回頂部](#目錄)
@ -120,9 +121,11 @@ providers:
[🔼 返回頂部](#目錄) [🔼 返回頂部](#目錄)
## 已知問題 ## 展示
- `autocert` 配置不能熱重載 ### idlesleeper
![idlesleeper](showcase/idlesleeper.webp)
[🔼 返回頂部](#目錄) [🔼 返回頂部](#目錄)

View file

@ -20,9 +20,9 @@
1. Install `wget` if not already 1. Install `wget` if not already
- Ubuntu based: `sudo apt install -y wget` - Ubuntu based: `sudo apt install -y wget`
- Fedora based: `sudo yum install -y wget` - Fedora based: `sudo yum install -y wget`
- Arch based: `sudo pacman -Sy wget` - Arch based: `sudo pacman -Sy wget`
2. Run setup script 2. Run setup script
@ -57,20 +57,20 @@
```yaml ```yaml
autocert: autocert:
email: john.doe@x.y.z # ACME Email email: john.doe@x.y.z # ACME Email
domains: # a list of domains for cert registration domains: # a list of domains for cert registration
- x.y.z - x.y.z
provider: cloudflare provider: cloudflare
options: options:
- auth_token: c1234565789-abcdefghijklmnopqrst # your zone API token - auth_token: c1234565789-abcdefghijklmnopqrst # your zone API token
``` ```
To use **existing certificate**, set path for cert and key in `config.yml`, e.g. To use **existing certificate**, set path for cert and key in `config.yml`, e.g.
```yaml ```yaml
autocert: autocert:
cert_path: /app/certs/cert.crt cert_path: /app/certs/cert.crt
key_path: /app/certs/priv.key key_path: /app/certs/priv.key
``` ```
5. Modify `compose.yml` to fit your needs 5. Modify `compose.yml` to fit your needs
@ -85,31 +85,31 @@
### Syntax ### Syntax
| Label | Description | Default | Accepted values | | Label | Description | Example | Default | Accepted values |
| ------------------------ | --------------------------------------------------------------------- | -------------------- | ------------------------------------------------------------------------- | | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | --------------------------- | ------------------------------------------------------------------------- |
| `proxy.aliases` | comma separated aliases for subdomain and label matching | `container_name` | any | | `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.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)** | empty **(disabled)** | `number[unit]...`, e.g. `1m30s` | | `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 container to start before responding a loading page | empty | `number[unit]...` | | `proxy.wake_timeout` | time to wait for target site to be ready | | `10s` | `number[unit]...` |
| `proxy.stop_method` | method to stop after `idle_timeout` | `stop` | `stop`, `pause`, `kill` | | `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_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.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 | N/A | N/A | | `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**) | 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 | N/A | N/A | | `proxy.*.<field>` | set field for all aliases | `proxy.*.set_headers` | N/A | N/A |
### Fields ### Fields
| Field | Description | Default | Allowed Values / Syntax | | 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` | | `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 | | `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 in `ports:` | number in range of `1 - 65535` | | `port` | proxy port **(http/s)** | first port returned from docker | number in range of `1 - 65535` |
| `port` **(required)** | proxy port **(tcp/udp)** | N/A | `x:y` <br><ul><li>x: port for `go-proxy` to listen on</li><li>y: port or [_service name_](../src/common/constants.go#L55) of target container</li></ul> | | `port` **(required)** | proxy port **(tcp/udp)** | N/A | `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 | | `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 | empty **(proxy all requests)** | yaml style list[<sup>1</sup>](#list-example) of path patterns ([syntax](https://pkg.go.dev/net/http#hdr-Patterns-ServeMux)) | | `path_patterns` | proxy path patterns **(http/s only)**<br> only requests that matched a pattern will be proxied | empty **(proxy all requests)** | yaml style list[<sup>1</sup>](#list-example) of ([path patterns](https://pkg.go.dev/net/http#hdr-Patterns-ServeMux)) |
| `set_headers` | header to set **(http/s only)** | empty | yaml style key-value mapping[<sup>2</sup>](#key-value-mapping-example) of header-value pairs | | `set_headers` | header to set **(http/s only)** | empty | yaml style key-value mapping[<sup>2</sup>](#key-value-mapping-example) of header-value pairs |
| `hide_headers` | header to hide **(http/s only)** | empty | yaml style list[<sup>1</sup>](#list-example) of headers | | `hide_headers` | header to hide **(http/s only)** | empty | yaml style list[<sup>1</sup>](#list-example) of headers |
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)
@ -134,11 +134,11 @@ File Provider
```yaml ```yaml
service_a: service_a:
host: service_a.internal host: service_a.internal
set_headers: set_headers:
# do not duplicate header keys, as it is not allowed in YAML # do not duplicate header keys, as it is not allowed in YAML
X-Custom-Header1: value1, value2 X-Custom-Header1: value1, value2
X-Custom-Header2: value3 X-Custom-Header2: value3
``` ```
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)
@ -164,52 +164,52 @@ File Provider
```yaml ```yaml
service_a: service_a:
host: service_a.internal host: service_a.internal
path_patterns: path_patterns:
- GET / - GET /
- POST /auth - POST /auth
hide_headers: hide_headers:
- X-Custom-Header1 - X-Custom-Header1
- X-Custom-Header2 - X-Custom-Header2
``` ```
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)
## Troubleshooting ## Troubleshooting
- Container not showing up in proxies list - Container not showing up in proxies list
Please check that either `ports` or label `proxy.<alias>.port` is declared, e.g. Please check that either `ports` or label `proxy.<alias>.port` is declared, e.g.
```yaml ```yaml
services: services:
nginx-1: # Option 1 nginx-1: # Option 1
... ...
ports: ports:
- 80 - 80
nginx-2: # Option 2 nginx-2: # Option 2
... ...
container_name: nginx-2 container_name: nginx-2
network_mode: host network_mode: host
labels: labels:
proxy.nginx-2.port: 80 proxy.nginx-2.port: 80
``` ```
- Firewall issues - Firewall issues
If you are using `ufw` with vpn that drop all inbound traffic except vpn, run below: 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` `sudo ufw allow from 172.16.0.0/16 to 100.64.0.0/10`
Explaination: Explaination:
Docker network is usually `172.16.0.0/16` Docker network is usually `172.16.0.0/16`
Tailscale is used as an example, `100.64.0.0/10` will be the CIDR 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: 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' -` `docker network inspect $(docker network ls | awk '$3 == "bridge" { print $1}') | jq -r '.[] | .Name + " " + .IPAM.Config[0].Subnet' -`
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)
@ -219,97 +219,97 @@ More examples in [here](examples/)
```yaml ```yaml
volumes: volumes:
adg-work: adg-work:
adg-conf: adg-conf:
mc-data: mc-data:
palworld: palworld:
nginx: nginx:
services: services:
adg: adg:
image: adguard/adguardhome image: adguard/adguardhome
restart: unless-stopped restart: unless-stopped
labels: labels:
- proxy.aliases=adg,adg-dns,adg-setup - proxy.aliases=adg,adg-dns,adg-setup
- proxy.$1.port=80 - proxy.$1.port=80
- proxy.$2.scheme=udp - proxy.$2.scheme=udp
- proxy.$2.port=20000:dns - proxy.$2.port=20000:dns
- proxy.$3.port=3000 - proxy.$3.port=3000
volumes: volumes:
- adg-work:/opt/adguardhome/work - adg-work:/opt/adguardhome/work
- adg-conf:/opt/adguardhome/conf - adg-conf:/opt/adguardhome/conf
ports: ports:
- 80 - 80
- 3000 - 3000
- 53/udp - 53/udp
mc: mc:
image: itzg/minecraft-server image: itzg/minecraft-server
tty: true tty: true
stdin_open: true stdin_open: true
container_name: mc container_name: mc
restart: unless-stopped restart: unless-stopped
ports: ports:
- 25565 - 25565
labels: labels:
- proxy.mc.port=20001:25565 - proxy.mc.port=20001:25565
environment: environment:
- EULA=TRUE - EULA=TRUE
volumes: volumes:
- mc-data:/data - mc-data:/data
palworld: palworld:
image: thijsvanloef/palworld-server-docker:latest image: thijsvanloef/palworld-server-docker:latest
restart: unless-stopped restart: unless-stopped
container_name: pal container_name: pal
stop_grace_period: 30s stop_grace_period: 30s
ports: ports:
- 8211/udp - 8211/udp
- 27015/udp - 27015/udp
labels: labels:
- proxy.aliases=pal1,pal2 - proxy.aliases=pal1,pal2
- proxy.*.scheme=udp - proxy.*.scheme=udp
- proxy.$1.port=20002:8211 - proxy.$1.port=20002:8211
- proxy.$2.port=20003:27015 - proxy.$2.port=20003:27015
environment: ... environment: ...
volumes: volumes:
- palworld:/palworld - palworld:/palworld
nginx: nginx:
image: nginx image: nginx
container_name: nginx container_name: nginx
volumes: volumes:
- nginx:/usr/share/nginx/html - nginx:/usr/share/nginx/html
ports: ports:
- 80 - 80
labels: labels:
proxy.idle_timeout: 1m proxy.idle_timeout: 1m
go-proxy: go-proxy:
image: ghcr.io/yusing/go-proxy:latest image: ghcr.io/yusing/go-proxy:latest
container_name: go-proxy container_name: go-proxy
restart: always restart: always
network_mode: host network_mode: host
volumes: volumes:
- ./config:/app/config - ./config:/app/config
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
go-proxy-frontend: go-proxy-frontend:
image: ghcr.io/yusing/go-proxy-frontend:latest image: ghcr.io/yusing/go-proxy-frontend:latest
container_name: go-proxy-frontend container_name: go-proxy-frontend
restart: unless-stopped restart: unless-stopped
network_mode: host network_mode: host
labels: labels:
- proxy.aliases=gp - proxy.aliases=gp
- proxy.gp.port=3000 - proxy.gp.port=3000
depends_on: depends_on:
- go-proxy - go-proxy
``` ```
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)
### Services URLs for above examples ### Services URLs for above examples
- `gp.yourdomain.com`: go-proxy web panel - `gp.yourdomain.com`: go-proxy web panel
- `adg-setup.yourdomain.com`: adguard setup (first time setup) - `adg-setup.yourdomain.com`: adguard setup (first time setup)
- `adg.yourdomain.com`: adguard dashboard - `adg.yourdomain.com`: adguard dashboard
- `nginx.yourdomain.com`: nginx - `nginx.yourdomain.com`: nginx
- `yourdomain.com:2000`: adguard dns (udp) - `yourdomain.com:2000`: adguard dns (udp)
- `yourdomain.com:20001`: minecraft server - `yourdomain.com:20001`: minecraft server
- `yourdomain.com:20002`: palworld server - `yourdomain.com:20002`: palworld server
[🔼Back to top](#table-of-content) [🔼Back to top](#table-of-content)

View file

@ -1,22 +1,22 @@
example: # matching `app.y.z` example: # matching `app.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/{$} - GET /home/{$}
- /b/{bucket}/o/{any} - /b/{bucket}/o/{any}
no_tls_verify: false no_tls_verify: false
set_headers: set_headers:
HEADER_A: VALUE_A, VALUE_B HEADER_A: VALUE_A, VALUE_B
HEADER_B: VALUE_C HEADER_B: VALUE_C
hide_headers: hide_headers:
- HEADER_C - HEADER_C
- HEADER_D - HEADER_D
app1: app1: # app1 -> localhost:8080
host: some_host port: 8080
app2: app2:
scheme: tcp scheme: tcp
host: 10.0.0.2 host: 10.0.0.2
port: 20000:tcp port: 20000:tcp

View file

@ -75,7 +75,10 @@
"scheme": { "scheme": {
"anyOf": [ "anyOf": [
{ {
"enum": ["http", "https"] "enum": [
"http",
"https"
]
}, },
{ {
"type": "null" "type": "null"
@ -87,7 +90,7 @@
"then": { "then": {
"properties": { "properties": {
"port": { "port": {
"markdownDescription": "Proxy port from **1** to **65535**", "markdownDescription": "Proxy port from **0** to **65535**",
"oneOf": [ "oneOf": [
{ {
"type": "string", "type": "string",
@ -96,7 +99,7 @@
}, },
{ {
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 0,
"maximum": 65535 "maximum": 65535
} }
] ]
@ -160,7 +163,9 @@
"not": true "not": true
} }
}, },
"required": ["port"] "required": [
"port"
]
} }
}, },
{ {

BIN
showcase/idlesleeper.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 KiB

View file

@ -7,6 +7,7 @@ import (
"sync" "sync"
"time" "time"
T "github.com/yusing/go-proxy/proxy/fields"
U "github.com/yusing/go-proxy/utils" U "github.com/yusing/go-proxy/utils"
) )
@ -35,6 +36,8 @@ func (route *TCPRoute) Setup() error {
if err != nil { if err != nil {
return err return err
} }
//! this read the allocated port from orginal ':0'
route.Port.ListeningPort = T.Port(in.Addr().(*net.TCPAddr).Port)
route.listener = in route.listener = in
return nil return nil
} }

View file

@ -5,6 +5,7 @@ import (
"io" "io"
"net" "net"
T "github.com/yusing/go-proxy/proxy/fields"
U "github.com/yusing/go-proxy/utils" U "github.com/yusing/go-proxy/utils"
F "github.com/yusing/go-proxy/utils/functional" F "github.com/yusing/go-proxy/utils/functional"
) )
@ -50,6 +51,9 @@ func (route *UDPRoute) Setup() error {
return err return err
} }
//! this read the allocated listeningPort from orginal ':0'
route.Port.ListeningPort = T.Port(laddr.Port)
route.listeningConn = source route.listeningConn = source
route.targetAddr = raddr route.targetAddr = raddr
return nil return nil

View file

@ -1,6 +1,10 @@
package utils package utils
import "strings" import (
"net/url"
"strconv"
"strings"
)
func CommaSeperatedList(s string) []string { func CommaSeperatedList(s string) []string {
res := strings.Split(s, ",") res := strings.Split(s, ",")
@ -9,3 +13,11 @@ func CommaSeperatedList(s string) []string {
} }
return res return res
} }
func ExtractPort(fullURL string) (int, error) {
url, err := url.Parse(fullURL)
if err != nil {
return 0, err
}
return strconv.Atoi(url.Port())
}