mirror of
https://github.com/sadoyan/aralez.git
synced 2026-06-11 01:34:14 +08:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
162c5060c9 | ||
|
|
132cf45dfe | ||
|
|
77dcafbb4e | ||
|
|
649bd979f7 | ||
|
|
bd315106b9 | ||
|
|
3ba2ed33ae | ||
|
|
c09efab9fd | ||
|
|
735d605f6d | ||
|
|
6773d0f502 | ||
|
|
a8cb727da5 | ||
|
|
f81194aee7 | ||
|
|
0f09a2e02b | ||
|
|
27aca0a3a5 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -8,10 +8,14 @@
|
|||||||
/docs/
|
/docs/
|
||||||
/docs
|
/docs
|
||||||
/etc
|
/etc
|
||||||
|
/etc/
|
||||||
|
etc
|
||||||
|
.etc/
|
||||||
|
assets/
|
||||||
|
assets
|
||||||
/target/
|
/target/
|
||||||
*.iml
|
*.iml
|
||||||
.idea/
|
.idea/
|
||||||
.etc/
|
|
||||||
*.ipr
|
*.ipr
|
||||||
*.iws
|
*.iws
|
||||||
/out/
|
/out/
|
||||||
|
|||||||
60
Cargo.lock
generated
60
Cargo.lock
generated
@@ -127,7 +127,7 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aralez"
|
name = "aralez"
|
||||||
version = "0.9.2"
|
version = "0.92.10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
@@ -141,6 +141,7 @@ dependencies = [
|
|||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"log",
|
"log",
|
||||||
"log4rs",
|
"log4rs",
|
||||||
|
"mimalloc",
|
||||||
"moka",
|
"moka",
|
||||||
"notify",
|
"notify",
|
||||||
"pingora",
|
"pingora",
|
||||||
@@ -161,8 +162,6 @@ dependencies = [
|
|||||||
"sha2 0.11.0",
|
"sha2 0.11.0",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"subtle",
|
"subtle",
|
||||||
"tikv-jemalloc-ctl",
|
|
||||||
"tikv-jemallocator",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"tonic",
|
"tonic",
|
||||||
"tower-http",
|
"tower-http",
|
||||||
@@ -1917,6 +1916,15 @@ version = "0.2.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libmimalloc-sys"
|
||||||
|
version = "0.1.49"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a45a52f43e1c16f667ccfe4dd8c85b7f7c204fd5e3bf46c5b0db9a5c3c0b8e9"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libyml"
|
name = "libyml"
|
||||||
version = "0.0.5"
|
version = "0.0.5"
|
||||||
@@ -2043,6 +2051,15 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mimalloc"
|
||||||
|
version = "0.1.52"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d4139bb28d14ad1facf21d5eb8825051b326e172d216b39f6d31df53cc97862"
|
||||||
|
dependencies = [
|
||||||
|
"libmimalloc-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
@@ -2428,12 +2445,6 @@ dependencies = [
|
|||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "paste"
|
|
||||||
version = "1.0.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem"
|
name = "pem"
|
||||||
version = "3.0.6"
|
version = "3.0.6"
|
||||||
@@ -3880,37 +3891,6 @@ dependencies = [
|
|||||||
"trackable",
|
"trackable",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tikv-jemalloc-ctl"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3a184c43b8ab2f41df2733b55556e3f5f632f4aeaa205b1bb018f574b7f5f142"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"paste",
|
|
||||||
"tikv-jemalloc-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tikv-jemalloc-sys"
|
|
||||||
version = "0.7.1+5.3.1-0-g81034ce1f1373e37dc865038e1bc8eeecf559ce8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1a2825c78386b4ae0314074867860ba9577875de945f05992c38815cbec327f0"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tikv-jemallocator"
|
|
||||||
version = "0.7.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "249f09e49ab1609436f34c776e84231bead18d6a955f119f939bdc1d847561bd"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"tikv-jemalloc-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.47"
|
version = "0.3.47"
|
||||||
|
|||||||
10
Cargo.toml
10
Cargo.toml
@@ -1,7 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "aralez"
|
name = "aralez"
|
||||||
version = "0.9.2"
|
version = "0.92.10"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
description = "Reverse proxy built on top of Cloudflare's Pingora"
|
||||||
|
exclude = ["etc/*"]
|
||||||
|
repository = "https://github.com/sadoyan/aralez"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
@@ -46,8 +50,6 @@ ahash = "0.8.12"
|
|||||||
instant-acme = "0.8.5"
|
instant-acme = "0.8.5"
|
||||||
rcgen = "0.14.8"
|
rcgen = "0.14.8"
|
||||||
log4rs = "1.4.0"
|
log4rs = "1.4.0"
|
||||||
#mimalloc = { version = "0.1.52", default-features = false }
|
mimalloc = { version = "0.1.52", default-features = false }
|
||||||
tikv-jemallocator = "0.7.0"
|
|
||||||
tikv-jemalloc-ctl = { version = "0.7.0", features = ["stats"] }
|
|
||||||
signal-hook = "0.4.4"
|
signal-hook = "0.4.4"
|
||||||
sd-notify = "0.5.0"
|
sd-notify = "0.5.0"
|
||||||
|
|||||||
22
README.md
22
README.md
@@ -9,13 +9,23 @@
|
|||||||
Aralez is a high-performance Rust reverse proxy with zero-configuration automatic protocol handling, TLS, and upstream management,
|
Aralez is a high-performance Rust reverse proxy with zero-configuration automatic protocol handling, TLS, and upstream management,
|
||||||
featuring Consul and Kubernetes integration for dynamic pod discovery and health-checked routing, acting as a lightweight ingress-style proxy.
|
featuring Consul and Kubernetes integration for dynamic pod discovery and health-checked routing, acting as a lightweight ingress-style proxy.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
What Aralez means ?
|
What Aralez means ?
|
||||||
**Aralez = Արալեզ** <ins>Named after the legendary Armenian guardian spirit, winged dog-like creature, that descend upon fallen heroes to lick their wounds and resurrect them</ins>.
|
**Aralez = Արալեզ** <ins>Named after the legendary Armenian guardian spirit, winged dog-like creature, that descend upon fallen heroes to lick their wounds and resurrect them</ins>.
|
||||||
|
|
||||||
Built on Rust, on top of **Cloudflare’s Pingora engine**, **Aralez** delivers world-class performance, security and scalability — right out of the box.
|
Built on Rust, on top of **Cloudflare’s Pingora engine**, **Aralez** delivers world-class performance, security and scalability — right out of the box.
|
||||||
|
|
||||||
[](https://www.buymeacoffee.com/sadoyan)
|
---
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [**Documentation**](https://aralez.rs) : The manual you should read
|
||||||
|
- [**Downloads**](https://github.com/sadoyan/aralez/releases) : Binary downloads
|
||||||
|
- [**Issues**](https://github.com/sadoyan/aralez/issues) : Issues and requests
|
||||||
|
- [**Crates**](https://crates.io/crates/aralez) : The Rust crate registry
|
||||||
|
- [**DockerHUB**](https://hub.docker.com/r/sadoyan/aralez) : DockerHUB official repository
|
||||||
|
- [**GitHUB Packages**](https://github.com/sadoyan/aralez/pkgs/container/aralez) : GitHUB ghcr.io images
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -107,6 +117,9 @@ For getting the best performance on newer hardware use `aralez-x86_64-*.gz`.
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker run -d -v /path/to/config:/etc/aralez:rw -p 80:80 -p 443:443 sadoyan/aralez
|
docker run -d -v /path/to/config:/etc/aralez:rw -p 80:80 -p 443:443 sadoyan/aralez
|
||||||
|
docker run -d -v /path/to/config:/etc/aralez:rw -p 80:80 -p 443:443 sadoyan/aralez:compat
|
||||||
|
docker run -d -v /path/to/config:/etc/aralez:rw -p 80:80 -p 443:443 ghcr.io/sadoyan/aralez:latest
|
||||||
|
docker run -d -v /path/to/config:/etc/aralez:rw -p 80:80 -p 443:443 ghcr.io/sadoyan/aralez:compat
|
||||||
```
|
```
|
||||||
|
|
||||||
**Dockerfile :**
|
**Dockerfile :**
|
||||||
@@ -554,10 +567,3 @@ The results show requests per second performed by Load balancer. You can see 3 b
|
|||||||
1. Requests via http1.1 to plain text endpoint.
|
1. Requests via http1.1 to plain text endpoint.
|
||||||
2. Requests to via http2 to SSL endpoint.
|
2. Requests to via http2 to SSL endpoint.
|
||||||
3. Mixed workload with plain http1.1 and htt2 SSL.
|
3. Mixed workload with plain http1.1 and htt2 SSL.
|
||||||
|
|
||||||
## Links
|
|
||||||
|
|
||||||
- [**Documentation**](https://aralez.rs) : The manual you should read
|
|
||||||
- [**Downloads**](https://github.com/sadoyan/aralez/releases) : Binary downloads
|
|
||||||
- [**Issues**](https://github.com/sadoyan/aralez/issues) : Issues and requests
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,22 +2,22 @@
|
|||||||
threads: 12 # Number of daemon threads default setting
|
threads: 12 # Number of daemon threads default setting
|
||||||
#runuser: pastor # Username for running aralez after dropping root privileges, requires program to start as root
|
#runuser: pastor # Username for running aralez after dropping root privileges, requires program to start as root
|
||||||
#rungroup: pastor # Group for running aralez after dropping root privileges, requires program to start as root
|
#rungroup: pastor # Group for running aralez after dropping root privileges, requires program to start as root
|
||||||
daemon: false # Run in background
|
#daemon: false # Run in background
|
||||||
upstream_keepalive_pool_size: 500 # Pool size for upstream keepalive connections
|
upstream_keepalive_pool_size: 500 # Pool size for upstream keepalive connections
|
||||||
pid_file: /tmp/aralez.pid # Path to PID file
|
#pid_file: /tmp/aralez.pid # Path to PID file
|
||||||
error_log: /tmp/aralez_err.log # Path to error log
|
#error_log: /tmp/aralez_err.log # Path to error log
|
||||||
upgrade_sock: /tmp/aralez.sock # Path to socket file
|
upgrade_sock: /tmp/aralez.sock # Path to socket file
|
||||||
config_api_enabled: true # Boolean to enable/disable remote config push capability.
|
config_api_enabled: true # Boolean to enable/disable remote config push capability.
|
||||||
config_address: 0.0.0.0:3000 # HTTP API address for pushing upstreams.yaml from remote location
|
config_address: 0.0.0.0+3000 # HTTP API address for pushing upstreams.yaml from remote location
|
||||||
proxy_address_http: 0.0.0.0:6193 # Proxy HTTP bind address
|
proxy_address_http: 0.0.0.0:6193 # Proxy HTTP bind address
|
||||||
proxy_address_tls: 0.0.0.0:6194 # Optional, Proxy TLS bind address
|
proxy_address_tls: 0.0.0.0:6194 # Optional, Proxy TLS bind address
|
||||||
proxy_configs: /opt/Rust/Projects/asyncweb/etc # Mandatory if proxy_address_tls set, should contain a certificate and key files strictly in a format {NAME}.crt, {NAME}.key.
|
proxy_configs: /opt/Rust/Projects/asyncweb/etc # Mandatory if proxy_address_tls set, should contain a certificate and key files strictly in a format {NAME}.crt, {NAME}.key.
|
||||||
proxy_tls_grade: high # Grade of TLS suite for proxy (high, medium, unsafe), matching grades of Qualys SSL Labs
|
proxy_tls_grade: high # Grade of TLS suite for proxy (high, medium, unsafe), matching grades of Qualys SSL Labs
|
||||||
upstreams_conf: /opt/Rust/Projects/asyncweb/etc/upstreams.yaml # the location of upstreams file
|
upstreams_conf: /opt/Rust/Projects/asyncweb/etc/upstreams.yaml # the location of upstreams file
|
||||||
#file_server_folder: /opt/storage # Optional, local folder to serve
|
file_server_folder: /tmp/gazan # Optional, local folder to serve
|
||||||
#file_server_address: 127.0.0.1:3002 # Optional, Local address for file server. Can set as upstream for public access.
|
file_server_address: 127.0.0.1:3002 # Optional, Local address for file server. Can set as upstream for public access.
|
||||||
log_level: info # info, warn, error, debug, trace, off
|
log_level: info # info, warn, error, debug, trace, off
|
||||||
log_file: /tmp/aralez.log # Optional, the location of log file. If this entry does not exist logs will be emitted to stdout.
|
#log_file: /tmp/aralez.log # Optional, the location of log file. If this entry does not exist logs will be emitted to stdout.
|
||||||
hc_method: HEAD # Healthcheck method (HEAD, GET, POST are supported) UPPERCASE
|
hc_method: HEAD # Healthcheck method (HEAD, GET, POST are supported) UPPERCASE
|
||||||
hc_interval: 2 #Interval for health checks in seconds
|
hc_interval: 2 #Interval for health checks in seconds
|
||||||
#master_key: 910517d9-f9a1-48de-8826-dbadacbd84af-cb6f830e-ab16-47ec-9d8f-0090de732774 # Mater key for working with API server and JWT Secret
|
#master_key: 910517d9-f9a1-48de-8826-dbadacbd84af-cb6f830e-ab16-47ec-9d8f-0090de732774 # Mater key for working with API server and JWT Secret
|
||||||
|
|||||||
@@ -1,49 +1,47 @@
|
|||||||
# The file under watch and hot reload, changes are applied immediately, no need to restart or reload.
|
# The file under watch and hot reload, changes are applied immediately, no need to restart or reload.
|
||||||
provider: "file" # "file" "consul" "kubernetes"
|
provider: "file" # "file" "consul" "kubernetes"
|
||||||
sticky_sessions: 8600
|
sticky_sessions: 172000
|
||||||
to_https: false
|
to_https: false
|
||||||
rate_limit: 300
|
rate_limit: 500000
|
||||||
x4xx_limit: 200
|
x4xx_limit: 100000
|
||||||
server_headers:
|
#server_headers:
|
||||||
- "X-Forwarded-Proto:https"
|
# - "Y-Global-Something: Yes this is something"
|
||||||
- "X-Forwarded-Port:443"
|
#client_headers:
|
||||||
client_headers:
|
# - "Access-Control-Allow-Origin:*"
|
||||||
- "Access-Control-Allow-Origin:*"
|
# - "Access-Control-Allow-Methods:POST, GET, OPTIONS"
|
||||||
- "Access-Control-Allow-Methods:POST, GET, OPTIONS"
|
# - "Access-Control-Max-Age:86400"
|
||||||
- "Access-Control-Max-Age:86400"
|
# - "Strict-Transport-Security:max-age=31536000; includeSubDomains; preload"
|
||||||
#authorization:
|
#authorization:
|
||||||
# type: "jwt"
|
|
||||||
# creds: "910517d9-f9a1-48de-8826-dbadacbd84af-cb6f830e-ab16-47ec-9d8f-0090de732774"
|
|
||||||
# type: "basic"
|
# type: "basic"
|
||||||
# creds: "username:Pa$$w0rd"
|
# data: "root:toor"
|
||||||
|
# type: "jwt"
|
||||||
|
# data: "910517d9-f9a1-48de-8826-dbadacbd84af-cb6f830e-ab16-47ec-9d8f-0090de732774"
|
||||||
# type: "apikey"
|
# type: "apikey"
|
||||||
# creds: "5ecbf799-1343-4e94-a9b5-e278af5cd313-56b45249-1839-4008-a450-a60dc76d2bae"
|
# data: "5ecbf799-1343-4e94-a9b5-e278af5cd313-56b45249-1839-4008-a450-a60dc76d2bae"
|
||||||
consul:
|
consul:
|
||||||
servers:
|
servers:
|
||||||
- "http://192.168.1.199:8500"
|
- "http://consul1:8500"
|
||||||
- "http://192.168.1.200:8500"
|
|
||||||
- "http://192.168.1.201:8500"
|
|
||||||
services: # hostname: The hostname to access the proxy server, upstream : The real service name in Consul database.
|
services: # hostname: The hostname to access the proxy server, upstream : The real service name in Consul database.
|
||||||
- hostname: "webapi-service"
|
- hostname: "nconsul"
|
||||||
upstream: "webapi-service-health"
|
upstream: "nginx-consul-NginX-health"
|
||||||
path: "/one"
|
path: "/one"
|
||||||
client_headers:
|
client_headers:
|
||||||
- "X-Some-Thing:Yaaaaaaaaaaaaaaa"
|
- "X-Some-Thing:Yaaaaaaaaaaaaaaa"
|
||||||
- "X-Proxy-From:Aralez"
|
- "X-Proxy-From:Aralez"
|
||||||
rate_limit: 1
|
rate_limit: 1
|
||||||
to_https: false
|
to_https: false
|
||||||
- hostname: "webapi-service"
|
- hostname: "nconsul"
|
||||||
upstream: "webapi-service-health"
|
upstream: "nginx-consul-NginX-health"
|
||||||
path: "/"
|
path: "/"
|
||||||
token: "8e2db809-845b-45e1-8b47-2c8356a09da0-a4370955-18c2-4d6e-a8f8-ffcc0b47be81" # Consul server access token, If Consul auth is enabled
|
token: "8e2db809-845b-45e1-8b47-2c8356a09da0-a4370955-18c2-4d6e-a8f8-ffcc0b47be81" # Consul server access token, If Consul auth is enabled
|
||||||
kubernetes:
|
kubernetes:
|
||||||
servers:
|
servers:
|
||||||
- "192.168.1.55:443" #For testing only, overrides with KUBERNETES_SERVICE_HOST : KUBERNETES_SERVICE_PORT_HTTPS env variables.
|
- "172.16.0.11:5443" # Gets KUBERNETES_SERVICE_HOST : KUBERNETES_SERVICE_PORT_HTTPS env variables.
|
||||||
services:
|
services:
|
||||||
- hostname: "webapi-service"
|
- hostname: "api-service-v2"
|
||||||
|
upstream: "api-service-v2"
|
||||||
path: "/"
|
path: "/"
|
||||||
upstream: "webapi-service"
|
- hostname: "api-service-v2"
|
||||||
- hostname: "webapi-service"
|
|
||||||
upstream: "console-service"
|
upstream: "console-service"
|
||||||
path: "/one"
|
path: "/one"
|
||||||
client_headers:
|
client_headers:
|
||||||
@@ -51,71 +49,146 @@ kubernetes:
|
|||||||
- "X-Proxy-From:Aralez"
|
- "X-Proxy-From:Aralez"
|
||||||
rate_limit: 100
|
rate_limit: 100
|
||||||
to_https: false
|
to_https: false
|
||||||
- hostname: "webapi-service"
|
- hostname: "api-service-v2"
|
||||||
upstream: "rambul-service"
|
upstream: "feed-fanout-service"
|
||||||
path: "/two"
|
path: "/two"
|
||||||
- hostname: "websocket-service"
|
- hostname: "websocket-service"
|
||||||
upstream: "websocket-service"
|
upstream: "websocket-service"
|
||||||
path: "/"
|
path: "/"
|
||||||
tokenpath: "/path/to/kubetoken.txt" #If not set, will default to /var/run/secrets/kubernetes.io/serviceaccount/token
|
tokenpath: "/opt/Rust/Projects/asyncweb/etc/kubetoken.txt" # Defaults to /var/run/secrets/kubernetes.io/serviceaccount/token
|
||||||
upstreams:
|
upstreams:
|
||||||
myip.mydomain.com:
|
myip.netangels.net:
|
||||||
paths:
|
paths:
|
||||||
"/":
|
"/":
|
||||||
rate_limit: 200
|
# rate_limit: 50
|
||||||
x4xx_limit: 100
|
# x4xx_limit: 100
|
||||||
to_https: false
|
# to_https: false
|
||||||
|
# authorization:
|
||||||
|
# type: "basic"
|
||||||
|
# data: "root:toor"
|
||||||
|
server_headers:
|
||||||
|
- "Y-Proxy-Server-Some:Yaaaaaaaaaaaaaaa"
|
||||||
|
- "Y-Proxy-Server-From:Aralez"
|
||||||
|
- "Y-Proxy-Server-Vers:Aralez v0.89"
|
||||||
client_headers:
|
client_headers:
|
||||||
- "X-Proxy-From:Aralez"
|
- "X-Proxy-From:Aralezzzzzzzzzzz"
|
||||||
|
- "X-Hopar-From:Hopaaaaaaaaaaaar"
|
||||||
|
- "X-Proxy-Some:X-Proxy-Somebody"
|
||||||
servers:
|
servers:
|
||||||
- "127.0.0.1:8000"
|
- "127.0.0.1:8000"
|
||||||
- "127.0.0.2:8000"
|
- "127.0.0.2:8000"
|
||||||
- "127.0.0.3:8000"
|
- "127.0.0.3:8000"
|
||||||
- "127.0.0.4:8000"
|
- "127.0.0.4:8000"
|
||||||
- "127.0.0.5:8000"
|
- "127.0.0.5:8000"
|
||||||
|
- "192.168.1.1:8000"
|
||||||
"/ping":
|
"/ping":
|
||||||
authorization: # Will be ignored if global authentication is enabled.
|
|
||||||
type: "basic"
|
|
||||||
creds: "admin:admin"
|
|
||||||
to_https: false
|
to_https: false
|
||||||
server_headers:
|
|
||||||
- "X-Forwarded-Proto:https"
|
|
||||||
- "X-Forwarded-Port:443"
|
|
||||||
client_headers:
|
client_headers:
|
||||||
- "X-Some-Thing:Yaaaaaaaaaaaaaaa"
|
- "X-Some-Thing:Yaaaaaaaaaaaaaaa"
|
||||||
- "X-Proxy-From:Aralez"
|
- "X-Proxy-From:Aralez"
|
||||||
servers:
|
servers:
|
||||||
- "127.0.0.1:8000"
|
- "127.0.0.1:8000"
|
||||||
- "127.0.0.2:8000"
|
- "127.0.0.2:8000"
|
||||||
"/draw":
|
"/pong":
|
||||||
servers:
|
|
||||||
- "192.168.1.1:8000"
|
|
||||||
polo.mydomain.com:
|
|
||||||
paths:
|
|
||||||
"/":
|
|
||||||
to_https: false
|
to_https: false
|
||||||
client_headers:
|
client_headers:
|
||||||
- "X-Some-Thing:Yaaaaaaaaaaaaaaa"
|
- "X-Some-Thing:Yaaaaaaaaaaaaaaa"
|
||||||
|
- "X-Proxy-From:Aralez"
|
||||||
servers:
|
servers:
|
||||||
- "192.168.1.1:8000"
|
|
||||||
- "192.168.1.10:8000"
|
|
||||||
- "127.0.0.1:8000"
|
- "127.0.0.1:8000"
|
||||||
- "127.0.0.2:8000"
|
"/secret":
|
||||||
- "127.0.0.3:8000"
|
authorization:
|
||||||
- "127.0.0.4:8000"
|
type: "forward"
|
||||||
apt.mydomain.com:
|
data: "http://192.168.1.1:8899/admin/login"
|
||||||
|
#data: "https://netangels.net/admin/login"
|
||||||
|
servers:
|
||||||
|
- "192.168.1.10:8000"
|
||||||
|
netangels.net:
|
||||||
paths:
|
paths:
|
||||||
"/":
|
"/":
|
||||||
|
redirect_to: "https://www.netangels.net:6194"
|
||||||
servers:
|
servers:
|
||||||
- "192.168.1.10:443"
|
- "192.168.1.1:80"
|
||||||
|
www.netangels.net:
|
||||||
|
paths:
|
||||||
|
"/":
|
||||||
|
to_https: true
|
||||||
|
servers:
|
||||||
|
- "192.168.1.1:80"
|
||||||
|
apt.netangels.net:
|
||||||
|
paths:
|
||||||
|
"/":
|
||||||
|
server_headers:
|
||||||
|
- "Y-Global-Something: Yes this is something"
|
||||||
|
client_headers:
|
||||||
|
- "Access-Control-Allow-Methods:POST, GET, OPTIONS"
|
||||||
|
rate_limit: 60
|
||||||
|
x4xx_limit: 30
|
||||||
|
#authorization:
|
||||||
|
# type: "jwt"
|
||||||
|
# data: "SOMETHING"
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:8000"
|
||||||
|
- "127.0.0.2:8000"
|
||||||
"/.well-known/acme-challenge":
|
"/.well-known/acme-challenge":
|
||||||
healthcheck: false
|
healthcheck: false
|
||||||
servers:
|
servers:
|
||||||
- "127.0.0.1:8001"
|
- "127.0.0.1:8001"
|
||||||
rdr.mydomain.com:
|
"/400":
|
||||||
paths:
|
rate_limit: 4
|
||||||
"/":
|
x4xx_limit: 2
|
||||||
redirect_to: "https://som.other.domain:6194"
|
servers:
|
||||||
|
- "192.168.1.1:8899"
|
||||||
|
"/500":
|
||||||
healthcheck: false
|
healthcheck: false
|
||||||
servers:
|
servers:
|
||||||
- "127.0.0.1:8080"
|
- "192.168.1.1:8899"
|
||||||
|
# grafanalocal:
|
||||||
|
# paths:
|
||||||
|
# "/":
|
||||||
|
# healthcheck: false
|
||||||
|
# servers:
|
||||||
|
# - "95.211.203.222:443"
|
||||||
|
# "/.well-known/acme-challenge":
|
||||||
|
# healthcheck: false
|
||||||
|
# servers:
|
||||||
|
# - "127.0.0.1:8001"
|
||||||
|
localpost:
|
||||||
|
paths:
|
||||||
|
"/":
|
||||||
|
to_https: true
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:9000"
|
||||||
|
# 192.168.177.2:
|
||||||
|
# paths:
|
||||||
|
# "/":
|
||||||
|
# servers:
|
||||||
|
# - "127.0.0.1:8000"
|
||||||
|
ara.matyan.org:
|
||||||
|
paths:
|
||||||
|
"/":
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:8000"
|
||||||
|
"/.well-known/acme-challenge":
|
||||||
|
healthcheck: false
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:3000"
|
||||||
|
aro.matyan.org:
|
||||||
|
paths:
|
||||||
|
"/":
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:8000"
|
||||||
|
"/.well-known/acme-challenge":
|
||||||
|
healthcheck: false
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:3000"
|
||||||
|
DEFAUwLT:
|
||||||
|
paths:
|
||||||
|
"/":
|
||||||
|
healthcheck: false
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:3000"
|
||||||
|
"/.well-known/acme-challenge":
|
||||||
|
healthcheck: false
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:3000"
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@@ -1,14 +1,16 @@
|
|||||||
use tikv_jemallocator::Jemalloc;
|
|
||||||
|
|
||||||
mod tls;
|
mod tls;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod web;
|
mod web;
|
||||||
|
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: Jemalloc = Jemalloc;
|
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||||
// static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
|
||||||
// pub static A: CountingAllocator = CountingAllocator;
|
// pub static A: CountingAllocator = CountingAllocator;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
if std::env::args().any(|a| a == "--version" || a == "-v") {
|
||||||
|
println!("aralez {}", env!("CARGO_PKG_VERSION"));
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
web::start::run();
|
web::start::run();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ use prometheus::{register_histogram, register_int_counter, register_int_counter_
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tikv_jemalloc_ctl::{epoch, stats};
|
|
||||||
|
|
||||||
pub struct MetricTypes {
|
pub struct MetricTypes {
|
||||||
pub method: Method,
|
pub method: Method,
|
||||||
@@ -66,9 +65,17 @@ pub fn calc_metrics(metric_types: &MetricTypes) {
|
|||||||
RESPONSE_LATENCY.observe(metric_types.latency.as_secs_f64());
|
RESPONSE_LATENCY.observe(metric_types.latency.as_secs_f64());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_memory_usage() -> usize {
|
pub(crate) fn get_memory_usage() -> usize {
|
||||||
epoch::mib().unwrap().advance().unwrap(); // refresh stats
|
std::fs::read_to_string("/proc/self/status")
|
||||||
stats::allocated::mib().unwrap().read().unwrap() // bytes allocated
|
.ok()
|
||||||
|
.and_then(|s| {
|
||||||
|
s.lines()
|
||||||
|
.find(|l| l.starts_with("VmRSS:"))
|
||||||
|
.and_then(|l| l.split_whitespace().nth(1))
|
||||||
|
.and_then(|v| v.parse::<usize>().ok())
|
||||||
|
})
|
||||||
|
.unwrap_or(0)
|
||||||
|
* 1024
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_open_files() -> usize {
|
pub fn get_open_files() -> usize {
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ pub struct AppConfig {
|
|||||||
pub hc_method: String,
|
pub hc_method: String,
|
||||||
pub upstreams_conf: String,
|
pub upstreams_conf: String,
|
||||||
pub log_level: String,
|
pub log_level: String,
|
||||||
|
pub pid_file: Option<String>,
|
||||||
pub master_key: Option<String>,
|
pub master_key: Option<String>,
|
||||||
pub config_address: String,
|
pub config_address: String,
|
||||||
pub proxy_address_http: String,
|
pub proxy_address_http: String,
|
||||||
@@ -130,6 +131,9 @@ pub struct AppConfig {
|
|||||||
pub runuser: Option<String>,
|
pub runuser: Option<String>,
|
||||||
pub rungroup: Option<String>,
|
pub rungroup: Option<String>,
|
||||||
pub log_file: Option<String>,
|
pub log_file: Option<String>,
|
||||||
|
pub tcp_keepalive_idle: Option<u64>,
|
||||||
|
pub tcp_keepalive_interval: Option<u64>,
|
||||||
|
pub tcp_keepalive_count: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ pub fn drop_priv(user: String, group: String, http_addr: String, tls_addr: Optio
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_priv(addr: &str) {
|
pub fn check_priv(addr: &str) {
|
||||||
let port = SocketAddr::from_str(addr).map(|sa| sa.port()).unwrap();
|
let port = SocketAddr::from_str(addr).map(|sa| sa.port()).expect("Failed to parse address port ");
|
||||||
if port < 1024 {
|
if port < 1024 {
|
||||||
let meta = std::fs::metadata("/proc/self").map(|m| m.uid()).unwrap();
|
let meta = std::fs::metadata("/proc/self").map(|m| m.uid()).unwrap();
|
||||||
if meta != 0 {
|
if meta != 0 {
|
||||||
|
|||||||
@@ -177,6 +177,20 @@ impl ProxyHttp for LB {
|
|||||||
peer.options.verify_cert = false;
|
peer.options.verify_cert = false;
|
||||||
peer.options.verify_hostname = false;
|
peer.options.verify_hostname = false;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
Experimental optionsv
|
||||||
|
The following TCP optimizations were tested but caused performance degrade under heavy load:
|
||||||
|
peer.options.tcp_keepalive = Some(TcpKeepalive {
|
||||||
|
idle: Duration::from_secs(60),
|
||||||
|
interval: Duration::from_secs(10),
|
||||||
|
count: 5,
|
||||||
|
user_timeout: Duration::from_secs(30),
|
||||||
|
});
|
||||||
|
|
||||||
|
peer.options.idle_timeout = Some(Duration::from_secs(300));
|
||||||
|
peer.options.tcp_recv_buf = Some(128 * 1024);
|
||||||
|
End of experimental options
|
||||||
|
*/
|
||||||
if let Some(_) = ctx.extraparams.sticky_sessions {
|
if let Some(_) = ctx.extraparams.sticky_sessions {
|
||||||
let mut s = String::with_capacity(64);
|
let mut s = String::with_capacity(64);
|
||||||
write!(
|
write!(
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ use dashmap::DashMap;
|
|||||||
use log::info;
|
use log::info;
|
||||||
use pingora::tls::ssl::{SslAlert, SslRef};
|
use pingora::tls::ssl::{SslAlert, SslRef};
|
||||||
use pingora_core::listeners::tls::TlsSettings;
|
use pingora_core::listeners::tls::TlsSettings;
|
||||||
|
use pingora_core::listeners::TcpSocketOptions;
|
||||||
use pingora_core::prelude::{background_service, Opt};
|
use pingora_core::prelude::{background_service, Opt};
|
||||||
|
use pingora_core::protocols::TcpKeepalive;
|
||||||
use pingora_core::server::Server;
|
use pingora_core::server::Server;
|
||||||
use privdrop::reexports::libc::SIGQUIT;
|
use privdrop::reexports::libc::SIGQUIT;
|
||||||
use sd_notify::NotifyState;
|
use sd_notify::NotifyState;
|
||||||
@@ -62,12 +64,34 @@ pub fn run() {
|
|||||||
info!("TLS grade set to: [ {} ]", grade);
|
info!("TLS grade set to: [ {} ]", grade);
|
||||||
|
|
||||||
let bg_srvc = background_service("bgsrvc", lb.clone());
|
let bg_srvc = background_service("bgsrvc", lb.clone());
|
||||||
let mut proxy = pingora_proxy::http_proxy_service(&server.configuration, lb.clone());
|
|
||||||
let bind_address_http = cfg.proxy_address_http.clone();
|
let bind_address_http = cfg.proxy_address_http.clone();
|
||||||
let bind_address_tls = cfg.proxy_address_tls.clone();
|
let bind_address_tls = cfg.proxy_address_tls.clone();
|
||||||
|
|
||||||
|
let mut proxy = pingora_proxy::http_proxy_service(&server.configuration, lb.clone());
|
||||||
|
|
||||||
check_priv(bind_address_http.as_str());
|
check_priv(bind_address_http.as_str());
|
||||||
|
|
||||||
|
// let mut tcp_options: Option<TcpSocketOptions> = Some(TcpSocketOptions::default());
|
||||||
|
// let mut tcp_options = TcpSocketOptions::default();
|
||||||
|
|
||||||
|
let mut tcp_options: Option<TcpSocketOptions> = None;
|
||||||
|
if let Some(idle) = cfg.tcp_keepalive_idle {
|
||||||
|
let mut to = TcpSocketOptions::default();
|
||||||
|
to.tcp_keepalive = Some(TcpKeepalive {
|
||||||
|
idle: Duration::from_secs(idle),
|
||||||
|
interval: Duration::from_secs(cfg.tcp_keepalive_interval.unwrap_or(10)),
|
||||||
|
user_timeout: Default::default(),
|
||||||
|
count: cfg.tcp_keepalive_count.unwrap_or(5usize),
|
||||||
|
});
|
||||||
|
tcp_options = Some(to);
|
||||||
|
info!(
|
||||||
|
"Applying kernel tcp_keepalive parameters: idle {}, interval {}, count {}",
|
||||||
|
idle,
|
||||||
|
cfg.tcp_keepalive_interval.unwrap_or(60),
|
||||||
|
cfg.tcp_keepalive_count.unwrap_or(5),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(bind_address_tls) = bind_address_tls {
|
if let Some(bind_address_tls) = bind_address_tls {
|
||||||
check_priv(bind_address_tls.as_str());
|
check_priv(bind_address_tls.as_str());
|
||||||
let (tx, rx): (Sender<Vec<CertificateConfig>>, Receiver<Vec<CertificateConfig>>) = channel();
|
let (tx, rx): (Sender<Vec<CertificateConfig>>, Receiver<Vec<CertificateConfig>>) = channel();
|
||||||
@@ -95,7 +119,7 @@ pub fn run() {
|
|||||||
tls_settings.set_servername_callback(move |ssl_ref: &mut SslRef, ssl_alert: &mut SslAlert| certs_for_callback.load().server_name_callback(ssl_ref, ssl_alert));
|
tls_settings.set_servername_callback(move |ssl_ref: &mut SslRef, ssl_alert: &mut SslAlert| certs_for_callback.load().server_name_callback(ssl_ref, ssl_alert));
|
||||||
tls_settings.set_alpn_select_callback(grades::prefer_h2);
|
tls_settings.set_alpn_select_callback(grades::prefer_h2);
|
||||||
|
|
||||||
proxy.add_tls_with_settings(&bind_address_tls, None, tls_settings);
|
proxy.add_tls_with_settings(&bind_address_tls, tcp_options.clone(), tls_settings);
|
||||||
|
|
||||||
let certs_for_watcher = certificates.clone();
|
let certs_for_watcher = certificates.clone();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
@@ -107,8 +131,13 @@ pub fn run() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
info!("Running HTTP listener on :{}", bind_address_http.as_str());
|
info!("Running HTTP listener on :{}", bind_address_http);
|
||||||
proxy.add_tcp(bind_address_http.as_str());
|
if let Some(tc) = tcp_options {
|
||||||
|
proxy.add_tcp_with_settings(&bind_address_http, tc);
|
||||||
|
} else {
|
||||||
|
proxy.add_tcp(&bind_address_http)
|
||||||
|
}
|
||||||
|
|
||||||
server.add_service(proxy);
|
server.add_service(proxy);
|
||||||
server.add_service(bg_srvc);
|
server.add_service(bg_srvc);
|
||||||
thread::spawn(move || server.run_forever());
|
thread::spawn(move || server.run_forever());
|
||||||
@@ -117,7 +146,7 @@ pub fn run() {
|
|||||||
drop_priv(user, group, cfg.proxy_address_http.clone(), cfg.proxy_address_tls.clone());
|
drop_priv(user, group, cfg.proxy_address_http.clone(), cfg.proxy_address_tls.clone());
|
||||||
}
|
}
|
||||||
let _ = sd_notify::notify(&[NotifyState::Ready]);
|
let _ = sd_notify::notify(&[NotifyState::Ready]);
|
||||||
let _ = fs::write("/tmp/aralez.pid", process::id().to_string());
|
let _ = fs::write(cfg.pid_file.clone().unwrap_or("/tmp/aralez.pid".to_string()), process::id().to_string());
|
||||||
|
|
||||||
let mut signals = Signals::new(&[SIGINT, SIGTERM, SIGQUIT]).unwrap();
|
let mut signals = Signals::new(&[SIGINT, SIGTERM, SIGQUIT]).unwrap();
|
||||||
for sig in signals.forever() {
|
for sig in signals.forever() {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ use prometheus::{gather, Encoder, TextEncoder};
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use signal_hook::{consts::SIGQUIT, iterator::Signals};
|
use signal_hook::{consts::SIGQUIT, iterator::Signals};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::net::SocketAddr;
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
@@ -67,16 +69,14 @@ pub async fn run_server(config: &APIUpstreamProvider, mut to_return: Sender<Conf
|
|||||||
|
|
||||||
let mut static_handle: Option<tokio::task::JoinHandle<()>> = None;
|
let mut static_handle: Option<tokio::task::JoinHandle<()>> = None;
|
||||||
if let (Some(address), Some(folder)) = (&config.file_server_address, &config.file_server_folder) {
|
if let (Some(address), Some(folder)) = (&config.file_server_address, &config.file_server_folder) {
|
||||||
port_is_available("File Server", &address).await;
|
let static_listen = port_is_available("File Server", &address).await;
|
||||||
let static_files = ServeDir::new(folder);
|
let static_files = ServeDir::new(folder);
|
||||||
let static_serve: Router = Router::new().fallback_service(static_files);
|
let static_serve: Router = Router::new().fallback_service(static_files);
|
||||||
let static_listen = TcpListener::bind(address).await.unwrap();
|
|
||||||
// drop(tokio::spawn(async move { axum::serve(static_listen, static_serve).await.unwrap() }));
|
// drop(tokio::spawn(async move { axum::serve(static_listen, static_serve).await.unwrap() }));
|
||||||
static_handle = Some(tokio::spawn(async move { axum::serve(static_listen, static_serve).await.unwrap() }))
|
static_handle = Some(tokio::spawn(async move { axum::serve(static_listen, static_serve).await.unwrap() }))
|
||||||
}
|
}
|
||||||
|
|
||||||
port_is_available("Config API", &config.address).await;
|
let listener = port_is_available("Config API", &config.address).await;
|
||||||
let listener = TcpListener::bind(config.address.clone()).await.unwrap();
|
|
||||||
info!("Starting the API server on: {}", config.address);
|
info!("Starting the API server on: {}", config.address);
|
||||||
let api_server = tokio::spawn(async move { axum::serve(listener, app).await.unwrap() });
|
let api_server = tokio::spawn(async move { axum::serve(listener, app).await.unwrap() });
|
||||||
|
|
||||||
@@ -227,20 +227,19 @@ async fn status(State(st): State<AppState>, Query(params): Query<HashMap<String,
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn port_is_available(name: &str, address: &str) {
|
pub async fn port_is_available(name: &str, address: &str) -> TcpListener {
|
||||||
let addr_port = address.split(":").collect::<Vec<&str>>();
|
let addr = SocketAddr::from_str(address)
|
||||||
|
.unwrap_or_else(|e| panic!("{}: Invalid address format: {:?}", name, e));
|
||||||
let t = Duration::from_secs(2);
|
let t = Duration::from_secs(2);
|
||||||
|
|
||||||
let mut a = addr_port[0];
|
//if addr.ip() == IpAddr::V4(Ipv4Addr::UNSPECIFIED) {
|
||||||
if address == "0.0.0.0" {
|
// addr.set_ip(IpAddr::V4(Ipv4Addr::LOCALHOST));
|
||||||
a = "127.0.0.1";
|
//}
|
||||||
}
|
let p = addr.port();
|
||||||
let p = addr_port[1].parse::<u16>().unwrap();
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match TcpListener::bind((a, p)).await {
|
match TcpListener::bind(addr).await {
|
||||||
Ok(_) => {
|
Ok(listener) => {
|
||||||
break;
|
return listener;
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
warn!("{} port is not available: {} will try again in {:?}", name, p, t);
|
warn!("{} port is not available: {} will try again in {:?}", name, p, t);
|
||||||
|
|||||||
Reference in New Issue
Block a user