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>
This commit is contained in:
yxrxy
2026-01-02 11:08:28 +08:00
committed by GitHub
parent 8d7cd4cb1b
commit cf53a9d84a
16 changed files with 299 additions and 444 deletions
Generated
+74 -315
View File
@@ -563,17 +563,6 @@ dependencies = [
"xattr", "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]] [[package]]
name = "async-channel" name = "async-channel"
version = "2.5.0" version = "2.5.0"
@@ -604,60 +593,13 @@ dependencies = [
"zstd-safe", "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]] [[package]]
name = "async-lock" name = "async-lock"
version = "3.4.2" version = "3.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
dependencies = [ dependencies = [
"event-listener 5.4.1", "event-listener",
"event-listener-strategy", "event-listener-strategy",
"pin-project-lite", "pin-project-lite",
] ]
@@ -673,32 +615,6 @@ dependencies = [
"syn 2.0.112", "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]] [[package]]
name = "async-stream" name = "async-stream"
version = "0.3.6" version = "0.3.6"
@@ -721,12 +637,6 @@ dependencies = [
"syn 2.0.112", "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]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.89" version = "0.1.89"
@@ -1433,19 +1343,6 @@ dependencies = [
"generic-array 0.14.7", "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]] [[package]]
name = "blowfish" name = "blowfish"
version = "0.9.1" version = "0.9.1"
@@ -2248,12 +2145,27 @@ dependencies = [
"cpufeatures", "cpufeatures",
"curve25519-dalek-derive", "curve25519-dalek-derive",
"digest 0.10.7", "digest 0.10.7",
"fiat-crypto", "fiat-crypto 0.2.9",
"rustc_version", "rustc_version",
"subtle", "subtle",
"zeroize", "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]] [[package]]
name = "curve25519-dalek-derive" name = "curve25519-dalek-derive"
version = "0.1.1" version = "0.1.1"
@@ -3362,7 +3274,6 @@ dependencies = [
"flatbuffers", "flatbuffers",
"futures", "futures",
"md5 0.8.0", "md5 0.8.0",
"native-tls",
"rand 0.10.0-rc.5", "rand 0.10.0-rc.5",
"rcgen", "rcgen",
"reqwest", "reqwest",
@@ -3379,7 +3290,6 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"serial_test", "serial_test",
"ssh2",
"suppaftp", "suppaftp",
"tokio", "tokio",
"tonic", "tonic",
@@ -3425,14 +3335,23 @@ dependencies = [
"signature 2.2.0", "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]] [[package]]
name = "ed25519-dalek" name = "ed25519-dalek"
version = "2.2.0" version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9"
dependencies = [ dependencies = [
"curve25519-dalek", "curve25519-dalek 4.1.3",
"ed25519", "ed25519 2.2.3",
"rand_core 0.6.4", "rand_core 0.6.4",
"serde", "serde",
"sha2 0.10.9", "sha2 0.10.9",
@@ -3440,6 +3359,18 @@ dependencies = [
"zeroize", "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]] [[package]]
name = "either" name = "either"
version = "1.15.0" version = "1.15.0"
@@ -3616,12 +3547,6 @@ dependencies = [
"windows-sys 0.61.2", "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]] [[package]]
name = "event-listener" name = "event-listener"
version = "5.4.1" version = "5.4.1"
@@ -3639,7 +3564,7 @@ version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
dependencies = [ dependencies = [
"event-listener 5.4.1", "event-listener",
"pin-project-lite", "pin-project-lite",
] ]
@@ -3685,6 +3610,12 @@ version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
[[package]]
name = "fiat-crypto"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24"
[[package]] [[package]]
name = "filetime" name = "filetime"
version = "0.2.26" version = "0.2.26"
@@ -3806,21 +3737,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" 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]] [[package]]
name = "form_urlencoded" name = "form_urlencoded"
version = "1.2.2" version = "1.2.2"
@@ -4067,18 +3983,6 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" 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]] [[package]]
name = "google-cloud-auth" name = "google-cloud-auth"
version = "1.3.0" version = "1.3.0"
@@ -4965,14 +4869,15 @@ checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02"
[[package]] [[package]]
name = "internal-russh-forked-ssh-key" 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" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a77eae781ed6a7709fb15b64862fcca13d886b07c7e2786f5ed34e5e2b9187" checksum = "fe44f2bbd99fcb302e246e2d6bcf51aeda346d02a365f80296a07a8c711b6da6"
dependencies = [ dependencies = [
"argon2 0.5.3", "argon2 0.5.3",
"bcrypt-pbkdf", "bcrypt-pbkdf",
"digest 0.11.0-rc.4",
"ecdsa 0.16.9", "ecdsa 0.16.9",
"ed25519-dalek", "ed25519-dalek 2.2.0",
"hex", "hex",
"hmac 0.12.1", "hmac 0.12.1",
"num-bigint-dig", "num-bigint-dig",
@@ -4980,11 +4885,13 @@ dependencies = [
"p384", "p384",
"p521", "p521",
"rand_core 0.6.4", "rand_core 0.6.4",
"rsa 0.9.9", "rsa 0.10.0-rc.10",
"sec1 0.7.3", "sec1 0.7.3",
"sha1 0.10.6", "sha1 0.10.6",
"sha1 0.11.0-rc.3",
"sha2 0.10.9", "sha2 0.10.9",
"signature 2.2.0", "signature 2.2.0",
"signature 3.0.0-rc.5",
"ssh-cipher 0.2.0", "ssh-cipher 0.2.0",
"ssh-encoding 0.2.0", "ssh-encoding 0.2.0",
"subtle", "subtle",
@@ -5107,7 +5014,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c76e1c7d7df3e34443b3621b459b066a7b79644f059fc8b2db7070c825fd417e" checksum = "c76e1c7d7df3e34443b3621b459b066a7b79644f059fc8b2db7070c825fd417e"
dependencies = [ dependencies = [
"base64", "base64",
"ed25519-dalek", "ed25519-dalek 2.2.0",
"getrandom 0.2.16", "getrandom 0.2.16",
"hmac 0.12.1", "hmac 0.12.1",
"js-sys", "js-sys",
@@ -5143,15 +5050,6 @@ dependencies = [
"libc", "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]] [[package]]
name = "lazy-regex" name = "lazy-regex"
version = "3.4.2" version = "3.4.2"
@@ -5356,20 +5254,6 @@ dependencies = [
"redox_syscall 0.7.0", "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]] [[package]]
name = "libsystemd" name = "libsystemd"
version = "0.7.2" version = "0.7.2"
@@ -5432,18 +5316,6 @@ dependencies = [
"zlib-rs", "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]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.15" version = "0.4.15"
@@ -5732,7 +5604,7 @@ dependencies = [
"crossbeam-epoch", "crossbeam-epoch",
"crossbeam-utils", "crossbeam-utils",
"equivalent", "equivalent",
"event-listener 5.4.1", "event-listener",
"futures-util", "futures-util",
"parking_lot", "parking_lot",
"portable-atomic", "portable-atomic",
@@ -5747,23 +5619,6 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" 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]] [[package]]
name = "neli" name = "neli"
version = "0.7.3" version = "0.7.3"
@@ -5949,6 +5804,7 @@ dependencies = [
"num-iter", "num-iter",
"num-traits", "num-traits",
"rand 0.8.5", "rand 0.8.5",
"serde",
"smallvec", "smallvec",
"zeroize", "zeroize",
] ]
@@ -6161,56 +6017,12 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" 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]] [[package]]
name = "openssl-probe" name = "openssl-probe"
version = "0.2.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" 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]] [[package]]
name = "opentelemetry" name = "opentelemetry"
version = "0.31.0" version = "0.31.0"
@@ -6724,17 +6536,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 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]] [[package]]
name = "pkcs1" name = "pkcs1"
version = "0.7.5" version = "0.7.5"
@@ -6837,20 +6638,6 @@ dependencies = [
"plotters-backend", "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]] [[package]]
name = "pollster" name = "pollster"
version = "0.4.0" version = "0.4.0"
@@ -7729,7 +7516,6 @@ dependencies = [
"pkcs1 0.7.5", "pkcs1 0.7.5",
"pkcs8 0.10.2", "pkcs8 0.10.2",
"rand_core 0.6.4", "rand_core 0.6.4",
"sha2 0.10.9",
"signature 2.2.0", "signature 2.2.0",
"spki 0.7.3", "spki 0.7.3",
"subtle", "subtle",
@@ -7749,6 +7535,7 @@ dependencies = [
"pkcs1 0.8.0-rc.4", "pkcs1 0.8.0-rc.4",
"pkcs8 0.11.0-rc.8", "pkcs8 0.11.0-rc.8",
"rand_core 0.10.0-rc-2", "rand_core 0.10.0-rc-2",
"sha2 0.11.0-rc.3",
"signature 3.0.0-rc.5", "signature 3.0.0-rc.5",
"spki 0.8.0-rc.4", "spki 0.8.0-rc.4",
"subtle", "subtle",
@@ -7807,9 +7594,9 @@ dependencies = [
[[package]] [[package]]
name = "russh" name = "russh"
version = "0.55.0" version = "0.56.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82b4d036bb45d7bbe99dbfef4ec60eaeb614708d22ff107124272f8ef6b54548" checksum = "bdbb7dcdd62c17ac911307ff693f55b3ec6712004d2d66ffdb8c0fa00269fd66"
dependencies = [ dependencies = [
"aes 0.8.4", "aes 0.8.4",
"aws-lc-rs", "aws-lc-rs",
@@ -7819,16 +7606,15 @@ dependencies = [
"bytes", "bytes",
"cbc", "cbc",
"ctr 0.9.2", "ctr 0.9.2",
"curve25519-dalek", "curve25519-dalek 4.1.3",
"data-encoding", "data-encoding",
"delegate", "delegate",
"der 0.7.10", "der 0.7.10",
"digest 0.10.7", "digest 0.10.7",
"ecdsa 0.16.9", "ecdsa 0.16.9",
"ed25519-dalek", "ed25519-dalek 2.2.0",
"elliptic-curve 0.13.8", "elliptic-curve 0.13.8",
"enum_dispatch", "enum_dispatch",
"flate2",
"futures", "futures",
"generic-array 1.3.5", "generic-array 1.3.5",
"getrandom 0.2.16", "getrandom 0.2.16",
@@ -7846,12 +7632,12 @@ dependencies = [
"p521", "p521",
"pageant", "pageant",
"pbkdf2 0.12.2", "pbkdf2 0.12.2",
"pkcs1 0.7.5", "pkcs1 0.8.0-rc.4",
"pkcs5", "pkcs5",
"pkcs8 0.10.2", "pkcs8 0.10.2",
"rand 0.8.5", "rand 0.8.5",
"rand_core 0.6.4", "rand_core 0.6.4",
"rsa 0.9.9", "rsa 0.10.0-rc.10",
"russh-cryptovec", "russh-cryptovec",
"russh-util", "russh-util",
"sec1 0.7.3", "sec1 0.7.3",
@@ -8002,7 +7788,7 @@ dependencies = [
"moka", "moka",
"pin-project-lite", "pin-project-lite",
"pprof", "pprof",
"rand 0.8.5", "rand 0.10.0-rc.5",
"reqwest", "reqwest",
"rmp-serde", "rmp-serde",
"russh", "russh",
@@ -8198,7 +7984,7 @@ dependencies = [
name = "rustfs-ecstore" name = "rustfs-ecstore"
version = "0.0.5" version = "0.0.5"
dependencies = [ dependencies = [
"async-channel 2.5.0", "async-channel",
"async-recursion", "async-recursion",
"async-trait", "async-trait",
"aws-config", "aws-config",
@@ -8765,10 +8551,10 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
dependencies = [ dependencies = [
"openssl-probe 0.2.0", "openssl-probe",
"rustls-pki-types", "rustls-pki-types",
"schannel", "schannel",
"security-framework 3.5.1", "security-framework",
] ]
[[package]] [[package]]
@@ -9009,19 +8795,6 @@ dependencies = [
"hybrid-array", "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]] [[package]]
name = "security-framework" name = "security-framework"
version = "3.5.1" version = "3.5.1"
@@ -9621,6 +9394,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ad6a09263583e83e934fcd436b7e3bb9d69602e2feef3787adb615c1fe3a343" checksum = "6ad6a09263583e83e934fcd436b7e3bb9d69602e2feef3787adb615c1fe3a343"
dependencies = [ dependencies = [
"base64ct", "base64ct",
"crypto-bigint 0.7.0-rc.10",
"digest 0.11.0-rc.4", "digest 0.11.0-rc.4",
"pem-rfc7468 1.0.0", "pem-rfc7468 1.0.0",
"subtle", "subtle",
@@ -9633,7 +9407,9 @@ version = "0.7.0-rc.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7faefb89d4a5304e31238913d1f7f164e22494276ed58cd84d5058ba7b04911f" checksum = "7faefb89d4a5304e31238913d1f7f164e22494276ed58cd84d5058ba7b04911f"
dependencies = [ dependencies = [
"ed25519-dalek 3.0.0-pre.2",
"rand_core 0.10.0-rc-2", "rand_core 0.10.0-rc-2",
"rsa 0.10.0-rc.10",
"sec1 0.8.0-rc.10", "sec1 0.8.0-rc.10",
"sha2 0.11.0-rc.3", "sha2 0.11.0-rc.3",
"signature 3.0.0-rc.5", "signature 3.0.0-rc.5",
@@ -9643,18 +9419,6 @@ dependencies = [
"zeroize", "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]] [[package]]
name = "stable_deref_trait" name = "stable_deref_trait"
version = "1.2.1" version = "1.2.1"
@@ -9754,16 +9518,17 @@ version = "7.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba8928c89e226be233f0eb1594e9bd023f72a948dc06581c0d908387f57de1de" checksum = "ba8928c89e226be233f0eb1594e9bd023f72a948dc06581c0d908387f57de1de"
dependencies = [ dependencies = [
"async-std",
"async-trait", "async-trait",
"chrono", "chrono",
"futures-lite", "futures-lite",
"lazy-regex", "lazy-regex",
"log", "log",
"native-tls",
"pin-project", "pin-project",
"rustls", "rustls",
"rustls-pki-types",
"thiserror 2.0.17", "thiserror 2.0.17",
"tokio",
"tokio-rustls",
] ]
[[package]] [[package]]
@@ -10859,12 +10624,6 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.5" version = "0.9.5"
+3 -6
View File
@@ -268,14 +268,11 @@ opentelemetry-stdout = { version = "0.31.0" }
# FTP and SFTP # FTP and SFTP
libunftp = "0.21.0" 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-sftp = "2.1.1"
russh-keys = "0.49.2" ssh-key = { version = "0.7.0-rc.4", features = ["std", "rsa", "ed25519"] }
ssh-key = "0.7.0-rc.4" suppaftp = { version = "7.0.7", features = ["tokio", "tokio-rustls", "rustls"] }
ssh2 = "0.9"
suppaftp = { version = "7.0.7", features = ["async-std", "rustls", "native-tls"] }
rcgen = "0.14.6" rcgen = "0.14.6"
native-tls = "0.2.14"
# Performance Analysis and Memory Profiling # Performance Analysis and Memory Profiling
mimalloc = "0.1" mimalloc = "0.1"
+1
View File
@@ -20,6 +20,7 @@ pub(crate) mod env;
pub(crate) mod heal; pub(crate) mod heal;
pub(crate) mod object; pub(crate) mod object;
pub(crate) mod profiler; pub(crate) mod profiler;
pub(crate) mod protocols;
pub(crate) mod runtime; pub(crate) mod runtime;
pub(crate) mod targets; pub(crate) mod targets;
pub(crate) mod tls; pub(crate) mod tls;
+40
View File
@@ -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";
+2
View File
@@ -31,6 +31,8 @@ pub use constants::object::*;
#[cfg(feature = "constants")] #[cfg(feature = "constants")]
pub use constants::profiler::*; pub use constants::profiler::*;
#[cfg(feature = "constants")] #[cfg(feature = "constants")]
pub use constants::protocols::*;
#[cfg(feature = "constants")]
pub use constants::runtime::*; pub use constants::runtime::*;
#[cfg(feature = "constants")] #[cfg(feature = "constants")]
pub use constants::targets::*; pub use constants::targets::*;
-2
View File
@@ -52,10 +52,8 @@ base64 = { workspace = true }
rand = { workspace = true } rand = { workspace = true }
chrono = { workspace = true } chrono = { workspace = true }
md5 = { workspace = true } md5 = { workspace = true }
ssh2.workspace = true
suppaftp.workspace = true suppaftp.workspace = true
rcgen.workspace = true rcgen.workspace = true
anyhow.workspace = true anyhow.workspace = true
native-tls.workspace = true
rustls.workspace = true rustls.workspace = true
rustls-pemfile.workspace = true rustls-pemfile.workspace = true
+32 -18
View File
@@ -17,12 +17,14 @@
use crate::common::rustfs_binary_path; use crate::common::rustfs_binary_path;
use crate::protocols::test_env::{DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY, ProtocolTestEnvironment}; use crate::protocols::test_env::{DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY, ProtocolTestEnvironment};
use anyhow::Result; use anyhow::Result;
use native_tls::TlsConnector;
use rcgen::generate_simple_self_signed; use rcgen::generate_simple_self_signed;
use rustls::crypto::aws_lc_rs::default_provider;
use rustls::{ClientConfig, RootCertStore};
use std::io::Cursor; use std::io::Cursor;
use std::path::PathBuf; use std::path::PathBuf;
use suppaftp::NativeTlsConnector; use std::sync::Arc;
use suppaftp::NativeTlsFtpStream; use suppaftp::RustlsConnector;
use suppaftp::RustlsFtpStream;
use tokio::process::Command; use tokio::process::Command;
use tracing::info; use tracing::info;
@@ -48,16 +50,11 @@ pub async fn test_ftps_core_operations() -> Result<()> {
info!("Starting FTPS server on {}", FTPS_ADDRESS); info!("Starting FTPS server on {}", FTPS_ADDRESS);
let binary_path = rustfs_binary_path(); let binary_path = rustfs_binary_path();
let mut server_process = Command::new(&binary_path) let mut server_process = Command::new(&binary_path)
.args([ .env("RUSTFS_FTPS_ENABLE", "true")
"--ftps-enable", .env("RUSTFS_FTPS_ADDRESS", FTPS_ADDRESS)
"--ftps-address", .env("RUSTFS_FTPS_CERTS_FILE", cert_path.to_str().unwrap())
FTPS_ADDRESS, .env("RUSTFS_FTPS_KEY_FILE", key_path.to_str().unwrap())
"--ftps-certs-file", .arg(&env.temp_dir)
cert_path.to_str().unwrap(),
"--ftps-key-file",
key_path.to_str().unwrap(),
&env.temp_dir,
])
.spawn()?; .spawn()?;
// Ensure server is cleaned up even on failure // Ensure server is cleaned up even on failure
@@ -67,14 +64,31 @@ pub async fn test_ftps_core_operations() -> Result<()> {
.await .await
.map_err(|e| anyhow::anyhow!("{}", e))?; .map_err(|e| anyhow::anyhow!("{}", e))?;
// Create native TLS connector that accepts the certificate // Install the aws-lc-rs crypto provider
let tls_connector = TlsConnector::builder().danger_accept_invalid_certs(true).build()?; default_provider()
.install_default()
.map_err(|e| anyhow::anyhow!("Failed to install crypto provider: {:?}", e))?;
// Wrap in suppaftp's NativeTlsConnector // Create a simple rustls config that accepts any certificate for testing
let tls_connector = NativeTlsConnector::from(tls_connector); 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::<Result<Vec<_>, _>>()
.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 // 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 // Upgrade to secure connection
let mut ftp_stream = ftp_stream let mut ftp_stream = ftp_stream
@@ -310,7 +310,6 @@ pub async fn list_path_raw(rx: CancellationToken, opts: ListPathRawOptions) -> d
if at_eof + has_err == readers.len() { if at_eof + has_err == readers.len() {
if has_err > 0 if has_err > 0
&& let Some(finished_fn) = opts.finished.as_ref() && let Some(finished_fn) = opts.finished.as_ref()
&& has_err > 0
{ {
finished_fn(&errs).await; finished_fn(&errs).await;
} }
+84
View File
@@ -108,11 +108,95 @@ export RUSTFS_ENABLE_LOCKS=false
./rustfs --address 127.0.0.1:9000 ... ./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 ## Performance Impact
- **Scanner**: Light to moderate CPU/IO impact during scans - **Scanner**: Light to moderate CPU/IO impact during scans
- **Heal**: Moderate to high CPU/IO impact during healing operations - **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 - **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 - **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. Disabling these services in resource-constrained environments can improve performance for primary storage operations.
+1 -2
View File
@@ -115,8 +115,7 @@ md5.workspace = true
mime_guess = { workspace = true } mime_guess = { workspace = true }
moka = { workspace = true } moka = { workspace = true }
pin-project-lite.workspace = true pin-project-lite.workspace = true
# rand = "0.8" is pinned due to dependency conflicts with workspace version rand = { workspace = true }
rand = "0.8"
rust-embed = { workspace = true, features = ["interpolate-folder-path"] } rust-embed = { workspace = true, features = ["interpolate-folder-path"] }
s3s.workspace = true s3s.workspace = true
shadow-rs = { workspace = true, features = ["build", "metadata"] } shadow-rs = { workspace = true, features = ["build", "metadata"] }
-41
View File
@@ -135,47 +135,6 @@ pub struct Opt {
/// Options: GeneralPurpose, AiTraining, DataAnalytics, WebWorkload, IndustrialIoT, SecureStorage /// Options: GeneralPurpose, AiTraining, DataAnalytics, WebWorkload, IndustrialIoT, SecureStorage
#[arg(long, default_value_t = String::from("GeneralPurpose"), env = "RUSTFS_BUFFER_PROFILE")] #[arg(long, default_value_t = String::from("GeneralPurpose"), env = "RUSTFS_BUFFER_PROFILE")]
pub buffer_profile: String, 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<String>,
/// FTPS server private key file path
#[arg(long, env = "RUSTFS_FTPS_KEY_FILE")]
pub ftps_key_file: Option<String>,
/// FTPS server passive ports range (e.g., "40000-50000")
#[arg(long, env = "RUSTFS_FTPS_PASSIVE_PORTS")]
pub ftps_passive_ports: Option<String>,
/// 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<String>,
/// 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<String>,
/// 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<String>,
} }
// lazy_static::lazy_static! { // lazy_static::lazy_static! {
+28 -18
View File
@@ -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. /// as other services and MUST integrate with the global shutdown system.
#[instrument(skip_all)] #[instrument(skip_all)]
pub async fn init_ftp_system( pub async fn init_ftp_system(
opt: &crate::config::Opt,
shutdown_tx: tokio::sync::broadcast::Sender<()>, shutdown_tx: tokio::sync::broadcast::Sender<()>,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
use crate::protocols::ftps::server::{FtpsConfig, FtpsServer}; use crate::protocols::ftps::server::{FtpsConfig, FtpsServer};
use std::net::SocketAddr; use std::net::SocketAddr;
// Check if FTPS is enabled // 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"); debug!("FTPS system is disabled");
return Ok(()); return Ok(());
} }
// Parse FTPS address // Parse FTPS address
let addr: SocketAddr = opt let ftps_address_str = rustfs_utils::get_env_str(rustfs_config::ENV_FTPS_ADDRESS, rustfs_config::DEFAULT_FTPS_ADDRESS);
.ftps_address let addr: SocketAddr = ftps_address_str
.parse() .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 // Create FTPS configuration
let config = FtpsConfig { let config = FtpsConfig {
bind_addr: addr, bind_addr: addr,
passive_ports: opt.ftps_passive_ports.clone(), passive_ports,
external_ip: opt.ftps_external_ip.clone(), external_ip,
ftps_required: true, ftps_required: true,
cert_file: opt.ftps_certs_file.clone(), cert_file,
key_file: opt.ftps_key_file.clone(), key_file,
}; };
// Create FTPS server // Create FTPS server
@@ -380,31 +386,35 @@ pub async fn init_ftp_system(
/// as other services and MUST integrate with the global shutdown system. /// as other services and MUST integrate with the global shutdown system.
#[instrument(skip_all)] #[instrument(skip_all)]
pub async fn init_sftp_system( pub async fn init_sftp_system(
opt: &config::Opt,
shutdown_tx: tokio::sync::broadcast::Sender<()>, shutdown_tx: tokio::sync::broadcast::Sender<()>,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
use crate::protocols::sftp::server::{SftpConfig, SftpServer}; use crate::protocols::sftp::server::{SftpConfig, SftpServer};
use std::net::SocketAddr; use std::net::SocketAddr;
// Check if SFTP is enabled // 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"); debug!("SFTP system is disabled");
return Ok(()); return Ok(());
} }
// Parse SFTP address // Parse SFTP address
let addr: SocketAddr = opt let sftp_address_str = rustfs_utils::get_env_str(rustfs_config::ENV_SFTP_ADDRESS, rustfs_config::DEFAULT_SFTP_ADDRESS);
.sftp_address let addr: SocketAddr = sftp_address_str
.parse() .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 // Create SFTP configuration
let config = SftpConfig { let config = SftpConfig {
bind_addr: addr, bind_addr: addr,
require_key_auth: false, // TODO: Add key auth configuration require_key_auth: false, // TODO: Add key auth configuration
cert_file: None, // CA certificates for client certificate authentication cert_file: None, // CA certificates for client certificate authentication
key_file: opt.sftp_host_key.clone(), // SFTP server host key key_file: host_key, // SFTP server host key
authorized_keys_file: opt.sftp_authorized_keys.clone(), // Pre-loaded authorized SSH public keys authorized_keys_file: authorized_keys, // Pre-loaded authorized SSH public keys
}; };
// Create SFTP server // Create SFTP server
+2 -6
View File
@@ -272,14 +272,10 @@ async fn run(opt: config::Opt) -> Result<()> {
let (ftp_sftp_shutdown_tx, _) = tokio::sync::broadcast::channel(1); let (ftp_sftp_shutdown_tx, _) = tokio::sync::broadcast::channel(1);
// Initialize FTP system if enabled // Initialize FTP system if enabled
init_ftp_system(&opt, ftp_sftp_shutdown_tx.clone()) init_ftp_system(ftp_sftp_shutdown_tx.clone()).await.map_err(Error::other)?;
.await
.map_err(Error::other)?;
// Initialize SFTP system if enabled // Initialize SFTP system if enabled
init_sftp_system(&opt, ftp_sftp_shutdown_tx.clone()) init_sftp_system(ftp_sftp_shutdown_tx.clone()).await.map_err(Error::other)?;
.await
.map_err(Error::other)?;
// Initialize buffer profiling system // Initialize buffer profiling system
init_buffer_profile_system(&opt); init_buffer_profile_system(&opt);
+27 -31
View File
@@ -10,27 +10,23 @@ RustFS provides multiple protocol interfaces for accessing object storage, inclu
### Enable Protocols on Startup ### Enable Protocols on Startup
```bash ```bash
# Start RustFS with all protocols enabled # Start RustFS with FTPS enabled
rustfs \ export RUSTFS_FTPS_ENABLE=true
--address 0.0.0.0:9000 \ export RUSTFS_FTPS_CERTS_FILE=/path/to/cert.pem
--access-key rustfsadmin \ export RUSTFS_FTPS_KEY_FILE=/path/to/key.pem
--secret-key rustfsadmin \ rustfs --address 0.0.0.0:9000 --access-key rustfsadmin --secret-key rustfsadmin /data
--ftps-enable \
--ftps-address 0.0.0.0:21 \ # Start RustFS with SFTP enabled
--ftps-certs-file /path/to/cert.pem \ export RUSTFS_SFTP_ENABLE=true
--ftps-key-file /path/to/key.pem \ export RUSTFS_SFTP_HOST_KEY=/path/to/host_key
--ftps-passive-ports "40000-41000" \ export RUSTFS_SFTP_AUTHORIZED_KEYS=/path/to/authorized_keys
--sftp-enable \ rustfs --address 0.0.0.0:9000 --access-key rustfsadmin --secret-key rustfsadmin /data
--sftp-address 0.0.0.0:22 \
--sftp-host-key /path/to/host_key \
--sftp-authorized-keys /path/to/authorized_keys \
/data
``` ```
## Protocol Details ## Protocol Details
### FTPS ### FTPS
- **Port**: 21 - **Port**: 8021 (default)
- **Protocol**: FTP over TLS (FTPS) - **Protocol**: FTP over TLS (FTPS)
- **Authentication**: Access Key / Secret Key (same as S3) - **Authentication**: Access Key / Secret Key (same as S3)
- **Features**: - **Features**:
@@ -44,7 +40,7 @@ rustfs \
- No multipart upload - No multipart upload
### SFTP ### SFTP
- **Port**: 22 - **Port**: 8022 (default)
- **Protocol**: SSH File Transfer Protocol - **Protocol**: SSH File Transfer Protocol
- **Authentication**: - **Authentication**:
- Password (Access Key / Secret Key) - Password (Access Key / Secret Key)
@@ -133,23 +129,23 @@ ssh-keygen -l -f /path/to/host_key
### FTPS Configuration ### FTPS Configuration
| Option | Environment Variable | Description | Default | | Environment Variable | Description | Default |
|--------|---------------------|-------------|---------| |---------------------|-------------|---------|
| `--ftps-enable` | `RUSTFS_FTPS_ENABLE` | Enable FTPS server | `false` | | `RUSTFS_FTPS_ENABLE` | Enable FTPS server | `false` |
| `--ftps-address` | `RUSTFS_FTPS_ADDRESS` | FTPS bind address | `0.0.0.0:21` | | `RUSTFS_FTPS_ADDRESS` | FTPS bind address | `0.0.0.0:8021` |
| `--ftps-certs-file` | `RUSTFS_FTPS_CERTS_FILE` | TLS certificate file | - | | `RUSTFS_FTPS_CERTS_FILE` | TLS certificate file | - |
| `--ftps-key-file` | `RUSTFS_FTPS_KEY_FILE` | TLS private key file | - | | `RUSTFS_FTPS_KEY_FILE` | TLS private key file | - |
| `--ftps-passive-ports` | `RUSTFS_FTPS_PASSIVE_PORTS` | Passive port range | - | | `RUSTFS_FTPS_PASSIVE_PORTS` | Passive port range | - |
| `--ftps-external-ip` | `RUSTFS_FTPS_EXTERNAL_IP` | External IP for NAT | - | | `RUSTFS_FTPS_EXTERNAL_IP` | External IP for NAT | - |
### SFTP Configuration ### SFTP Configuration
| Option | Environment Variable | Description | Default | | Environment Variable | Description | Default |
|--------|---------------------|-------------|---------| |---------------------|-------------|---------|
| `--sftp-enable` | `RUSTFS_SFTP_ENABLE` | Enable SFTP server | `false` | | `RUSTFS_SFTP_ENABLE` | Enable SFTP server | `false` |
| `--sftp-address` | `RUSTFS_SFTP_ADDRESS` | SFTP bind address | `0.0.0.0:22` | | `RUSTFS_SFTP_ADDRESS` | SFTP bind address | `0.0.0.0:8022` |
| `--sftp-host-key` | `RUSTFS_SFTP_HOST_KEY` | SSH host key file | - | | `RUSTFS_SFTP_HOST_KEY` | SSH host key file | - |
| `--sftp-authorized-keys` | `RUSTFS_SFTP_AUTHORIZED_KEYS` | Authorized keys file | - | | `RUSTFS_SFTP_AUTHORIZED_KEYS` | Authorized keys file | - |
## See Also ## See Also
+3 -3
View File
@@ -20,9 +20,9 @@ use crate::protocols::session::context::Protocol;
pub fn is_operation_supported(protocol: Protocol, action: &S3Action) -> bool { pub fn is_operation_supported(protocol: Protocol, action: &S3Action) -> bool {
match protocol { match protocol {
Protocol::Ftps => match action { Protocol::Ftps => match action {
// Bucket operations: FTPS cannot create buckets via protocol commands // Bucket operations: FTPS has no native bucket commands, but gateway allows create/delete
S3Action::CreateBucket => false, S3Action::CreateBucket => true,
S3Action::DeleteBucket => false, S3Action::DeleteBucket => true,
// Object operations: All file operations supported // Object operations: All file operations supported
S3Action::GetObject => true, // RETR command S3Action::GetObject => true, // RETR command
+2 -1
View File
@@ -69,7 +69,8 @@ impl SftpServer {
russh::keys::load_secret_key(path, None)? russh::keys::load_secret_key(path, None)?
} else { } else {
warn!("No host key provided, generating random key (not recommended for production)."); 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)? PrivateKey::random(&mut rng, Algorithm::Ed25519)?
}; };