Skip to content

Latest commit

 

History

History
843 lines (689 loc) · 44.1 KB

File metadata and controls

843 lines (689 loc) · 44.1 KB

Changelog

All notable changes to bssh will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

Added

  • Internal fork of russh-sftp as crates/bssh-russh-sftp with a serde_bytes performance fix for SSH_FXP_WRITE and SSH_FXP_DATA packets. The upstream serde derive routes Vec<u8> through deserialize_seq (byte-by-byte), accounting for ~42% of server CPU during 1 GiB SFTP uploads in perf profiling. Annotating the data fields with #[serde(with = "serde_bytes")] and implementing wire-compatible serialize_bytes on the SFTP Serializer routes through the existing bulk deserialize_byte_buf/try_get_bytes path. Measured impact on a CPU-bound host (Xeon Silver 4214): 1 GiB SFTP upload throughput improves from 74.8 MiB/s to 96.4 MiB/s (+29%), closing the gap to OpenSSH sftp-server from ~26% to ~5%.
  • scp.root configuration field. SCP transfers now honor a chroot setting separate from SFTP. When unset, SCP falls back to sftp.root, so a single top-level chroot setting governs both subsystems unless an admin explicitly wants them split.

Changed

  • Switched the top-level russh-sftp dependency from crates.io russh-sftp = "2.1.1" to russh-sftp = { package = "bssh-russh-sftp", version = "2.1.1", path = "crates/bssh-russh-sftp" }. All existing use russh_sftp::... imports continue to work unchanged.
  • Default file-transfer behavior is no longer chrooted to the user's home directory. With sftp.root/scp.root unset (the default), absolute client paths are honored verbatim and relative paths resolve from the user's home directory, matching OpenSSH sftp-server/scp defaults. Deployments that intentionally want chroot-at-home-dir must now set sftp.root: <home dir> (or equivalent) explicitly. (#186)

Fixed

  • bssh-server SCP/SFTP path doubling on absolute client paths (#186). ScpHandler::resolve_path and SftpHandler::resolve_path_static previously re-rooted every absolute client path under the user's home directory, so scp local user@host:/home/work/file.bin wrote to /home/work/home/work/file.bin and bssh upload local /abs/remote.bin failed with No such file. The resolver now treats absolute client paths verbatim when no chroot is configured and rejects out-of-chroot absolute paths with permission_denied when one is. Path-traversal and symlink-escape protections continue to apply.
  • SCP single-file destinations no longer have the source filename appended (#186). ScpHandler::receive_file now consults target_is_directory (parsed from -d/-r) and the filesystem state of the resolved target. scp local.bin user@host:/tmp/dest.bin now writes to /tmp/dest.bin instead of /tmp/dest.bin/local.bin. Directory destinations (/tmp/dir/, existing directory, or -d/-r flag) keep the previous filename-appending behavior.
  • Configured sftp.root is no longer dead code (#186). The handler-construction sites in SshHandler previously hard-coded user_info.home_dir as the chroot root and ignored config.sftp.root entirely. Setting sftp.root in the YAML configuration now actually changes the SFTP chroot. The same plumbing now exists for scp.root.
  • Chroot bypass via intermediate-directory symlink. The chroot resolver previously checked only lexical containment for paths whose final component did not exist (typical for new-file creates and mkdir). A symlink inside the chroot pointing to a directory outside the chroot would let a client target chroot/escape/newfile and have open(...)/create_dir(...) follow the symlink, writing outside the chroot. Both ScpHandler::resolve_path and SftpHandler::resolve_path_static now canonicalize the closest existing ancestor of the target path and verify it stays inside the canonicalized chroot, blocking the parent-symlink escape. Found during PR #194 review.

2.1.2 - 2026-04-27

Fixed

  • PTY session mouse tracking leak: after a PTY session disconnects (normal exit, Ctrl+C, network drop, or panic), the local terminal no longer prints raw SGR mouse escape sequences when the mouse is moved. All cleanup paths (TerminalStateGuard::Drop, force_terminal_cleanup, and the panic hook via TerminalGuard) now emit the full set of mouse-tracking-off sequences (modes 1000, 1002, 1003, 1006, 1015) plus cursor-show and alternate-screen-exit on teardown. (#189, #190)
  • Panic-hook safety in terminal cleanup: force_terminal_cleanup() now uses try_lock() instead of lock() so the panic hook path (TerminalGuard::restore_terminalforce_terminal_cleanup) cannot deadlock if the panicking thread already holds TERMINAL_MUTEX, and a previously poisoned mutex no longer triggers a secondary panic. The lock only serializes concurrent teardown; the underlying stdout writes and disable_raw_mode are individually safe. (#190)

Changed

  • Centralized terminal teardown logic: TerminalGuard::restore_terminal() in interactive_signal.rs now delegates to force_terminal_cleanup() instead of carrying its own incomplete cleanup, closing the gap on the panic-hook path.

Tests

  • Added unit tests for force_terminal_cleanup() covering idempotency, poisoned-mutex resilience, and held-mutex resilience (using local Mutex instances rather than the global TERMINAL_MUTEX to keep the global state undisturbed).

CI/CD

  • Trigger the Homebrew formula update workflow only after the official release: release.yml now calls update_homebrew_formula.yml via workflow_call from the publish-release job (which converts pre-release to official), instead of workflow_run firing on every Release workflow completion (including pre-release builds).
  • Prevent the release workflow from being triggered twice: removed the published event type from the trigger list since publish-release already handles the pre-release → official conversion. workflow_dispatch continues to cover manual runs.

2.1.1 - 2026-04-17

Fixed

  • bssh-server panic on client connection: new_client_with_addr called block_on() inside the tokio async runtime to check the auth rate limiter ban list, causing an immediate "Cannot start a runtime from within a runtime" panic on every incoming connection. Added non-blocking AuthRateLimiter::try_is_banned() using RwLock::try_read(). (#185)
  • bssh-server auth rejection after successful verification: All SshHandler constructors created a local SessionInfo that was never registered with SessionManager. After public key or password verification succeeded, authenticate_session() returned SessionNotFound, rejecting the client. Fixed by deferring session creation to the authentication flow via SessionManager::create_session(). (#185)

Changed

  • Improved Launchpad PPA packaging for Rust 2024 edition: updated debian/rules variants, added debian/sanitize-vendor.py for vendored crate checksum sanitization, fixed hidden path handling
  • Added .pyc files to .gitignore

2.1.0 - 2026-04-14

Added

  • EnvGuard RAII wrapper (src/test_helpers/env_guard.rs) for safe environment variable handling in tests, with Drop-based restore semantics and soundness contract documentation (#179, #181)
  • Test Environment-Variable Mutation Pattern section in ARCHITECTURE.md documenting the EnvGuard soundness contract and #[serial] usage

Changed

  • Migrated bssh and the bundled bssh-russh crate to the Rust 2024 edition
  • Applied 2024 edition clippy improvements: collapsed 38 nested if let statements into guard-clause form (if let Some(x) = y && condition) across bssh-russh client/server/keys/kex modules
  • Replaced 177 ad-hoc unsafe { env::set_var/remove_var } call sites across 17 test-bearing files with EnvGuard::set / EnvGuard::remove plus #[serial] from the serial_test crate
  • Removed hand-rolled ENV_MUTEX / once_cell::sync::Lazy<Mutex<()>> pattern in integration tests in favor of #[serial]
  • Pinned bytes dependency to v1.11.1

Fixed

  • Fixed pattern matching for Rust 2024 edition: removed explicit ref / ref mut bindings in if let patterns in src/server/handler.rs and src/server/shell.rs

2.0.1 - 2026-04-13

Added

  • bssh-keygen now included in Debian package build pipeline for all architectures

Changed

  • Bumped bssh-russh from 0.60.0 to 0.60.1 with security updates

Fixed

  • Fixed GitHub Actions debian_build.yml distro configuration (questing -> resolute)
  • Fixed debian_build.yml matrix validation issue causing workflow failures

Security

  • Updated rsa to 0.10.0-rc.17 (fixes RUSTSEC-2023-0071 RSA Marvin Attack)
  • Updated RC dependencies to latest versions: elliptic-curve 0.14.0-rc.30, p256/p384/p521 0.14.0-rc.8, ml-kem 0.3.0-rc.2, spki 0.8.0 (stable)

2.0.0 - 2026-04-13

Added

  • bssh-server SSH Server - A lightweight SSH server designed for container environments

    • Full SSH, SFTP, and SCP protocol support
    • PTY/shell session support with terminal handling
    • Password and public key authentication
    • YAML-based comprehensive configuration system
    • Command execution handler with security controls
  • Audit Logging Infrastructure

    • File-based audit exporter (JSON Lines format)
    • OpenTelemetry audit exporter for observability platforms
    • Logstash audit exporter for ELK stack integration
    • Configurable audit event types and logging levels
  • Security Features

    • IP-based access control (allow/deny lists)
    • Authentication rate limiting (fail2ban-like protection)
    • Session management and connection limits
    • Path traversal prevention in SFTP handler
  • File Transfer Filtering

    • Path-based filter rules for upload/download control
    • Pattern-based filtering with glob support
    • Configurable filter actions (allow/deny)
  • bssh-keygen Tool

    • SSH key pair generation utility
    • Support for RSA, Ed25519, and ECDSA key types
    • Configurable key sizes and comments
  • Server Configuration

    • Per-jump-host SSH private key configuration
    • SSH config Host alias reference in jump_host configuration
    • SSH keepalive settings in interactive mode
  • Separate Packaging

    • bssh and bssh-server now distributed as separate packages
    • Independent Debian packages for client and server
    • Separate Homebrew formulas for each component

Changed

  • Documentation: Added comprehensive server configuration manual and manpages
  • CI/CD: Updated release workflow for dual-package distribution; Teams release notification added
  • Dependencies: Synced bssh-russh fork with upstream warp-tech/russh v0.60.0, which brings the RustCrypto chain migration — rand 0.9 → 0.10 stable, signature 3.0.0-rc.10, ed25519-dalek 3.0.0-pre.6, elliptic-curve 0.14.0-rc.28, p256/p384/p521 0.14.0-rc.7, ecdsa 0.17.0-rc.16, curve25519-dalek 5.0.0-pre.6, der 0.8, sec1 0.8, pkcs8 0.11.0-rc.11, pkcs5 0.8.0-rc.13, spki 0.8.0-rc.4, ml-kem 0.3.0-rc.1, ssh-key 0.6.18, tokio 1.51.1, socket2 0.6.3, signal-hook 0.4.4, fastrand 2.4.1
  • Cluster flag help: Help examples and man pages now correctly show -C (uppercase) for the cluster flag; running the previous -c examples failed with clap's "unexpected argument" error

Fixed

  • SSH idle disconnects: Interactive sessions could disconnect inconsistently after idle time — sometimes within minutes, sometimes ~10 minutes
    • russh::Config::inactivity_timeout (10-minute client-side ceiling) is now explicitly set to None when keepalive is enabled so the keepalive mechanism alone decides peer liveness
    • TCP-level SO_KEEPALIVE (via socket2::TcpKeepalive) is now applied to every SSH socket so the kernel can detect broken paths even when SSH keepalive replies are dropped by middleboxes
    • The exec-mode code path previously dropped the user-configured SshConnectionConfig at the ConnectionConfig boundary; it now flows through connect_direct / connect_via_jump_hosts / the jump chain, so server_alive_interval actually takes effect in non-interactive runs
  • bssh-server: Use consistent source package name in Debian control file so dual-package builds resolve correctly
  • bssh-server: Use type inference for ioctl to support both glibc and musl builds

Technical Details

  • Shared module structure for client/server code reuse
  • russh-based SSH server handler implementation
  • Modular audit exporter architecture with trait-based design
  • SshConnectionConfig::to_russh_config() now overrides inactivity_timeout based on keepalive state; to_tcp_keepalive() derives a kernel TCP keepalive config from the same settings
  • Client::connect_with_config rewritten around russh::client::connect_stream, building the TcpStream manually so SO_KEEPALIVE can be applied before the SSH handshake
  • Dropped the ssh_key::rand_core::OsRng workaround in key-generation sites; now pass &mut rand::rng() (rand 0.10's thread RNG implements the new rand_core 0.10 CryptoRng trait directly)

1.7.0 - 2026-01-09

Added

  • SSH Keepalive Support (Issue #122)
    • --server-alive-interval option: Configure keepalive interval in seconds (default: 60, 0 to disable)
    • --server-alive-count-max option: Maximum keepalive messages without response before disconnect (default: 3)
    • Configuration support in config.yaml via server_alive_interval and server_alive_count_max fields
    • Helps maintain long-running sessions through firewalls and NATs that drop idle connections
    • Full integration with exec, interactive, and file transfer modes

Changed

  • Documentation: Added GitHub downloads badge to README

Dependencies

  • Updated russh from 0.55.0 to 0.56.0
  • Updated ratatui from 0.29.0 to 0.30.0
  • Updated signal-hook from 0.3.18 to 0.4.1
  • Updated whoami from 1.6.1 to 2.0.1
  • Updated unicode-width from 0.2.0 to 0.2.2

Technical Details

  • Implemented SSH keepalive packet sending at configurable intervals
  • Automatic connection termination after max retries without response
  • Keepalive settings work with jump host connections
  • Adapted to whoami 2.0 API changes (username() now returns Result)

1.6.0 - 2025-12-19

Added

  • Jump Host Configuration Support in YAML (Issue #115, PR #120)
    • Global defaults level: defaults.jump_host for all clusters
    • Cluster level: clusters.<name>.jump_host for cluster-specific settings
    • Node level: Per-node jump_host in detailed node configuration
    • Environment variable expansion supported (${VAR} or $VAR syntax)
    • Empty string ("") explicitly disables jump host inheritance
    • CLI -J option always takes precedence over configuration

Changed

  • SSH Config ProxyJump Directive (Issue #117, PR #119)
    • ProxyJump directive from SSH config now properly applied when -J option not specified
    • Priority order: CLI -J > config.yaml jump_host > SSH config ProxyJump
  • Documentation Improvements
    • Added comprehensive jump_host configuration documentation to README.md
    • Updated docs/architecture/ssh-jump-hosts.md with detailed architecture
    • Updated example-config.yaml with all jump_host configuration patterns
  • CI/CD
    • Updated GitHub workflows

Fixed

  • Jump Host Authentication (Issue #116, PR #118)
    • Properly handle empty SSH agent when authenticating through jump hosts
    • Fall back to key-based authentication when agent has no identities
  • Config Fallback (PR #120)
    • Environment variables now properly expanded in jump_host values via expand_env_vars
    • Configuration jump_host properly used in exec and interactive modes

Technical Details

  • Added ConfigResolver::resolve_jump_host() method for centralized jump host resolution
  • Jump host priority: CLI > Node > Cluster > Global defaults
  • Comprehensive test coverage: 424 lines of tests for jump_host configuration
  • Integration tests for all priority levels and edge cases

1.5.1 - 2025-12-18

Fixed

  • SSH Disconnect Error Handling (Issue #113, PR #114)
    • Handle SshError(Disconnect) during authentication for password fallback
    • Fixed handling of SSH disconnect errors during authentication phase
    • Enables proper password fallback when SSH connection is disconnected during auth

1.5.0 - 2025-12-18

Added

  • pdsh Compatibility Mode (Issues #100-103, #105, #107, #110)

    • Full pdsh-style command line compatibility when invoked as pdsh or with --pdsh-compat
    • -w hosts option mapped to -H hosts for target host specification
    • -x hosts option mapped to --exclude hosts for host exclusion
    • -f N option mapped to --parallel N for fanout control
    • -l user option for remote username
    • -t N option mapped to --connect-timeout N for connection timeout
    • -u N option mapped to --timeout N for command timeout
    • -N option mapped to --no-prefix for disabling hostname prefix in output
    • -b option mapped to --batch for single Ctrl+C termination
    • -k option mapped to --fail-fast for stop on first failure
    • -q query mode to show target hosts and exit
    • -S option mapped to --any-failure for returning largest exit code
  • Hostlist Expressions (Issue #107)

    • pdsh-style range expansion: node[1-5] → node1, node2, node3, node4, node5
    • Zero-padded ranges: node[01-05] → node01, node02, node03, node04, node05
    • Comma-separated values: node[1,3,5] → node1, node3, node5
    • Cartesian product: rack[1-2]-node[1-3] → 6 hosts
    • Domain suffix support: web[1-3].example.com
    • User and port preservation: admin@db[01-03]:5432
    • File input with ^/path/to/hostfile
  • In-TUI Log Panel (Issue #106)

    • Toggle visibility with l key
    • Color-coded by level: ERROR (red), WARN (yellow), INFO (white), DEBUG (gray)
    • Configurable buffer size via BSSH_TUI_LOG_MAX_ENTRIES (default: 1000, max: 10000)
    • Panel height adjustable from 3-10 lines with +/- keys
    • Scroll with j/k keys, toggle timestamps with t
  • --fail-fast Option (Issue #103)

    • -k / --fail-fast flag to stop immediately on first failure
    • Compatible with pdsh -k option
    • Cancels pending commands when any node fails
    • Can be combined with --require-all-success for strict error handling
  • --batch Option (Issue #102)

    • -b / --batch flag for single Ctrl+C termination
    • Compatible with pdsh -b option
    • Useful for non-interactive scripts and CI/CD pipelines
  • --exclude Option (Issue #100)

    • --exclude / -x for host exclusion
    • Supports wildcards, glob patterns, and hostlist expressions
    • Applied after --filter option
  • --no-prefix Option (Issue #101)

    • -N / --no-prefix for disabling hostname prefix in output
    • Compatible with pdsh -N option
    • Works with both stream mode and file mode
  • --connect-timeout Option (PR #103)

    • Separate connection timeout from command execution timeout
    • Default: 30 seconds, minimum: 1 second
    • Useful for fast failure detection on unreachable hosts

Changed

  • CI Workflow Simplification
    • Merged multiple jobs into single pipeline for efficiency

Fixed

  • --timeout 0 Handling (Issue #112)

    • Fixed --timeout 0 to correctly treat as unlimited execution time
    • Previously the 0 value was being ignored, causing unexpected timeout behavior
    • Added explicit CLI test to prevent regression
  • Environment Variable Test Race Conditions

    • Added #[serial] attribute to env var tests to prevent race conditions
    • Tests now run sequentially when accessing shared environment state
  • Connect Timeout Propagation

    • Fixed connect_timeout not being propagated through all SSH connection paths

Documentation

  • Architecture Restructure (Issue #109)

    • Restructured ARCHITECTURE.md into modular documentation
    • Removed residual dates and fixed incomplete sentences
  • pdsh Compatibility Documentation (Issue #110)

    • Added comprehensive pdsh migration guide (docs/pdsh-migration.md)
    • Added pdsh options reference (docs/pdsh-options.md)
    • Added pdsh usage examples (docs/pdsh-examples.md)
    • Added installation scripts for pdsh symlink setup

1.4.2 - 2025-12-16

Fixed

  • PTY Session Terminal Handling (PR #90)
    • Fixed terminal escape sequence responses displayed on first prompt when starting tmux
    • Improved terminal compatibility with multiplexers
  • PTY Session Paste (PR #89)
    • Fixed paste not working in PTY sessions
    • Improved clipboard/paste functionality in interactive terminal sessions

Changed

  • Dependencies
    • Bumped dependencies to latest versions for security and compatibility

1.4.1 - 2025-12-16

Added

  • Comprehensive Test Suite (Issue #82, PR #86)
    • tests/tui_snapshot_tests.rs: 20 tests for TUI rendering using ratatui's TestBackend
    • tests/tui_event_tests.rs: 36 tests for keyboard navigation, scroll behavior, and view transitions
    • tests/streaming_integration_tests.rs: 28 tests for NodeStream, MultiNodeStreamManager, and streaming execution
    • benches/large_output_benchmark.rs: Performance benchmarks for large output handling
    • Total: 84 new tests added

Fixed

  • SSH Agent Password Fallback (Issue #84, PR #85)
    • Extended password fallback to handle all SSH agent authentication failures
    • Now correctly triggers for: AgentAuthenticationFailed, AgentNoIdentities, AgentConnectionFailed, AgentRequestIdentitiesFailed
    • Added is_auth_error_for_password_fallback() helper function for testability
    • Added unit tests and integration tests for all error types

Documentation

  • TUI Module Documentation (Issue #81, PR #83)
    • Added comprehensive TUI architecture section to ARCHITECTURE.md
    • Enhanced README.md with keyboard shortcuts reference table
    • Added view modes description table
    • Added TUI activation conditions and requirements
    • Added missing "1-9: Jump to node N" shortcut in detail view help text

Dependencies

  • Added insta 1.34 (snapshot testing)
  • Added criterion 0.5 (benchmarking)
  • Added mockall 0.12 (mocking for integration tests)

Technical Details

  • Refactored test code quality: removed unused functions, replaced panic! with matches! macro
  • Added Unicode test cases (Korean, Chinese, Emoji)
  • Improved assertion messages for better debugging

1.4.0 - 2025-12-15

Added

  • Sudo Password Support (Issue #74, PR #78)
    • -S/--sudo-password flag for automated sudo authentication
    • Securely prompts for sudo password before command execution
    • Automatically detects and responds to sudo password prompts
    • Works with both streaming and non-streaming execution modes
    • BSSH_SUDO_PASSWORD environment variable support (with security warnings)
    • Uses secrecy crate for secure memory handling
    • Password cleared from memory immediately after use
  • Developer Tooling
    • Added githooks for development workflow
    • Setup script for githooks configuration

Fixed

  • Password Fallback (PR #80)
    • Improved SSH debugging for better compatibility
    • Enhanced password authentication fallback logic
  • Fixed clippy warnings for useless_vec and same_item_push

1.3.0 - 2025-12-10

Added

  • Interactive TUI (Terminal User Interface) (Phase 3 of #68)
    • Summary view: All nodes at a glance with progress bars
    • Detail view (1-9): Full output from specific node with scrolling
    • Split view (s): Monitor 2-4 nodes simultaneously
    • Diff view (d): Compare output from two nodes side-by-side
    • Auto-scroll (f): Toggle automatic scrolling
    • Navigation: Arrow keys, PgUp/PgDn, Home/End
    • Help (?): Show keyboard shortcuts
    • Press q to quit
  • Multi-node Stream Management (Phase 2 of #68)
    • Real-time output modes for multi-node operations
    • Stream mode with [node] prefixes for real-time monitoring
    • Enhanced streaming infrastructure for real-time updates

Fixed

  • PTY Escape Sequence Filtering (PR #77)
    • Filter terminal escape sequence responses in PTY sessions
    • Fixed issue with terminal response codes appearing in output

Technical Details

  • Implemented ratatui-based TUI rendering
  • Added multi-node output aggregation and display
  • Performance optimizations for real-time output streaming

1.2.2 - 2025-10-29

Fixed

  • Backend.AI Auto-detection (PR #66)
    • Improved host heuristics for Backend.AI environments
    • Added localhost and localhost.localdomain detection
    • Added IPv4 address validation (127.0.0.1, 192.168.x.x, etc.)
    • Enhanced detection for user@host, host:port, FQDN, IPv6 patterns
    • Users can now use bssh localhost "command" naturally in Backend.AI

Technical Details

  • Extracted testable looks_like_host_specification() function
  • Added is_ipv4_address() helper with strict validation
  • Performance optimized with early returns
  • 16 comprehensive tests added for host detection logic

1.2.1 - 2025-10-28

Fixed

  • Password Authentication Fallback in Interactive Mode (PR #65)
    • Re-implemented password authentication fallback logic for interactive mode
    • Fixed issue where password prompt was not appearing after key-based authentication failed
    • Ensured proper authentication flow in interactive sessions
  • Test Race Condition (commit d2e8ce9)
    • Added #[serial] attribute to tests calling RankDetector to prevent environment variable race conditions
    • Tests now run sequentially when accessing shared environment state
    • Prevents intermittent test failures due to concurrent environment variable access

1.2.0 - 2025-10-27

BREAKING CHANGES

  • Exit code behavior changed (Issue #62)
    • Old behavior (v1.0-v1.1): Returns 0 only if all nodes succeeded, 1 if any failed
    • New behavior (v1.2.0+): Returns main rank's actual exit code (matches MPI standard: mpirun, srun, mpiexec)
    • Impact: Users relying on "all nodes must succeed" semantics must add --require-all-success flag
    • Benefit: Preserves actual exit codes (139=SIGSEGV, 137=OOM, 124=timeout) for better diagnostics
    • MPI users: No changes needed - behavior improved and matches standard tools
    • Health checks: Add --require-all-success flag to preserve old behavior

Added

  • Exit Code Strategy (Issue #62)
    • Main rank exit code returned by default (matches MPI standard: mpirun, srun, mpiexec)
    • Preserves actual exit codes: 139 (SIGSEGV), 137 (OOM), 124 (timeout), etc.
    • --require-all-success flag for v1.0-v1.1 behavior (returns 0 only if all nodes succeed)
    • --check-all-nodes flag for hybrid mode (main rank code + all-node check)
    • Automatic main rank detection via BACKENDAI_CLUSTER_ROLE environment variable
    • Example scripts: examples/mpi_exit_code.sh, examples/health_check.sh

Changed

  • Exit code behavior now aligns with HPC and distributed computing best practices
  • Enables sophisticated error handling in shell scripts and CI/CD pipelines

1.1.0 - 2025-10-24

Added

  • macOS Keychain Integration (Issue #59, PR #61)
    • Automatic passphrase storage in macOS Keychain after successful SSH key authentication
    • Automatic passphrase retrieval before prompting user
    • Secure memory handling with Zeroizing for all sensitive data
    • Integration with SSH config UseKeychain option per host
    • New module src/ssh/keychain_macos.rs with complete Keychain API wrapper
  • ProxyUseFdpass SSH Option (Issue #58, PR #60)
    • Added ProxyUseFdpass SSH configuration option support
    • Optimizes ProxyCommand usage by passing connected file descriptors back to ssh
    • Reduces overhead from lingering processes and extra read/write operations
  • Password Authentication Fallback
    • Automatic password retry when publickey authentication fails
    • Matches OpenSSH standard behavior for seamless user experience
    • Interactive terminal detection with TTY checks
    • Works for both exec and interactive modes

Security

  • SSH Key File Ownership Validation (PR #61)
    • Prevents storing passphrases for SSH keys owned by other users
    • Added macOS user ID checks using libc
    • World-readable SSH key permission warnings
  • User Consent for Password Fallback (PR #61)
    • Explicit user consent prompt before attempting password authentication
    • 30-second timeout for consent prompt
    • Prevents unexpected password prompts that could lead to credential exposure
  • Rate Limiting (PR #61)
    • 100ms delay before initial connection attempts
    • 1 second delay before password fallback
    • Prevents brute-force attacks and fail2ban triggers

Improved

  • Code Quality (PR #61)
    • Eliminated 251 lines of code duplication in connection logic
    • Created establish_connection() helper function
    • Centralized authentication logic in auth module
    • 60% reduction in connection.rs complexity
  • Cross-Platform Support
    • All macOS-specific code properly isolated with #[cfg(target_os = "macos")]
    • Conditional imports to prevent unused code warnings on non-macOS platforms
    • Stub functions for API consistency across platforms

Fixed

  • Fixed clippy warnings on non-macOS platforms (unused_mut, unused_imports, dead_code)
    • Variable shadowing for macOS-specific code paths
    • Conditional imports for platform-specific functions
  • Fixed interactive mode missing use_keychain field causing authentication failures
  • Fixed password prompt not appearing when connecting to new servers in interactive mode

Dependencies

  • Added security-framework = "2.12.1" for macOS Keychain API integration
  • Added libc for macOS user ID checks (conditional on macOS)

1.0.0 - 2025-10-24

Added

  • SSH Configuration: Certificate Authentication Options

    • CertificateFile - Specify SSH certificate files for PKI authentication (maximum 100 certificates)
    • CASignatureAlgorithms - Define CA signature algorithms for certificate validation (maximum 50 algorithms)
    • HostbasedAuthentication - Enable/disable host-based authentication
    • HostbasedAcceptedAlgorithms - Specify accepted algorithms for host-based authentication (maximum 50 algorithms)
  • SSH Configuration: Advanced Port Forwarding Control

    • GatewayPorts - Control remote port forwarding access (yes/no/clientspecified)
    • ExitOnForwardFailure - Terminate connection when port forwarding fails
    • PermitRemoteOpen - Specify allowed destinations for remote TCP port forwarding (maximum 1000 entries)
  • SSH Configuration: Command Execution and Automation Options

    • PermitLocalCommand - Allow execution of local commands after successful SSH connection (yes/no, default: no)
    • LocalCommand - Execute local command after connection with token substitution support (%h, %H, %n, %p, %r, %u, %%)
    • RemoteCommand - Execute command on remote host instead of starting interactive shell
    • KnownHostsCommand - Execute command to obtain host keys dynamically (supports token substitution)
    • ForkAfterAuthentication - Fork SSH process to background after successful authentication (yes/no)
    • SessionType - Specify session type: none (port forwarding only), subsystem (e.g., SFTP), or default (shell)
    • StdinNull - Redirect stdin from /dev/null for background operations and scripting (yes/no)
  • SSH Configuration: Host Key Verification & Security Options

    • NoHostAuthenticationForLocalhost - Skip host key verification for localhost connections (convenient for local development, default: no)
    • HashKnownHosts - Hash hostnames in known_hosts file to prevent hostname disclosure if compromised (default: no)
    • CheckHostIP - Check host IP address in known_hosts for DNS spoofing detection (deprecated in OpenSSH 8.5+, retained for legacy compatibility)
    • VisualHostKey - Display ASCII art of host key fingerprint for visual verification (default: no)
    • HostKeyAlias - Specify alias for host key lookup in known_hosts (useful for load-balanced services with shared keys)
    • VerifyHostKeyDNS - Verify host keys using DNS SSHFP records (yes/no/ask, default: no)
    • UpdateHostKeys - Accept updated host keys from server automatically (yes/no/ask, default: no)
  • SSH Configuration: Additional Authentication Options

    • NumberOfPasswordPrompts - Control password authentication retry attempts (valid range: 1-10, default: 3)
    • EnableSSHKeysign - Enable ssh-keysign for host-based authentication (yes/no, default: no)
  • SSH Configuration: Network & Connection Options

    • BindInterface - Bind SSH connection to specific network interface (alternative to BindAddress for multi-homed hosts)
    • IPQoS - Set IP type-of-service/DSCP values for interactive and bulk traffic (e.g., "lowdelay throughput")
    • RekeyLimit - Control SSH session key renegotiation frequency (format: "data [time]", e.g., "1G 1h")
  • SSH Configuration: X11 Forwarding Options

    • ForwardX11Timeout - Set timeout for untrusted X11 forwarding connections (time interval, default: 0 = no timeout)
    • ForwardX11Trusted - Enable trusted X11 forwarding with full display access (yes/no, default: no)
  • Security Enhancements

    • Path validation to prevent usage of sensitive system files (e.g., /etc/passwd, /etc/shadow)
    • Memory exhaustion prevention with entry limits for certificates and forwarding rules
    • Algorithm list validation with maximum entry limits
    • Deduplication for certificate files and remote forwarding destinations
    • Command injection prevention for LocalCommand and KnownHostsCommand
    • Token validation to prevent invalid substitution patterns
    • Dangerous character detection in command strings (semicolons, backticks, pipes, etc.)

Changed

  • SSH Config Parser: Refactored into modular structure for better maintainability
    • Split oversized parser.rs (1706 lines) into category-based modules (~200-350 lines each)
    • Organized option parsing by categories: authentication, security, forwarding, connection, etc.
    • Improved code organization and maintainability

Technical Details

  • Enhanced SSH configuration merging logic with proper priority handling
  • Support for both "Option Value" and "Option=Value" syntax
  • Scalar options override in later blocks, vector options accumulate with deduplication
  • SSH Configuration Coverage: ~71 options (~69% of OpenSSH's 103 options)
    • Basic options + Include + Match directives (structural)
    • Certificate authentication and port forwarding (7 options)
    • Command execution and automation (7 options)
    • Host key verification, authentication, network, and X11 options (15 options)
  • Comprehensive test coverage: 278 tests including parser, resolver, integration, and security tests
  • Validation: NumberOfPasswordPrompts range checking (1-10), CheckHostIP deprecation warnings

0.9.1 - 2025-10-14

Added

None

Changed

  • PTY Terminal Modes: Complete implementation of PTY terminal modes for better interactive session support
  • Shift Key Input Support: Full Shift key input handling in PTY mode for proper terminal behavior

Fixed

  • Terminal mode implementation for PTY sessions
  • Shift key input handling in interactive mode

Technical Details

  • Enhanced terminal mode settings for PTY allocation
  • Implemented proper terminal flag handling for interactive sessions
  • Improved keyboard input processing for special keys

0.9.0 - 2025-10-14

Added

  • Configurable Jump Host Limit: Maximum number of jump hosts can now be configured via environment variable

    • BSSH_MAX_JUMP_HOSTS environment variable for dynamic limit configuration
    • Default: 10 jump hosts, Absolute maximum: 30 (security cap)
    • Invalid/zero values fall back to default with warning logs
    • Example: BSSH_MAX_JUMP_HOSTS=20 bssh -J host1,...,host20 target
    • Prevents resource exhaustion attacks while allowing flexible configurations
  • Jump Host File Transfer Support: Added complete file transfer operations through SSH jump hosts

    • upload_file_with_jump_hosts() - Upload single files through jump host chains
    • download_file_with_jump_hosts() - Download single files through jump hosts
    • upload_dir_with_jump_hosts() - Upload directories recursively through jump hosts
    • download_dir_with_jump_hosts() - Download directories through jump hosts
    • All file transfer operations now fully support multi-hop SSH connections
  • Jump Host Interactive Mode Support: Interactive shell sessions now work through jump hosts

    • Added jump_hosts field to InteractiveCommand structure
    • Dynamic timeout calculation based on hop count (30s base + 15s per hop)
    • Prevents premature timeouts on multi-hop connections
    • Full authentication support (SSH keys, agent, password) for each hop
  • Parallel Executor Integration: Jump host support across all parallel operations

    • Updated executor.rs to propagate jump_hosts to all node operations
    • Maintains backward compatibility with Option<&str> type
    • All *_to_node() functions now accept jump_hosts parameter

Changed

  • Interactive Mode: Now includes jump host support with automatic timeout adjustment

    • Connection timeout scales with hop count for reliability
    • Example timeouts: Direct (30s), 1 hop (45s), 2 hops (60s), 3 hops (75s)
  • Test Coverage: Updated all test files to include jump_hosts parameter

    • tests/interactive_test.rs: Added jump_hosts: None to test cases
    • tests/interactive_integration_test.rs: Updated all 9 test instances
    • examples/interactive_demo.rs: Updated example with jump_hosts field
  • Dependencies: Updated various dependencies for security patches and stability

Fixed

  • Interactive mode timeout issues when connecting through jump hosts
  • File transfer operations not working with jump host chains

Security

  • Added serial_test dependency for thread-safe environment variable testing
  • Comprehensive test coverage for environment variable functionality (6 new tests)

Technical Details

  • Files Modified: 8 files
  • Lines Added: +623
  • Lines Removed: -26
  • Net Change: +597 lines
  • Test Results: All 132 tests passing

0.8.0 - 2025-09-12

Added

  • Comprehensive SSH port forwarding support
    • Local port forwarding (-L) for tunneling to remote services
    • Remote port forwarding (-R) for exposing local services
    • Dynamic port forwarding (-D) for SOCKS4/5 proxy functionality
  • Improved error messages with better context and recovery suggestions

Changed

  • Removed dangerous unwrap() calls throughout codebase
  • Enhanced error handling with detailed failure reasons

0.7.0 - 2025-08-30

Added

  • SSH jump host infrastructure (-J option)
    • OpenSSH ProxyJump format parsing
    • Multiple jump hosts support (comma-separated)
    • IPv6 address handling with bracket notation
    • Jump host chain management and connection establishment

Changed

  • Improved Ubuntu PPA support with better packaging
  • Fixed deprecated GitHub Actions workflows

0.6.1 - 2025-08-28

Changed

  • Rebranded from "Backend.AI SSH" to "Broadcast SSH"
    • Emphasizes core broadcast/parallel functionality
    • Better reflects the tool's primary purpose

0.6.0 - 2025-08-28

Added

  • SSH configuration file support (-F option)
    • Auto-loads from ~/.ssh/config by default
    • Supports 40+ SSH directives
    • Wildcard pattern matching and negation
    • Environment variable expansion in paths
  • PTY allocation for interactive sessions (-t/-T options)
  • SSH configuration caching for improved performance
    • LRU cache with configurable size and TTL
    • File modification detection
    • 10-100x faster repeated operations

Changed

  • Enhanced security with improved host key verification
  • Performance improvements across core operations
  • SSH-compatible command-line interface (drop-in replacement)

0.5.4 - 2025-08-27

Fixed

  • Parallel configuration value handling issues
  • Interactive mode authentication alignment with exec mode

0.5.3 - 2025-08-27

Changed

  • Backend.AI cluster auto-detection now uses cluster SSH key configuration

0.5.2 - 2025-08-27

Fixed

  • Configuration file loading priority issues
  • Backend.AI environment variable handling improvements

Changed

  • Now uses cluster SSH key configuration when available

0.5.1 - 2025-08-25

Added

  • Configurable command timeout support
    • Set timeout via --timeout flag or configuration file
    • Support for unlimited execution time (timeout=0)
    • Default timeout: 300 seconds (5 minutes)

0.5.0 - 2025-08-22

Added

  • Interactive mode with PTY support
    • Single-node mode for focused interaction
    • Multiplex mode for parallel command execution
    • Node switching commands (!node1, !node2, etc.)
    • Broadcast command (!broadcast <cmd>)
    • Visual status indicators (● active, ○ inactive)
    • Command history with rustyline
    • Configurable prompts and settings

Changed

  • Improved Backend.AI cluster auto-detection
  • Enhanced interactive shell capabilities

0.4.0 - 2025-08-22

Added

  • Password authentication support (-P flag)
  • SSH key passphrase support with secure prompting
  • Modern UI with semantic colors and Unicode symbols
  • Debian package distribution (.deb)

Changed

  • XDG Base Directory specification compliance
  • Improved configuration management
  • Enhanced visual feedback and progress indicators

0.3.0 - 2025-08-22

Added

  • Native SFTP directory operations
  • Recursive file transfer support
    • Upload directories with -r flag
    • Download entire directory trees
    • Glob pattern support for batch operations

0.2.0 - 2025-08-21

Added

  • Backend.AI multi-node session support
    • Automatic cluster detection from environment variables
    • Default SSH port 2200 for Backend.AI clusters
  • SSH authentication enhancements
    • SSH agent authentication with auto-detection
    • Host key verification with known_hosts support
    • Multiple authentication method fallback
  • Environment variable expansion in configuration files
  • Connection and command timeout configuration
  • SFTP file transfer (upload/download)
    • SCP-compatible file copy functionality
    • Progress tracking for file operations

Changed

  • Improved error messages and diagnostics
  • Enhanced security with host key verification

0.1.0 - 2025-08-21

Added

  • Initial release of bssh
  • Parallel SSH command execution across multiple nodes
  • Cluster configuration management via YAML files
  • Node specification via CLI (-H flag)
  • SSH key-based authentication
  • Real-time progress tracking with progress bars
  • Per-node output collection and aggregation
  • Configurable parallel execution limits
  • Connectivity testing (ping command)
  • Cluster listing (list command)

Features

  • Built with Rust for performance and safety
  • Async/await pattern for maximum concurrency
  • Tokio runtime for efficient I/O operations
  • russh library for native SSH implementation
  • Cross-platform support (Linux and macOS)