mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
a80699b6dd
feat(targets): add an opt-in NATS JetStream publish path for the notify and audit targets The NATS notify and audit targets publish through NATS Core, which returns before the server has durably accepted the message. A broker restart or a connection drop between the publish and the flush loses the event, even though the send queue has already cleared it, and no acknowledgement gates that clear. An opt-in JetStream publish path clears a queued event only after the server returns a durable PublishAck, so delivery is at-least-once across a broker restart or a reconnect. It applies to both the notify and audit NATS targets, is off by default, and is byte-identical to the NATS Core path when disabled. The path includes durable store-and-forward, a stable dedup id sent as the Nats-Msg-Id header so a replayed event is collapsed by the stream duplicate window, pre-flight stream validation, and a bounded failed-events store for terminally-failed and retry-exhausted events. Three configuration keys per target select it: JETSTREAM_ENABLE, JETSTREAM_STREAM_NAME, and JETSTREAM_ACK_TIMEOUT_SECS, under the RUSTFS_NOTIFY_NATS_ and RUSTFS_AUDIT_NATS_ prefixes. The on-disk batch filename separator changes from colon to underscore so batch names are valid on Windows filesystems, with transparent read-back of files written under the previous separator. The migration affects the shared queue store for every target type and lands with this feature because the store gains its first Windows-exercised paths here. Co-authored-by: houseme <housemecn@gmail.com>
18 KiB
18 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
Fixed
- Helm Ingress:
customAnnotationsare now merged with class-specific annotations (nginx/traefik) instead of being ignored wheningress.classNameis set.
Added
- NATS JetStream Publish Path: Opt-in at-least-once delivery for the NATS notify and audit targets. A NATS Core publish flushes to the connection without awaiting a broker acknowledgement, so an event can be lost across a broker restart or a reconnect after the send queue has already cleared it. A queued event now clears only after the JetStream
PublishAck, so bucket notifications survive those interruptions. Off by default and byte-identical to the NATS Core path when disabled.- Three configuration keys per target:
JETSTREAM_ENABLE,JETSTREAM_STREAM_NAME, andJETSTREAM_ACK_TIMEOUT_SECS, under theRUSTFS_NOTIFY_NATS_andRUSTFS_AUDIT_NATS_prefixes - Durable store-and-forward with a stable dedup id sent as the
Nats-Msg-Idheader, so a replay after a crash is collapsed by the server duplicate window - Pre-flight stream validation, and a bounded failed-events store (count and TTL). Only a non-retryable rejection is recorded in the failed-events store. A retryable condition keeps the entry on the live queue until it is delivered
- Operator guide at
docs/operations/nats-jetstream.md
- Three configuration keys per target:
- OpenStack Keystone Authentication Integration: Full support for OpenStack Keystone authentication via X-Auth-Token headers
- Tower-based middleware (
KeystoneAuthLayer) self-contained withinrustfs-keystonecrate - Task-local storage for async-safe credential passing between middleware and auth handlers
- Automatic detection of Keystone credentials (access keys prefixed with
keystone:) - Role-based permission mapping (admin/reseller_admin roles grant owner permissions)
- Token caching for high-performance validation with configurable cache size and TTL
- Dual authentication support: Keystone and standard AWS Signature v4 work simultaneously
- Immediate 401 response for invalid tokens (no fallback to local auth)
- XML-formatted error responses compatible with S3 API
- Comprehensive integration documentation with manual testing guide
- 32 unit and integration tests covering middleware, auth handlers, task-local storage, and role detection
- Tower-based middleware (
- SFTPv3 Protocol Support: SSH-hosted SFTPv3 subsystem that translates each file operation into S3 calls against the local object store. Authentication uses IAM credentials (SSH username = access key, SSH password = secret key).
- Full SFTPv3 packet coverage: open, read, write, stat, lstat, fstat, mkdir, rmdir, rename, remove, opendir, readdir, realpath, close, plus the rest of the 21-packet specification
- Streaming multipart write up to the part size times 10000 parts (156.25 GiB at the default part size)
- Per-handle read-ahead cache with configurable window size and process-wide memory ceiling
- Per-session liveness watchdog: Linux probes
/proc/net/tcpand cancels wedged sessions on the order of 45 seconds; non-Linux falls back to an inactivity ceiling on the order of 30 minutes - 30-second SSH handshake deadline, per-call backend operation timeout, bounded multipart-abort fan-out, graceful-shutdown cascade
- 34 SFTPv3 compliance test cases under
crates/e2e_test/src/protocols/sftp_compliance.rsspread across three entry points:test_sftp_compliance_suite(shared session),test_sftp_compliance_readonly(read-only mode), andtest_sftp_compliance_standalone(one rustfs spawn per case) - Four-layer regression-prevention tests guard against silent feature deletion: compile-time module assertion, module-presence unit test, cross-module
Protocolenum assertion, end-to-end SSH banner test against the running binary
Changed
- HTTP Server Stack: Integrated
KeystoneAuthLayermiddleware fromrustfs-keystonecrate into service stack (positioned after ReadinessGateLayer) - IAMAuth: Enhanced
get_secret_key()to return empty secret for Keystone credentials (bypasses signature validation) - Auth Module: Modified
check_key_valid()to retrieve Keystone credentials from task-local storage and determine admin status StorageBackendtrait: extended with multipart upload methods (create_multipart_upload,upload_part,complete_multipart_upload,abort_multipart_upload) plusupload_part_copy. Streaming-upload code path is now available to FTPS, WebDAV, and Swift drivers as well.Protocolenum: newProtocol::Sftpvariant with correspondingS3Actionmappings. Every match arm onProtocolupdated to handle the new variant exhaustively.
Technical Details
- Middleware is self-contained in
rustfs-keystonecrate following the trusted-proxies pattern for integration-specific middleware - Uses
BoxBodypattern for Hyper 1.x compatibility - Task-local storage provides request-scoped credential passing without modifying HTTP request/response types
- Integration preserves existing S3 authentication flow while adding Keystone support
- Zero breaking changes to existing functionality
- No new top-level directories in main binary crate (middleware lives in integration crate)
- SSH/SFTP wire handling via the
russhandrussh-sftpcrates. SFTPv3 framing is implemented byrussh-sftp; the rustfs-sideSftpDriverimplementsrussh_sftp::server::Handlerand dispatches to the storage backend - Drop-time abort for in-flight multipart uploads honours IAM Deny on
AbortMultipartUpload.start_multipart_uploadcaches the authorisation decision so the synchronousDroppath can honour Allow / Deny policies without re-querying IAM - Per-handle read cache uses an
Arc<AtomicU64>shared across everySftpDriverinstance to enforce a process-wide memory ceiling. On ceiling breach the populate is skipped and the read serves correctly via a single-call backend fetch - Per-session liveness watchdog runs as a tokio task per accepted connection. Reads
/proc/net/tcpand/proc/net/tcp6to look up the (local, peer) tuple's TCP state and cancels viatokio_util::sync::CancellationTokenwhen wedge conditions are confirmed across two consecutive ticks - Path canonicalisation rejects paths containing
\0,\r, or\nand resolves traversal viapath::clean()before any backend dispatch - Cipher / KEX / MAC / host-key algorithm allowlists are hardcoded with no environment override. Strict-KEX (CVE-2023-48795 / Terrapin) marker presence asserted by unit test
- Per-session handle cap (default 64, configurable 8 to 1024) with UUID-generated handle ids
- Crate-level
#![deny(unsafe_code)]is in force acrosscrates/protocols. Socket fd duplication for the watchdog uses the safeAsFd::try_clone_to_ownedpath (Linux). Non-Linux targets use the inactivity-ceiling watchdog - Platform-specific imports are cfg-gated. Unix enforces owner-only host-key mode bits (no group or other permission bits). Windows loads host keys without a mode check and trusts operator-managed NTFS ACLs. Targets that are neither Unix nor Windows fail SFTP at config-load with SftpInitError::UnsupportedPlatform
Documentation
- Updated
crates/keystone/README.mdwith complete integration architecture and workflow - Added detailed manual testing guide with 10 test scenarios
- Updated main
README.mdto list Keystone authentication as available feature - Added troubleshooting section for common integration issues
- Module-level rustdoc on
crates/protocols/src/sftp/mod.rsdescribing the public API surface, configuration contract, and the architecture of the read cache and the wedge watchdog
Configuration
New environment variables:
RUSTFS_KEYSTONE_ENABLE- Enable/disable Keystone authentication (default: false)RUSTFS_KEYSTONE_AUTH_URL- Keystone API endpoint URLRUSTFS_KEYSTONE_VERSION- Keystone API version (v3)RUSTFS_KEYSTONE_ADMIN_USER- Admin username for privileged operationsRUSTFS_KEYSTONE_ADMIN_PASSWORD- Admin passwordRUSTFS_KEYSTONE_ADMIN_PROJECT- Admin project nameRUSTFS_KEYSTONE_ADMIN_DOMAIN- Admin domain name (default: Default)RUSTFS_KEYSTONE_CACHE_SIZE- Token cache size (default: 10000)RUSTFS_KEYSTONE_CACHE_TTL- Token cache TTL in seconds (default: 300)RUSTFS_KEYSTONE_VERIFY_SSL- Verify SSL certificates (default: true)RUSTFS_SFTP_ENABLE- Enable/disable SFTP (default: false)RUSTFS_SFTP_ADDRESS- Listen address (default: 0.0.0.0:2222)RUSTFS_SFTP_HOST_KEY_DIR- Directory containing host key files (must exist). On Unix each file must grant no group or other permission bits (owner access only). On Windows the files load without a mode check and rustfs trusts the directory NTFS ACLRUSTFS_SFTP_HOST_KEY_RELOAD_ENABLE- Rescan the host-key directory without a restart (default: false)RUSTFS_SFTP_HOST_KEY_RELOAD_INTERVAL- Host-key rescan interval in seconds, minimum 5 (default: 30)RUSTFS_SFTP_IDLE_TIMEOUT- Session idle timeout in seconds (default: 600)RUSTFS_SFTP_PART_SIZE- Multipart part size in bytes (default: 16 MiB)RUSTFS_SFTP_READ_ONLY- Reject write packets at the protocol layer (default: false)RUSTFS_SFTP_BANNER- SSH protocol identification string, must begin withSSH-2.0-(default:SSH-2.0-RustFS)RUSTFS_SFTP_HANDLES_PER_SESSION- Per-session open-handle cap, 8 to 1024 (default: 64)RUSTFS_SFTP_BACKEND_OP_TIMEOUT_SECS- Per-call backend deadline in seconds, 5 to 600 (default: 60)RUSTFS_SFTP_READ_CACHE_WINDOW_BYTES- Per-handle read-cache window in bytes, 256 KiB to 64 MiB or 0 to disable (default: 4 MiB)RUSTFS_SFTP_READ_CACHE_TOTAL_MEM_BYTES- Process-wide read-cache memory ceiling in bytes, 16 MiB minimum (default: 256 MiB)
Files Added
crates/protocols/src/sftp/mod.rs- SFTP module entry point, public API surface, crate-level rustdoc, regression-prevention testcrates/protocols/src/sftp/config.rs-SftpConfigandSftpInitErrortypes, env-var resolvers, host-key directory loader with permission enforcementcrates/protocols/src/sftp/constants.rs- Named constants grouped by purpose: S3 error codes, HTTP error codes, POSIX mode bits, protocol identifiers, operational limitscrates/protocols/src/sftp/server.rs-SftpServerSSH server, russh handler, password authentication against IAM, accept loop, per-session task spawncrates/protocols/src/sftp/driver.rs-SftpDriverper-session SFTPv3 handler dispatching each operation onto theStorageBackendcrates/protocols/src/sftp/state.rs-HandleStatevariants for read, write-buffering, write-streaming, write-failed handlescrates/protocols/src/sftp/lifecycle.rs- Per-session activity stamp, weak-ref registry,/proc/net/tcpprobe for the wedge watchdogcrates/protocols/src/sftp/wedge_watchdog.rs- Per-session liveness watchdog cancelling sessions silent at the SFTP layer while the kernel reports CLOSE_WAITcrates/protocols/src/sftp/fallback_watchdog.rs- Per-session silence-only liveness backstop for non-Linux targets, cancelling sessions only at the fallback idle ceilingcrates/protocols/src/sftp/read_cache.rs- Per-handle in-memory read-ahead cache with shared atomic accumulator for the process-wide memory ceilingcrates/protocols/src/sftp/attrs.rs- SFTPv3FileAttributesmapping for objects and directories, longname formatting, mtime clampingcrates/protocols/src/sftp/dir.rs- OPENDIR / READDIR pagination, root-bucket listing, sub-directory listing under a prefixcrates/protocols/src/sftp/errors.rs-SftpErrorthiserror enum and S3-error classification into SFTPv3 status codescrates/protocols/src/sftp/paths.rs- Path canonicalisation, traversal rejection,\0/\r/\nrejection, bucket+key decompositioncrates/protocols/src/sftp/read.rs- READ packet handler, EOF semantics,MAX_READ_LENbound, integration with the read cachecrates/protocols/src/sftp/write.rs- WRITE packet handler, in-memory buffering up to part size, transition to streaming multipart, CLOSE finalisationcrates/protocols/src/sftp/test_support.rs- Test fixtures and helper builders for SFTP unit testscrates/protocols/src/common/dummy_storage.rs- In-memoryStorageBackendtest backend covering every method, used by SFTP unit tests and the FTPS / Swift / WebDAV test suitescrates/e2e_test/src/protocols/sftp_core.rs- End-to-end regressions for the handshake deadline, idle-timeout disconnect, and the wedge watchdogcrates/e2e_test/src/protocols/sftp_compliance.rs- SFTPv3 compliance suite entry points (test_sftp_compliance_suite,test_sftp_compliance_readonly,test_sftp_compliance_standalone)crates/e2e_test/src/protocols/sftp_compliance_tests.rs- Per-case test bodies (CMPTST-01..34), shared fixture helpers, lifecycle counterscrates/e2e_test/src/protocols/sftp_helpers.rs- SFTP-specific test helpers and fixture seeders
Files Modified
crates/keystone/src/middleware.rs- Created Keystone authentication middleware (self-contained in keystone crate)crates/keystone/src/lib.rs- Exported middleware module and KEYSTONE_CREDENTIALScrates/keystone/Cargo.toml- Added Tower/HTTP dependencies for middleware functionalityrustfs/src/server/http.rs- Integrated KeystoneAuthLayer from rustfs-keystone craterustfs/src/auth.rs- Enhanced IAMAuth and check_key_valid for Keystone support, imported KEYSTONE_CREDENTIALS from rustfs-keystonecrates/keystone/README.md- Comprehensive integration documentationREADME.md- Added Keystone as available featureCargo.toml- Added thesftpfeature alongside the existing protocol featuresCargo.lock- Updated to include the newrussh,russh-sftp,socket2,tokio-util,subtle,uuiddependencies and their transitive cratescrates/protocols/Cargo.toml- Declaredrussh,russh-sftp,socket2,tokio-util,subtle,uuidunder thesftpfeature flagcrates/protocols/src/lib.rs- Addedpub mod sftpbehind#[cfg(feature = "sftp")]plus the crate-level#![deny(unsafe_code)]lintcrates/protocols/src/common/client/s3.rs- Extended theStorageBackendtrait withcreate_multipart_upload,upload_part,complete_multipart_upload,abort_multipart_upload, andupload_part_copycrates/protocols/src/common/session.rs- Added theProtocol::Sftpvariant and itsS3Actionmappingscrates/protocols/src/common/gateway.rs- Handles the newProtocol::Sftpvariant exhaustivelycrates/protocols/src/common/mod.rs- Exposed the newdummy_storagemodulecrates/protocols/src/constants.rs- Added shared POSIX mode-bit constants used by SFTP and other protocolscrates/config/src/constants/protocols.rs-RUSTFS_SFTP_*environment variable names and defaultscrates/utils/src/retry.rs- Added the generic exponential-backoff retry helper used by the SFTP write pathcrates/e2e_test/Cargo.toml- Added the e2e test dependencies for SFTP (paramiko fixture, SSH keypair generation)crates/e2e_test/src/protocols/mod.rs- Registered the newsftp_core,sftp_compliance,sftp_compliance_tests, andsftp_helpersmodulescrates/e2e_test/src/protocols/README.md- Documented the SFTP test entry points and case indexcrates/e2e_test/src/protocols/test_env.rs- Added SFTP host-key directory provisioning to the shared protocol test environmentcrates/e2e_test/src/protocols/test_runner.rs- Wired the SFTP entry points into the runnerrustfs/Cargo.toml- Added thesftpfeature flagrustfs/src/lib.rs- One-line addition exporting the SFTP wiringrustfs/src/init.rs- Build and start theSftpServerwhenRUSTFS_SFTP_ENABLEis truerustfs/src/main.rs- Routed shutdown signals to the SFTP server alongside the other protocolsrustfs/src/protocols/client.rs- Client-builder support for the newProtocol::Sftpvariant
Testing
- 16 unit tests in rustfs-keystone crate (config, auth, middleware, identity)
- 10 integration tests in rustfs-keystone crate (task-local storage, middleware layer, scope isolation)
- 6 auth unit tests in rustfs crate (role detection, task-local storage, Keystone credential handling)
- Total: 32 tests passing with zero compilation errors
- Manual testing guide provided for end-to-end validation
- All Keystone tests passing with
cargo test --all --exclude e2e_test - 34 SFTPv3 compliance test cases (CMPTST-01..34) split across three entry points:
test_sftp_compliance_suite(shared session, cases 01-14),test_sftp_compliance_readonly(read-only mode, cases 15-23),test_sftp_compliance_standalone(one rustfs spawn per case, cases 24-34) - Regression-prevention tests at four layers: compile-time module assertion in
crates/protocols/src/lib.rs, module-presence unit test incrates/protocols/src/sftp/mod.rs, cross-moduleProtocolenum assertion, and end-to-end SSH banner test against the running binary - Standalone end-to-end regressions for the SSH handshake deadline, the idle-timeout disconnect path, and the wedge watchdog (Linux fast-kill and the cross-platform fallback path)
- Inline unit tests in every SFTP source file covering pure helpers (path canonicalisation, attribute mapping, S3-error classification, env-var bound resolvers)
- Strict-KEX (CVE-2023-48795) marker presence assertion as a unit test in
crates/protocols/src/sftp/server.rs - All tests passing with
cargo test --all --features sftpagainst a 64-bit Linux target
Previous Releases
See GitHub Releases for previous version history.