From 5847d4b1361724be57dfaf8e9db2abcd70a0a5b5 Mon Sep 17 00:00:00 2001 From: Eric Rodrigues Pires Date: Sun, 23 Mar 2025 10:09:25 -0300 Subject: [PATCH] Update deps, clean up feature usage, and try to improve release build --- .github/workflows/validate.yml | 2 +- CHANGELOG.md | 6 +- Cargo.lock | 730 +++++++++++++------- Cargo.toml | 70 +- README.md | 4 +- book/src/admin_interface.md | 2 +- book/src/advanced_uses.md | 2 +- book/src/exposing_your_first_service.md | 14 +- book/src/faq.md | 8 +- book/src/local_forwarding.md | 6 +- docker-compose-example/client/compose.yml | 2 +- src/addressing.rs | 39 +- src/certificates.rs | 3 +- src/config.rs | 2 +- src/lib.rs | 2 +- src/login.rs | 2 +- src/quota.rs | 4 +- tests/alias_aliasing_tunnel.rs | 2 +- tests/alias_local_forward_existing_http.rs | 2 +- tests/alias_require_allowed_fingerprints.rs | 2 +- tests/alias_timeout.rs | 2 +- tests/auth_prevent_unauthorized_actions.rs | 16 +- tests/config_disable_aliasing.rs | 2 +- tests/ssh_proxy_jump.rs | 4 +- tests/tcp_allow_requested_ports.rs | 2 +- 25 files changed, 604 insertions(+), 326 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 39bfb17..52fb42c 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -24,7 +24,7 @@ jobs: - name: Run rustfmt run: | rustup component add rustfmt - cargo fmt --check + cargo fmt --check --all clippy: name: Check Clippy lints runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index af2e8d5..49cf961 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,13 @@ ## Unreleased +### Added + +- Add `http2` option for remote forwarding connections. + ### Fixed -- Fix reading messages from all data channels. +- Fix interpreting messages from all data channels. - Improve logic for SSH exec commands. - Flush messages to data channel when closing connection. - Show cursor in admin interface only on shutdown. diff --git a/Cargo.lock b/Cargo.lock index a24f2a8..44cc731 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "argon2" @@ -261,6 +261,17 @@ dependencies = [ "futures-lite", ] +[[package]] +name = "async-recursion" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-task" version = "4.7.1" @@ -269,9 +280,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.86" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", @@ -430,9 +441,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "bcrypt-pbkdf" @@ -451,7 +462,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -476,9 +487,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "blake2" @@ -555,9 +566,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cassowary" @@ -585,9 +596,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.15" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ "jobserver", "libc", @@ -634,16 +645,16 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -669,9 +680,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.30" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92b7b18d71fad5313a1e320fa9897994228ce274b60faa4d694fe0ea89cd9e6d" +checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" dependencies = [ "clap_builder", "clap_derive", @@ -679,9 +690,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.30" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35db2071778a7344791a4fb4f95308b5673d219dee3ae348b86642574ecc90c" +checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" dependencies = [ "anstream", "anstyle", @@ -691,9 +702,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.28" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck", "proc-macro2", @@ -757,9 +768,9 @@ dependencies = [ [[package]] name = "console" -version = "0.15.10" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", "libc", @@ -807,6 +818,21 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam-channel" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -838,7 +864,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "crossterm_winapi", "mio", "parking_lot", @@ -1009,9 +1035,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -1098,9 +1124,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" @@ -1189,19 +1215,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" dependencies = [ "log", - "regex", ] [[package]] name = "env_logger" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" +checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" dependencies = [ "anstream", "anstyle", "env_filter", - "humantime", + "jiff", "log", ] @@ -1250,9 +1275,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "ff" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ "rand_core 0.6.4", "subtle", @@ -1293,9 +1318,9 @@ checksum = "94c970b525906eb37d3940083aa65b95e481fc1857d467d13374e1d925cfc163" [[package]] name = "flate2" -version = "1.0.35" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", "miniz_oxide", @@ -1309,9 +1334,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "foreign-types" @@ -1471,6 +1496,19 @@ dependencies = [ "slab", ] +[[package]] +name = "generator" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" +dependencies = [ + "cfg-if", + "libc", + "log", + "rustversion", + "windows 0.58.0", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1497,14 +1535,16 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", + "js-sys", "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.6", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -1624,6 +1664,33 @@ dependencies = [ "url", ] +[[package]] +name = "hickory-proto" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d844af74f7b799e41c78221be863bade11c430d46042c3b49ca8ae0c6d27287" +dependencies = [ + "async-recursion", + "async-trait", + "cfg-if", + "critical-section", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand 0.9.0", + "ring", + "thiserror 2.0.12", + "tinyvec", + "tokio", + "tracing", + "url", +] + [[package]] name = "hickory-resolver" version = "0.24.4" @@ -1632,7 +1699,7 @@ checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" dependencies = [ "cfg-if", "futures-util", - "hickory-proto", + "hickory-proto 0.24.4", "ipconfig", "lru-cache", "once_cell", @@ -1645,6 +1712,27 @@ dependencies = [ "tracing", ] +[[package]] +name = "hickory-resolver" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a128410b38d6f931fcc6ca5c107a3b02cabd6c05967841269a4ad65d23c44331" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto 0.25.1", + "ipconfig", + "moka", + "once_cell", + "parking_lot", + "rand 0.9.0", + "resolv-conf", + "smallvec", + "thiserror 2.0.12", + "tokio", + "tracing", +] + [[package]] name = "hkdf" version = "0.12.4" @@ -1674,20 +1762,20 @@ dependencies = [ [[package]] name = "hostname" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" dependencies = [ + "cfg-if", "libc", - "match_cfg", - "winapi", + "windows 0.52.0", ] [[package]] name = "http" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -1706,12 +1794,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "pin-project-lite", @@ -1719,9 +1807,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -1737,9 +1825,9 @@ checksum = "91f255a4535024abf7640cb288260811fc14794f62b063652ed349f9a6c2348e" [[package]] name = "humantime" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] name = "hyper" @@ -1968,9 +2056,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -1978,9 +2066,9 @@ dependencies = [ [[package]] name = "indoc" -version = "2.0.5" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" [[package]] name = "inotify" @@ -1988,7 +2076,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "inotify-sys", "libc", ] @@ -2014,9 +2102,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.42.1" +version = "1.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c1b125e30d93896b365e156c33dadfffab45ee8400afcbba4752f59de08a86" +checksum = "50259abbaa67d11d2bcafc7ba1d094ed7a0c70e3ce893f0d0997f73558cb3084" dependencies = [ "console", "linked-hash-map", @@ -2139,9 +2227,33 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "jni" @@ -2221,9 +2333,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.170" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libloading" @@ -2247,7 +2359,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "libc", "redox_syscall", ] @@ -2266,9 +2378,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "lock_api" @@ -2286,6 +2398,19 @@ version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + [[package]] name = "louds-rs" version = "0.7.0" @@ -2314,10 +2439,13 @@ dependencies = [ ] [[package]] -name = "match_cfg" +name = "matchers" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] [[package]] name = "matchit" @@ -2396,13 +2524,32 @@ dependencies = [ "syn", ] +[[package]] +name = "moka" +version = "0.12.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +dependencies = [ + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "loom", + "parking_lot", + "portable-atomic", + "rustc_version", + "smallvec", + "tagptr", + "thiserror 1.0.69", + "uuid", +] + [[package]] name = "nix" version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "cfg-if", "cfg_aliases", "libc", @@ -2424,7 +2571,7 @@ version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "filetime", "fsevent-sys", "inotify", @@ -2452,6 +2599,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -2536,9 +2693,13 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.3" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +dependencies = [ + "critical-section", + "portable-atomic", +] [[package]] name = "opaque-debug" @@ -2552,7 +2713,7 @@ version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "cfg-if", "foreign-types", "libc", @@ -2600,6 +2761,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "p256" version = "0.13.2" @@ -2737,18 +2904,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", @@ -2818,9 +2985,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "polling" @@ -2860,6 +3027,21 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -2868,11 +3050,11 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -2919,9 +3101,9 @@ checksum = "d8868e7264af614b3634ff0abbe37b178e61000611b8a75221aea40221924aba" [[package]] name = "prettyplease" -version = "0.2.29" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" +checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" dependencies = [ "proc-macro2", "syn", @@ -2938,52 +3120,48 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quinn" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" dependencies = [ "bytes", + "cfg_aliases", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash 2.1.1", "rustls", "socket2", - "thiserror 2.0.11", + "thiserror 2.0.12", "tokio", "tracing", + "web-time", ] [[package]] name = "quinn-proto" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" dependencies = [ "bytes", - "getrandom 0.2.15", - "rand 0.8.5", + "getrandom 0.3.2", + "rand 0.9.0", "ring", "rustc-hash 2.1.1", "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.11", + "thiserror 2.0.12", "tinyvec", "tracing", "web-time", @@ -3000,18 +3178,24 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -3030,8 +3214,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.1", - "zerocopy 0.8.20", + "rand_core 0.9.3", + "zerocopy", ] [[package]] @@ -3051,7 +3235,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.1", + "rand_core 0.9.3", ] [[package]] @@ -3065,12 +3249,11 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88e0da7a2c97baa202165137c158d0a2e824ac465d13d81046727b34cb247d3" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.1", - "zerocopy 0.8.20", + "getrandom 0.3.2", ] [[package]] @@ -3088,7 +3271,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "502927fdfc3c9645d53e0c95bb2d53783b5a15bfeaeeb96f7703c21fbb76841e" dependencies = [ - "rand_core 0.9.1", + "rand_core 0.9.3", ] [[package]] @@ -3097,7 +3280,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "cassowary", "compact_str", "crossterm", @@ -3147,11 +3330,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", ] [[package]] @@ -3162,8 +3345,17 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -3174,9 +3366,15 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.5" @@ -3185,9 +3383,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e327e510263980e231de548a33e63d34962d29ae61b467389a1a09627a254" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "base64", "bytes", @@ -3195,7 +3393,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "hickory-resolver", + "hickory-resolver 0.24.4", "http", "http-body", "http-body-util", @@ -3230,12 +3428,11 @@ dependencies = [ [[package]] name = "resolv-conf" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +checksum = "48375394603e3dd4b2d64371f7148fd8c7baa2680e28741f2cb8d23b59e3d4c4" dependencies = [ "hostname", - "quick-error", ] [[package]] @@ -3250,9 +3447,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.10" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34b5020fcdea098ef7d95e9f89ec15952123a4a039badd09fabebe9e963e839" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", @@ -3264,9 +3461,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" dependencies = [ "const-oid", "digest", @@ -3291,7 +3488,7 @@ checksum = "c4816b748109d26daa30e72d231a3a6e42f9e2fffe6c08cbfed63113db0ce884" dependencies = [ "aes", "aes-gcm", - "bitflags 2.8.0", + "bitflags 2.9.0", "block-padding", "byteorder", "bytes", @@ -3414,7 +3611,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys", @@ -3423,9 +3620,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.23" +version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ "aws-lc-rs", "log", @@ -3458,7 +3655,7 @@ dependencies = [ "rcgen", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.12", "webpki-roots", "x509-parser", ] @@ -3495,9 +3692,9 @@ dependencies = [ [[package]] name = "rustls-platform-verifier" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e012c45844a1790332c9386ed4ca3a06def221092eda277e6f079728f8ea99da" +checksum = "4a5467026f437b4cb2a533865eaa73eb840019a0916f4b9ec563c6e617e086c9" dependencies = [ "core-foundation", "core-foundation-sys", @@ -3511,7 +3708,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3522,9 +3719,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" dependencies = [ "aws-lc-rs", "ring", @@ -3534,9 +3731,9 @@ dependencies = [ [[package]] name = "rustrict" -version = "0.7.33" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a566beb65e3d86654ff5cc7091d947589ef06f4bc6ba946455c2851ab1193914" +checksum = "c70a914735778db9d814414e2e7a94f56b811550a9219994d799f427b201d777" dependencies = [ "arrayvec", "bitflags 1.3.2", @@ -3551,15 +3748,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "salsa20" @@ -3595,7 +3792,7 @@ dependencies = [ "enumflags2", "env_logger", "futures-util", - "hickory-resolver", + "hickory-resolver 0.25.1", "http", "http-body-util", "human_bytes", @@ -3621,13 +3818,14 @@ dependencies = [ "russh", "rustls", "rustls-acme", + "rustls-pki-types", "rustls-platform-verifier", "rustls-webpki", "rustrict", "serde", "serde_json", "sysinfo", - "thiserror 2.0.11", + "thiserror 2.0.12", "tokio", "tokio-rustls", "tokio-stream", @@ -3647,6 +3845,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -3684,7 +3888,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", "core-foundation", "core-foundation-sys", "libc", @@ -3703,24 +3907,24 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "serde" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -3729,9 +3933,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.139" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -3741,9 +3945,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" +checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" dependencies = [ "itoa", "serde", @@ -3783,6 +3987,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -3959,9 +4172,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.98" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -4002,6 +4215,12 @@ dependencies = [ "windows 0.57.0", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "termtree" version = "0.5.1" @@ -4019,11 +4238,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.11", + "thiserror-impl 2.0.12", ] [[package]] @@ -4039,20 +4258,30 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" -version = "0.3.37" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618" dependencies = [ "deranged", "itoa", @@ -4065,15 +4294,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.19" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04" dependencies = [ "num-conv", "time-core", @@ -4091,9 +4320,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" dependencies = [ "tinyvec_macros", ] @@ -4106,9 +4335,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.43.0" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ "backtrace", "bytes", @@ -4135,9 +4364,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ "rustls", "tokio", @@ -4168,9 +4397,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" dependencies = [ "bytes", "futures-core", @@ -4237,6 +4466,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -4254,15 +4513,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "tui-term" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72af159125ce32b02ceaced6cffae6394b0e6b6dfd4dc164a6c59a2db9b3c0b0" -dependencies = [ - "ratatui", -] - [[package]] name = "tungstenite" version = "0.26.2" @@ -4276,7 +4526,7 @@ dependencies = [ "log", "rand 0.9.0", "sha1", - "thiserror 2.0.11", + "thiserror 2.0.12", "utf-8", ] @@ -4288,9 +4538,9 @@ checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-normalization" @@ -4387,6 +4637,21 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +dependencies = [ + "getrandom 0.3.2", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "vcpkg" version = "0.2.15" @@ -4407,8 +4672,6 @@ checksum = "298aca8af9c2d1395da31a65eb711abef2dc948e475e819212c8ed5008d52c9f" dependencies = [ "itoa", "log", - "ratatui", - "tui-term", "unicode-width 0.2.0", "vte", ] @@ -4461,9 +4724,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] @@ -4591,9 +4854,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" +checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" [[package]] name = "winapi" @@ -4626,6 +4889,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows" version = "0.57.0" @@ -4726,9 +4999,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-registry" @@ -4736,7 +5009,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ - "windows-result 0.3.1", + "windows-result 0.3.2", "windows-strings 0.3.1", "windows-targets 0.53.0", ] @@ -4761,9 +5034,9 @@ dependencies = [ [[package]] name = "windows-result" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" dependencies = [ "windows-link", ] @@ -5077,11 +5350,11 @@ dependencies = [ [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.9.0", ] [[package]] @@ -5148,39 +5421,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde3bb8c68a8f3f1ed4ac9221aad6b10cece3e60a8e2ea54a6a2dec806d0084c" -dependencies = [ - "zerocopy-derive 0.8.20", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ - "proc-macro2", - "quote", - "syn", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.20" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea57037071898bf96a6da35fd626f4f27e9cee3ead2a6c703cf09d472b2e700" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", @@ -5189,18 +5441,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 4cad377..6a5b392 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,27 +9,30 @@ homepage = "https://sandhole.eric.dev.br/" license = "MIT" authors = ["Eric Rodrigues Pires "] readme = "README.md" -keywords = ["ssh", "proxy", "tunnel", "hole-punching"] +keywords = ["ssh", "proxy", "reverse-proxy", "tunnel", "hole-punching"] categories = ["network-programming", "web-programming", "authentication"] exclude = [".github", "book", "docker-compose-example", "tests/data"] [dependencies] -anyhow = "1.0.96" +anyhow = "1.0.97" aws-lc-rs = "1.12.6" axum = { version = "0.8.1", default-features = false } block-id = "0.2.1" -bytes = "1.10.0" +bytes = "1.10.1" chrono = "0.4.39" -clap = { version = "4.5.30", features = ["derive", "string"] } -crossterm = "0.28.1" +clap = { version = "4.5.32", features = ["derive", "string"] } +crossterm = { version = "0.28.1", default-features = false } dashmap = "6.1.0" enumflags2 = "0.7.11" -env_logger = "0.11.6" -hickory-resolver = "0.24.4" -http = "1.2.0" -http-body-util = "0.1.2" +env_logger = { version = "0.11.7", default-features = false, features = [ + "auto-color", + "humantime", +] } +hickory-resolver = "0.25.1" +http = "1.3.1" +http-body-util = "0.1.3" human_bytes = { version = "0.4.3", default-features = false } -humantime = "2.1.0" +humantime = "2.2.0" hyper = { version = "1.6.0", features = ["full"] } hyper-util = { version = "0.1.10", features = ["full"] } ipnet = "2.11.0" @@ -39,10 +42,17 @@ log = "0.4.26" notify = "8.0.0" openssl = { version = "0.10.71", features = ["vendored"] } pretty-duration = "0.1.1" -rand = "0.9.0" +rand = { version = "0.9.0", default-features = false, features = [ + "std", + "std_rng", + "os_rng", + "thread_rng", +] } rand_chacha = "0.9.0" rand_seeder = "0.4.0" -ratatui = "0.29.0" +ratatui = { version = "0.29.0", default-features = false, features = [ + "crossterm", +] } reqwest = { version = "0.12.14", default-features = false, features = [ "charset", "http2", @@ -51,31 +61,41 @@ reqwest = { version = "0.12.14", default-features = false, features = [ "rustls-tls-manual-roots", ] } russh = "0.51.1" -rustls = "0.23.16" +rustls = "0.23.25" rustls-acme = "0.13.0" -rustls-platform-verifier = "0.5.0" -rustls-webpki = "0.102.8" -rustrict = { version = "0.7.33", features = ["customize"] } -serde = "1.0.218" -serde_json = "1.0.139" +rustls-pki-types = "1.11.0" +rustls-platform-verifier = "0.5.1" +rustls-webpki = "0.103.0" +rustrict = { version = "0.7.34", features = ["customize"] } +serde = "1.0.219" +serde_json = "1.0.140" sysinfo = "0.33.1" -thiserror = "2.0.11" -tokio = { version = "1.43.0", features = ["full"] } -tokio-rustls = "0.26.1" +thiserror = "2.0.12" +tokio = { version = "1.44.1", features = ["full"] } +tokio-rustls = "0.26.2" tokio-stream = "0.1.17" -tokio-util = "0.7.13" +tokio-util = "0.7.14" trie-rs = "0.4.2" [dev-dependencies] axum = { version = "0.8.1", features = ["macros", "ws"] } -futures-util = "0.3.31" -insta = { version = "1.42.1", features = ["yaml"] } +futures-util = { version = "0.3.31", default-features = false, features = [ + "std", +] } +insta = { version = "1.42.2", features = ["yaml"] } mockall = "0.13.1" nix = "0.29.0" regex = "1.11.1" tokio-tungstenite = "0.26.2" tower = "0.5.2" -vt100-ctt = "0.16.0" +vt100-ctt = { version = "0.16.0", default-features = false } + +[profile.release] +strip = true +lto = true [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage_nightly)'] } + +[package.metadata.cargo-udeps.ignore] +normal = ["openssl"] diff --git a/README.md b/README.md index abd6cd6..c741a8e 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,12 @@ Expose HTTP/SSH/TCP services through SSH port forwarding. A self-hosted ngrok / ## Features - Reverse proxy that just works with an OpenSSH client. No extra software required! -- Automatic HTTPS support (with [dnsrobocert](https://github.com/adferrand/dnsrobocert) and/or ACME). +- Automatic HTTPS support (with [dnsrobocert](https://github.com/adferrand/dnsrobocert) and/or ACME), including HTTP/2. - Easily load-balance by pointing multiple services to the same domain/port. - Bring your own custom domains and authorize them via DNS records. - Random subdomain assignment by default, with options for deterministic assignment. - Option to connect with SSH via the HTTPS port, if your network blocks outbound connections to SSH ports. -- A terminal-based admin interface to view current connections. +- A terminal-based admin interface to view and manage current connections. - Written in Rust, with comprehensive testing of most features. ## Status diff --git a/book/src/admin_interface.md b/book/src/admin_interface.md index f9fbf76..cb73bd6 100644 --- a/book/src/admin_interface.md +++ b/book/src/admin_interface.md @@ -5,7 +5,7 @@ Sandhole comes with a command-line admin interface available through SSH, which To access it, simply run the command: ```bash -ssh -t sandhole.com -p 2222 admin +ssh -p 2222 -t sandhole.com admin ``` where `sandhole.com` is your hostname and `2222` is Sandhole's SSH port. diff --git a/book/src/advanced_uses.md b/book/src/advanced_uses.md index 4fa9b07..9bf23ec 100644 --- a/book/src/advanced_uses.md +++ b/book/src/advanced_uses.md @@ -34,7 +34,7 @@ If you need to use multiple keys for the same domain, simply add a TXT record fo Then, expose your service at the given domain: ```bash -ssh -R my.domain.net:80:localhost:3000 sandhole.com -p 2222 +ssh -p 2222 -R my.domain.net:80:localhost:3000 sandhole.com ``` ### HTTPS support diff --git a/book/src/exposing_your_first_service.md b/book/src/exposing_your_first_service.md index 01d63f7..e2e02fc 100644 --- a/book/src/exposing_your_first_service.md +++ b/book/src/exposing_your_first_service.md @@ -3,7 +3,7 @@ Once you have [an authorized public key](./configuration.md#adding-users-and-admins) in Sandhole, you can expose a local service. Assuming that your local HTTP service is running on port 3000, and that Sandhole is listening on `sandhole.com:2222`, all you have to do is run ```bash -ssh -i /your/private/key -R 80:localhost:3000 sandhole.com -p 2222 +ssh -i /your/private/key -p 2222 -R 80:localhost:3000 sandhole.com ``` Yep, that's it! Sandhole will log that HTTP is being served for you on a certain subdomain, and you can access the URL printed to the console to see that your service is available to the public. @@ -13,7 +13,7 @@ Yep, that's it! Sandhole will log that HTTP is being served for you on a certain You can request tunnels for several services in a single SSH command. ```bash -ssh -i /your/private/key -R 80:localhost:3000 -R 80:localhost:4000 -R 22:localhost:5000 sandhole.com -p 2222 +ssh -i /your/private/key -p 2222 -R 80:localhost:3000 -R 80:localhost:4000 -R 22:localhost:5000 sandhole.com ``` ## Requesting a particular subdomain/port @@ -23,17 +23,17 @@ After the server owner [allows binding on any subdomain/port](configuration.md#a For example, to bind under `test.sandhole.com`, we could use either of these commands: ```bash -ssh -i /your/private/key -R test:80:localhost:3000 sandhole.com -p 2222 +ssh -i /your/private/key -p 2222 -R test:80:localhost:3000 sandhole.com # -- OR -- -ssh -i /your/private/key -R test.sandhole.com:80:localhost:3000 sandhole.com -p 2222 +ssh -i /your/private/key -p 2222 -R test.sandhole.com:80:localhost:3000 sandhole.com ``` And if we'd like to bind to a specific port, say 4321: ```bash -ssh -i /your/private/key -R 4321:localhost:3000 sandhole.com -p 2222 +ssh -i /your/private/key -p 2222 -R 4321:localhost:3000 sandhole.com # -- OR -- -ssh -i /your/private/key -R localhost:4321:localhost:3000 sandhole.com -p 2222 +ssh -i /your/private/key -p 2222 -R localhost:4321:localhost:3000 sandhole.com ``` ## Connecting with user + password @@ -41,7 +41,7 @@ ssh -i /your/private/key -R localhost:4321:localhost:3000 sandhole.com -p 2222 If you'd like to connect with a password instead of your public key, make sure that [password authentication](./configuration.md#alternative-authentication-with-password) has been enabled by the administrator, then run: ```bash -ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password username@sandhole.com -p 2222 ... +ssh -p 2222 -o PubkeyAuthentication=no -o PreferredAuthentications=password username@sandhole.com ... ``` ## Automatic reconnection diff --git a/book/src/faq.md b/book/src/faq.md index 750a4a4..513faf6 100644 --- a/book/src/faq.md +++ b/book/src/faq.md @@ -3,14 +3,14 @@ ## How do I expose my service on multiple URLs (for example, `website.com` and `www.website.com`)? ```bash -ssh -R website.com:80:localhost:3000 -R www.website.com:80:localhost:3000 sandhole.com -p 2222 +ssh -p 2222 -R website.com:80:localhost:3000 -R www.website.com:80:localhost:3000 sandhole.com ``` See also ["Advanced uses"](./advanced_uses.md#custom-domains) on how to add custom domains. ## How do I connect to a forwarded SSH server? -Use `ssh -J sandhole.com:2222 mysshserver.com -p 2222` (replace the ports with Sandhole's SSH port if not using the default `2222`). +Use `ssh -p 2222 -J sandhole.com:2222 mysshserver.com ` (replace the ports with Sandhole's SSH port if not using the default `2222`). If you'd like to avoid typing out the proxy jump command every time, make sure to edit your SSH config file (usually `~/.ssh/config`) and add the following entry (changing the port where appropriate): @@ -37,7 +37,7 @@ With the `--load-balancing=deny` or `--load-balancing=replace` [CLI flag](./cli. You may do so globally with the `--force-https` [CLI flag](./cli.md), or per service by passing `force-https` on the tunneling connection(s): ```bash -ssh -R website.com:443:localhost:3000 sandhole.com -p 2222 force-https +ssh -p -R website.com:443:localhost:3000 sandhole.com 2222 force-https ``` ## How do I allow/block certain IP ranges? @@ -45,7 +45,7 @@ ssh -R website.com:443:localhost:3000 sandhole.com -p 2222 force-https You may do so globally with the `--ip-allowlist` and `--ip-blocklist` [CLI flags](./cli.md) respectively, or per service by passing `ip-allowist=...` and/or `ip-blocklist=...` on the tunneling connection(s): ```bash -ssh -R website.com:80:localhost:3000 sandhole.com -p 2222 ip-allowlist=10.0.0.0/8 ip-blocklist=10.1.0.0/16 +ssh -p 2222 -R website.com:80:localhost:3000 sandhole.com ip-allowlist=10.0.0.0/8 ip-blocklist=10.1.0.0/16 ``` ## How do I run the Docker container without mounting root certificates from the host? diff --git a/book/src/local_forwarding.md b/book/src/local_forwarding.md index 5cc508d..9a055b3 100644 --- a/book/src/local_forwarding.md +++ b/book/src/local_forwarding.md @@ -5,7 +5,7 @@ In addition to remote port forwarding, Sandhole also supports local port forward Given a remote service running as: ```bash -ssh -R my.tunnel:3000:localhost:2000 sandhole.com -p 2222 +ssh -p 2222 -R my.tunnel:3000:localhost:2000 sandhole.com ``` Note that the server won't listen on port 3000; the service will instead alias to `my.tunnel`. You can establish a local forward to the port from your machine: @@ -23,7 +23,7 @@ Aliasing is always enabled for SSH hosts, and is conditionally enabled for TCP h To enable aliasing for HTTP hosts, pass either the `tcp-alias` command to the remote forwarding command as follows: ```bash -ssh -R my.tunnel:80:localhost:8080 sandhole.com -p 2222 tcp-alias +ssh -p 2222 -R my.tunnel:80:localhost:8080 sandhole.com tcp-alias ``` ## Restricting access to local forwardings @@ -31,7 +31,7 @@ ssh -R my.tunnel:80:localhost:8080 sandhole.com -p 2222 tcp-alias If you'd like to restrict which users can access your service, you can provide the allowed fingerprints as a comma-separated list at the end of the command, like so: ```bash -ssh -R my.tunnel:3000:localhost:2000 sandhole.com -p 2222 allowed-fingerprints=SHA256:GehKyA21BBK6eJCouziacUmqYDNl8BPMGG0CTtLSrbQ,SHA256:bwf4FDtNeZzFv8xHBzHJwRpDRxssCll8w2tCHFC9n1o +ssh -p 2222 -R my.tunnel:3000:localhost:2000 sandhole.com allowed-fingerprints=SHA256:GehKyA21BBK6eJCouziacUmqYDNl8BPMGG0CTtLSrbQ,SHA256:bwf4FDtNeZzFv8xHBzHJwRpDRxssCll8w2tCHFC9n1o ``` These fingerprints may belong to keys unrecognized by Sandhole, and they'll still be able to connect to your tunnel. diff --git a/docker-compose-example/client/compose.yml b/docker-compose-example/client/compose.yml index ddd5103..c209dfc 100644 --- a/docker-compose-example/client/compose.yml +++ b/docker-compose-example/client/compose.yml @@ -24,8 +24,8 @@ services: # Make sure to change at least the Sandhole domain below command: | -i /secret/id_ed25519 + -p 2222 -o StrictHostKeyChecking=accept-new -o ServerAliveInterval=30 -R example:80:nginx:80 - -p 2222 sandhole.com diff --git a/src/addressing.rs b/src/addressing.rs index 039feb3..aa81ad2 100644 --- a/src/addressing.rs +++ b/src/addressing.rs @@ -1,7 +1,7 @@ use std::{hash::Hash, net::SocketAddr, num::NonZero, sync::Mutex}; use block_id::{Alphabet, BlockId}; -use hickory_resolver::{TokioAsyncResolver, proto::rr::RecordType}; +use hickory_resolver::{TokioResolver, proto::rr::RecordType}; use itertools::Itertools; use log::{debug, warn}; #[cfg(test)] @@ -10,13 +10,13 @@ use rand::{self, Rng, SeedableRng, seq::IndexedRandom}; use rand_chacha::ChaCha20Rng; use rand_seeder::SipHasher; use russh::keys::ssh_key::Fingerprint; +use rustls_pki_types::DnsName; use rustrict::{Censor, CensorStr, Type}; -use webpki::types::DnsName; use crate::config::{BindHostnames, RandomSubdomainSeed}; // Struct wrapping a DNS async resolver. -pub(crate) struct DnsResolver(TokioAsyncResolver); +pub(crate) struct DnsResolver(TokioResolver); // Trait for DNS record verification. #[cfg_attr(test, automock)] @@ -35,10 +35,11 @@ pub(crate) trait Resolver { impl DnsResolver { pub(crate) fn new() -> Self { - DnsResolver(TokioAsyncResolver::tokio( - Default::default(), - Default::default(), - )) + DnsResolver( + TokioResolver::builder_tokio() + .expect("failed to create DNS resolver") + .build(), + ) } } @@ -372,7 +373,7 @@ mod address_delegator_tests { use rand_chacha::ChaCha20Rng; use regex::Regex; use russh::keys::{HashAlg, ssh_key::private::Ed25519Keypair}; - use webpki::types::DnsName; + use rustls_pki_types::DnsName; use crate::config::{BindHostnames, RandomSubdomainSeed}; @@ -477,7 +478,7 @@ mod address_delegator_tests { #[tokio::test] async fn returns_provided_address_if_cname_matches_fingerprint() { let fingerprint = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )) .fingerprint(HashAlg::Sha256); let mut mock = MockResolver::new(); @@ -517,7 +518,7 @@ mod address_delegator_tests { #[tokio::test] async fn returns_provided_address_if_txt_record_matches_fingerprint() { let fingerprint = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )) .fingerprint(HashAlg::Sha256); let mut mock = MockResolver::new(); @@ -587,7 +588,7 @@ mod address_delegator_tests { #[tokio::test] async fn returns_subdomain_if_no_txt_record_matches_fingerprint() { let fingerprint = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )) .fingerprint(HashAlg::Sha256); let mut mock = MockResolver::new(); @@ -655,7 +656,7 @@ mod address_delegator_tests { #[tokio::test] async fn returns_host_domain_if_address_equals_host_domain_and_has_fingerprint() { let fingerprint = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )) .fingerprint(HashAlg::Sha256); let mut mock = MockResolver::new(); @@ -692,7 +693,7 @@ mod address_delegator_tests { #[tokio::test] async fn returns_random_subdomain_if_address_equals_host_domain_and_doesnt_have_fingerprint() { let fingerprint = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )) .fingerprint(HashAlg::Sha256); let mut mock = MockResolver::new(); @@ -735,7 +736,7 @@ mod address_delegator_tests { #[tokio::test] async fn returns_random_subdomain_if_requested_address_is_not_direct_subdomain() { let fingerprint = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )) .fingerprint(HashAlg::Sha256); let mut mock = MockResolver::new(); @@ -778,7 +779,7 @@ mod address_delegator_tests { #[tokio::test] async fn returns_random_subdomain_if_invalid_address() { let fingerprint = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )) .fingerprint(HashAlg::Sha256); let mut mock = MockResolver::new(); @@ -819,7 +820,7 @@ mod address_delegator_tests { #[tokio::test] async fn returns_unique_random_subdomains_if_forced() { let fingerprint = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )) .fingerprint(HashAlg::Sha256); let mut mock = MockResolver::new(); @@ -869,7 +870,7 @@ mod address_delegator_tests { #[tokio::test] async fn returns_unique_random_subdomains_with_different_size_and_no_profanities() { let fingerprint = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )) .fingerprint(HashAlg::Sha256); let mut mock = MockResolver::new(); @@ -1036,11 +1037,11 @@ mod address_delegator_tests { #[tokio::test] async fn returns_unique_random_subdomains_per_fingerprint_user_and_address_if_forced() { let f1: russh::keys::ssh_key::Fingerprint = russh::keys::PrivateKey::from( - Ed25519Keypair::from_seed(&ChaCha20Rng::try_from_os_rng().unwrap().random()), + Ed25519Keypair::from_seed(&ChaCha20Rng::from_os_rng().random()), ) .fingerprint(HashAlg::Sha256); let f2 = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )) .fingerprint(HashAlg::Sha256); let mut mock = MockResolver::new(); diff --git a/src/certificates.rs b/src/certificates.rs index d6b3b3f..0e6615e 100644 --- a/src/certificates.rs +++ b/src/certificates.rs @@ -18,9 +18,10 @@ use rustls::{ server::{ClientHello, ParsedCertificate, ResolvesServerCert}, sign::CertifiedKey, }; +use rustls_pki_types::CertificateDer; use tokio::{fs::read_dir, sync::oneshot}; use trie_rs::map::{Trie, TrieBuilder}; -use webpki::{EndEntityCert, types::CertificateDer}; +use webpki::EndEntityCert; #[derive(Debug)] pub(crate) struct DummyAlpnChallengeResolver; diff --git a/src/config.rs b/src/config.rs index d62bbb8..ea5919a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -8,7 +8,7 @@ use std::{ use clap::{Parser, ValueEnum, command}; use ipnet::IpNet; -use webpki::types::DnsName; +use rustls_pki_types::DnsName; // Which value to seed with when generating random subdomains, for determinism. // This allows binding to the same random address until Sandhole is restarted. diff --git a/src/lib.rs b/src/lib.rs index 258530c..0c46716 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -200,7 +200,7 @@ pub async fn entrypoint(config: ApplicationConfig) -> anyhow::Result<()> { Err(err) if err.kind() == std::io::ErrorKind::NotFound => { info!("Key file not found. Creating..."); let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); if !config.disable_directory_creation { fs::create_dir_all( diff --git a/src/login.rs b/src/login.rs index 5bf244f..6a5a239 100644 --- a/src/login.rs +++ b/src/login.rs @@ -122,10 +122,10 @@ mod api_login_tests { use hyper::{body::Incoming, service::service_fn}; use hyper_util::rt::{TokioExecutor, TokioIo}; use rustls::{ClientConfig, RootCertStore, ServerConfig}; + use rustls_pki_types::{CertificateDer, PrivateKeyDer, pem::PemObject}; use tokio::{io::AsyncReadExt, net::TcpListener}; use tokio_rustls::TlsAcceptor; use tower::Service; - use webpki::types::{CertificateDer, PrivateKeyDer, pem::PemObject}; use super::{ApiLogin, AuthenticationRequest, MockConfigurer}; diff --git a/src/quota.rs b/src/quota.rs index 54ff26a..e4c582b 100644 --- a/src/quota.rs +++ b/src/quota.rs @@ -161,7 +161,7 @@ mod quota_map_tests { #[test] fn returns_unlimited_tokens_for_admin_holder() { let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let map = Arc::new(QuotaMap::new(3.try_into().unwrap())); let mut tokens = Vec::with_capacity(5); @@ -178,7 +178,7 @@ mod quota_map_tests { #[test] fn returns_tokens_for_different_holders() { let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let fingerprint = key.fingerprint(HashAlg::Sha256); let user_a = UserIdentification::Username("a".into()); diff --git a/tests/alias_aliasing_tunnel.rs b/tests/alias_aliasing_tunnel.rs index ef81254..2a0ac52 100644 --- a/tests/alias_aliasing_tunnel.rs +++ b/tests/alias_aliasing_tunnel.rs @@ -98,7 +98,7 @@ async fn alias_aliasing_tunnel() { // 3. Establish a tunnel via aliasing let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut client_session = diff --git a/tests/alias_local_forward_existing_http.rs b/tests/alias_local_forward_existing_http.rs index 5127b03..53c3725 100644 --- a/tests/alias_local_forward_existing_http.rs +++ b/tests/alias_local_forward_existing_http.rs @@ -102,7 +102,7 @@ async fn alias_local_forward_existing_http() { // 3. Local-forward instead of connecting directly let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) diff --git a/tests/alias_require_allowed_fingerprints.rs b/tests/alias_require_allowed_fingerprints.rs index 18198f1..a3bb7a3 100644 --- a/tests/alias_require_allowed_fingerprints.rs +++ b/tests/alias_require_allowed_fingerprints.rs @@ -151,7 +151,7 @@ async fn alias_require_allowed_fingerprints() { // 3b. Try to local-forward with invalid key let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) diff --git a/tests/alias_timeout.rs b/tests/alias_timeout.rs index bbb3501..a001bf4 100644 --- a/tests/alias_timeout.rs +++ b/tests/alias_timeout.rs @@ -110,7 +110,7 @@ async fn alias_timeout() { // 3. Start anonymous SSH client that will forward the proxies via aliasing let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut client_session = diff --git a/tests/auth_prevent_unauthorized_actions.rs b/tests/auth_prevent_unauthorized_actions.rs index 3b36159..3321988 100644 --- a/tests/auth_prevent_unauthorized_actions.rs +++ b/tests/auth_prevent_unauthorized_actions.rs @@ -100,7 +100,7 @@ async fn auth_prevent_unauthorized_actions() { // 3a. Try to port forward without credentials let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) @@ -128,7 +128,7 @@ async fn auth_prevent_unauthorized_actions() { // 3b. Try to close port forward without credentials let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) @@ -159,7 +159,7 @@ async fn auth_prevent_unauthorized_actions() { // 3c. Try to local-forward with an inexistent alias let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) @@ -190,7 +190,7 @@ async fn auth_prevent_unauthorized_actions() { // 3d. Try to open multiple sessions without credentials let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) @@ -223,7 +223,7 @@ async fn auth_prevent_unauthorized_actions() { // 3e. Local-forward with HTTP proxy, then try to port forward let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) @@ -262,7 +262,7 @@ async fn auth_prevent_unauthorized_actions() { // 3f. Local-forward with TCP proxy, then try to port forward let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) @@ -304,7 +304,7 @@ async fn auth_prevent_unauthorized_actions() { // 3g. Try to idle longer than the idle_connection_timeout configuration let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) @@ -336,7 +336,7 @@ async fn auth_prevent_unauthorized_actions() { // 3h. Local-forward, then idle let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) diff --git a/tests/config_disable_aliasing.rs b/tests/config_disable_aliasing.rs index 4a8de0b..f77e31c 100644 --- a/tests/config_disable_aliasing.rs +++ b/tests/config_disable_aliasing.rs @@ -187,7 +187,7 @@ async fn config_disable_aliasing() { // 4. Reject anonymous users if aliasing is disabled let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClientTwo; let mut session_three = diff --git a/tests/ssh_proxy_jump.rs b/tests/ssh_proxy_jump.rs index bb6e947..673dd51 100644 --- a/tests/ssh_proxy_jump.rs +++ b/tests/ssh_proxy_jump.rs @@ -102,7 +102,7 @@ async fn ssh_proxy_jump() { // 3. Connect to the SSH port of our proxy with anonymous user let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = ProxyClient; let mut session_two = client::connect(Default::default(), "127.0.0.1:18022", ssh_client) @@ -264,7 +264,7 @@ impl client::Handler for SshClient { let session = match server::run_stream( Arc::new(server::Config { keys: vec![russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), ))], ..Default::default() }), diff --git a/tests/tcp_allow_requested_ports.rs b/tests/tcp_allow_requested_ports.rs index 10f298e..4673bd8 100644 --- a/tests/tcp_allow_requested_ports.rs +++ b/tests/tcp_allow_requested_ports.rs @@ -103,7 +103,7 @@ async fn tcp_allow_requested_ports() { // 4. Local-forward the TCP port for random user let key = russh::keys::PrivateKey::from(Ed25519Keypair::from_seed( - &ChaCha20Rng::try_from_os_rng().unwrap().random(), + &ChaCha20Rng::from_os_rng().random(), )); let ssh_client = SshClient; let mut session_two = russh::client::connect(Default::default(), "127.0.0.1:18022", ssh_client) -- 2.51.2