mirror of
https://github.com/sadoyan/aralez.git
synced 2026-06-22 23:32:40 +08:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5815da6576 | ||
|
|
1ab0916026 | ||
|
|
707f725b88 | ||
|
|
eb4e73ece0 | ||
|
|
53e7dcfd33 | ||
|
|
f3b346a28d | ||
|
|
c011800e1e | ||
|
|
265ff6b774 | ||
|
|
1c3d9a263f | ||
|
|
162c5060c9 | ||
|
|
132cf45dfe | ||
|
|
77dcafbb4e | ||
|
|
649bd979f7 | ||
|
|
bd315106b9 | ||
|
|
3ba2ed33ae | ||
|
|
c09efab9fd | ||
|
|
735d605f6d | ||
|
|
6773d0f502 | ||
|
|
a8cb727da5 | ||
|
|
f81194aee7 | ||
|
|
0f09a2e02b |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -5,13 +5,13 @@
|
|||||||
*.dll
|
*.dll
|
||||||
*.exe
|
*.exe
|
||||||
*.sh
|
*.sh
|
||||||
/docs/
|
*.yaml
|
||||||
/docs
|
/docs
|
||||||
/etc
|
assets/
|
||||||
|
assets
|
||||||
/target/
|
/target/
|
||||||
*.iml
|
*.iml
|
||||||
.idea/
|
.idea/
|
||||||
.etc/
|
|
||||||
*.ipr
|
*.ipr
|
||||||
*.iws
|
*.iws
|
||||||
/out/
|
/out/
|
||||||
@@ -22,4 +22,5 @@ crashlytics.properties
|
|||||||
crashlytics-build.properties
|
crashlytics-build.properties
|
||||||
/target
|
/target
|
||||||
/z_shpo
|
/z_shpo
|
||||||
|
/configs
|
||||||
Makefile
|
Makefile
|
||||||
|
|||||||
164
Cargo.lock
generated
164
Cargo.lock
generated
@@ -127,7 +127,7 @@ checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aralez"
|
name = "aralez"
|
||||||
version = "0.9.2"
|
version = "0.92.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
@@ -139,11 +139,13 @@ dependencies = [
|
|||||||
"futures",
|
"futures",
|
||||||
"instant-acme",
|
"instant-acme",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"log4rs",
|
"log4rs",
|
||||||
"mimalloc",
|
"mimalloc",
|
||||||
"moka",
|
"moka",
|
||||||
"notify",
|
"notify",
|
||||||
|
"noyalib",
|
||||||
"pingora",
|
"pingora",
|
||||||
"pingora-core",
|
"pingora-core",
|
||||||
"pingora-http",
|
"pingora-http",
|
||||||
@@ -158,13 +160,12 @@ dependencies = [
|
|||||||
"sd-notify",
|
"sd-notify",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yml",
|
|
||||||
"sha2 0.11.0",
|
"sha2 0.11.0",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"subtle",
|
"subtle",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tonic",
|
"tonic",
|
||||||
"tower-http",
|
"tower-http 0.7.0",
|
||||||
"urlencoding",
|
"urlencoding",
|
||||||
"x509-parser",
|
"x509-parser",
|
||||||
]
|
]
|
||||||
@@ -472,27 +473,27 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cf-rustracing"
|
name = "cf-rustracing"
|
||||||
version = "1.3.0"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6565523d8145e63e0cf1b397a5f1bd4e90d5652a7dffb2de8cec460ff23ef6b1"
|
checksum = "93f85c3824e4191621dec0551e3cef3d511f329da9a8990bf3e450a85651d97e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"rand 0.10.1",
|
"rand 0.8.6",
|
||||||
"tokio",
|
"tokio",
|
||||||
"trackable",
|
"trackable",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cf-rustracing-jaeger"
|
name = "cf-rustracing-jaeger"
|
||||||
version = "1.3.0"
|
version = "1.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16c0e4d8cce27f6a6eaff58d2b66f063a18b8ed0d6ef0947ae7a263afa3b7c08"
|
checksum = "a6a5f80d44c257c3300a7f45ada676c211e64bbbac591bbec19344a8f61fbcab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cf-rustracing",
|
"cf-rustracing",
|
||||||
"hostname",
|
"hostname",
|
||||||
"local-ip-address",
|
"local-ip-address",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"rand 0.10.1",
|
"rand 0.9.4",
|
||||||
"thrift_codec",
|
"thrift_codec",
|
||||||
"tokio",
|
"tokio",
|
||||||
"trackable",
|
"trackable",
|
||||||
@@ -1712,9 +1713,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inotify"
|
name = "inotify"
|
||||||
version = "0.11.1"
|
version = "0.11.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bd5b3eaf1a28b758ac0faa5a4254e8ab2705605496f1b1f3fbbc3988ad73d199"
|
checksum = "533e68a5842e734946fe159fb03fc9bbbb254f590dd0d8ad321ae5ff7beca2c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.11.1",
|
"bitflags 2.11.1",
|
||||||
"inotify-sys",
|
"inotify-sys",
|
||||||
@@ -1871,9 +1872,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kqueue"
|
name = "kqueue"
|
||||||
version = "1.1.1"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a"
|
checksum = "273c0752728918e0ac4976f2b275b6fefb9ecd400585dec929419f3844cd87b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kqueue-sys",
|
"kqueue-sys",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -1881,9 +1882,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kqueue-sys"
|
name = "kqueue-sys"
|
||||||
version = "1.1.0"
|
version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7b65860415f949f23fa882e669f2dbd4a0f0eeb1acdd56790b30494afd7da2f"
|
checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.11.1",
|
"bitflags 2.11.1",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -1925,16 +1926,6 @@ dependencies = [
|
|||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libyml"
|
|
||||||
version = "0.0.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libz-ng-sys"
|
name = "libz-ng-sys"
|
||||||
version = "1.1.28"
|
version = "1.1.28"
|
||||||
@@ -2219,6 +2210,22 @@ dependencies = [
|
|||||||
"bitflags 2.11.1",
|
"bitflags 2.11.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "noyalib"
|
||||||
|
version = "0.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14057395c16a4230575c6f86bfa074db87e8458626d3e56b20c2454334a7e50c"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap 2.14.0",
|
||||||
|
"itoa",
|
||||||
|
"memchr",
|
||||||
|
"rustc-hash",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"serde_ignored",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint"
|
name = "num-bigint"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@@ -2508,9 +2515,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora"
|
name = "pingora"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "844a13b16e556293f4ea96dc5ac0923ac6f36855a9dfc13b640d0da183f6b5b7"
|
checksum = "54a75f2ff8e122aa80ab202dc865294fe59cd856c2a5dab2d3df6e122c93b941"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pingora-cache",
|
"pingora-cache",
|
||||||
"pingora-core",
|
"pingora-core",
|
||||||
@@ -2522,9 +2529,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-cache"
|
name = "pingora-cache"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c59d8c4c939a3a193a3da0e061aa7acf7432431f92ee62a26f5a9e5167a0ade2"
|
checksum = "527735ac204efb9fa3884bfd9224d016c5735fabe1d394ebed145b40e7545b99"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -2559,9 +2566,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-core"
|
name = "pingora-core"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08973c4853cef4c682f7a592907e81a32dcad69476c4846e5de079f16448b177"
|
checksum = "6a7ffe2f5acf9f94fd255cfd1438866bc9124f8f0c7d42562bd3f853df2094b7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -2611,15 +2618,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-error"
|
name = "pingora-error"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9fa97a500e7e5c27a7b8609b9294c8922c9656322285268bfad9520f12feb38"
|
checksum = "b23f7bc013de67e44ed902a82843f6157460b89d11da882bcc6f09f8ae380af1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-header-serde"
|
name = "pingora-header-serde"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2705feb8b50d4e734e0c7d3879aa040e655a45656276323ff530e254585dd816"
|
checksum = "828c0e53e74160cbfe8e67dd3a811eb6a253c36acbaf7a39a01d9aacfb9ac139"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -2633,9 +2640,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-http"
|
name = "pingora-http"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fbb52d4651b687fab6abf669539cfd97b7cd94b301fde8f57c63354f9c9cc5e2"
|
checksum = "d553d310a15ec88107b9388a02885f798efc57764d8e9bdaaf32a76722927a10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http",
|
"http",
|
||||||
@@ -2644,27 +2651,27 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-ketama"
|
name = "pingora-ketama"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0286fb5a0359dca1e2e137dfe14ca4d94f676635a5eae4616bb3d8d4ce06d120"
|
checksum = "3e2a2e43a14f1d291fba7905542c7c1d1f89528f470b3cd48b6806e702ea772f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-limits"
|
name = "pingora-limits"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7568624fc0e2f11fa32d27053ac862048b40bad98140b07a11d82f1b4989700"
|
checksum = "4bafc633ceb95dc8b39a0d1b52d105758ae0913d360ef3a3365a6f6494d0fe17"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-load-balancing"
|
name = "pingora-load-balancing"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2606e9e22e72927a69772cefe56b0d41d251c3ffdfcd548a6020fe157fb79ad"
|
checksum = "361b69af0234d2e4d10234e2efd106bb3b8147c575d52f45604a46aaf26def7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -2684,9 +2691,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-lru"
|
name = "pingora-lru"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "91bb5030596a3d442c0866ac68afe29c14ba558e77c726dcdf7016b0dbb359d9"
|
checksum = "6705a26ad89d241a989a5395641931ba37076f5ab5fbd19ee92402414a43af32"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"hashbrown 0.17.0",
|
"hashbrown 0.17.0",
|
||||||
@@ -2696,9 +2703,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-openssl"
|
name = "pingora-openssl"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1cb7f135948a5c5a28a634e40fabd40c2588c757372f8a358bfca634a56514a6"
|
checksum = "5f288cacd77196168db0f6ae80817bc4844a8dd1448b75bb2da935eb6d9c3118"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"foreign-types",
|
"foreign-types",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -2709,9 +2716,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-pool"
|
name = "pingora-pool"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "67f034be36772f318370d058913db43dbd22c3763ad974c995ba2e4afb2bb52a"
|
checksum = "feb1237893b15a9cf6b371bee8d7e2e1c10742e4be6eb00ed38cfe87fd1363f8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"log",
|
"log",
|
||||||
@@ -2724,9 +2731,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-proxy"
|
name = "pingora-proxy"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4e1e070a98a70d0d05f2fdcfb706237e06a043b2fbc9261e8772a3459cc2175e"
|
checksum = "8a92ee756ecf6ecb6419864da651cad6cecd933b6d420a26877031efa16bef57"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -2747,9 +2754,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-runtime"
|
name = "pingora-runtime"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e371315b1c44c2e5a8788fdc61577527b785e121e6ff49144755f40d86511430"
|
checksum = "41815a13691a3e7d9ad0e34767d4140284132e31b95a4481f5e73ab6f407f834"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rand 0.8.6",
|
"rand 0.8.6",
|
||||||
@@ -2759,9 +2766,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pingora-timeout"
|
name = "pingora-timeout"
|
||||||
version = "0.8.0"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a853fee5ce510a7f5db2561f99c752724112ed13fc3820e70d462d278d704ea"
|
checksum = "8e3e321452eaa461e0b6c5aaa35b7e42527ee89df33710279f37fae7f066b68e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
@@ -3184,7 +3191,7 @@ dependencies = [
|
|||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-http",
|
"tower-http 0.6.11",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"url",
|
"url",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
@@ -3508,6 +3515,16 @@ dependencies = [
|
|||||||
"syn 2.0.117",
|
"syn 2.0.117",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_ignored"
|
||||||
|
version = "0.1.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "115dffd5f3853e06e746965a20dcbae6ee747ae30b543d91b0e089668bb07798"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.150"
|
version = "1.0.150"
|
||||||
@@ -3557,21 +3574,6 @@ dependencies = [
|
|||||||
"unsafe-libyaml",
|
"unsafe-libyaml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "serde_yml"
|
|
||||||
version = "0.0.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd"
|
|
||||||
dependencies = [
|
|
||||||
"indexmap 2.14.0",
|
|
||||||
"itoa",
|
|
||||||
"libyml",
|
|
||||||
"memchr",
|
|
||||||
"ryu",
|
|
||||||
"serde",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sfv"
|
name = "sfv"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
@@ -4084,6 +4086,24 @@ name = "tower-http"
|
|||||||
version = "0.6.11"
|
version = "0.6.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
|
checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.11.1",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tower",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-http"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b11f75e912b0c2be01b63d8cf8057b8c3f97cf34abb3d431a3a4c8675498e233"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.11.1",
|
"bitflags 2.11.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
@@ -4100,10 +4120,8 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower",
|
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"url",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
23
Cargo.toml
23
Cargo.toml
@@ -1,7 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "aralez"
|
name = "aralez"
|
||||||
version = "0.9.2"
|
version = "0.92.11"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
description = "Reverse proxy built on top of Cloudflare's Pingora"
|
||||||
|
exclude = ["configs/*"]
|
||||||
|
repository = "https://github.com/sadoyan/aralez"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
@@ -12,20 +16,20 @@ strip = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio = { version = "1.52.3", features = ["full"] }
|
tokio = { version = "1.52.3", features = ["full"] }
|
||||||
pingora = { version = "0.8.0", features = ["lb", "openssl"] } # openssl, rustls, boringssl
|
pingora = { version = "0.8.1", features = ["lb", "openssl"] } # openssl, rustls, boringssl
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
pingora-core = "0.8.1"
|
||||||
|
pingora-proxy = "0.8.1"
|
||||||
|
pingora-http = "0.8.1"
|
||||||
|
pingora-limits = "0.8.1"
|
||||||
dashmap = "7.0.0-rc2"
|
dashmap = "7.0.0-rc2"
|
||||||
pingora-core = "0.8.0"
|
|
||||||
pingora-proxy = "0.8.0"
|
|
||||||
pingora-http = "0.8.0"
|
|
||||||
pingora-limits = "0.8.0"
|
|
||||||
async-trait = "0.1.89"
|
async-trait = "0.1.89"
|
||||||
log = "0.4.30"
|
log = "0.4.30"
|
||||||
futures = "0.3.32"
|
futures = "0.3.32"
|
||||||
notify = "9.0.0-rc.4"
|
notify = "9.0.0-rc.4"
|
||||||
axum = { version = "0.8.9" }
|
axum = { version = "0.8.9" }
|
||||||
reqwest = { version = "0.13.4", features = ["json", "stream", "blocking"] }
|
reqwest = { version = "0.13.4", features = ["json", "stream", "blocking"] }
|
||||||
serde_yml = "0.0.12"
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
|
noyalib = { version = "0.0.8", features = ["compat-serde-yaml"] }
|
||||||
rand = "0.10.1"
|
rand = "0.10.1"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
jsonwebtoken = { version = "10.4.0", default-features = false, features = ["use_pem", "rust_crypto"] }
|
jsonwebtoken = { version = "10.4.0", default-features = false, features = ["use_pem", "rust_crypto"] }
|
||||||
@@ -37,7 +41,7 @@ arc-swap = "1.9.1"
|
|||||||
prometheus = "0.14.0"
|
prometheus = "0.14.0"
|
||||||
x509-parser = "0.18.1"
|
x509-parser = "0.18.1"
|
||||||
rustls-pemfile = "2.2.0"
|
rustls-pemfile = "2.2.0"
|
||||||
tower-http = { version = "0.6.11", features = ["fs"] }
|
tower-http = { version = "0.7.0", features = ["fs"] }
|
||||||
privdrop = "0.5.6"
|
privdrop = "0.5.6"
|
||||||
serde_json = "1.0.150"
|
serde_json = "1.0.150"
|
||||||
subtle = "2.6.1"
|
subtle = "2.6.1"
|
||||||
@@ -49,3 +53,4 @@ log4rs = "1.4.0"
|
|||||||
mimalloc = { version = "0.1.52", default-features = false }
|
mimalloc = { version = "0.1.52", default-features = false }
|
||||||
signal-hook = "0.4.4"
|
signal-hook = "0.4.4"
|
||||||
sd-notify = "0.5.0"
|
sd-notify = "0.5.0"
|
||||||
|
libc = "0.2.186"
|
||||||
|
|||||||
23
README.md
23
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
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -64,6 +74,7 @@ Built on Rust, on top of **Cloudflare’s Pingora engine**, **Aralez** delivers
|
|||||||
| **proxy_address_tls** | 0.0.0.0:6194 | Aralez HTTPS bind address (Optional) |
|
| **proxy_address_tls** | 0.0.0.0:6194 | Aralez HTTPS bind address (Optional) |
|
||||||
| **proxy_configs** | /etc/aralez/ | Direcotry containing configuration files, must be writeable by user `aralez` |
|
| **proxy_configs** | /etc/aralez/ | Direcotry containing configuration files, must be writeable by user `aralez` |
|
||||||
| **upstreams_conf** | /etc/aralez/upstreams.yaml | Location of the upstreams file |
|
| **upstreams_conf** | /etc/aralez/upstreams.yaml | Location of the upstreams file |
|
||||||
|
| **access_log** | access | Configure access logging. Values: `access, error` |
|
||||||
| **log_level** | info | Log level: `info`, `warn`, `error`, `debug`, `trace`, `off` |
|
| **log_level** | info | Log level: `info`, `warn`, `error`, `debug`, `trace`, `off` |
|
||||||
| **log_file** | /full/path/to/aralez.log | Optional, the location of log file. If thi entry does not exist logs will be emitted to stdout. |
|
| **log_file** | /full/path/to/aralez.log | Optional, the location of log file. If thi entry does not exist logs will be emitted to stdout. |
|
||||||
| **hc_method** | HEAD | Healthcheck method: HEAD, GET, POST (UPPERCASE) |
|
| **hc_method** | HEAD | Healthcheck method: HEAD, GET, POST (UPPERCASE) |
|
||||||
@@ -107,6 +118,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 +568,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
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,25 @@
|
|||||||
# Main configuration file, applied on startup
|
# Main configuration file, applied on startup
|
||||||
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: aralez # 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: aralez # Group for running aralez after dropping root privileges, requires program to start as root
|
||||||
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
|
|
||||||
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: 127.0.0.1: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:80 # Proxy HTTP bind address
|
||||||
proxy_address_tls: 0.0.0.0:6194 # Optional, Proxy TLS bind address
|
proxy_address_tls: 0.0.0.0:443 # 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/aralez/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/aralez/etc/upstreams.yaml # the location of upstreams file
|
||||||
#file_server_folder: /opt/storage # Optional, local folder to serve
|
file_server_folder: /opt/aralez/public # 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: 0.0.0.0: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.
|
||||||
|
access_log: error # all, error, (Off if commented)
|
||||||
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
|
tcp_keepalive_idle: 60 # Seconds of inactivity before the kernel starts sending keepalive probes to a downstream client
|
||||||
|
tcp_keepalive_interval: 10 # Seconds between individual keepalive probes if the client does not respond
|
||||||
|
tcp_keepalive_count: 5 # Number of unanswered probes before the kernel declares the connection dead and closes it
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
provider: "file"
|
|
||||||
globals:
|
|
||||||
headers:
|
|
||||||
- "Access-Control-Allow-Origin:*"
|
|
||||||
- "Access-Control-Allow-Methods:POST, GET, OPTIONS"
|
|
||||||
- "Access-Control-Max-Age:86400"
|
|
||||||
- "X-Custom-Header:Something Special"
|
|
||||||
upstreams:
|
|
||||||
myip.netangels.net:
|
|
||||||
paths:
|
|
||||||
"/":
|
|
||||||
ssl: false
|
|
||||||
headers:
|
|
||||||
- "X-Proxy-From:Aralez"
|
|
||||||
servers:
|
|
||||||
- "192.168.221.213:8000"
|
|
||||||
- "192.168.221.214:8000"
|
|
||||||
- "192.168.221.210:8000"
|
|
||||||
- "192.168.221.212:8000"
|
|
||||||
@@ -1,49 +1,44 @@
|
|||||||
# 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: Something For Servers"
|
||||||
- "X-Forwarded-Port:443"
|
|
||||||
client_headers:
|
client_headers:
|
||||||
- "Access-Control-Allow-Origin:*"
|
- "X-Global-Something: Something For Clients"
|
||||||
- "Access-Control-Allow-Methods:POST, GET, OPTIONS"
|
|
||||||
- "Access-Control-Max-Age:86400"
|
|
||||||
#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: "apikey"
|
# type: "jwt"
|
||||||
# creds: "5ecbf799-1343-4e94-a9b5-e278af5cd313-56b45249-1839-4008-a450-a60dc76d2bae"
|
# data: "910517d9-f9a1-48de-8826-dbadacbd84af-cb6f830e-ab16-47ec-9d8f-0090de732774"
|
||||||
|
# type: "apikey"
|
||||||
|
# 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"
|
||||||
|
upstream: "api-service"
|
||||||
path: "/"
|
path: "/"
|
||||||
upstream: "webapi-service"
|
- hostname: "api-service"
|
||||||
- hostname: "webapi-service"
|
|
||||||
upstream: "console-service"
|
upstream: "console-service"
|
||||||
path: "/one"
|
path: "/one"
|
||||||
client_headers:
|
client_headers:
|
||||||
@@ -51,71 +46,92 @@ 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"
|
||||||
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:
|
www.example.com:
|
||||||
paths:
|
paths:
|
||||||
"/":
|
"/":
|
||||||
rate_limit: 200
|
rate_limit: 50
|
||||||
x4xx_limit: 100
|
x4xx_limit: 100
|
||||||
to_https: false
|
to_https: false
|
||||||
client_headers:
|
authorization:
|
||||||
- "X-Proxy-From:Aralez"
|
|
||||||
servers:
|
|
||||||
- "127.0.0.1:8000"
|
|
||||||
- "127.0.0.2:8000"
|
|
||||||
- "127.0.0.3:8000"
|
|
||||||
- "127.0.0.4:8000"
|
|
||||||
- "127.0.0.5:8000"
|
|
||||||
"/ping":
|
|
||||||
authorization: # Will be ignored if global authentication is enabled.
|
|
||||||
type: "basic"
|
type: "basic"
|
||||||
creds: "admin:admin"
|
data: "root:toor"
|
||||||
to_https: false
|
|
||||||
server_headers:
|
server_headers:
|
||||||
- "X-Forwarded-Proto:https"
|
- "Y-Proxy-Server-Some:Yaaaaaaaaaaaaaaa"
|
||||||
- "X-Forwarded-Port:443"
|
- "Y-Proxy-Server-From:Aralez"
|
||||||
|
- "Y-Proxy-Server-Vers:Aralez v-xxx"
|
||||||
client_headers:
|
client_headers:
|
||||||
- "X-Some-Thing:Yaaaaaaaaaaaaaaa"
|
- "Access-Control-Allow-Origin:*"
|
||||||
- "X-Proxy-From:Aralez"
|
- "Access-Control-Allow-Methods:POST, GET, OPTIONS"
|
||||||
|
- "Access-Control-Max-Age:86400"
|
||||||
|
- "Strict-Transport-Security:max-age=31536000; includeSubDomains; preload"
|
||||||
servers:
|
servers:
|
||||||
- "127.0.0.1:8000"
|
- "127.0.0.1:8000"
|
||||||
- "127.0.0.2:8000"
|
- "127.0.0.2:8000"
|
||||||
"/draw":
|
|
||||||
servers:
|
|
||||||
- "192.168.1.1:8000"
|
|
||||||
polo.mydomain.com:
|
|
||||||
paths:
|
|
||||||
"/":
|
|
||||||
to_https: false
|
|
||||||
client_headers:
|
|
||||||
- "X-Some-Thing:Yaaaaaaaaaaaaaaa"
|
|
||||||
servers:
|
|
||||||
- "192.168.1.1:8000"
|
|
||||||
- "192.168.1.10:8000"
|
|
||||||
- "127.0.0.1:8000"
|
|
||||||
- "127.0.0.2:8000"
|
|
||||||
- "127.0.0.3:8000"
|
- "127.0.0.3:8000"
|
||||||
- "127.0.0.4:8000"
|
"/ping":
|
||||||
apt.mydomain.com:
|
to_https: true
|
||||||
|
client_headers:
|
||||||
|
- "X-Some-Thing:Something Else"
|
||||||
|
- "Access-Control-Allow-Origin:*"
|
||||||
|
- "Access-Control-Allow-Methods:POST, GET, OPTIONS"
|
||||||
|
- "Access-Control-Max-Age:86400"
|
||||||
|
- "Strict-Transport-Security:max-age=31536000; includeSubDomains; preload"
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:8000"
|
||||||
|
"/secret":
|
||||||
|
authorization:
|
||||||
|
type: "forward"
|
||||||
|
data: "http://127.0.0.1:8899/admin/login"
|
||||||
|
servers:
|
||||||
|
- "127.0.0.10:8000"
|
||||||
|
example.com:
|
||||||
paths:
|
paths:
|
||||||
"/":
|
"/":
|
||||||
|
redirect_to: "https://www.example.com:443"
|
||||||
servers:
|
servers:
|
||||||
- "192.168.1.10:443"
|
- "127.0.0.1:80"
|
||||||
|
h2.example.com:
|
||||||
|
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"
|
||||||
|
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:
|
||||||
|
- "127.0.0.1:8899"
|
||||||
|
"/500":
|
||||||
healthcheck: false
|
healthcheck: false
|
||||||
servers:
|
servers:
|
||||||
- "127.0.0.1:8080"
|
- "127.0.0.1:8899"
|
||||||
|
DEFAULT:
|
||||||
|
paths:
|
||||||
|
"/":
|
||||||
|
healthcheck: false
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:3000"
|
||||||
|
"/.well-known/acme-challenge":
|
||||||
|
healthcheck: false
|
||||||
|
servers:
|
||||||
|
- "127.0.0.1:3000"
|
||||||
|
|||||||
@@ -3,10 +3,14 @@ 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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ pub async fn load_configuration(d: &str, kind: &str) -> (Option<Configuration>,
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut parsed: Config = match serde_yml::from_str(&yaml_data) {
|
let mut parsed: Config = match noyalib::from_str(&yaml_data) {
|
||||||
Ok(cfg) => cfg,
|
Ok(cfg) => cfg,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to parse upstreams file: {}", e);
|
error!("Failed to parse upstreams file: {}", e);
|
||||||
@@ -118,7 +118,7 @@ pub async fn load_configuration(d: &str, kind: &str) -> (Option<Configuration>,
|
|||||||
|
|
||||||
if let Some(ref mut upstreams) = parsed.upstreams {
|
if let Some(ref mut upstreams) = parsed.upstreams {
|
||||||
for uconf in conf_files {
|
for uconf in conf_files {
|
||||||
let p: HashMap<String, HostConfig> = match serde_yml::from_str(&uconf) {
|
let p: HashMap<String, HostConfig> = match noyalib::from_str(&uconf) {
|
||||||
Ok(ucfg) => ucfg,
|
Ok(ucfg) => ucfg,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to parse upstreams file: {}", e);
|
error!("Failed to parse upstreams file: {}", e);
|
||||||
@@ -264,19 +264,13 @@ async fn populate_file_upstreams(config: &mut Configuration, parsed: &Config) {
|
|||||||
}
|
}
|
||||||
pub fn parce_main_config(path: &str) -> AppConfig {
|
pub fn parce_main_config(path: &str) -> AppConfig {
|
||||||
let data = fs::read_to_string(path).unwrap();
|
let data = fs::read_to_string(path).unwrap();
|
||||||
let reply = DashMap::new();
|
let mut cfo: AppConfig = noyalib::from_str(&data).expect("Failed to parse main config file");
|
||||||
let cfg: HashMap<String, String> = serde_yml::from_str(&data).expect("Failed to parse main config file");
|
|
||||||
let mut cfo: AppConfig = serde_yml::from_str(&data).expect("Failed to parse main config file");
|
|
||||||
|
|
||||||
if let Ok(jwt_key) = env::var("JWT_KEY") {
|
if let Ok(jwt_key) = env::var("JWT_KEY") {
|
||||||
cfo.master_key = Some(jwt_key);
|
cfo.master_key = Some(jwt_key);
|
||||||
};
|
};
|
||||||
|
|
||||||
log_builder(&cfo, &cfo.log_file);
|
log_builder(&cfo, &cfo.log_file);
|
||||||
cfo.hc_method = cfo.hc_method.to_uppercase();
|
cfo.hc_method = cfo.hc_method.to_uppercase();
|
||||||
for (k, v) in cfg {
|
|
||||||
reply.insert(k.to_string(), v.to_string());
|
|
||||||
}
|
|
||||||
if let Some((ip, port_str)) = cfo.config_address.split_once(':') {
|
if let Some((ip, port_str)) = cfo.config_address.split_once(':') {
|
||||||
if let Ok(port) = port_str.parse::<u16>() {
|
if let Ok(port) = port_str.parse::<u16>() {
|
||||||
cfo.local_server = Option::from((ip.to_string(), port));
|
cfo.local_server = Option::from((ip.to_string(), port));
|
||||||
|
|||||||
@@ -112,6 +112,8 @@ 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 access_log: Option<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 +132,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)]
|
||||||
|
|||||||
@@ -10,9 +10,12 @@ use sha2::{Digest, Sha256};
|
|||||||
use std::any::type_name;
|
use std::any::type_name;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
use std::fs::OpenOptions;
|
||||||
|
use std::io::Write as IoWrite;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
|
use std::os::unix::fs::OpenOptionsExt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::mpsc::{channel, Sender};
|
use std::sync::mpsc::{channel, Sender};
|
||||||
@@ -274,7 +277,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 {
|
||||||
@@ -380,3 +383,14 @@ pub fn prepend(prefix: &str, val: &Option<Arc<str>>, uri: &str, port: &str) -> O
|
|||||||
buf
|
buf
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn write_pid_file(path: &str) -> std::io::Result<()> {
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.create(true)
|
||||||
|
.truncate(true)
|
||||||
|
.custom_flags(libc::O_NOFOLLOW) // refuse to follow symlinks
|
||||||
|
.open(path)?;
|
||||||
|
file.write_all(process::id().to_string().as_bytes())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
pub mod acme;
|
pub mod acme;
|
||||||
pub mod bgservice;
|
pub mod bgservice;
|
||||||
pub mod gethosts;
|
pub mod gethosts;
|
||||||
|
pub mod logging;
|
||||||
pub mod proxyhttp;
|
pub mod proxyhttp;
|
||||||
pub mod start;
|
pub mod start;
|
||||||
pub mod webserver;
|
pub mod webserver;
|
||||||
|
|||||||
57
src/web/logging.rs
Normal file
57
src/web/logging.rs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
use log::info;
|
||||||
|
use pingora_proxy::Session;
|
||||||
|
use std::net::{IpAddr, Ipv4Addr};
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
pub static ACCESS_LOG: OnceLock<LogLevel> = OnceLock::new();
|
||||||
|
|
||||||
|
pub fn init_access_log(level_str: &str) {
|
||||||
|
let level = LogLevel::from_str(level_str);
|
||||||
|
let _ = ACCESS_LOG.set(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum LogLevel {
|
||||||
|
Access,
|
||||||
|
Error,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LogLevel {
|
||||||
|
pub fn from_str(s: &str) -> Self {
|
||||||
|
match s {
|
||||||
|
"all" => LogLevel::Access,
|
||||||
|
"error" => LogLevel::Error,
|
||||||
|
_ => LogLevel::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn access_log(response_code: u16, summary: &str, session: &Session) {
|
||||||
|
let level = ACCESS_LOG.get().unwrap_or(&LogLevel::None);
|
||||||
|
|
||||||
|
let should_log = match level {
|
||||||
|
LogLevel::Access => true,
|
||||||
|
LogLevel::None => false,
|
||||||
|
LogLevel::Error => !(100..=399).contains(&response_code),
|
||||||
|
};
|
||||||
|
|
||||||
|
if !should_log {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ip = session
|
||||||
|
.client_addr()
|
||||||
|
.and_then(|addr| addr.as_inet())
|
||||||
|
.map(|addr| addr.ip())
|
||||||
|
.unwrap_or(IpAddr::V4(Ipv4Addr::LOCALHOST));
|
||||||
|
|
||||||
|
let user_agent = session.req_header().headers.get("user-agent").and_then(|v| v.to_str().ok()).unwrap_or("-");
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"{}, response code: {response_code}, client: {}, version: {:?}, useragent: {}",
|
||||||
|
summary,
|
||||||
|
ip,
|
||||||
|
session.req_header().version,
|
||||||
|
user_agent,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,10 +3,11 @@ use crate::utils::lazylock::{LOCALHOST, RATE_LIMITER, REQUESTS_4XX, REVERSE_STOR
|
|||||||
use crate::utils::metrics::*;
|
use crate::utils::metrics::*;
|
||||||
use crate::utils::structs::{AppConfig, Extraparams, Headers, InnerMap, UpstreamsDashMap, UpstreamsIdMap};
|
use crate::utils::structs::{AppConfig, Extraparams, Headers, InnerMap, UpstreamsDashMap, UpstreamsIdMap};
|
||||||
use crate::web::gethosts::{GetHost, GetHostsReturHeaders};
|
use crate::web::gethosts::{GetHost, GetHostsReturHeaders};
|
||||||
|
use crate::web::logging::access_log;
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use axum::body::Bytes;
|
use axum::body::Bytes;
|
||||||
use log::{debug, error, warn};
|
use log::error;
|
||||||
use pingora::http::{RequestHeader, ResponseHeader, StatusCode};
|
use pingora::http::{RequestHeader, ResponseHeader, StatusCode};
|
||||||
use pingora::prelude::*;
|
use pingora::prelude::*;
|
||||||
use pingora::ErrorSource::Upstream;
|
use pingora::ErrorSource::Upstream;
|
||||||
@@ -20,10 +21,6 @@ use std::sync::Arc;
|
|||||||
use tokio::time::Instant;
|
use tokio::time::Instant;
|
||||||
|
|
||||||
thread_local! {static IP_BUFFER: RefCell<String> = RefCell::new(String::with_capacity(50));}
|
thread_local! {static IP_BUFFER: RefCell<String> = RefCell::new(String::with_capacity(50));}
|
||||||
// static REVERSE_STORE: LazyLock<DashMap<String, String>> = LazyLock::new(DashMap::new);
|
|
||||||
// pub static RATE_LIMITER: LazyLock<Rate> = LazyLock::new(|| Rate::new(Duration::from_secs(1)));
|
|
||||||
// pub static REQUESTS_4XX: LazyLock<Cache<IpAddr, u32>> = LazyLock::new(|| Cache::builder().time_to_live(Duration::from_secs(1)).build());
|
|
||||||
// pub static LOCALHOST: LazyLock<Arc<str>> = LazyLock::new(|| Arc::from("localhost"));
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct LB {
|
pub struct LB {
|
||||||
@@ -86,7 +83,6 @@ impl ProxyHttp for LB {
|
|||||||
if let Some(auth) = _ctx.extraparams.authentication.as_ref().or(innermap.authorization.as_ref()) {
|
if let Some(auth) = _ctx.extraparams.authentication.as_ref().or(innermap.authorization.as_ref()) {
|
||||||
if !authenticate(&auth, session).await {
|
if !authenticate(&auth, session).await {
|
||||||
let _ = session.respond_error(401).await;
|
let _ = session.respond_error(401).await;
|
||||||
warn!("Forbidden: {:?}, {}", session.client_addr(), session.req_header().uri.path());
|
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,9 +95,9 @@ impl ProxyHttp for LB {
|
|||||||
let header = ResponseHeader::build(429, None)?;
|
let header = ResponseHeader::build(429, None)?;
|
||||||
session.set_keepalive(None);
|
session.set_keepalive(None);
|
||||||
session.write_response_header(Box::new(header), true).await?;
|
session.write_response_header(Box::new(header), true).await?;
|
||||||
if let (Some(oi), Some(oa)) = (&_ctx.hostname, rate_key) {
|
// if let (Some(oi), Some(oa)) = (&_ctx.hostname, rate_key) {
|
||||||
warn!("Limit 4XX: {}-rps exceed on {} from {} path {}", rate, oi, oa, session.req_header().uri.path());
|
// warn!("Limit 4XX: {}-rps exceed on {} from {} path {}", rate, oi, oa, session.req_header().uri.path());
|
||||||
}
|
// }
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,9 +109,9 @@ impl ProxyHttp for LB {
|
|||||||
let header = ResponseHeader::build(429, None)?;
|
let header = ResponseHeader::build(429, None)?;
|
||||||
session.set_keepalive(None);
|
session.set_keepalive(None);
|
||||||
session.write_response_header(Box::new(header), true).await?;
|
session.write_response_header(Box::new(header), true).await?;
|
||||||
if let (Some(oi), Some(oa)) = (&_ctx.hostname, rate_key) {
|
// if let (Some(oi), Some(oa)) = (&_ctx.hostname, rate_key) {
|
||||||
warn!("Limit: {}-rps exceed on {} from {}", rate, oi, oa);
|
// warn!("Limit: {}-rps exceed on {} from {}", rate, oi, oa);
|
||||||
}
|
// }
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,6 +173,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!(
|
||||||
@@ -267,14 +277,12 @@ impl ProxyHttp for LB {
|
|||||||
REVERSE_STORE.insert(hh.clone(), bid.clone());
|
REVERSE_STORE.insert(hh.clone(), bid.clone());
|
||||||
hh
|
hh
|
||||||
};
|
};
|
||||||
// let _ = _upstream_response.insert_header("set-cookie", format!("backend_id={}; Path=/; Max-Age=600; HttpOnly; SameSite=Lax", tt));
|
|
||||||
let mut buf = String::with_capacity(80);
|
let mut buf = String::with_capacity(80);
|
||||||
buf.push_str("backend_id=");
|
buf.push_str("backend_id=");
|
||||||
buf.push_str(&tt);
|
buf.push_str(&tt);
|
||||||
buf.push_str("; Path=/; Max-Age=");
|
buf.push_str("; Path=/; Max-Age=");
|
||||||
buf.push_str(&val.to_string());
|
buf.push_str(&val.to_string());
|
||||||
buf.push_str("; HttpOnly; SameSite=Lax");
|
buf.push_str("; HttpOnly; SameSite=Lax");
|
||||||
// buf.push_str("; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax");
|
|
||||||
let _ = _upstream_response.insert_header("set-cookie", buf.as_str());
|
let _ = _upstream_response.insert_header("set-cookie", buf.as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,7 +297,6 @@ impl ProxyHttp for LB {
|
|||||||
|
|
||||||
async fn logging(&self, session: &mut Session, _e: Option<&pingora::Error>, ctx: &mut Self::CTX) {
|
async fn logging(&self, session: &mut Session, _e: Option<&pingora::Error>, ctx: &mut Self::CTX) {
|
||||||
let response_code = session.response_written().map_or(0, |resp| resp.status.as_u16());
|
let response_code = session.response_written().map_or(0, |resp| resp.status.as_u16());
|
||||||
debug!("{}, response code: {response_code}", self.request_summary(session, ctx));
|
|
||||||
let m = &MetricTypes {
|
let m = &MetricTypes {
|
||||||
method: session.req_header().method.clone(),
|
method: session.req_header().method.clone(),
|
||||||
code: session.response_written().map(|resp| resp.status),
|
code: session.response_written().map(|resp| resp.status),
|
||||||
@@ -300,13 +307,14 @@ impl ProxyHttp for LB {
|
|||||||
calc_metrics(m);
|
calc_metrics(m);
|
||||||
ACTIVE_SESSIONS.dec();
|
ACTIVE_SESSIONS.dec();
|
||||||
if let Some(_) = ctx.x4xx_limit.or(ctx.extraparams.x4xx_limit) {
|
if let Some(_) = ctx.x4xx_limit.or(ctx.extraparams.x4xx_limit) {
|
||||||
if 400 <= response_code && response_code <= 499 {
|
if (400..=499).contains(&response_code) {
|
||||||
if let Some(ip) = session.client_addr().and_then(|a| a.as_inet()).map(|i| i.ip()) {
|
if let Some(ip) = session.client_addr().and_then(|a| a.as_inet()).map(|i| i.ip()) {
|
||||||
let current = REQUESTS_4XX.get(&ip).unwrap_or(0);
|
let current = REQUESTS_4XX.get(&ip).unwrap_or(0);
|
||||||
REQUESTS_4XX.insert(ip, current + 1);
|
REQUESTS_4XX.insert(ip, current + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
access_log(response_code, &self.request_summary(session, ctx), session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,16 @@ use crate::tls::load;
|
|||||||
use crate::tls::load::CertificateConfig;
|
use crate::tls::load::CertificateConfig;
|
||||||
use crate::utils::structs::Extraparams;
|
use crate::utils::structs::Extraparams;
|
||||||
use crate::utils::tools::*;
|
use crate::utils::tools::*;
|
||||||
|
use crate::web::logging::init_access_log;
|
||||||
use crate::web::proxyhttp::LB;
|
use crate::web::proxyhttp::LB;
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
use dashmap::DashMap;
|
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;
|
||||||
@@ -21,7 +24,7 @@ use signal_hook::{
|
|||||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{fs, process, thread};
|
use std::{fs, thread};
|
||||||
|
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
// default_provider().install_default().expect("Failed to install rustls crypto provider");
|
// default_provider().install_default().expect("Failed to install rustls crypto provider");
|
||||||
@@ -57,17 +60,41 @@ pub fn run() {
|
|||||||
server_headers: sh_config,
|
server_headers: sh_config,
|
||||||
extraparams: ec_config,
|
extraparams: ec_config,
|
||||||
};
|
};
|
||||||
|
let al = cfg.access_log.clone().unwrap_or("none".to_string());
|
||||||
|
init_access_log(al.as_str());
|
||||||
|
|
||||||
let grade = cfg.proxy_tls_grade.clone().unwrap_or("medium".to_string());
|
let grade = cfg.proxy_tls_grade.clone().unwrap_or("medium".to_string());
|
||||||
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 +122,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 +134,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,8 +149,11 @@ 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 pf = cfg.pid_file.clone().unwrap_or("/tmp/aralez.pid".to_string());
|
||||||
|
if let Err(e) = write_pid_file(pf.as_str()) {
|
||||||
|
panic!("Failed to write PID file: {} : {}", pf, e);
|
||||||
|
}
|
||||||
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() {
|
||||||
match sig {
|
match sig {
|
||||||
|
|||||||
@@ -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() });
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ async fn conf(State(st): State<AppState>, Query(params): Query<HashMap<String, S
|
|||||||
}
|
}
|
||||||
|
|
||||||
let strcontent = content.as_str();
|
let strcontent = content.as_str();
|
||||||
let parsed = serde_yml::from_str::<Config>(strcontent);
|
let parsed = noyalib::from_str::<Config>(strcontent);
|
||||||
match parsed {
|
match parsed {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
if let Some(_) = params.get("save") {
|
if let Some(_) = params.get("save") {
|
||||||
@@ -227,20 +227,18 @@ 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