├── .DS_Store ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── cf ├── _redirects └── install.sh ├── config.example.toml ├── config.toml ├── install_rust.sh ├── release.sh ├── screenshot.png └── src ├── main.rs ├── options.rs └── server ├── http.rs ├── https.rs ├── mod.rs ├── proxy.rs ├── tunnel.rs └── utils.rs /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doroved/proxerver-cli/02d3644db9a8ba6f91b4dffb5b31f8cf4d496217/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /certs 3 | config.dev.toml -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "anstream" 31 | version = "0.6.15" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" 34 | dependencies = [ 35 | "anstyle", 36 | "anstyle-parse", 37 | "anstyle-query", 38 | "anstyle-wincon", 39 | "colorchoice", 40 | "is_terminal_polyfill", 41 | "utf8parse", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle" 46 | version = "1.0.8" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" 49 | 50 | [[package]] 51 | name = "anstyle-parse" 52 | version = "0.2.5" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" 55 | dependencies = [ 56 | "utf8parse", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle-query" 61 | version = "1.1.1" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" 64 | dependencies = [ 65 | "windows-sys 0.52.0", 66 | ] 67 | 68 | [[package]] 69 | name = "anstyle-wincon" 70 | version = "3.0.4" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" 73 | dependencies = [ 74 | "anstyle", 75 | "windows-sys 0.52.0", 76 | ] 77 | 78 | [[package]] 79 | name = "atomic-waker" 80 | version = "1.1.2" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 83 | 84 | [[package]] 85 | name = "autocfg" 86 | version = "1.4.0" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 89 | 90 | [[package]] 91 | name = "aws-lc-rs" 92 | version = "1.12.0" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "f409eb70b561706bf8abba8ca9c112729c481595893fd06a2dd9af8ed8441148" 95 | dependencies = [ 96 | "aws-lc-sys", 97 | "paste", 98 | "zeroize", 99 | ] 100 | 101 | [[package]] 102 | name = "aws-lc-sys" 103 | version = "0.24.1" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "923ded50f602b3007e5e63e3f094c479d9c8a9b42d7f4034e4afe456aa48bfd2" 106 | dependencies = [ 107 | "bindgen", 108 | "cc", 109 | "cmake", 110 | "dunce", 111 | "fs_extra", 112 | "paste", 113 | ] 114 | 115 | [[package]] 116 | name = "backtrace" 117 | version = "0.3.74" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 120 | dependencies = [ 121 | "addr2line", 122 | "cfg-if", 123 | "libc", 124 | "miniz_oxide", 125 | "object", 126 | "rustc-demangle", 127 | "windows-targets", 128 | ] 129 | 130 | [[package]] 131 | name = "base64" 132 | version = "0.22.1" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 135 | 136 | [[package]] 137 | name = "bindgen" 138 | version = "0.69.5" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" 141 | dependencies = [ 142 | "bitflags", 143 | "cexpr", 144 | "clang-sys", 145 | "itertools", 146 | "lazy_static", 147 | "lazycell", 148 | "log", 149 | "prettyplease", 150 | "proc-macro2", 151 | "quote", 152 | "regex", 153 | "rustc-hash", 154 | "shlex", 155 | "syn", 156 | "which", 157 | ] 158 | 159 | [[package]] 160 | name = "bitflags" 161 | version = "2.6.0" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 164 | 165 | [[package]] 166 | name = "block-buffer" 167 | version = "0.10.4" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 170 | dependencies = [ 171 | "generic-array", 172 | ] 173 | 174 | [[package]] 175 | name = "bytes" 176 | version = "1.9.0" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" 179 | 180 | [[package]] 181 | name = "cc" 182 | version = "1.2.2" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" 185 | dependencies = [ 186 | "jobserver", 187 | "libc", 188 | "shlex", 189 | ] 190 | 191 | [[package]] 192 | name = "cexpr" 193 | version = "0.6.0" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 196 | dependencies = [ 197 | "nom", 198 | ] 199 | 200 | [[package]] 201 | name = "cfg-if" 202 | version = "1.0.0" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 205 | 206 | [[package]] 207 | name = "clang-sys" 208 | version = "1.8.1" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" 211 | dependencies = [ 212 | "glob", 213 | "libc", 214 | "libloading", 215 | ] 216 | 217 | [[package]] 218 | name = "clap" 219 | version = "4.5.27" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796" 222 | dependencies = [ 223 | "clap_builder", 224 | "clap_derive", 225 | ] 226 | 227 | [[package]] 228 | name = "clap_builder" 229 | version = "4.5.27" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" 232 | dependencies = [ 233 | "anstream", 234 | "anstyle", 235 | "clap_lex", 236 | "strsim", 237 | ] 238 | 239 | [[package]] 240 | name = "clap_derive" 241 | version = "4.5.24" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" 244 | dependencies = [ 245 | "heck", 246 | "proc-macro2", 247 | "quote", 248 | "syn", 249 | ] 250 | 251 | [[package]] 252 | name = "clap_lex" 253 | version = "0.7.4" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 256 | 257 | [[package]] 258 | name = "cmake" 259 | version = "0.1.52" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" 262 | dependencies = [ 263 | "cc", 264 | ] 265 | 266 | [[package]] 267 | name = "colorchoice" 268 | version = "1.0.2" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" 271 | 272 | [[package]] 273 | name = "core-foundation" 274 | version = "0.9.4" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 277 | dependencies = [ 278 | "core-foundation-sys", 279 | "libc", 280 | ] 281 | 282 | [[package]] 283 | name = "core-foundation-sys" 284 | version = "0.8.7" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 287 | 288 | [[package]] 289 | name = "cpufeatures" 290 | version = "0.2.14" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" 293 | dependencies = [ 294 | "libc", 295 | ] 296 | 297 | [[package]] 298 | name = "crypto-common" 299 | version = "0.1.6" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 302 | dependencies = [ 303 | "generic-array", 304 | "typenum", 305 | ] 306 | 307 | [[package]] 308 | name = "digest" 309 | version = "0.10.7" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 312 | dependencies = [ 313 | "block-buffer", 314 | "crypto-common", 315 | ] 316 | 317 | [[package]] 318 | name = "dunce" 319 | version = "1.0.5" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" 322 | 323 | [[package]] 324 | name = "either" 325 | version = "1.13.0" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 328 | 329 | [[package]] 330 | name = "equivalent" 331 | version = "1.0.1" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 334 | 335 | [[package]] 336 | name = "errno" 337 | version = "0.3.10" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 340 | dependencies = [ 341 | "libc", 342 | "windows-sys 0.59.0", 343 | ] 344 | 345 | [[package]] 346 | name = "fastrand" 347 | version = "2.2.0" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" 350 | 351 | [[package]] 352 | name = "fnv" 353 | version = "1.0.7" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 356 | 357 | [[package]] 358 | name = "foreign-types" 359 | version = "0.3.2" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 362 | dependencies = [ 363 | "foreign-types-shared", 364 | ] 365 | 366 | [[package]] 367 | name = "foreign-types-shared" 368 | version = "0.1.1" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 371 | 372 | [[package]] 373 | name = "fs_extra" 374 | version = "1.3.0" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" 377 | 378 | [[package]] 379 | name = "futures-channel" 380 | version = "0.3.31" 381 | source = "registry+https://github.com/rust-lang/crates.io-index" 382 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 383 | dependencies = [ 384 | "futures-core", 385 | ] 386 | 387 | [[package]] 388 | name = "futures-core" 389 | version = "0.3.31" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 392 | 393 | [[package]] 394 | name = "futures-sink" 395 | version = "0.3.31" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 398 | 399 | [[package]] 400 | name = "futures-task" 401 | version = "0.3.31" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 404 | 405 | [[package]] 406 | name = "futures-util" 407 | version = "0.3.31" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 410 | dependencies = [ 411 | "futures-core", 412 | "futures-task", 413 | "pin-project-lite", 414 | "pin-utils", 415 | ] 416 | 417 | [[package]] 418 | name = "generic-array" 419 | version = "0.14.7" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 422 | dependencies = [ 423 | "typenum", 424 | "version_check", 425 | ] 426 | 427 | [[package]] 428 | name = "getrandom" 429 | version = "0.2.15" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 432 | dependencies = [ 433 | "cfg-if", 434 | "libc", 435 | "wasi", 436 | ] 437 | 438 | [[package]] 439 | name = "gimli" 440 | version = "0.31.0" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" 443 | 444 | [[package]] 445 | name = "glob" 446 | version = "0.3.1" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 449 | 450 | [[package]] 451 | name = "h2" 452 | version = "0.4.7" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" 455 | dependencies = [ 456 | "atomic-waker", 457 | "bytes", 458 | "fnv", 459 | "futures-core", 460 | "futures-sink", 461 | "http", 462 | "indexmap", 463 | "slab", 464 | "tokio", 465 | "tokio-util", 466 | "tracing", 467 | ] 468 | 469 | [[package]] 470 | name = "hashbrown" 471 | version = "0.15.2" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 474 | 475 | [[package]] 476 | name = "heck" 477 | version = "0.5.0" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 480 | 481 | [[package]] 482 | name = "hermit-abi" 483 | version = "0.3.9" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 486 | 487 | [[package]] 488 | name = "home" 489 | version = "0.5.9" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" 492 | dependencies = [ 493 | "windows-sys 0.52.0", 494 | ] 495 | 496 | [[package]] 497 | name = "http" 498 | version = "1.2.0" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" 501 | dependencies = [ 502 | "bytes", 503 | "fnv", 504 | "itoa", 505 | ] 506 | 507 | [[package]] 508 | name = "http-body" 509 | version = "1.0.1" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 512 | dependencies = [ 513 | "bytes", 514 | "http", 515 | ] 516 | 517 | [[package]] 518 | name = "http-body-util" 519 | version = "0.1.2" 520 | source = "registry+https://github.com/rust-lang/crates.io-index" 521 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 522 | dependencies = [ 523 | "bytes", 524 | "futures-util", 525 | "http", 526 | "http-body", 527 | "pin-project-lite", 528 | ] 529 | 530 | [[package]] 531 | name = "httparse" 532 | version = "1.9.4" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" 535 | 536 | [[package]] 537 | name = "httpdate" 538 | version = "1.0.3" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 541 | 542 | [[package]] 543 | name = "hyper" 544 | version = "1.6.0" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 547 | dependencies = [ 548 | "bytes", 549 | "futures-channel", 550 | "futures-util", 551 | "h2", 552 | "http", 553 | "http-body", 554 | "httparse", 555 | "httpdate", 556 | "itoa", 557 | "pin-project-lite", 558 | "smallvec", 559 | "tokio", 560 | "want", 561 | ] 562 | 563 | [[package]] 564 | name = "hyper-tls" 565 | version = "0.6.0" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 568 | dependencies = [ 569 | "bytes", 570 | "http-body-util", 571 | "hyper", 572 | "hyper-util", 573 | "native-tls", 574 | "tokio", 575 | "tokio-native-tls", 576 | "tower-service", 577 | ] 578 | 579 | [[package]] 580 | name = "hyper-util" 581 | version = "0.1.10" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" 584 | dependencies = [ 585 | "bytes", 586 | "futures-channel", 587 | "futures-util", 588 | "http", 589 | "http-body", 590 | "hyper", 591 | "pin-project-lite", 592 | "socket2", 593 | "tokio", 594 | "tower-service", 595 | "tracing", 596 | ] 597 | 598 | [[package]] 599 | name = "indexmap" 600 | version = "2.7.0" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" 603 | dependencies = [ 604 | "equivalent", 605 | "hashbrown", 606 | ] 607 | 608 | [[package]] 609 | name = "is_terminal_polyfill" 610 | version = "1.70.1" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 613 | 614 | [[package]] 615 | name = "itertools" 616 | version = "0.12.1" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" 619 | dependencies = [ 620 | "either", 621 | ] 622 | 623 | [[package]] 624 | name = "itoa" 625 | version = "1.0.11" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 628 | 629 | [[package]] 630 | name = "jobserver" 631 | version = "0.1.32" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" 634 | dependencies = [ 635 | "libc", 636 | ] 637 | 638 | [[package]] 639 | name = "lazy_static" 640 | version = "1.5.0" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 643 | 644 | [[package]] 645 | name = "lazycell" 646 | version = "1.3.0" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 649 | 650 | [[package]] 651 | name = "libc" 652 | version = "0.2.169" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" 655 | 656 | [[package]] 657 | name = "libloading" 658 | version = "0.8.6" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" 661 | dependencies = [ 662 | "cfg-if", 663 | "windows-targets", 664 | ] 665 | 666 | [[package]] 667 | name = "linux-raw-sys" 668 | version = "0.4.14" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 671 | 672 | [[package]] 673 | name = "log" 674 | version = "0.4.22" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 677 | 678 | [[package]] 679 | name = "memchr" 680 | version = "2.7.4" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 683 | 684 | [[package]] 685 | name = "minimal-lexical" 686 | version = "0.2.1" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 689 | 690 | [[package]] 691 | name = "miniz_oxide" 692 | version = "0.8.0" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" 695 | dependencies = [ 696 | "adler2", 697 | ] 698 | 699 | [[package]] 700 | name = "mio" 701 | version = "1.0.2" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 704 | dependencies = [ 705 | "hermit-abi", 706 | "libc", 707 | "wasi", 708 | "windows-sys 0.52.0", 709 | ] 710 | 711 | [[package]] 712 | name = "native-tls" 713 | version = "0.2.12" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" 716 | dependencies = [ 717 | "libc", 718 | "log", 719 | "openssl", 720 | "openssl-probe", 721 | "openssl-sys", 722 | "schannel", 723 | "security-framework", 724 | "security-framework-sys", 725 | "tempfile", 726 | ] 727 | 728 | [[package]] 729 | name = "nom" 730 | version = "7.1.3" 731 | source = "registry+https://github.com/rust-lang/crates.io-index" 732 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 733 | dependencies = [ 734 | "memchr", 735 | "minimal-lexical", 736 | ] 737 | 738 | [[package]] 739 | name = "nu-ansi-term" 740 | version = "0.46.0" 741 | source = "registry+https://github.com/rust-lang/crates.io-index" 742 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 743 | dependencies = [ 744 | "overload", 745 | "winapi", 746 | ] 747 | 748 | [[package]] 749 | name = "object" 750 | version = "0.36.4" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" 753 | dependencies = [ 754 | "memchr", 755 | ] 756 | 757 | [[package]] 758 | name = "once_cell" 759 | version = "1.19.0" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 762 | 763 | [[package]] 764 | name = "openssl" 765 | version = "0.10.69" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | checksum = "f5e534d133a060a3c19daec1eb3e98ec6f4685978834f2dbadfe2ec215bab64e" 768 | dependencies = [ 769 | "bitflags", 770 | "cfg-if", 771 | "foreign-types", 772 | "libc", 773 | "once_cell", 774 | "openssl-macros", 775 | "openssl-sys", 776 | ] 777 | 778 | [[package]] 779 | name = "openssl-macros" 780 | version = "0.1.1" 781 | source = "registry+https://github.com/rust-lang/crates.io-index" 782 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 783 | dependencies = [ 784 | "proc-macro2", 785 | "quote", 786 | "syn", 787 | ] 788 | 789 | [[package]] 790 | name = "openssl-probe" 791 | version = "0.1.5" 792 | source = "registry+https://github.com/rust-lang/crates.io-index" 793 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 794 | 795 | [[package]] 796 | name = "openssl-src" 797 | version = "300.4.1+3.4.0" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "faa4eac4138c62414b5622d1b31c5c304f34b406b013c079c2bbc652fdd6678c" 800 | dependencies = [ 801 | "cc", 802 | ] 803 | 804 | [[package]] 805 | name = "openssl-sys" 806 | version = "0.9.104" 807 | source = "registry+https://github.com/rust-lang/crates.io-index" 808 | checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" 809 | dependencies = [ 810 | "cc", 811 | "libc", 812 | "openssl-src", 813 | "pkg-config", 814 | "vcpkg", 815 | ] 816 | 817 | [[package]] 818 | name = "overload" 819 | version = "0.1.1" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 822 | 823 | [[package]] 824 | name = "paste" 825 | version = "1.0.15" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 828 | 829 | [[package]] 830 | name = "pin-project-lite" 831 | version = "0.2.14" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 834 | 835 | [[package]] 836 | name = "pin-utils" 837 | version = "0.1.0" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 840 | 841 | [[package]] 842 | name = "pkg-config" 843 | version = "0.3.31" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 846 | 847 | [[package]] 848 | name = "prettyplease" 849 | version = "0.2.25" 850 | source = "registry+https://github.com/rust-lang/crates.io-index" 851 | checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" 852 | dependencies = [ 853 | "proc-macro2", 854 | "syn", 855 | ] 856 | 857 | [[package]] 858 | name = "proc-macro2" 859 | version = "1.0.92" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 862 | dependencies = [ 863 | "unicode-ident", 864 | ] 865 | 866 | [[package]] 867 | name = "proxerver-cli" 868 | version = "0.2.0" 869 | dependencies = [ 870 | "base64", 871 | "bytes", 872 | "clap", 873 | "http", 874 | "http-body-util", 875 | "hyper", 876 | "hyper-tls", 877 | "hyper-util", 878 | "openssl", 879 | "rlimit", 880 | "rustls", 881 | "serde", 882 | "sha2", 883 | "tokio", 884 | "tokio-rustls", 885 | "toml", 886 | "tracing", 887 | "tracing-subscriber", 888 | "wildmatch", 889 | ] 890 | 891 | [[package]] 892 | name = "quote" 893 | version = "1.0.37" 894 | source = "registry+https://github.com/rust-lang/crates.io-index" 895 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 896 | dependencies = [ 897 | "proc-macro2", 898 | ] 899 | 900 | [[package]] 901 | name = "regex" 902 | version = "1.11.1" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 905 | dependencies = [ 906 | "aho-corasick", 907 | "memchr", 908 | "regex-automata", 909 | "regex-syntax", 910 | ] 911 | 912 | [[package]] 913 | name = "regex-automata" 914 | version = "0.4.9" 915 | source = "registry+https://github.com/rust-lang/crates.io-index" 916 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 917 | dependencies = [ 918 | "aho-corasick", 919 | "memchr", 920 | "regex-syntax", 921 | ] 922 | 923 | [[package]] 924 | name = "regex-syntax" 925 | version = "0.8.5" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 928 | 929 | [[package]] 930 | name = "ring" 931 | version = "0.17.8" 932 | source = "registry+https://github.com/rust-lang/crates.io-index" 933 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 934 | dependencies = [ 935 | "cc", 936 | "cfg-if", 937 | "getrandom", 938 | "libc", 939 | "spin", 940 | "untrusted", 941 | "windows-sys 0.52.0", 942 | ] 943 | 944 | [[package]] 945 | name = "rlimit" 946 | version = "0.10.2" 947 | source = "registry+https://github.com/rust-lang/crates.io-index" 948 | checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" 949 | dependencies = [ 950 | "libc", 951 | ] 952 | 953 | [[package]] 954 | name = "rustc-demangle" 955 | version = "0.1.24" 956 | source = "registry+https://github.com/rust-lang/crates.io-index" 957 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 958 | 959 | [[package]] 960 | name = "rustc-hash" 961 | version = "1.1.0" 962 | source = "registry+https://github.com/rust-lang/crates.io-index" 963 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 964 | 965 | [[package]] 966 | name = "rustix" 967 | version = "0.38.37" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" 970 | dependencies = [ 971 | "bitflags", 972 | "errno", 973 | "libc", 974 | "linux-raw-sys", 975 | "windows-sys 0.52.0", 976 | ] 977 | 978 | [[package]] 979 | name = "rustls" 980 | version = "0.23.21" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" 983 | dependencies = [ 984 | "aws-lc-rs", 985 | "log", 986 | "once_cell", 987 | "rustls-pki-types", 988 | "rustls-webpki", 989 | "subtle", 990 | "zeroize", 991 | ] 992 | 993 | [[package]] 994 | name = "rustls-pki-types" 995 | version = "1.10.0" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" 998 | 999 | [[package]] 1000 | name = "rustls-webpki" 1001 | version = "0.102.8" 1002 | source = "registry+https://github.com/rust-lang/crates.io-index" 1003 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 1004 | dependencies = [ 1005 | "aws-lc-rs", 1006 | "ring", 1007 | "rustls-pki-types", 1008 | "untrusted", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "schannel" 1013 | version = "0.1.27" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" 1016 | dependencies = [ 1017 | "windows-sys 0.59.0", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "security-framework" 1022 | version = "2.11.1" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 1025 | dependencies = [ 1026 | "bitflags", 1027 | "core-foundation", 1028 | "core-foundation-sys", 1029 | "libc", 1030 | "security-framework-sys", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "security-framework-sys" 1035 | version = "2.12.1" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" 1038 | dependencies = [ 1039 | "core-foundation-sys", 1040 | "libc", 1041 | ] 1042 | 1043 | [[package]] 1044 | name = "serde" 1045 | version = "1.0.217" 1046 | source = "registry+https://github.com/rust-lang/crates.io-index" 1047 | checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" 1048 | dependencies = [ 1049 | "serde_derive", 1050 | ] 1051 | 1052 | [[package]] 1053 | name = "serde_derive" 1054 | version = "1.0.217" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" 1057 | dependencies = [ 1058 | "proc-macro2", 1059 | "quote", 1060 | "syn", 1061 | ] 1062 | 1063 | [[package]] 1064 | name = "serde_spanned" 1065 | version = "0.6.8" 1066 | source = "registry+https://github.com/rust-lang/crates.io-index" 1067 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 1068 | dependencies = [ 1069 | "serde", 1070 | ] 1071 | 1072 | [[package]] 1073 | name = "sha2" 1074 | version = "0.10.8" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1077 | dependencies = [ 1078 | "cfg-if", 1079 | "cpufeatures", 1080 | "digest", 1081 | ] 1082 | 1083 | [[package]] 1084 | name = "sharded-slab" 1085 | version = "0.1.7" 1086 | source = "registry+https://github.com/rust-lang/crates.io-index" 1087 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1088 | dependencies = [ 1089 | "lazy_static", 1090 | ] 1091 | 1092 | [[package]] 1093 | name = "shlex" 1094 | version = "1.3.0" 1095 | source = "registry+https://github.com/rust-lang/crates.io-index" 1096 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1097 | 1098 | [[package]] 1099 | name = "signal-hook-registry" 1100 | version = "1.4.2" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 1103 | dependencies = [ 1104 | "libc", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "slab" 1109 | version = "0.4.9" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1112 | dependencies = [ 1113 | "autocfg", 1114 | ] 1115 | 1116 | [[package]] 1117 | name = "smallvec" 1118 | version = "1.13.2" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1121 | 1122 | [[package]] 1123 | name = "socket2" 1124 | version = "0.5.7" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 1127 | dependencies = [ 1128 | "libc", 1129 | "windows-sys 0.52.0", 1130 | ] 1131 | 1132 | [[package]] 1133 | name = "spin" 1134 | version = "0.9.8" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1137 | 1138 | [[package]] 1139 | name = "strsim" 1140 | version = "0.11.1" 1141 | source = "registry+https://github.com/rust-lang/crates.io-index" 1142 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1143 | 1144 | [[package]] 1145 | name = "subtle" 1146 | version = "2.6.1" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1149 | 1150 | [[package]] 1151 | name = "syn" 1152 | version = "2.0.90" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" 1155 | dependencies = [ 1156 | "proc-macro2", 1157 | "quote", 1158 | "unicode-ident", 1159 | ] 1160 | 1161 | [[package]] 1162 | name = "tempfile" 1163 | version = "3.13.0" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" 1166 | dependencies = [ 1167 | "cfg-if", 1168 | "fastrand", 1169 | "once_cell", 1170 | "rustix", 1171 | "windows-sys 0.59.0", 1172 | ] 1173 | 1174 | [[package]] 1175 | name = "thread_local" 1176 | version = "1.1.8" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 1179 | dependencies = [ 1180 | "cfg-if", 1181 | "once_cell", 1182 | ] 1183 | 1184 | [[package]] 1185 | name = "tokio" 1186 | version = "1.43.0" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" 1189 | dependencies = [ 1190 | "backtrace", 1191 | "bytes", 1192 | "libc", 1193 | "mio", 1194 | "pin-project-lite", 1195 | "signal-hook-registry", 1196 | "socket2", 1197 | "tokio-macros", 1198 | "windows-sys 0.52.0", 1199 | ] 1200 | 1201 | [[package]] 1202 | name = "tokio-macros" 1203 | version = "2.5.0" 1204 | source = "registry+https://github.com/rust-lang/crates.io-index" 1205 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 1206 | dependencies = [ 1207 | "proc-macro2", 1208 | "quote", 1209 | "syn", 1210 | ] 1211 | 1212 | [[package]] 1213 | name = "tokio-native-tls" 1214 | version = "0.3.1" 1215 | source = "registry+https://github.com/rust-lang/crates.io-index" 1216 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1217 | dependencies = [ 1218 | "native-tls", 1219 | "tokio", 1220 | ] 1221 | 1222 | [[package]] 1223 | name = "tokio-rustls" 1224 | version = "0.26.1" 1225 | source = "registry+https://github.com/rust-lang/crates.io-index" 1226 | checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" 1227 | dependencies = [ 1228 | "rustls", 1229 | "tokio", 1230 | ] 1231 | 1232 | [[package]] 1233 | name = "tokio-util" 1234 | version = "0.7.13" 1235 | source = "registry+https://github.com/rust-lang/crates.io-index" 1236 | checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" 1237 | dependencies = [ 1238 | "bytes", 1239 | "futures-core", 1240 | "futures-sink", 1241 | "pin-project-lite", 1242 | "tokio", 1243 | ] 1244 | 1245 | [[package]] 1246 | name = "toml" 1247 | version = "0.8.19" 1248 | source = "registry+https://github.com/rust-lang/crates.io-index" 1249 | checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" 1250 | dependencies = [ 1251 | "serde", 1252 | "serde_spanned", 1253 | "toml_datetime", 1254 | "toml_edit", 1255 | ] 1256 | 1257 | [[package]] 1258 | name = "toml_datetime" 1259 | version = "0.6.8" 1260 | source = "registry+https://github.com/rust-lang/crates.io-index" 1261 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 1262 | dependencies = [ 1263 | "serde", 1264 | ] 1265 | 1266 | [[package]] 1267 | name = "toml_edit" 1268 | version = "0.22.22" 1269 | source = "registry+https://github.com/rust-lang/crates.io-index" 1270 | checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" 1271 | dependencies = [ 1272 | "indexmap", 1273 | "serde", 1274 | "serde_spanned", 1275 | "toml_datetime", 1276 | "winnow", 1277 | ] 1278 | 1279 | [[package]] 1280 | name = "tower-service" 1281 | version = "0.3.3" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1284 | 1285 | [[package]] 1286 | name = "tracing" 1287 | version = "0.1.41" 1288 | source = "registry+https://github.com/rust-lang/crates.io-index" 1289 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1290 | dependencies = [ 1291 | "pin-project-lite", 1292 | "tracing-attributes", 1293 | "tracing-core", 1294 | ] 1295 | 1296 | [[package]] 1297 | name = "tracing-attributes" 1298 | version = "0.1.28" 1299 | source = "registry+https://github.com/rust-lang/crates.io-index" 1300 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 1301 | dependencies = [ 1302 | "proc-macro2", 1303 | "quote", 1304 | "syn", 1305 | ] 1306 | 1307 | [[package]] 1308 | name = "tracing-core" 1309 | version = "0.1.33" 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" 1311 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1312 | dependencies = [ 1313 | "once_cell", 1314 | "valuable", 1315 | ] 1316 | 1317 | [[package]] 1318 | name = "tracing-log" 1319 | version = "0.2.0" 1320 | source = "registry+https://github.com/rust-lang/crates.io-index" 1321 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 1322 | dependencies = [ 1323 | "log", 1324 | "once_cell", 1325 | "tracing-core", 1326 | ] 1327 | 1328 | [[package]] 1329 | name = "tracing-subscriber" 1330 | version = "0.3.19" 1331 | source = "registry+https://github.com/rust-lang/crates.io-index" 1332 | checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" 1333 | dependencies = [ 1334 | "nu-ansi-term", 1335 | "sharded-slab", 1336 | "smallvec", 1337 | "thread_local", 1338 | "tracing-core", 1339 | "tracing-log", 1340 | ] 1341 | 1342 | [[package]] 1343 | name = "try-lock" 1344 | version = "0.2.5" 1345 | source = "registry+https://github.com/rust-lang/crates.io-index" 1346 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1347 | 1348 | [[package]] 1349 | name = "typenum" 1350 | version = "1.17.0" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1353 | 1354 | [[package]] 1355 | name = "unicode-ident" 1356 | version = "1.0.13" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" 1359 | 1360 | [[package]] 1361 | name = "untrusted" 1362 | version = "0.9.0" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1365 | 1366 | [[package]] 1367 | name = "utf8parse" 1368 | version = "0.2.2" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1371 | 1372 | [[package]] 1373 | name = "valuable" 1374 | version = "0.1.0" 1375 | source = "registry+https://github.com/rust-lang/crates.io-index" 1376 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 1377 | 1378 | [[package]] 1379 | name = "vcpkg" 1380 | version = "0.2.15" 1381 | source = "registry+https://github.com/rust-lang/crates.io-index" 1382 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1383 | 1384 | [[package]] 1385 | name = "version_check" 1386 | version = "0.9.5" 1387 | source = "registry+https://github.com/rust-lang/crates.io-index" 1388 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 1389 | 1390 | [[package]] 1391 | name = "want" 1392 | version = "0.3.1" 1393 | source = "registry+https://github.com/rust-lang/crates.io-index" 1394 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1395 | dependencies = [ 1396 | "try-lock", 1397 | ] 1398 | 1399 | [[package]] 1400 | name = "wasi" 1401 | version = "0.11.0+wasi-snapshot-preview1" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1404 | 1405 | [[package]] 1406 | name = "which" 1407 | version = "4.4.2" 1408 | source = "registry+https://github.com/rust-lang/crates.io-index" 1409 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" 1410 | dependencies = [ 1411 | "either", 1412 | "home", 1413 | "once_cell", 1414 | "rustix", 1415 | ] 1416 | 1417 | [[package]] 1418 | name = "wildmatch" 1419 | version = "2.4.0" 1420 | source = "registry+https://github.com/rust-lang/crates.io-index" 1421 | checksum = "68ce1ab1f8c62655ebe1350f589c61e505cf94d385bc6a12899442d9081e71fd" 1422 | 1423 | [[package]] 1424 | name = "winapi" 1425 | version = "0.3.9" 1426 | source = "registry+https://github.com/rust-lang/crates.io-index" 1427 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1428 | dependencies = [ 1429 | "winapi-i686-pc-windows-gnu", 1430 | "winapi-x86_64-pc-windows-gnu", 1431 | ] 1432 | 1433 | [[package]] 1434 | name = "winapi-i686-pc-windows-gnu" 1435 | version = "0.4.0" 1436 | source = "registry+https://github.com/rust-lang/crates.io-index" 1437 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1438 | 1439 | [[package]] 1440 | name = "winapi-x86_64-pc-windows-gnu" 1441 | version = "0.4.0" 1442 | source = "registry+https://github.com/rust-lang/crates.io-index" 1443 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1444 | 1445 | [[package]] 1446 | name = "windows-sys" 1447 | version = "0.52.0" 1448 | source = "registry+https://github.com/rust-lang/crates.io-index" 1449 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1450 | dependencies = [ 1451 | "windows-targets", 1452 | ] 1453 | 1454 | [[package]] 1455 | name = "windows-sys" 1456 | version = "0.59.0" 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" 1458 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1459 | dependencies = [ 1460 | "windows-targets", 1461 | ] 1462 | 1463 | [[package]] 1464 | name = "windows-targets" 1465 | version = "0.52.6" 1466 | source = "registry+https://github.com/rust-lang/crates.io-index" 1467 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1468 | dependencies = [ 1469 | "windows_aarch64_gnullvm", 1470 | "windows_aarch64_msvc", 1471 | "windows_i686_gnu", 1472 | "windows_i686_gnullvm", 1473 | "windows_i686_msvc", 1474 | "windows_x86_64_gnu", 1475 | "windows_x86_64_gnullvm", 1476 | "windows_x86_64_msvc", 1477 | ] 1478 | 1479 | [[package]] 1480 | name = "windows_aarch64_gnullvm" 1481 | version = "0.52.6" 1482 | source = "registry+https://github.com/rust-lang/crates.io-index" 1483 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1484 | 1485 | [[package]] 1486 | name = "windows_aarch64_msvc" 1487 | version = "0.52.6" 1488 | source = "registry+https://github.com/rust-lang/crates.io-index" 1489 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1490 | 1491 | [[package]] 1492 | name = "windows_i686_gnu" 1493 | version = "0.52.6" 1494 | source = "registry+https://github.com/rust-lang/crates.io-index" 1495 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1496 | 1497 | [[package]] 1498 | name = "windows_i686_gnullvm" 1499 | version = "0.52.6" 1500 | source = "registry+https://github.com/rust-lang/crates.io-index" 1501 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1502 | 1503 | [[package]] 1504 | name = "windows_i686_msvc" 1505 | version = "0.52.6" 1506 | source = "registry+https://github.com/rust-lang/crates.io-index" 1507 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1508 | 1509 | [[package]] 1510 | name = "windows_x86_64_gnu" 1511 | version = "0.52.6" 1512 | source = "registry+https://github.com/rust-lang/crates.io-index" 1513 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1514 | 1515 | [[package]] 1516 | name = "windows_x86_64_gnullvm" 1517 | version = "0.52.6" 1518 | source = "registry+https://github.com/rust-lang/crates.io-index" 1519 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1520 | 1521 | [[package]] 1522 | name = "windows_x86_64_msvc" 1523 | version = "0.52.6" 1524 | source = "registry+https://github.com/rust-lang/crates.io-index" 1525 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1526 | 1527 | [[package]] 1528 | name = "winnow" 1529 | version = "0.6.20" 1530 | source = "registry+https://github.com/rust-lang/crates.io-index" 1531 | checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" 1532 | dependencies = [ 1533 | "memchr", 1534 | ] 1535 | 1536 | [[package]] 1537 | name = "zeroize" 1538 | version = "1.8.1" 1539 | source = "registry+https://github.com/rust-lang/crates.io-index" 1540 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 1541 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "proxerver-cli" 3 | version = "0.2.0" 4 | edition = "2021" 5 | authors = ["doroved"] 6 | description = "User Friendly HTTP and HTTPS (HTTP over TLS) proxy server." 7 | readme = "README.md" 8 | repository = "https://github.com/doroved/proxerver-cli" 9 | license = "MIT OR Apache-2.0" 10 | keywords = ["proxy", "proxy-server", "http", "https", "http-over-tls"] 11 | categories = ["command-line-utilities", "network-programming"] 12 | 13 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 14 | 15 | [dependencies] 16 | tokio = { version = "1.43.0", features = [ 17 | "rt", 18 | "rt-multi-thread", 19 | "macros", 20 | "process", 21 | ] } 22 | 23 | hyper = { version = "1.6.0" } 24 | hyper-tls = "0.6.0" 25 | hyper-util = { version = "0.1.10", features = ["server", "http1", "http2"] } 26 | 27 | wildmatch = "2.4.0" 28 | clap = { version = "4.5.27", features = ["derive"] } 29 | serde = { version = "1.0.217", features = ["derive"] } 30 | sha2 = "0.10.8" 31 | bytes = "1.9.0" 32 | rlimit = "0.10.2" 33 | toml = "0.8.19" 34 | 35 | http = "1.2.0" 36 | http-body-util = "0.1.2" 37 | 38 | tracing = "0.1.41" 39 | tracing-subscriber = { version = "0.3.19" } 40 | 41 | rustls = "0.23.21" 42 | tokio-rustls = "0.26.1" 43 | 44 | openssl = { version = "0.10.69", features = ["vendored"] } 45 | base64 = "0.22.1" 46 | 47 | 48 | 49 | [profile.release] 50 | panic = "abort" # Strip expensive panic clean-up logic 51 | codegen-units = 1 # Compile crates one after another so the compiler can optimize better 52 | lto = true # Enables link to optimizations 53 | opt-level = "z" # Optimize for binary size s = 1.4 mb | z = 1.2 mb 54 | strip = true # Remove debug symbols 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Proxerver 2 | 3 | > **Subscribe to us on [Telegram](https://t.me/macproxer) to receive notifications about new versions and updates.** 4 | 5 | Create your own HTTP and/or HTTPS (HTTP over TLS) proxy server with one click. Use this proxy to enhance the security of your internet connections or to bypass restrictions. 6 | 7 | Available on Linux `x86_64` and ~~`aarch64`~~ (temporarily unavailable in installer). 8 | 9 | ![proxerver screenshot](screenshot.png) 10 | 11 | ## How to Install 12 | 13 | Just log into your server/VPS terminal and run the command: 14 | 15 | ```bash 16 | curl -fsSL https://proxerver-cli.pages.dev | bash 17 | ``` 18 | 19 | After installation, be sure to run this command to make proxerver available in the current terminal session: 20 | 21 | ```bash 22 | export PATH=$PATH:~/.proxerver-cli/bin 23 | ``` 24 | 25 | To update proxerver to the latest version, use the same command that was used for installation. 26 | 27 | ## Key Features: 28 | 29 | - Easy to set up and use. 30 | - Support for HTTP and HTTPS (HTTP over TLS). 31 | - List of allowed hosts that can be proxied. Use [wildcard matching](#wildcard-matching-usage-rules). 32 | - Using multiple credentials for authentication. 33 | - Authentication via tokens supported by the [Proxer CLI](https://github.com/doroved/proxer-cli) client. It is recommended for use as it helps protect your proxies from proxy server detection through active probing. 34 | 35 | ``` 36 | proxerver-cli --help 37 | 38 | User Friendly HTTP and HTTPS (HTTP over TLS) proxy server. 39 | 40 | Usage: proxerver-cli [OPTIONS] 41 | 42 | Options: 43 | --config Path to the configuration file. Default: '~/.proxerver-cli/config.toml' 44 | -h, --help Print help 45 | -V, --version Print version 46 | ``` 47 | 48 | ## Configuration File 49 | 50 | A configuration file is used to store the proxy server settings. The default configuration file is located at `~/.proxerver-cli/config.toml`. You can specify a different path using the `--config` option. 51 | 52 | To change the default configuration file, use the following command: 53 | 54 | ```bash 55 | nano ~/.proxerver-cli/config.toml 56 | ``` 57 | 58 | ```toml 59 | # HTTP server configuration 60 | [http] 61 | enabled = true 62 | port = 8080 63 | allowed_hosts = [] 64 | 65 | [http.auth] 66 | credentials = [] 67 | tokens = [] 68 | 69 | # HTTPS server configuration 70 | [https] 71 | enabled = false 72 | port = 443 73 | allowed_hosts = [] 74 | 75 | [https.auth] 76 | credentials = [] 77 | tokens = [] 78 | 79 | [https.tls] 80 | cert = "" 81 | key = "" 82 | ``` 83 | 84 | The configuration file is in TOML format and contains the following sections: 85 | 86 | - `http`: HTTP server configuration 87 | - `https`: HTTPS server configuration 88 | 89 | ### HTTP Server Configuration 90 | 91 | - `enabled`: Enables or disables the HTTP server. Default: `true` 92 | - `port`: The port to listen on. Default: `8080` 93 | - `allowed_hosts`: A list of allowed hosts. Default: `[]` 94 | - `auth`: Authentication configuration 95 | - `credentials`: A list of allowed credentials. Default: `[]` 96 | - `tokens`: A list of allowed tokens. Default: `[]` 97 | 98 | ### HTTPS Server Configuration 99 | 100 | - `enabled`: Enables or disables the HTTPS server. Default: `false` 101 | - `port`: The port to listen on. Default: `443` 102 | - `allowed_hosts` and `auth`: Same as HTTP server configuration 103 | - `tls`: TLS configuration 104 | - `cert`: Path to the certificate file. Default: `""` 105 | - `key`: Path to the private key file. Default: `""` 106 | 107 | See example configuration files in the [`config.example.toml`](./config.example.toml) file for more details. 108 | 109 | ## Starting the Proxy Server 110 | 111 | To quickly start the HTTP proxy server on port 8080, use the following command: 112 | 113 | ```bash 114 | proxerver-cli 115 | ``` 116 | 117 | Create configuration files with the parameters you need and start the proxy server using the command: 118 | 119 | ```bash 120 | proxerver-cli --config custom.toml 121 | ``` 122 | 123 | To run the proxy server in the background, use nohup, for example: 124 | 125 | ```bash 126 | nohup proxerver-cli [OPTIONS] >/dev/null 2>&1 & 127 | ``` 128 | 129 | Running the proxy server in the background using nohup and saving the output to a file: 130 | 131 | ```bash 132 | nohup proxerver-cli [OPTIONS] > ~/.proxerver-cli/log.txt 2>&1 & 133 | ``` 134 | 135 | Remove the background process proxerver-cli: 136 | 137 | ```bash 138 | pkill proxerver-cli 139 | ``` 140 | 141 | ## Let's Encrypt Certificate Generation 142 | 143 | Install certbot, test automatic renewal, and check for a timer for automatic certificate updates. 144 | 145 | ```bash 146 | apt-get install certbot -y 147 | certbot certonly --standalone --agree-tos --register-unsafely-without-email -d yourdomain.com 148 | certbot renew --dry-run 149 | systemctl list-timers | grep certbot 150 | ``` 151 | 152 | `yourdomain.com` - Your domain pointing to the server's IP 153 | 154 | ## Wildcard Matching Usage Rules 155 | 156 | 1. Use `*` to replace any number of characters. For example, `*.example.com` will match all subdomains of `example.com`. 157 | 2. Use `?` to replace a single character. For example, `*.example?.com` will match `*.example1.com`, `*.exampleA.com`, but not `*.example.com`. 158 | 3. You can combine `*` and `?` for more complex patterns. For example, `*example?.com` will match `example1.com`, `myexampleA.com`, but not `example.com`. 159 | 4. Be cautious when using wildcard matching, as it can lead to unwanted access if not configured properly. 160 | 5. Check allowed hosts for duplicates to avoid conflicts in rules. 161 | 162 | ## TODO: 163 | 164 | - [ ] Automatic creation and renewal of Let's Encrypt certificates for custom domains and [IP](https://letsencrypt.org/2025/01/16/6-day-and-ip-certs/). 165 | - [ ] Daemonization of the process to run the program in the background. 166 | -------------------------------------------------------------------------------- /cf/_redirects: -------------------------------------------------------------------------------- 1 | / /install.sh 302 -------------------------------------------------------------------------------- /cf/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check architecture 4 | arch=$(uname -m) 5 | if [[ "$arch" != "x86_64" && "$arch" != "aarch64" ]]; then 6 | echo "Error: Unsupported architecture $arch. Exiting script." 7 | exit 1 8 | fi 9 | 10 | # Function to add PATH to the configuration file 11 | add_to_path() { 12 | local rc_file=$1 13 | if ! grep -q "export PATH=.*proxerver-cli/bin" "$rc_file"; then 14 | echo "" >> "$rc_file" 15 | echo "# Proxerver CLI" >> "$rc_file" 16 | echo "export PATH=\$PATH:~/.proxerver-cli/bin" >> "$rc_file" 17 | source "$rc_file" 18 | echo "Updated $rc_file" 19 | else 20 | echo "Path already added in $rc_file" 21 | fi 22 | } 23 | 24 | # Create directory for installation 25 | mkdir -p ~/.proxerver-cli/bin 26 | 27 | # Fetch the latest release from GitHub 28 | curl "https://api.github.com/repos/doroved/proxerver-cli/releases/latest" | 29 | grep '"tag_name":' | 30 | sed -E 's/.*"([^"]+)".*/\1/' | 31 | xargs -I {} curl -OL "https://github.com/doroved/proxerver-cli/releases/download/"\{\}"/proxerver-cli.${arch}.tar.gz" 32 | 33 | # Extract and move the files 34 | tar -xzvf ./proxerver-cli.${arch}.tar.gz && \ 35 | rm -rf ./proxerver-cli.${arch}.tar.gz && \ 36 | rm ./._proxerver-cli && \ 37 | mv ./proxerver-cli ~/.proxerver-cli/bin 38 | 39 | # Download config.toml 40 | curl -OL https://raw.githubusercontent.com/doroved/proxerver-cli/refs/heads/main/config.toml 41 | 42 | # Check if config.toml exists and move it if not 43 | if [ ! -f ~/.proxerver-cli/config.toml ]; then 44 | mv config.toml ~/.proxerver-cli/ 45 | fi 46 | 47 | # Check for errors in the previous commands 48 | if [ $? -ne 0 ]; then 49 | echo "Error. Exiting now." 50 | exit 51 | fi 52 | 53 | # Add to PATH 54 | export PATH=$PATH:~/.proxerver-cli/bin 55 | 56 | # Check for .bashrc and .zshrc and append PATH export if they exist 57 | if [ -f ~/.bashrc ]; then 58 | add_to_path ~/.bashrc 59 | fi 60 | 61 | if [ -f ~/.zshrc ]; then 62 | add_to_path ~/.zshrc 63 | fi 64 | 65 | # Success message with version 66 | proxerver_version=$(proxerver-cli --version) 67 | echo "" 68 | echo "Successfully installed $proxerver_version" 69 | 70 | # Run the proxerver help command 71 | proxerver --help 72 | echo "" 73 | echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; 74 | echo "Please copy and paste this command into the terminal and press Enter:" 75 | echo "export PATH=\$PATH:~/.proxerver-cli/bin" -------------------------------------------------------------------------------- /config.example.toml: -------------------------------------------------------------------------------- 1 | # HTTP server configuration 2 | [http] 3 | enabled = true 4 | port = 8080 5 | allowed_hosts = [] 6 | 7 | [http.auth] 8 | credentials = [] 9 | tokens = [] 10 | 11 | # HTTPS server configuration 12 | [https] 13 | enabled = true 14 | port = 443 15 | allowed_hosts = [ 16 | # Youtube 17 | "youtu.be", 18 | "*.googlevideo.com", 19 | "*.youtube.com", 20 | "*.ytimg.com", 21 | "*.ggpht.com", 22 | "*.googleapis.com", 23 | # Discord 24 | "*discord*.*", 25 | ] 26 | 27 | [https.auth] 28 | credentials = ["user:pass", "user2:pass2", "user3:pass3"] 29 | tokens = [ 30 | "eb43660b36516c77d677be623a0cd7c895c890a71cbe5aa902326d516285b6e5", 31 | "42dd16829a94f7393658311558eea8b51566da2afd262e51094b308740dce347", 32 | # "a9d8f2bdce2fd548fab769cf1ddca0a4043a50583030fe2a391507b8f352bd01" 33 | ] 34 | 35 | [https.tls] 36 | cert = "/etc/letsencrypt/live/example.com/cert.pem" 37 | key = "/etc/letsencrypt/live/example.com/privkey.pem" 38 | -------------------------------------------------------------------------------- /config.toml: -------------------------------------------------------------------------------- 1 | # HTTP server configuration 2 | [http] 3 | enabled = true # true/false to enable/disable HTTP proxy server 4 | port = 8080 # Port to listen on 5 | allowed_hosts = [] # List of allowed hosts 6 | 7 | [http.auth] 8 | credentials = [] # List of allowed auth credentials 9 | tokens = [] # List of allowed auth tokens 10 | 11 | # HTTPS server configuration 12 | [https] 13 | enabled = false 14 | port = 443 15 | allowed_hosts = [] 16 | 17 | [https.auth] 18 | credentials = [] 19 | tokens = [] 20 | 21 | [https.tls] 22 | cert = "" # Path to certificate file 23 | key = "" # Path to private key file 24 | -------------------------------------------------------------------------------- /install_rust.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Updating package lists 4 | echo "--> Updating package lists..." 5 | sudo apt update -y > /dev/null 2>&1 6 | sudo apt upgrade -y > /dev/null 2>&1 7 | 8 | # Installing necessary packages 9 | echo "--> Installing build-essential, pkg-config, and libssl-dev..." 10 | sudo apt install build-essential pkg-config libssl-dev -y > /dev/null 2>&1 11 | 12 | # Installing Rust without requiring confirmation 13 | echo "--> Installing Rust..." 14 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y > /dev/null 2>&1 15 | 16 | # Install cross 17 | echo "--> Installing cross..." 18 | cargo install cross > /dev/null 2>&1 19 | 20 | # Install musl-tools 21 | echo "--> Installing musl-tools..." 22 | sudo apt install musl-tools -y > /dev/null 2>&1 23 | 24 | # Adding musl target 25 | echo "--> Adding musl target..." 26 | rustup target add x86_64-unknown-linux-musl > /dev/null 2>&1 27 | rustup target add aarch64-unknown-linux-musl > /dev/null 2>&1 28 | 29 | # Installing docker 30 | echo "--> Installing docker..." 31 | curl -fsSL https://get.docker.com -o get-docker.sh > /dev/null 2>&1 32 | sudo sh get-docker.sh > /dev/null 2>&1 33 | rm get-docker.sh 34 | 35 | # Adding user to docker group 36 | echo "--> Adding user to docker group..." 37 | sudo usermod -aG docker $USER > /dev/null 2>&1 38 | 39 | echo "--> Installation completed!" -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Extract project name and version from Cargo.toml 4 | project_name=$(grep '^name' Cargo.toml | sed 's/name = "\(.*\)"/\1/' | tr -d '[:space:]') 5 | version=$(grep '^version' Cargo.toml | sed 's/version = "\(.*\)"/\1/' | tr -d '[:space:]') 6 | 7 | # Define architectures for Linux 8 | # architectures=("x86_64-unknown-linux-musl" "aarch64-unknown-linux-musl") 9 | architectures=("x86_64-unknown-linux-musl") 10 | 11 | # Build for each architecture 12 | for arch in "${architectures[@]}"; do 13 | # Extract architecture for naming 14 | short_arch=$(echo $arch | sed 's/-unknown-linux-musl//') 15 | 16 | # Determine the appropriate architecture for the orb command 17 | if [ "$short_arch" = "x86_64" ]; then 18 | orb_arch="amd64" 19 | elif [ "$short_arch" = "aarch64" ]; then 20 | orb_arch="arm64" 21 | else 22 | echo "Unsupported architecture: $short_arch" 23 | exit 1 24 | fi 25 | 26 | # https://docs.orbstack.dev/machines/commands#orb 27 | orb -m ubuntu-24.04-$orb_arch cross build --release --target=$arch 28 | orbctl stop ubuntu-24.04-$orb_arch 29 | 30 | # Move the binary to the release directory with a new name 31 | mkdir -p ./target/release/v${version} 32 | mv ./target/$arch/release/$project_name ./target/release/v${version}/${project_name}.${short_arch} 33 | done 34 | 35 | # Change to the release directory 36 | cd ./target/release/v${version} || exit 37 | 38 | # Create tar.gz and delete the original binaries 39 | for arch in "${architectures[@]}"; do 40 | short_arch=$(echo $arch | sed 's/-unknown-linux-musl//') 41 | binary_name="${project_name}.${short_arch}" 42 | mv ${binary_name} ${project_name} 43 | tar -czf "${binary_name}.tar.gz" --no-xattr "${project_name}" 44 | rm "${project_name}" 45 | done 46 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doroved/proxerver-cli/02d3644db9a8ba6f91b4dffb5b31f8cf4d496217/screenshot.png -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod options; 2 | mod server; 3 | 4 | #[tokio::main] 5 | async fn main() -> Result<(), Box> { 6 | tracing_subscriber::fmt() 7 | .with_max_level(tracing::Level::INFO) 8 | .init(); 9 | 10 | server::run().await?; 11 | Ok(()) 12 | } 13 | -------------------------------------------------------------------------------- /src/options.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | #[derive(Parser, Debug, Clone)] 4 | #[clap(author, version, about, long_about = None)] 5 | pub struct Opt { 6 | #[clap( 7 | long, 8 | value_name = "PATH", 9 | help = "Path to the configuration file. Default: '/config.toml'" 10 | )] 11 | pub config: Option, 12 | } 13 | -------------------------------------------------------------------------------- /src/server/http.rs: -------------------------------------------------------------------------------- 1 | use crate::server::proxy; 2 | 3 | use std::net::SocketAddr; 4 | use std::sync::Arc; 5 | 6 | use hyper::server::conn::http1; 7 | use hyper::{body, service::service_fn, Request}; 8 | use hyper_util::rt::TokioIo; 9 | 10 | use tokio::net::TcpListener; 11 | 12 | pub async fn start( 13 | addr: SocketAddr, 14 | allowed_hosts: &Arc>, 15 | auth_credentials: &Arc>, 16 | auth_tokens: &Arc>, 17 | ) -> Result<(), Box> { 18 | let listener = TcpListener::bind(addr).await?; 19 | tracing::info!("Listening on http://{}", addr); 20 | 21 | loop { 22 | let (stream, addr) = listener.accept().await?; 23 | 24 | let allowed_hosts = Arc::clone(allowed_hosts); 25 | let auth_credentials = Arc::clone(auth_credentials); 26 | let auth_tokens = Arc::clone(auth_tokens); 27 | 28 | let service = service_fn(move |req: Request| { 29 | let allowed_hosts = Arc::clone(&allowed_hosts); 30 | let auth_credentials = Arc::clone(&auth_credentials); 31 | let auth_tokens = Arc::clone(&auth_tokens); 32 | async move { 33 | proxy::handle_request(req, addr.ip(), allowed_hosts, auth_credentials, auth_tokens) 34 | .await 35 | } 36 | }); 37 | 38 | tokio::spawn(async move { 39 | if let Err(err) = http1::Builder::new() 40 | .preserve_header_case(true) 41 | .title_case_headers(true) 42 | .serve_connection(TokioIo::new(stream), service) 43 | .with_upgrades() 44 | .await 45 | { 46 | tracing::error!("\x1B[31mfailed to serve connection: {err:#}\x1B[0m") 47 | } 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/server/https.rs: -------------------------------------------------------------------------------- 1 | use crate::server::proxy; 2 | 3 | use std::net::SocketAddr; 4 | use std::sync::Arc; 5 | 6 | use hyper::{body, service::service_fn, Request}; 7 | use hyper_util::rt::{TokioExecutor, TokioIo}; 8 | use hyper_util::server::conn::auto::Builder; 9 | 10 | use rustls::pki_types::pem::PemObject; 11 | use rustls::pki_types::{CertificateDer, PrivateKeyDer}; 12 | use rustls::ServerConfig; 13 | 14 | use tokio::net::TcpListener; 15 | use tokio_rustls::TlsAcceptor; 16 | 17 | use super::utils::load_proxy_config; 18 | 19 | pub async fn start( 20 | addr: SocketAddr, 21 | allowed_hosts: &Arc>, 22 | auth_credentials: &Arc>, 23 | auth_tokens: &Arc>, 24 | ) -> Result<(), Box> { 25 | let config = create_server_config()?; 26 | let acceptor = TlsAcceptor::from(Arc::new(config)); 27 | 28 | let listener = TcpListener::bind(addr).await?; 29 | tracing::info!("Listening on https://{}", addr); 30 | 31 | loop { 32 | let (stream, addr) = listener.accept().await?; 33 | let acceptor = acceptor.clone(); 34 | 35 | let allowed_hosts = Arc::clone(allowed_hosts); 36 | let auth_credentials = Arc::clone(auth_credentials); 37 | let auth_tokens = Arc::clone(auth_tokens); 38 | 39 | let service = service_fn(move |req: Request| { 40 | let allowed_hosts = Arc::clone(&allowed_hosts); 41 | let auth_credentials = Arc::clone(&auth_credentials); 42 | let auth_tokens = Arc::clone(&auth_tokens); 43 | async move { 44 | proxy::handle_request(req, addr.ip(), allowed_hosts, auth_credentials, auth_tokens) 45 | .await 46 | } 47 | }); 48 | 49 | tokio::spawn(async move { 50 | let tls_stream = match acceptor.accept(stream).await { 51 | Ok(tls_stream) => tls_stream, 52 | Err(_) => return, 53 | }; 54 | 55 | if let Err(err) = Builder::new(TokioExecutor::new()) 56 | .serve_connection_with_upgrades(TokioIo::new(tls_stream), service) 57 | .await 58 | { 59 | tracing::error!("\x1B[31mfailed to serve connection: {err:#}\x1B[0m") 60 | } 61 | }); 62 | } 63 | } 64 | 65 | fn create_server_config() -> Result> { 66 | let proxy_config = load_proxy_config(); 67 | 68 | let cert = CertificateDer::pem_file_iter(proxy_config.https.tls.cert.unwrap()) 69 | .expect("cannot open certificate file") 70 | .map(|result| result.unwrap()) 71 | .collect(); 72 | let private_key = PrivateKeyDer::from_pem_file(proxy_config.https.tls.key.unwrap()) 73 | .expect("cannot open private key file"); 74 | 75 | let mut config = ServerConfig::builder() 76 | .with_no_client_auth() 77 | .with_single_cert(cert, private_key) 78 | .expect("failed to create server configuration"); 79 | 80 | config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; 81 | 82 | Ok(config) 83 | } 84 | -------------------------------------------------------------------------------- /src/server/mod.rs: -------------------------------------------------------------------------------- 1 | use std::{net::SocketAddr, sync::Arc}; 2 | 3 | mod http; 4 | mod https; 5 | mod proxy; 6 | mod tunnel; 7 | mod utils; 8 | 9 | use utils::{get_server_ip, load_proxy_config, terminate_process_on_port}; 10 | 11 | pub async fn run() -> Result<(), Box> { 12 | let proxy_config = load_proxy_config(); 13 | 14 | tracing::info!( 15 | "Default connection limit (soft, hard): {:?}", 16 | rlimit::Resource::NOFILE.get()? 17 | ); 18 | 19 | // Set max open connection limit 20 | match rlimit::increase_nofile_limit(rlimit::INFINITY) { 21 | Ok(limit) => { 22 | tracing::info!("Setting max open connection limit to {}", limit); 23 | } 24 | Err(e) => { 25 | tracing::error!("\x1B[31mFailed to increase the open connection limit: {e}\x1B[0m"); 26 | std::process::exit(1); 27 | } 28 | } 29 | 30 | let ip = get_server_ip().await; 31 | 32 | let http_future = async { 33 | if !proxy_config.http.enabled { 34 | return; 35 | } 36 | 37 | let port = proxy_config.http.port; 38 | let addr = SocketAddr::new(ip, port); 39 | 40 | terminate_process_on_port(port).await; 41 | 42 | let allowed_hosts = Arc::new(proxy_config.http.allowed_hosts); 43 | let auth_credentials = Arc::new(proxy_config.http.auth.credentials); 44 | let auth_tokens = Arc::new(proxy_config.http.auth.tokens); 45 | 46 | tracing::info!("[HTTP] Allowed hosts: {:?}", allowed_hosts); 47 | tracing::info!("[HTTP] Allowed tokens: {:?}", auth_tokens); 48 | 49 | if let Err(e) = http::start(addr, &allowed_hosts, &auth_credentials, &auth_tokens).await { 50 | tracing::error!("\x1B[31mHTTP server failed to start: {e}\x1B[0m"); 51 | std::process::exit(1); 52 | } 53 | }; 54 | 55 | let https_future = async { 56 | if !proxy_config.https.enabled { 57 | return; 58 | } 59 | 60 | let port = proxy_config.https.port; 61 | let addr = SocketAddr::new(ip, port); 62 | 63 | terminate_process_on_port(port).await; 64 | 65 | let allowed_hosts = Arc::new(proxy_config.https.allowed_hosts); 66 | let auth_credentials = Arc::new(proxy_config.https.auth.credentials); 67 | let auth_tokens = Arc::new(proxy_config.https.auth.tokens); 68 | 69 | tracing::info!("[HTTPS] Allowed hosts: {:?}", allowed_hosts); 70 | tracing::info!("[HTTPS] Allowed tokens: {:?}", auth_tokens); 71 | 72 | if let Err(e) = https::start(addr, &allowed_hosts, &auth_credentials, &auth_tokens).await { 73 | tracing::error!("\x1B[31mHTTPS server failed to start: {e}\x1B[0m"); 74 | std::process::exit(1); 75 | } 76 | }; 77 | 78 | tokio::join!(http_future, https_future); 79 | Ok(()) 80 | } 81 | -------------------------------------------------------------------------------- /src/server/proxy.rs: -------------------------------------------------------------------------------- 1 | use std::net::IpAddr; 2 | use std::sync::Arc; 3 | 4 | use base64::{engine::general_purpose::STANDARD as b64, Engine}; 5 | use bytes::Bytes; 6 | use http::header::{PROXY_AUTHENTICATE, PROXY_AUTHORIZATION}; 7 | use http::{Method, Request, Response}; 8 | use http_body_util::{combinators::BoxBody, Empty}; 9 | use http_body_util::{BodyExt, Full}; 10 | use hyper::client::conn::http1::Builder; 11 | use hyper_util::rt::TokioIo; 12 | use tokio::net::TcpStream; 13 | use wildmatch::WildMatch; 14 | 15 | use crate::server::tunnel::tunnel_direct; 16 | 17 | pub async fn handle_request( 18 | req: Request, 19 | client_ip: IpAddr, 20 | allowed_hosts: Arc>, 21 | auth_credentials: Arc>, 22 | auth_tokens: Arc>, 23 | ) -> Result>, hyper::Error> { 24 | tracing::info!("\x1B[34m{client_ip}\x1B[0m → {req:?}"); 25 | 26 | let host = match req.uri().host() { 27 | Some(host) => host, 28 | None => { 29 | tracing::error!("\x1B[31mURI has no host\x1B[0m"); 30 | return Ok(bad_request_response()); 31 | } 32 | }; 33 | 34 | let headers = req.headers(); 35 | 36 | // Check allowed hosts 37 | if let Some(resp) = check_allowed_hosts(host, &allowed_hosts).await { 38 | return Ok(resp); 39 | } 40 | 41 | // Check auth credentials 42 | if let Some(resp) = check_auth_credentials(headers, &auth_credentials).await { 43 | return Ok(resp); 44 | } 45 | 46 | // Check auth tokens 47 | if let Some(resp) = check_auth_tokens(headers, &auth_tokens).await { 48 | return Ok(resp); 49 | } 50 | 51 | // HTTPS request 52 | if Method::CONNECT == req.method() { 53 | if let Some(addr) = host_addr(req.uri()) { 54 | tokio::spawn(async move { 55 | match hyper::upgrade::on(req).await { 56 | Ok(upgraded) => { 57 | if let Err(e) = tunnel_direct(upgraded, &addr).await { 58 | tracing::error!("\x1B[31m{addr} → TUNNEL connection error: {e}\x1B[0m"); 59 | } 60 | } 61 | Err(e) => tracing::error!("\x1B[31m{addr} → UPGRADE error: {e}\x1B[0m"), 62 | } 63 | }); 64 | 65 | Ok(Response::new(empty())) 66 | } else { 67 | tracing::error!( 68 | "\x1B[31mCONNECT host is not socket addr: {:?}\x1B[0m", 69 | req.uri() 70 | ); 71 | Ok(bad_request_response()) 72 | } 73 | } else { 74 | // HTTP request 75 | tracing::info!("{:?} {:?} → HTTP connection", req.method(), req.uri()); 76 | 77 | let port = req.uri().port_u16().unwrap_or(80); 78 | 79 | match TcpStream::connect((host, port)).await { 80 | Ok(stream) => { 81 | let (mut sender, conn) = Builder::new() 82 | .preserve_header_case(true) 83 | .title_case_headers(true) 84 | .handshake(TokioIo::new(stream)) 85 | .await?; 86 | 87 | tokio::spawn(async move { 88 | if let Err(err) = conn.await { 89 | tracing::error!("\x1B[31mConnection failed: {:?}\x1B[0m", err); 90 | } 91 | }); 92 | 93 | let resp = sender.send_request(req).await?; 94 | Ok(resp.map(|b| b.boxed())) 95 | } 96 | Err(e) => { 97 | tracing::error!("\x1B[31m{host}:{port} → Failed to connect: {:?}\x1B[0m", e); 98 | Ok(bad_request_response()) 99 | } 100 | } 101 | } 102 | } 103 | 104 | fn empty() -> BoxBody { 105 | Empty::::new() 106 | .map_err(|never| match never {}) 107 | .boxed() 108 | } 109 | 110 | fn _full>(chunk: T) -> BoxBody { 111 | Full::new(chunk.into()) 112 | .map_err(|never| match never {}) 113 | .boxed() 114 | } 115 | 116 | fn bad_request_response() -> Response> { 117 | let mut resp = Response::new(empty()); 118 | *resp.status_mut() = http::StatusCode::BAD_REQUEST; 119 | resp 120 | } 121 | 122 | fn require_basic_auth() -> Response> { 123 | let mut resp = Response::new(empty()); 124 | *resp.status_mut() = http::StatusCode::PROXY_AUTHENTICATION_REQUIRED; 125 | resp.headers_mut().insert( 126 | PROXY_AUTHENTICATE, 127 | http::HeaderValue::from_static("Basic realm=\"proxerver-cli\""), 128 | ); 129 | resp 130 | } 131 | 132 | fn host_addr(uri: &http::Uri) -> Option { 133 | uri.authority().map(|auth| auth.to_string()) 134 | } 135 | 136 | fn is_host_allowed(req_host: &str, allowed_hosts: &[String]) -> bool { 137 | for allowed_host in allowed_hosts { 138 | if WildMatch::new(allowed_host).matches(req_host) { 139 | return true; 140 | } 141 | } 142 | false 143 | } 144 | 145 | fn is_credentials_allowed(credentials_header: &str, credentials_allowed: &[String]) -> bool { 146 | for credentials in credentials_allowed { 147 | let credentials_allowed = b64.encode(credentials); 148 | 149 | if credentials_header.contains(&credentials_allowed) { 150 | return true; 151 | } 152 | } 153 | false 154 | } 155 | 156 | async fn check_allowed_hosts( 157 | host: &str, 158 | allowed_hosts: &[String], 159 | ) -> Option>> { 160 | if !allowed_hosts.is_empty() && !is_host_allowed(host, allowed_hosts) { 161 | tracing::error!("\x1B[31m{host} not allowed\x1B[0m"); 162 | return Some(bad_request_response()); 163 | } 164 | None 165 | } 166 | 167 | async fn check_auth_credentials( 168 | headers: &http::HeaderMap, 169 | auth_credentials: &[String], 170 | ) -> Option>> { 171 | if !auth_credentials.is_empty() { 172 | if let Some(auth_credentials_header) = headers.get(PROXY_AUTHORIZATION) { 173 | let auth_credentials_header = auth_credentials_header.to_str().unwrap_or(""); 174 | 175 | if !is_credentials_allowed(auth_credentials_header, auth_credentials) { 176 | tracing::error!( 177 | "\x1B[31mNot allowed auth credentials: {auth_credentials_header}\x1B[0m" 178 | ); 179 | return Some(require_basic_auth()); 180 | } 181 | } else { 182 | tracing::error!("\x1B[31mNo auth credentials provided\x1B[0m"); 183 | return Some(require_basic_auth()); 184 | } 185 | } 186 | 187 | None 188 | } 189 | 190 | async fn check_auth_tokens( 191 | headers: &http::HeaderMap, 192 | auth_tokens: &[String], 193 | ) -> Option>> { 194 | if !auth_tokens.is_empty() { 195 | if let Some(auth_token_header) = headers.get("x-auth-token") { 196 | let auth_token_header = auth_token_header.to_str().unwrap_or(""); 197 | 198 | if !auth_tokens.contains(&auth_token_header.to_string()) { 199 | tracing::error!("\x1B[31mNot allowed auth token: {auth_token_header}\x1B[0m"); 200 | return Some(bad_request_response()); 201 | } 202 | } else { 203 | tracing::error!("\x1B[31mNo auth token provided\x1B[0m"); 204 | return Some(bad_request_response()); 205 | } 206 | } 207 | 208 | None 209 | } 210 | -------------------------------------------------------------------------------- /src/server/tunnel.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use hyper::upgrade::Upgraded; 4 | use hyper_util::rt::TokioIo; 5 | 6 | use tokio::{net::TcpStream, time::timeout}; 7 | 8 | pub async fn tunnel_direct( 9 | client_connection: Upgraded, 10 | addr: &str, 11 | ) -> Result<(), Box> { 12 | tracing::info!("{addr} → TUNNEL connection"); 13 | 14 | let mut remote_server = timeout(Duration::from_secs(30), TcpStream::connect(&addr)).await??; 15 | 16 | timeout( 17 | Duration::from_secs(600), 18 | tokio::io::copy_bidirectional(&mut TokioIo::new(client_connection), &mut remote_server), 19 | ) 20 | .await??; 21 | 22 | Ok(()) 23 | } 24 | -------------------------------------------------------------------------------- /src/server/utils.rs: -------------------------------------------------------------------------------- 1 | use crate::options::Opt; 2 | use clap::Parser; 3 | use serde::Deserialize; 4 | use sha2::{Digest, Sha256}; 5 | use std::{ 6 | fs, 7 | net::{IpAddr, Ipv4Addr}, 8 | process::Command, 9 | }; 10 | use tokio::process::Command as TokioCommand; 11 | 12 | #[derive(Debug, Deserialize)] 13 | pub struct ProxyServerConfig { 14 | pub http: HttpConfig, 15 | pub https: HttpsConfig, 16 | } 17 | 18 | #[derive(Debug, Deserialize)] 19 | pub struct HttpConfig { 20 | pub enabled: bool, 21 | pub port: u16, 22 | pub allowed_hosts: Vec, 23 | pub auth: AuthConfig, 24 | } 25 | 26 | #[derive(Debug, Deserialize)] 27 | pub struct HttpsConfig { 28 | pub enabled: bool, 29 | pub port: u16, 30 | pub allowed_hosts: Vec, 31 | pub auth: AuthConfig, 32 | pub tls: TlsConfig, 33 | } 34 | 35 | #[derive(Debug, Deserialize)] 36 | pub struct AuthConfig { 37 | pub credentials: Vec, 38 | pub tokens: Vec, 39 | } 40 | 41 | #[derive(Debug, Deserialize)] 42 | pub struct TlsConfig { 43 | pub cert: Option, 44 | pub key: Option, 45 | } 46 | 47 | pub fn to_sha256(input: &str) -> String { 48 | let mut hasher = Sha256::new(); 49 | hasher.update(input); 50 | format!("{:x}", hasher.finalize()) 51 | } 52 | 53 | pub async fn get_server_ip() -> IpAddr { 54 | let output = Command::new("sh") 55 | .arg("-c") 56 | .arg("hostname -I | awk '{print $1}'") 57 | .output() 58 | .expect("Failed to execute command"); 59 | 60 | if output.status.success() { 61 | match String::from_utf8_lossy(&output.stdout) 62 | .trim() 63 | .parse::() 64 | { 65 | Ok(ip) => ip, 66 | Err(_) => IpAddr::V4(Ipv4Addr::LOCALHOST), 67 | } 68 | } else { 69 | panic!("Failed to get Server IP: {:?}", output.status); 70 | } 71 | } 72 | 73 | pub async fn terminate_process_on_port(port: u16) { 74 | let output = TokioCommand::new("lsof") 75 | .arg("-t") 76 | .arg(format!("-i:{}", port)) 77 | .output() 78 | .await 79 | .expect("Failed to execute lsof command"); 80 | 81 | if !output.stdout.is_empty() { 82 | let pid = String::from_utf8_lossy(&output.stdout).trim().to_string(); 83 | TokioCommand::new("kill") 84 | .arg("-9") 85 | .arg(&pid) 86 | .output() 87 | .await 88 | .expect("Failed to terminate proxerver"); 89 | tracing::info!("Proxerver on port {} has been terminated", port); 90 | 91 | tokio::time::sleep(tokio::time::Duration::from_millis(500)).await; 92 | } 93 | } 94 | 95 | pub fn load_proxy_config() -> ProxyServerConfig { 96 | let options = Opt::parse(); 97 | let home = std::env::var("HOME").unwrap(); 98 | let file_path = options 99 | .config 100 | .unwrap_or(format!("{}/.proxerver-cli/config.toml", home)); 101 | 102 | let content = fs::read_to_string(file_path).expect("Failed to read configuration file"); 103 | let proxy_config: ProxyServerConfig = 104 | toml::de::from_str(&content).expect("Failed to parse configuration file"); 105 | 106 | ProxyServerConfig { 107 | http: HttpConfig { 108 | enabled: proxy_config.http.enabled, 109 | port: proxy_config.http.port, 110 | allowed_hosts: proxy_config.http.allowed_hosts, 111 | auth: AuthConfig { 112 | credentials: proxy_config.http.auth.credentials, 113 | tokens: hash_tokens(&proxy_config.http.auth.tokens), 114 | }, 115 | }, 116 | https: HttpsConfig { 117 | enabled: proxy_config.https.enabled, 118 | port: proxy_config.https.port, 119 | allowed_hosts: proxy_config.https.allowed_hosts, 120 | auth: AuthConfig { 121 | credentials: proxy_config.https.auth.credentials, 122 | tokens: hash_tokens(&proxy_config.https.auth.tokens), 123 | }, 124 | tls: TlsConfig { 125 | cert: proxy_config.https.tls.cert, 126 | key: proxy_config.https.tls.key, 127 | }, 128 | }, 129 | } 130 | } 131 | 132 | fn hash_tokens(tokens: &[String]) -> Vec { 133 | tokens.iter().map(|token| to_sha256(token.trim())).collect() 134 | } 135 | --------------------------------------------------------------------------------