From cf53a9d84a03623b2830bc01c4441746e232d8b2 Mon Sep 17 00:00:00 2001 From: yxrxy <1532529704@qq.com> Date: Fri, 2 Jan 2026 11:08:28 +0800 Subject: [PATCH] chore: replace native-tls with pure rustls for FTPS/SFTP e2e tests (#1334) Signed-off-by: yxrxy <1532529704@qq.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Cargo.lock | 389 ++++-------------- Cargo.toml | 9 +- crates/config/src/constants/mod.rs | 1 + crates/config/src/constants/protocols.rs | 40 ++ crates/config/src/lib.rs | 2 + crates/e2e_test/Cargo.toml | 2 - crates/e2e_test/src/protocols/ftps_core.rs | 50 ++- .../ecstore/src/cache_value/metacache_set.rs | 1 - docs/ENVIRONMENT_VARIABLES.md | 84 ++++ rustfs/Cargo.toml | 3 +- rustfs/src/config/mod.rs | 41 -- rustfs/src/init.rs | 46 ++- rustfs/src/main.rs | 8 +- rustfs/src/protocols/README.md | 58 ++- rustfs/src/protocols/gateway/adapter.rs | 6 +- rustfs/src/protocols/sftp/server.rs | 3 +- 16 files changed, 299 insertions(+), 444 deletions(-) create mode 100644 crates/config/src/constants/protocols.rs diff --git a/Cargo.lock b/Cargo.lock index 73fe7347..ce051409 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -563,17 +563,6 @@ dependencies = [ "xattr", ] -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - [[package]] name = "async-channel" version = "2.5.0" @@ -604,60 +593,13 @@ dependencies = [ "zstd-safe", ] -[[package]] -name = "async-executor" -version = "1.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.5.0", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "async-io" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" -dependencies = [ - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix 1.1.3", - "slab", - "windows-sys 0.61.2", -] - [[package]] name = "async-lock" version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ - "event-listener 5.4.1", + "event-listener", "event-listener-strategy", "pin-project-lite", ] @@ -673,32 +615,6 @@ dependencies = [ "syn 2.0.112", ] -[[package]] -name = "async-std" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" -dependencies = [ - "async-channel 1.9.0", - "async-global-executor", - "async-io", - "async-lock", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - [[package]] name = "async-stream" version = "0.3.6" @@ -721,12 +637,6 @@ dependencies = [ "syn 2.0.112", ] -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - [[package]] name = "async-trait" version = "0.1.89" @@ -1433,19 +1343,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "blocking" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" -dependencies = [ - "async-channel 2.5.0", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - [[package]] name = "blowfish" version = "0.9.1" @@ -2248,12 +2145,27 @@ dependencies = [ "cpufeatures", "curve25519-dalek-derive", "digest 0.10.7", - "fiat-crypto", + "fiat-crypto 0.2.9", "rustc_version", "subtle", "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "5.0.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d8cfa313d59919eda35b420bd37db85bf58d6754d6f128b9949932b0c0fcce7" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.11.0-rc.4", + "fiat-crypto 0.3.0", + "rustc_version", + "subtle", +] + [[package]] name = "curve25519-dalek-derive" version = "0.1.1" @@ -3362,7 +3274,6 @@ dependencies = [ "flatbuffers", "futures", "md5 0.8.0", - "native-tls", "rand 0.10.0-rc.5", "rcgen", "reqwest", @@ -3379,7 +3290,6 @@ dependencies = [ "serde", "serde_json", "serial_test", - "ssh2", "suppaftp", "tokio", "tonic", @@ -3425,14 +3335,23 @@ dependencies = [ "signature 2.2.0", ] +[[package]] +name = "ed25519" +version = "3.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "594435fe09e345ee388e4e8422072ff7dfeca8729389fbd997b3f5504c44cd47" +dependencies = [ + "signature 3.0.0-rc.5", +] + [[package]] name = "ed25519-dalek" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ - "curve25519-dalek", - "ed25519", + "curve25519-dalek 4.1.3", + "ed25519 2.2.3", "rand_core 0.6.4", "serde", "sha2 0.10.9", @@ -3440,6 +3359,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ed25519-dalek" +version = "3.0.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbef01b6e6a5f913ae480bb34ddd798ce6d358054bebf77177200ec84af61ad5" +dependencies = [ + "curve25519-dalek 5.0.0-pre.2", + "ed25519 3.0.0-rc.2", + "sha2 0.11.0-rc.3", + "subtle", +] + [[package]] name = "either" version = "1.15.0" @@ -3616,12 +3547,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - [[package]] name = "event-listener" version = "5.4.1" @@ -3639,7 +3564,7 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "event-listener 5.4.1", + "event-listener", "pin-project-lite", ] @@ -3685,6 +3610,12 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "fiat-crypto" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" + [[package]] name = "filetime" version = "0.2.26" @@ -3806,21 +3737,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.2" @@ -4067,18 +3983,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - [[package]] name = "google-cloud-auth" version = "1.3.0" @@ -4965,14 +4869,15 @@ checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" [[package]] name = "internal-russh-forked-ssh-key" -version = "0.6.11+upstream-0.6.7" +version = "0.6.16+upstream-0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a77eae781ed6a7709fb15b64862fcca13d886b07c7e2786f5ed34e5e2b9187" +checksum = "fe44f2bbd99fcb302e246e2d6bcf51aeda346d02a365f80296a07a8c711b6da6" dependencies = [ "argon2 0.5.3", "bcrypt-pbkdf", + "digest 0.11.0-rc.4", "ecdsa 0.16.9", - "ed25519-dalek", + "ed25519-dalek 2.2.0", "hex", "hmac 0.12.1", "num-bigint-dig", @@ -4980,11 +4885,13 @@ dependencies = [ "p384", "p521", "rand_core 0.6.4", - "rsa 0.9.9", + "rsa 0.10.0-rc.10", "sec1 0.7.3", "sha1 0.10.6", + "sha1 0.11.0-rc.3", "sha2 0.10.9", "signature 2.2.0", + "signature 3.0.0-rc.5", "ssh-cipher 0.2.0", "ssh-encoding 0.2.0", "subtle", @@ -5107,7 +5014,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c76e1c7d7df3e34443b3621b459b066a7b79644f059fc8b2db7070c825fd417e" dependencies = [ "base64", - "ed25519-dalek", + "ed25519-dalek 2.2.0", "getrandom 0.2.16", "hmac 0.12.1", "js-sys", @@ -5143,15 +5050,6 @@ dependencies = [ "libc", ] -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - [[package]] name = "lazy-regex" version = "3.4.2" @@ -5356,20 +5254,6 @@ dependencies = [ "redox_syscall 0.7.0", ] -[[package]] -name = "libssh2-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "220e4f05ad4a218192533b300327f5150e809b54c4ec83b5a1d91833601811b9" -dependencies = [ - "cc", - "libc", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", -] - [[package]] name = "libsystemd" version = "0.7.2" @@ -5432,18 +5316,6 @@ dependencies = [ "zlib-rs", ] -[[package]] -name = "libz-sys" -version = "1.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -5732,7 +5604,7 @@ dependencies = [ "crossbeam-epoch", "crossbeam-utils", "equivalent", - "event-listener 5.4.1", + "event-listener", "futures-util", "parking_lot", "portable-atomic", @@ -5747,23 +5619,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe 0.1.6", - "openssl-sys", - "schannel", - "security-framework 2.11.1", - "security-framework-sys", - "tempfile", -] - [[package]] name = "neli" version = "0.7.3" @@ -5949,6 +5804,7 @@ dependencies = [ "num-iter", "num-traits", "rand 0.8.5", + "serde", "smallvec", "zeroize", ] @@ -6161,56 +6017,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" -dependencies = [ - "bitflags 2.10.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.112", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - [[package]] name = "openssl-probe" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" -[[package]] -name = "openssl-sys" -version = "0.9.111" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "opentelemetry" version = "0.31.0" @@ -6724,17 +6536,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - [[package]] name = "pkcs1" version = "0.7.5" @@ -6837,20 +6638,6 @@ dependencies = [ "plotters-backend", ] -[[package]] -name = "polling" -version = "3.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix 1.1.3", - "windows-sys 0.61.2", -] - [[package]] name = "pollster" version = "0.4.0" @@ -7729,7 +7516,6 @@ dependencies = [ "pkcs1 0.7.5", "pkcs8 0.10.2", "rand_core 0.6.4", - "sha2 0.10.9", "signature 2.2.0", "spki 0.7.3", "subtle", @@ -7749,6 +7535,7 @@ dependencies = [ "pkcs1 0.8.0-rc.4", "pkcs8 0.11.0-rc.8", "rand_core 0.10.0-rc-2", + "sha2 0.11.0-rc.3", "signature 3.0.0-rc.5", "spki 0.8.0-rc.4", "subtle", @@ -7807,9 +7594,9 @@ dependencies = [ [[package]] name = "russh" -version = "0.55.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b4d036bb45d7bbe99dbfef4ec60eaeb614708d22ff107124272f8ef6b54548" +checksum = "bdbb7dcdd62c17ac911307ff693f55b3ec6712004d2d66ffdb8c0fa00269fd66" dependencies = [ "aes 0.8.4", "aws-lc-rs", @@ -7819,16 +7606,15 @@ dependencies = [ "bytes", "cbc", "ctr 0.9.2", - "curve25519-dalek", + "curve25519-dalek 4.1.3", "data-encoding", "delegate", "der 0.7.10", "digest 0.10.7", "ecdsa 0.16.9", - "ed25519-dalek", + "ed25519-dalek 2.2.0", "elliptic-curve 0.13.8", "enum_dispatch", - "flate2", "futures", "generic-array 1.3.5", "getrandom 0.2.16", @@ -7846,12 +7632,12 @@ dependencies = [ "p521", "pageant", "pbkdf2 0.12.2", - "pkcs1 0.7.5", + "pkcs1 0.8.0-rc.4", "pkcs5", "pkcs8 0.10.2", "rand 0.8.5", "rand_core 0.6.4", - "rsa 0.9.9", + "rsa 0.10.0-rc.10", "russh-cryptovec", "russh-util", "sec1 0.7.3", @@ -8002,7 +7788,7 @@ dependencies = [ "moka", "pin-project-lite", "pprof", - "rand 0.8.5", + "rand 0.10.0-rc.5", "reqwest", "rmp-serde", "russh", @@ -8198,7 +7984,7 @@ dependencies = [ name = "rustfs-ecstore" version = "0.0.5" dependencies = [ - "async-channel 2.5.0", + "async-channel", "async-recursion", "async-trait", "aws-config", @@ -8765,10 +8551,10 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ - "openssl-probe 0.2.0", + "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.5.1", + "security-framework", ] [[package]] @@ -9009,19 +8795,6 @@ dependencies = [ "hybrid-array", ] -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.10.0", - "core-foundation 0.9.4", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - [[package]] name = "security-framework" version = "3.5.1" @@ -9621,6 +9394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ad6a09263583e83e934fcd436b7e3bb9d69602e2feef3787adb615c1fe3a343" dependencies = [ "base64ct", + "crypto-bigint 0.7.0-rc.10", "digest 0.11.0-rc.4", "pem-rfc7468 1.0.0", "subtle", @@ -9633,7 +9407,9 @@ version = "0.7.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7faefb89d4a5304e31238913d1f7f164e22494276ed58cd84d5058ba7b04911f" dependencies = [ + "ed25519-dalek 3.0.0-pre.2", "rand_core 0.10.0-rc-2", + "rsa 0.10.0-rc.10", "sec1 0.8.0-rc.10", "sha2 0.11.0-rc.3", "signature 3.0.0-rc.5", @@ -9643,18 +9419,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ssh2" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f84d13b3b8a0d4e91a2629911e951db1bb8671512f5c09d7d4ba34500ba68c8" -dependencies = [ - "bitflags 2.10.0", - "libc", - "libssh2-sys", - "parking_lot", -] - [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -9754,16 +9518,17 @@ version = "7.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba8928c89e226be233f0eb1594e9bd023f72a948dc06581c0d908387f57de1de" dependencies = [ - "async-std", "async-trait", "chrono", "futures-lite", "lazy-regex", "log", - "native-tls", "pin-project", "rustls", + "rustls-pki-types", "thiserror 2.0.17", + "tokio", + "tokio-rustls", ] [[package]] @@ -10859,12 +10624,6 @@ dependencies = [ "url", ] -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index d3cc3f2f..1b8d7b82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -268,14 +268,11 @@ opentelemetry-stdout = { version = "0.31.0" } # FTP and SFTP libunftp = "0.21.0" -russh = "0.55.0" +russh = { version = "0.56.0", features = ["aws-lc-rs", "rsa"], default-features = false } russh-sftp = "2.1.1" -russh-keys = "0.49.2" -ssh-key = "0.7.0-rc.4" -ssh2 = "0.9" -suppaftp = { version = "7.0.7", features = ["async-std", "rustls", "native-tls"] } +ssh-key = { version = "0.7.0-rc.4", features = ["std", "rsa", "ed25519"] } +suppaftp = { version = "7.0.7", features = ["tokio", "tokio-rustls", "rustls"] } rcgen = "0.14.6" -native-tls = "0.2.14" # Performance Analysis and Memory Profiling mimalloc = "0.1" diff --git a/crates/config/src/constants/mod.rs b/crates/config/src/constants/mod.rs index 7f6dbff9..49fa0080 100644 --- a/crates/config/src/constants/mod.rs +++ b/crates/config/src/constants/mod.rs @@ -20,6 +20,7 @@ pub(crate) mod env; pub(crate) mod heal; pub(crate) mod object; pub(crate) mod profiler; +pub(crate) mod protocols; pub(crate) mod runtime; pub(crate) mod targets; pub(crate) mod tls; diff --git a/crates/config/src/constants/protocols.rs b/crates/config/src/constants/protocols.rs new file mode 100644 index 00000000..52881be3 --- /dev/null +++ b/crates/config/src/constants/protocols.rs @@ -0,0 +1,40 @@ +// Copyright 2024 RustFS Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Protocol server configuration constants + +/// Default FTPS server bind address +pub const DEFAULT_FTPS_ADDRESS: &str = "0.0.0.0:8021"; + +/// Default SFTP server bind address +pub const DEFAULT_SFTP_ADDRESS: &str = "0.0.0.0:8022"; + +/// Default FTPS passive ports range (optional) +pub const DEFAULT_FTPS_PASSIVE_PORTS: Option<&str> = None; + +/// Default FTPS external IP (auto-detected) +pub const DEFAULT_FTPS_EXTERNAL_IP: Option<&str> = None; + +/// Environment variable names +pub const ENV_FTPS_ENABLE: &str = "RUSTFS_FTPS_ENABLE"; +pub const ENV_FTPS_ADDRESS: &str = "RUSTFS_FTPS_ADDRESS"; +pub const ENV_FTPS_CERTS_FILE: &str = "RUSTFS_FTPS_CERTS_FILE"; +pub const ENV_FTPS_KEY_FILE: &str = "RUSTFS_FTPS_KEY_FILE"; +pub const ENV_FTPS_PASSIVE_PORTS: &str = "RUSTFS_FTPS_PASSIVE_PORTS"; +pub const ENV_FTPS_EXTERNAL_IP: &str = "RUSTFS_FTPS_EXTERNAL_IP"; + +pub const ENV_SFTP_ENABLE: &str = "RUSTFS_SFTP_ENABLE"; +pub const ENV_SFTP_ADDRESS: &str = "RUSTFS_SFTP_ADDRESS"; +pub const ENV_SFTP_HOST_KEY: &str = "RUSTFS_SFTP_HOST_KEY"; +pub const ENV_SFTP_AUTHORIZED_KEYS: &str = "RUSTFS_SFTP_AUTHORIZED_KEYS"; diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index 9d83800e..4b6d42fb 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -31,6 +31,8 @@ pub use constants::object::*; #[cfg(feature = "constants")] pub use constants::profiler::*; #[cfg(feature = "constants")] +pub use constants::protocols::*; +#[cfg(feature = "constants")] pub use constants::runtime::*; #[cfg(feature = "constants")] pub use constants::targets::*; diff --git a/crates/e2e_test/Cargo.toml b/crates/e2e_test/Cargo.toml index e1e9f41b..a25c8636 100644 --- a/crates/e2e_test/Cargo.toml +++ b/crates/e2e_test/Cargo.toml @@ -52,10 +52,8 @@ base64 = { workspace = true } rand = { workspace = true } chrono = { workspace = true } md5 = { workspace = true } -ssh2.workspace = true suppaftp.workspace = true rcgen.workspace = true anyhow.workspace = true -native-tls.workspace = true rustls.workspace = true rustls-pemfile.workspace = true \ No newline at end of file diff --git a/crates/e2e_test/src/protocols/ftps_core.rs b/crates/e2e_test/src/protocols/ftps_core.rs index 1e70d0de..5d156525 100644 --- a/crates/e2e_test/src/protocols/ftps_core.rs +++ b/crates/e2e_test/src/protocols/ftps_core.rs @@ -17,12 +17,14 @@ use crate::common::rustfs_binary_path; use crate::protocols::test_env::{DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY, ProtocolTestEnvironment}; use anyhow::Result; -use native_tls::TlsConnector; use rcgen::generate_simple_self_signed; +use rustls::crypto::aws_lc_rs::default_provider; +use rustls::{ClientConfig, RootCertStore}; use std::io::Cursor; use std::path::PathBuf; -use suppaftp::NativeTlsConnector; -use suppaftp::NativeTlsFtpStream; +use std::sync::Arc; +use suppaftp::RustlsConnector; +use suppaftp::RustlsFtpStream; use tokio::process::Command; use tracing::info; @@ -48,16 +50,11 @@ pub async fn test_ftps_core_operations() -> Result<()> { info!("Starting FTPS server on {}", FTPS_ADDRESS); let binary_path = rustfs_binary_path(); let mut server_process = Command::new(&binary_path) - .args([ - "--ftps-enable", - "--ftps-address", - FTPS_ADDRESS, - "--ftps-certs-file", - cert_path.to_str().unwrap(), - "--ftps-key-file", - key_path.to_str().unwrap(), - &env.temp_dir, - ]) + .env("RUSTFS_FTPS_ENABLE", "true") + .env("RUSTFS_FTPS_ADDRESS", FTPS_ADDRESS) + .env("RUSTFS_FTPS_CERTS_FILE", cert_path.to_str().unwrap()) + .env("RUSTFS_FTPS_KEY_FILE", key_path.to_str().unwrap()) + .arg(&env.temp_dir) .spawn()?; // Ensure server is cleaned up even on failure @@ -67,14 +64,31 @@ pub async fn test_ftps_core_operations() -> Result<()> { .await .map_err(|e| anyhow::anyhow!("{}", e))?; - // Create native TLS connector that accepts the certificate - let tls_connector = TlsConnector::builder().danger_accept_invalid_certs(true).build()?; + // Install the aws-lc-rs crypto provider + default_provider() + .install_default() + .map_err(|e| anyhow::anyhow!("Failed to install crypto provider: {:?}", e))?; - // Wrap in suppaftp's NativeTlsConnector - let tls_connector = NativeTlsConnector::from(tls_connector); + // Create a simple rustls config that accepts any certificate for testing + let mut root_store = RootCertStore::empty(); + // Add the self-signed certificate to the trust store for e2e + // Note: In a real environment, you'd use proper root certificates + let cert_pem = cert.cert.pem(); + let cert_der = rustls_pemfile::certs(&mut Cursor::new(cert_pem)) + .collect::, _>>() + .map_err(|e| anyhow::anyhow!("Failed to parse cert: {}", e))?; + + root_store.add_parsable_certificates(cert_der); + + let config = ClientConfig::builder() + .with_root_certificates(root_store) + .with_no_client_auth(); + + // Wrap in suppaftp's RustlsConnector + let tls_connector = RustlsConnector::from(Arc::new(config)); // Connect to FTPS server - let ftp_stream = NativeTlsFtpStream::connect(FTPS_ADDRESS).map_err(|e| anyhow::anyhow!("Failed to connect: {}", e))?; + let ftp_stream = RustlsFtpStream::connect(FTPS_ADDRESS).map_err(|e| anyhow::anyhow!("Failed to connect: {}", e))?; // Upgrade to secure connection let mut ftp_stream = ftp_stream diff --git a/crates/ecstore/src/cache_value/metacache_set.rs b/crates/ecstore/src/cache_value/metacache_set.rs index 88a03e23..f6b2cce4 100644 --- a/crates/ecstore/src/cache_value/metacache_set.rs +++ b/crates/ecstore/src/cache_value/metacache_set.rs @@ -310,7 +310,6 @@ pub async fn list_path_raw(rx: CancellationToken, opts: ListPathRawOptions) -> d if at_eof + has_err == readers.len() { if has_err > 0 && let Some(finished_fn) = opts.finished.as_ref() - && has_err > 0 { finished_fn(&errs).await; } diff --git a/docs/ENVIRONMENT_VARIABLES.md b/docs/ENVIRONMENT_VARIABLES.md index aee3fc4b..6dac9d74 100644 --- a/docs/ENVIRONMENT_VARIABLES.md +++ b/docs/ENVIRONMENT_VARIABLES.md @@ -108,11 +108,95 @@ export RUSTFS_ENABLE_LOCKS=false ./rustfs --address 127.0.0.1:9000 ... ``` +## Protocol Servers + +### RUSTFS_FTPS_ENABLE + +Controls whether the FTPS (FTP over TLS) server should be started. + +- **Default**: `false` +- **Valid values**: `true`, `false` +- **Description**: When enabled, starts an FTPS server for secure file transfers over TLS. + +### RUSTFS_FTPS_ADDRESS + +FTPS server bind address. + +- **Default**: `0.0.0.0:8021` +- **Valid values**: Valid IP:PORT combination +- **Description**: The address and port where the FTPS server will listen for connections. + +### RUSTFS_FTPS_CERTS_FILE + +Path to FTPS server TLS certificate file. + +- **Default**: None (required when FTPS is enabled) +- **Valid values**: Path to a PEM-encoded certificate file +- **Description**: TLS certificate used for securing FTPS connections. + +### RUSTFS_FTPS_KEY_FILE + +Path to FTPS server TLS private key file. + +- **Default**: None (required when FTPS is enabled) +- **Valid values**: Path to a PEM-encoded private key file +- **Description**: TLS private key corresponding to the certificate. + +### RUSTFS_FTPS_PASSIVE_PORTS + +Passive port range for FTPS data connections. + +- **Default**: None (system-assigned ports) +- **Valid values**: Port range in format "START-END" (e.g., "40000-50000") +- **Description**: Range of ports for FTPS passive mode data connections. + +### RUSTFS_FTPS_EXTERNAL_IP + +External IP address for FTPS passive mode. + +- **Default**: None (auto-detected) +- **Valid values**: Valid IP address +- **Description**: External IP address advertised to FTPS clients for passive mode, useful for NAT setups. + +### RUSTFS_SFTP_ENABLE + +Controls whether the SFTP (SSH File Transfer Protocol) server should be started. + +- **Default**: `false` +- **Valid values**: `true`, `false` +- **Description**: When enabled, starts an SFTP server for secure file transfers over SSH. + +### RUSTFS_SFTP_ADDRESS + +SFTP server bind address. + +- **Default**: `0.0.0.0:8022` +- **Valid values**: Valid IP:PORT combination +- **Description**: The address and port where the SFTP server will listen for connections. + +### RUSTFS_SFTP_HOST_KEY + +Path to SFTP server SSH host key file. + +- **Default**: None (required when SFTP is enabled) +- **Valid values**: Path to an SSH host key file +- **Description**: SSH host key used for server identification. + +### RUSTFS_SFTP_AUTHORIZED_KEYS + +Path to SFTP authorized keys file. + +- **Default**: None (required when SFTP is enabled) +- **Valid values**: Path to a file containing OpenSSH public keys +- **Description**: File containing authorized SSH public keys for client authentication. + ## Performance Impact - **Scanner**: Light to moderate CPU/IO impact during scans - **Heal**: Moderate to high CPU/IO impact during healing operations - **Locks**: Minimal CPU/memory overhead for coordination; disabling can improve throughput in single-client scenarios - **Memory**: Each service uses additional memory for processing queues and metadata +- **FTPS**: Moderate CPU/memory overhead for TLS operations and connection management +- **SFTP**: Moderate CPU/memory overhead for SSH operations and key management Disabling these services in resource-constrained environments can improve performance for primary storage operations. \ No newline at end of file diff --git a/rustfs/Cargo.toml b/rustfs/Cargo.toml index 2c66b696..b5109926 100644 --- a/rustfs/Cargo.toml +++ b/rustfs/Cargo.toml @@ -115,8 +115,7 @@ md5.workspace = true mime_guess = { workspace = true } moka = { workspace = true } pin-project-lite.workspace = true -# rand = "0.8" is pinned due to dependency conflicts with workspace version -rand = "0.8" +rand = { workspace = true } rust-embed = { workspace = true, features = ["interpolate-folder-path"] } s3s.workspace = true shadow-rs = { workspace = true, features = ["build", "metadata"] } diff --git a/rustfs/src/config/mod.rs b/rustfs/src/config/mod.rs index 64d15c4a..00d068ba 100644 --- a/rustfs/src/config/mod.rs +++ b/rustfs/src/config/mod.rs @@ -135,47 +135,6 @@ pub struct Opt { /// Options: GeneralPurpose, AiTraining, DataAnalytics, WebWorkload, IndustrialIoT, SecureStorage #[arg(long, default_value_t = String::from("GeneralPurpose"), env = "RUSTFS_BUFFER_PROFILE")] pub buffer_profile: String, - - /// Enable FTPS server - #[arg(long, default_value_t = false, env = "RUSTFS_FTPS_ENABLE")] - pub ftps_enable: bool, - - /// FTPS server bind address - #[arg(long, default_value_t = String::from("0.0.0.0:21"), env = "RUSTFS_FTPS_ADDRESS")] - pub ftps_address: String, - - /// FTPS server certificate file path - #[arg(long, env = "RUSTFS_FTPS_CERTS_FILE")] - pub ftps_certs_file: Option, - - /// FTPS server private key file path - #[arg(long, env = "RUSTFS_FTPS_KEY_FILE")] - pub ftps_key_file: Option, - - /// FTPS server passive ports range (e.g., "40000-50000") - #[arg(long, env = "RUSTFS_FTPS_PASSIVE_PORTS")] - pub ftps_passive_ports: Option, - - /// FTPS server external IP address for passive mode (auto-detected if not specified) - #[arg(long, env = "RUSTFS_FTPS_EXTERNAL_IP")] - pub ftps_external_ip: Option, - - /// Enable SFTP server - #[arg(long, default_value_t = false, env = "RUSTFS_SFTP_ENABLE")] - pub sftp_enable: bool, - - /// SFTP server bind address - #[arg(long, default_value_t = String::from("0.0.0.0:22"), env = "RUSTFS_SFTP_ADDRESS")] - pub sftp_address: String, - - /// SFTP server host key file path - #[arg(long, env = "RUSTFS_SFTP_HOST_KEY")] - pub sftp_host_key: Option, - - /// Path to authorized SSH public keys file for SFTP authentication - /// Each line should contain an OpenSSH public key: ssh-rsa AAAA... comment - #[arg(long, env = "RUSTFS_SFTP_AUTHORIZED_KEYS")] - pub sftp_authorized_keys: Option, } // lazy_static::lazy_static! { diff --git a/rustfs/src/init.rs b/rustfs/src/init.rs index a415a96a..b24088a0 100644 --- a/rustfs/src/init.rs +++ b/rustfs/src/init.rs @@ -320,32 +320,38 @@ pub(crate) fn init_buffer_profile_system(opt: &config::Opt) { /// as other services and MUST integrate with the global shutdown system. #[instrument(skip_all)] pub async fn init_ftp_system( - opt: &crate::config::Opt, shutdown_tx: tokio::sync::broadcast::Sender<()>, ) -> Result<(), Box> { use crate::protocols::ftps::server::{FtpsConfig, FtpsServer}; use std::net::SocketAddr; // Check if FTPS is enabled - if !opt.ftps_enable { + let ftps_enable = rustfs_utils::get_env_bool(rustfs_config::ENV_FTPS_ENABLE, false); + if !ftps_enable { debug!("FTPS system is disabled"); return Ok(()); } // Parse FTPS address - let addr: SocketAddr = opt - .ftps_address + let ftps_address_str = rustfs_utils::get_env_str(rustfs_config::ENV_FTPS_ADDRESS, rustfs_config::DEFAULT_FTPS_ADDRESS); + let addr: SocketAddr = ftps_address_str .parse() - .map_err(|e| format!("Invalid FTPS address '{}': {}", opt.ftps_address, e))?; + .map_err(|e| format!("Invalid FTPS address '{}': {}", ftps_address_str, e))?; + + // Get FTPS configuration from environment variables + let cert_file = rustfs_utils::get_env_opt_str(rustfs_config::ENV_FTPS_CERTS_FILE); + let key_file = rustfs_utils::get_env_opt_str(rustfs_config::ENV_FTPS_KEY_FILE); + let passive_ports = rustfs_utils::get_env_opt_str(rustfs_config::ENV_FTPS_PASSIVE_PORTS); + let external_ip = rustfs_utils::get_env_opt_str(rustfs_config::ENV_FTPS_EXTERNAL_IP); // Create FTPS configuration let config = FtpsConfig { bind_addr: addr, - passive_ports: opt.ftps_passive_ports.clone(), - external_ip: opt.ftps_external_ip.clone(), + passive_ports, + external_ip, ftps_required: true, - cert_file: opt.ftps_certs_file.clone(), - key_file: opt.ftps_key_file.clone(), + cert_file, + key_file, }; // Create FTPS server @@ -380,31 +386,35 @@ pub async fn init_ftp_system( /// as other services and MUST integrate with the global shutdown system. #[instrument(skip_all)] pub async fn init_sftp_system( - opt: &config::Opt, shutdown_tx: tokio::sync::broadcast::Sender<()>, ) -> Result<(), Box> { use crate::protocols::sftp::server::{SftpConfig, SftpServer}; use std::net::SocketAddr; // Check if SFTP is enabled - if !opt.sftp_enable { + let sftp_enable = rustfs_utils::get_env_bool(rustfs_config::ENV_SFTP_ENABLE, false); + if !sftp_enable { debug!("SFTP system is disabled"); return Ok(()); } // Parse SFTP address - let addr: SocketAddr = opt - .sftp_address + let sftp_address_str = rustfs_utils::get_env_str(rustfs_config::ENV_SFTP_ADDRESS, rustfs_config::DEFAULT_SFTP_ADDRESS); + let addr: SocketAddr = sftp_address_str .parse() - .map_err(|e| format!("Invalid SFTP address '{}': {}", opt.sftp_address, e))?; + .map_err(|e| format!("Invalid SFTP address '{}': {}", sftp_address_str, e))?; + + // Get SFTP configuration from environment variables + let host_key = rustfs_utils::get_env_opt_str(rustfs_config::ENV_SFTP_HOST_KEY); + let authorized_keys = rustfs_utils::get_env_opt_str(rustfs_config::ENV_SFTP_AUTHORIZED_KEYS); // Create SFTP configuration let config = SftpConfig { bind_addr: addr, - require_key_auth: false, // TODO: Add key auth configuration - cert_file: None, // CA certificates for client certificate authentication - key_file: opt.sftp_host_key.clone(), // SFTP server host key - authorized_keys_file: opt.sftp_authorized_keys.clone(), // Pre-loaded authorized SSH public keys + require_key_auth: false, // TODO: Add key auth configuration + cert_file: None, // CA certificates for client certificate authentication + key_file: host_key, // SFTP server host key + authorized_keys_file: authorized_keys, // Pre-loaded authorized SSH public keys }; // Create SFTP server diff --git a/rustfs/src/main.rs b/rustfs/src/main.rs index db42f8f1..9e571245 100644 --- a/rustfs/src/main.rs +++ b/rustfs/src/main.rs @@ -272,14 +272,10 @@ async fn run(opt: config::Opt) -> Result<()> { let (ftp_sftp_shutdown_tx, _) = tokio::sync::broadcast::channel(1); // Initialize FTP system if enabled - init_ftp_system(&opt, ftp_sftp_shutdown_tx.clone()) - .await - .map_err(Error::other)?; + init_ftp_system(ftp_sftp_shutdown_tx.clone()).await.map_err(Error::other)?; // Initialize SFTP system if enabled - init_sftp_system(&opt, ftp_sftp_shutdown_tx.clone()) - .await - .map_err(Error::other)?; + init_sftp_system(ftp_sftp_shutdown_tx.clone()).await.map_err(Error::other)?; // Initialize buffer profiling system init_buffer_profile_system(&opt); diff --git a/rustfs/src/protocols/README.md b/rustfs/src/protocols/README.md index 6537ee16..1aa0c893 100644 --- a/rustfs/src/protocols/README.md +++ b/rustfs/src/protocols/README.md @@ -10,27 +10,23 @@ RustFS provides multiple protocol interfaces for accessing object storage, inclu ### Enable Protocols on Startup ```bash -# Start RustFS with all protocols enabled -rustfs \ - --address 0.0.0.0:9000 \ - --access-key rustfsadmin \ - --secret-key rustfsadmin \ - --ftps-enable \ - --ftps-address 0.0.0.0:21 \ - --ftps-certs-file /path/to/cert.pem \ - --ftps-key-file /path/to/key.pem \ - --ftps-passive-ports "40000-41000" \ - --sftp-enable \ - --sftp-address 0.0.0.0:22 \ - --sftp-host-key /path/to/host_key \ - --sftp-authorized-keys /path/to/authorized_keys \ - /data +# Start RustFS with FTPS enabled +export RUSTFS_FTPS_ENABLE=true +export RUSTFS_FTPS_CERTS_FILE=/path/to/cert.pem +export RUSTFS_FTPS_KEY_FILE=/path/to/key.pem +rustfs --address 0.0.0.0:9000 --access-key rustfsadmin --secret-key rustfsadmin /data + +# Start RustFS with SFTP enabled +export RUSTFS_SFTP_ENABLE=true +export RUSTFS_SFTP_HOST_KEY=/path/to/host_key +export RUSTFS_SFTP_AUTHORIZED_KEYS=/path/to/authorized_keys +rustfs --address 0.0.0.0:9000 --access-key rustfsadmin --secret-key rustfsadmin /data ``` ## Protocol Details ### FTPS -- **Port**: 21 +- **Port**: 8021 (default) - **Protocol**: FTP over TLS (FTPS) - **Authentication**: Access Key / Secret Key (same as S3) - **Features**: @@ -44,7 +40,7 @@ rustfs \ - No multipart upload ### SFTP -- **Port**: 22 +- **Port**: 8022 (default) - **Protocol**: SSH File Transfer Protocol - **Authentication**: - Password (Access Key / Secret Key) @@ -133,23 +129,23 @@ ssh-keygen -l -f /path/to/host_key ### FTPS Configuration -| Option | Environment Variable | Description | Default | -|--------|---------------------|-------------|---------| -| `--ftps-enable` | `RUSTFS_FTPS_ENABLE` | Enable FTPS server | `false` | -| `--ftps-address` | `RUSTFS_FTPS_ADDRESS` | FTPS bind address | `0.0.0.0:21` | -| `--ftps-certs-file` | `RUSTFS_FTPS_CERTS_FILE` | TLS certificate file | - | -| `--ftps-key-file` | `RUSTFS_FTPS_KEY_FILE` | TLS private key file | - | -| `--ftps-passive-ports` | `RUSTFS_FTPS_PASSIVE_PORTS` | Passive port range | - | -| `--ftps-external-ip` | `RUSTFS_FTPS_EXTERNAL_IP` | External IP for NAT | - | +| Environment Variable | Description | Default | +|---------------------|-------------|---------| +| `RUSTFS_FTPS_ENABLE` | Enable FTPS server | `false` | +| `RUSTFS_FTPS_ADDRESS` | FTPS bind address | `0.0.0.0:8021` | +| `RUSTFS_FTPS_CERTS_FILE` | TLS certificate file | - | +| `RUSTFS_FTPS_KEY_FILE` | TLS private key file | - | +| `RUSTFS_FTPS_PASSIVE_PORTS` | Passive port range | - | +| `RUSTFS_FTPS_EXTERNAL_IP` | External IP for NAT | - | ### SFTP Configuration -| Option | Environment Variable | Description | Default | -|--------|---------------------|-------------|---------| -| `--sftp-enable` | `RUSTFS_SFTP_ENABLE` | Enable SFTP server | `false` | -| `--sftp-address` | `RUSTFS_SFTP_ADDRESS` | SFTP bind address | `0.0.0.0:22` | -| `--sftp-host-key` | `RUSTFS_SFTP_HOST_KEY` | SSH host key file | - | -| `--sftp-authorized-keys` | `RUSTFS_SFTP_AUTHORIZED_KEYS` | Authorized keys file | - | +| Environment Variable | Description | Default | +|---------------------|-------------|---------| +| `RUSTFS_SFTP_ENABLE` | Enable SFTP server | `false` | +| `RUSTFS_SFTP_ADDRESS` | SFTP bind address | `0.0.0.0:8022` | +| `RUSTFS_SFTP_HOST_KEY` | SSH host key file | - | +| `RUSTFS_SFTP_AUTHORIZED_KEYS` | Authorized keys file | - | ## See Also diff --git a/rustfs/src/protocols/gateway/adapter.rs b/rustfs/src/protocols/gateway/adapter.rs index e8f775a9..21715791 100644 --- a/rustfs/src/protocols/gateway/adapter.rs +++ b/rustfs/src/protocols/gateway/adapter.rs @@ -20,9 +20,9 @@ use crate::protocols::session::context::Protocol; pub fn is_operation_supported(protocol: Protocol, action: &S3Action) -> bool { match protocol { Protocol::Ftps => match action { - // Bucket operations: FTPS cannot create buckets via protocol commands - S3Action::CreateBucket => false, - S3Action::DeleteBucket => false, + // Bucket operations: FTPS has no native bucket commands, but gateway allows create/delete + S3Action::CreateBucket => true, + S3Action::DeleteBucket => true, // Object operations: All file operations supported S3Action::GetObject => true, // RETR command diff --git a/rustfs/src/protocols/sftp/server.rs b/rustfs/src/protocols/sftp/server.rs index 744700f4..8cdde4c0 100644 --- a/rustfs/src/protocols/sftp/server.rs +++ b/rustfs/src/protocols/sftp/server.rs @@ -69,7 +69,8 @@ impl SftpServer { russh::keys::load_secret_key(path, None)? } else { warn!("No host key provided, generating random key (not recommended for production)."); - let mut rng = rand::rngs::OsRng; + use russh::keys::signature::rand_core::OsRng; + let mut rng = OsRng; PrivateKey::random(&mut rng, Algorithm::Ed25519)? };