Skip to content

Repository files navigation

SSH MountMate

中文说明

SSH MountMate is a cross-platform desktop app for mounting Linux servers as local drives or folders over SSH/SFTP.

It uses rclone for the actual mount operation and provides a small GUI around the parts that are usually tedious: dependency checks, SSH config import, rclone remote generation, mount options, logs, and startup mounts.

What It Does

  • Mount a Linux server directory on Windows, macOS, or Linux.
  • Import hosts from your existing OpenSSH config and use them as editable defaults.
  • Batch import all concrete hosts from a selected SSH config file.
  • Start from an SAI cluster preset and write app-managed SSH config entries.
  • Add connections manually with host, username, port, password, key file, and key passphrase.
  • Optionally copy a selected key into ~/.ssh and write the copied IdentityFile path.
  • Choose the connection method per mount: rclone native SFTP, system OpenSSH, or an interactive shared SSH session for OAuth/2FA-style login.
  • Store passwords and key passphrases through rclone obscure, not as plain text.
  • Check for rclone and platform mount dependencies.
  • Bundle and verify the official rclone binary in release builds.
  • Configure global rclone VFS cache options in the GUI.
  • Show mount status, capacity usage, logs, and common actions per connection.
  • Show the real rclone upload queue and remote-transfer progress after local file copies appear complete.
  • Verify remote directory contents on refresh and expose refresh/transfer actions from connection-card context menus.
  • Mount or unmount all saved connections from the main window.
  • Build native Rust packages for Windows, macOS, and Linux on x64 and arm64 with GitHub Actions.

Requirements

SSH MountMate release builds bundle the official rclone binary for the target platform and verify it before use. Source builds can use an explicitly configured rclone, a previously managed copy, or a compatible rclone found on PATH.

Windows:

  • Windows 10 or 11
  • bundled rclone, or a source-build configured/system rclone
  • WinFsp
  • OpenSSH Client

Copyable Windows dependency commands:

WinFsp can be downloaded directly from https://winfsp.dev/rel/ . If winget works well on your network, this command is also available:

winget install --id WinFsp.WinFsp -e
powershell -NoProfile -ExecutionPolicy Bypass -Command "Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0"

macOS:

  • bundled rclone, or a source-build configured/system rclone
  • macFUSE or FUSE-T
  • OpenSSH Client

Important macOS note: SSH MountMate release builds use the bundled official rclone binary, so users normally do not need Homebrew rclone. If you override rclone or run from source, do not use the Homebrew rclone package for mounting. Homebrew's rclone package cannot run rclone mount on macOS. Use the official rclone binary instead:

curl https://rclone.org/install.sh | sudo bash

SSH MountMate supports both mount layers documented by rclone on macOS. macFUSE uses a system extension and can be installed with Homebrew Cask:

brew install --cask macfuse

After installing macFUSE, macOS may ask you to allow the system extension in System Settings -> Privacy & Security. Approve it if prompted, then retry the mount.

FUSE-T is a kernel-extension-free alternative that exposes the rclone FUSE filesystem through a local NFSv4 mount:

brew install --cask fuse-t

FUSE-T may require Network Volumes access under System Settings -> Privacy & Security -> Files and Folders. Its NFS-backed semantics also have documented differences, including access/modification-time behavior; review the rclone FUSE-T caveats. FUSE-T is not bundled with SSH MountMate, and its published binary license requires a separate commercial license for commercial use or bundling.

Development builds after v0.4.0 also expose Settings -> Mount method -> rclone built-in NFS (Experimental) on macOS. This opt-in backend runs rclone's own NFS service on an explicitly loopback-only address and does not require macFUSE or FUSE-T. FUSE remains the default for new and migrated settings. Changing the option affects only the next mount, never interrupts an existing mount, and never falls back silently if NFS startup fails. NFS filesystem semantics, performance, and cache behavior can differ from FUSE. Windows continues to use WinFsp and Linux continues to use FUSE3 regardless of this stored macOS setting.

If macOS blocks the downloaded app because it is not notarized, remove the quarantine attribute after unzipping:

sudo xattr -r -d com.apple.quarantine /path/to/SSHMountMate*

Linux:

  • bundled rclone, or a source-build configured/system rclone
  • FUSE support, usually fuse3
  • OpenSSH Client

SSH MountMate detects Linux distributions from /etc/os-release and shows the matching FUSE/OpenSSH command first in the app. The main families are:

  • Debian family: Debian, Ubuntu, Linux Mint, Pop!_OS
  • Fedora/RHEL family: Fedora, RHEL, CentOS Stream, Rocky Linux, AlmaLinux
  • Arch family: Arch Linux, Manjaro, EndeavourOS
  • openSUSE/SUSE family: openSUSE Leap, Tumbleweed, SLES
All common Linux dependency commands
# Debian family: Debian, Ubuntu, Linux Mint, Pop!_OS
sudo apt update && sudo apt install -y fuse3 openssh-client

# Fedora/RHEL family: Fedora, RHEL, CentOS Stream, Rocky Linux, AlmaLinux
sudo dnf install -y fuse3 openssh-clients

# Arch family: Arch Linux, Manjaro, EndeavourOS
sudo pacman -S --needed fuse3 openssh

# openSUSE/SUSE family: openSUSE Leap, Tumbleweed, SLES
sudo zypper install -y fuse3 openssh

In the Settings window, Check dependencies reports rclone, OpenSSH, and the current mount-layer dependency (WinFsp, macFUSE / FUSE-T, or FUSE). SSH MountMate does not silently modify system packages.

Bundled And Managed rclone

Release workflows download a pinned official rclone archive for the target platform and architecture, verify its SHA-256 digest, and include the verified binary in the release artifacts. At runtime SSH MountMate verifies the bundled digest again and materializes a content-addressed managed copy in the application data directory. Explicitly configured and existing legacy managed copies remain supported for migration; a compatible system rclone is the final source-build fallback.

The remote server is assumed to be a Linux server reachable over SSH/SFTP.

Download

Use the latest GitHub Release and download the package for your platform:

  • SSHMountMate-windows-x64.zip
  • SSHMountMate-windows-arm64.zip
  • SSHMountMate-macos-x64.zip
  • SSHMountMate-macos-arm64.zip
  • SSHMountMate-linux-x64.zip
  • SSHMountMate-linux-arm64.zip

Release builds are produced from the Rust workspace by six native GitHub Actions runners. Windows and Linux ZIPs contain one executable with the verified official rclone embedded; Windows builds also embed the independently verified official Plink used by interactive sharing. macOS ZIPs contain the native SSH MountMate.app bundle with rclone and license notices inside the application.

Bundled third-party notices can be viewed from Settings or with:

SSHMountMate --licenses

Program updates can be checked from Settings -> Check for updates, or from the command line:

SSHMountMate --check-update

The in-app updater first verifies an Ed25519-signed manifest embedded in the application trust root. The signature binds the release version, stable/prerelease channel, all six canonical asset names, sizes, and SHA-256 digests. GitHub's published asset digest and metadata must independently match that signed manifest before the matching ZIP can be installed. Missing signatures, unknown keys, mismatched release metadata, or changed ZIPs remain visible in the update view but disable automatic installation with an explicit reason.

After verification, the updater rejects unsafe ZIP paths, stages the new executable or macOS application beside the current installation, and restarts SSH MountMate after confirmation. A startup health handshake commits the update; timeout or failure restores and relaunches the previous build. Existing native SFTP and OpenSSH mounts and uploads can continue while the GUI restarts. Interactive shared SSH depends on the application's login session: installation is blocked while an interactive mount is active, starting, or waiting for login. Finish or cancel pending login, wait for uploads to finish, and unmount those connections before installing.

Automatic installation requires SSH MountMate to be extracted to a permanent, user-writable folder. Builds launched directly from a ZIP temporary directory and releases that fail any signed manifest, platform, size, or digest check remain manual-update only. Current Releases intentionally contain no Windows/Linux onedir update assets, so automatic replacement of those legacy directory layouts is explicitly unsupported; canonical onefile packages and macOS .app updates remain the supported paths. Automatic background checks can be disabled in Settings.

Check CPU architecture:

# Windows
$env:PROCESSOR_ARCHITECTURE
# macOS / Linux
uname -m

Use x64 packages for AMD64 / x86_64, and arm64 packages for ARM64 / arm64 / aarch64. Windows and Linux provide one canonical onefile package per architecture; the executable materializes embedded tools as content-addressed managed copies on first use. Windows includes rclone and Plink, while Linux includes rclone. macOS provides one canonical native .app package per architecture. The release matrix intentionally has six ZIPs instead of separate onefile and onedir variants.

On the first Linux GUI launch, SSH MountMate registers a per-user application launcher and installs its icon under $XDG_DATA_HOME, using applications/ and icons/hicolor/. An unset, empty, or relative XDG_DATA_HOME falls back to ~/.local/share. Later GUI launches update changed files; after moving the executable, launch it again to update the launcher path. The ZIP still contains only the executable.

On macOS, choose the x64 asset for Intel Macs and arm64 for Apple Silicon; both contain the native application bundle.

Quick Start

  1. Install the platform dependencies above.

  2. Confirm normal SSH login works:

    ssh your-host
  3. Start SSHMountMate.

  4. Click Add config.

  5. Choose either:

    • SSH config: select an existing Host entry and let the app fill defaults.
    • SSH config (batch): choose an SSH config file, preview it, then import all concrete Host entries.
    • SAI cluster: start from the SAI preset. HostName and port are prefilled; fill username and key file.
    • Manual: enter host, username, port, and authentication details yourself.
  6. Pick a remote path. $HOME is the default base.

  7. Choose a connection method if the default does not fit.

  8. Save, then click the mount button on the connection card.

On Windows, Auto mountpoint picks an available drive letter. On macOS and Linux, the app uses a per-connection mount folder by default. You can also type a custom mountpoint path.

Mountpoint rules:

  • Windows drive letters such as Z: must be unused.
  • Windows folder mountpoints must be absolute paths. The parent folder must exist, and the target folder itself must not already exist.
  • macOS/Linux custom mountpoints must be absolute paths or start with ~.
  • macOS/Linux custom mountpoint folders are created automatically if missing.
  • Existing macOS/Linux mountpoints are rejected to avoid mounting over another filesystem.

SSH Config Import

SSH MountMate can read your OpenSSH config and list concrete Host entries. Selecting one fills:

  • name
  • host/IP
  • username
  • port
  • key file

After import, the connection is saved as an editable profile. Native SFTP uses the saved host, username, port, and authentication settings. Older alias-only profiles still resolve missing defaults from the source SSH config.

OpenSSH and supported interactive shared SSH connections apply the saved host, username, and port while retaining the original alias and config for features such as ProxyJump and Include. The selected key is preferred; other IdentityFile entries in that config remain available as OpenSSH authentication fallbacks. Keep the source config available when using these methods.

Batch import uses the selected config file and resolves each host with OpenSSH's ssh -F <config> -G <host> behavior. This keeps OpenSSH include/default handling while still saving normal editable SSH MountMate connections.

During batch import, duplicate entries are marked in the preview and skipped:

  • SAME: same SSH Host alias and same HostName/User/Port.
  • SAME HOST: same SSH Host alias but different resolved target.
  • SAME TARGET: different alias but same HostName/User/Port.

Manual and SAI preset connections can also write an app-managed SSH config entry. For SAI, the default profile name and SSH Host are SAI-<username>, with HostName c1.sai.ai-4s.com and Port 12022. SSH MountMate creates ~/.ssh when needed, adds this include line to ~/.ssh/config, and writes each managed Host into its own file:

Include ~/.ssh/ssh-mountmate.d/*.conf

If Copy key to ~/.ssh is enabled, the selected private key is copied into ~/.ssh, and both the mount profile and generated SSH config use the copied IdentityFile path. Passwords and key passphrases are never written to SSH config.

Connection Method

Each saved connection can use one of three methods:

  • rclone native SFTP: the default. rclone handles SSH/SFTP itself and can use saved rclone-obscured passwords or key passphrases.
  • OpenSSH: rclone calls the system ssh command. This is useful for OpenSSH features such as ProxyJump, ProxyCommand, custom Include logic, or system ssh-agent behavior.
  • Interactive shared SSH: the first mount attempt opens an app-managed PTY terminal for OAuth, 2FA, dynamic password, or other keyboard-interactive authentication. Complete login there; the queued mount resumes exactly once when the shared session is ready. The terminal can be hidden while its session remains alive, or explicitly ended. rclone receives only a non-interactive connector to the verified shared session; the one-time response is never passed through SSH MountMate arguments or configuration.

On macOS and Linux, interactive sharing uses an OpenSSH ControlMaster socket in a private state directory. On Windows, portable packages include the pinned official PuTTY Plink 0.84 binary and verify its SHA-256 before using connection sharing. The initial Windows implementation supports direct Manual connections only; imported SSH-config profiles, ProxyJump, and ProxyCommand translation remain unsupported. Ending the app-managed session ends the reusable session, so new mounts and capacity probes that need it will ask for login again; already running rclone mounts are not automatically unmounted, but they can report transport errors until a shared session is re-established.

When OpenSSH is selected, SSH MountMate does not save or pass key passphrases to ssh. Add passphrase-protected keys to your agent first:

ssh-add ~/.ssh/id_ed25519

On macOS, use Keychain support when available:

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Passwords And Key Passphrases

Passwords and key passphrases are passed through:

rclone obscure

The obscured value is stored in SSH MountMate's private configuration. This avoids plain-text storage, but it is reversible and is not strong encryption. It remains the default for compatibility. On macOS and Linux, SSH MountMate writes configuration files with owner-only permissions. Treat the local user account and its config directory as sensitive.

The Settings page also offers a manually enabled System credential store mode. It uses Windows Credential Manager, macOS Keychain, or the Linux Secret Service through the platform's native credential provider. Enabling it asks for confirmation, reveals existing rclone-obscured values locally, writes passwords and private-key passphrases to the OS store, and reads every value back for verification. SSH MountMate's private configuration retains a reversible rclone-obscured compatibility copy, including for newly saved secrets in this mode. Native SFTP operations read the system store whenever a credential reference exists; a failed read stops the operation without falling back to the compatibility copy. Private key files and one-time 2FA/OAuth tokens are never stored in the vault. Native SFTP mounts temporarily fill the rclone configuration with the required secrets and remove its secret fields immediately after startup; this cleanup does not remove the compatibility copy from SSH MountMate's configuration. A cleanup failure stops the new mount. Returning to rclone obscure is an explicit confirmed migration in the other direction.

Interactive shared SSH deliberately bypasses both stored credential modes. Passwords, OAuth responses, and rotating 2FA codes are entered only in the terminal owned by OpenSSH or Plink.

Host Key Validation

SSH MountMate requires host key validation for native rclone SFTP connections.

For rclone SFTP remotes, the app maintains its own known_hosts file. The first connection to a host and port records the keys returned by ssh-keyscan; later connections keep those pinned keys instead of replacing them from the network.

If host key scanning fails or returns no usable key, the app may use an existing readable known_hosts file only when it already contains a binding for the exact host and port. Otherwise the mount stops. Native SFTP never silently starts without a host-key binding. OpenSSH and interactive shared-SSH transports continue to apply their own SSH host-key policy.

If rclone reports knownhosts: key mismatch, SSH MountMate stops the mount rather than disabling validation. Verify the new fingerprint with the server administrator before removing that host's old entry from the app-managed known_hosts file and trying again.

Local Control Authentication

Each mount exposes rclone's remote-control API only on an allocated IPv4 loopback address. The client password remains random per mount and is not placed in rclone's process arguments. Rclone instead reads an owner-private Apache-compatible htpasswd file containing a BCrypt hash; SSH MountMate removes that file with the mount state after startup failures, normal unmounts, and stale state cleanup. The raw client credential remains in the owner-private mount state because the GUI needs it for authenticated status, refresh, transfer, and quit requests.

File-manager and second-instance commands use a separate random token and loopback listener. Unauthenticated requests have a fixed total deadline and are handled by a bounded worker pool, so a slow local connection cannot monopolize the listener or delay normal shutdown indefinitely.

Transfers And Remote Refresh

Mounted connection cards show rclone's real VFS upload queue. The recommended cache profile keeps rclone's upstream five-second write-back window so Explorer/Finder can finish close, rename, and metadata operations before remote upload begins. When automatic transfer display is enabled, queued or active uploads open one shared bottom-right progress window that summarizes active connections and can expand to show details. The Transfer center remains available for manually viewing all mounts together. A file is only shown as cloud-synced after rclone reports no queued or active uploads. SSH MountMate warns before unmounting or exiting while uploads remain.

The simultaneous-upload setting limits how many different cached files rclone may upload at once. The default is 4, with presets for 8 and 12 and a custom range of 1 through 32. Extra files remain queued in the local cache. Rewriting the same path does not create reliable parallel revisions: rclone cancels or reschedules that path's write-back and the latest local content may overwrite another writer's remote change.

The transfer display keeps completed bytes in the current upload session when rclone removes a file from vfs/queue, so the overall progress denominator does not shrink as files finish. The display still waits for rclone's queue and disk-cache counters to report an idle state before declaring the remote synchronized. rclone's own queue is intentionally short-lived and does not expose a durable history, so this smoothing is kept in the app and is reset after each confirmed idle period.

rclone writes a closed file back to the remote after --vfs-write-back (5 seconds by default), and --vfs-cache-min-free-space is a cache eviction target rather than a reserved per-file allowance. Open or recently written files can temporarily exceed cache limits and cannot be evicted while in use. The app therefore keeps the existing full-file VFS cache semantics; allowing a small uncached tail would weaken read-after-write consistency and cannot guarantee that the remote copy is complete.

Refresh clears the VFS directory cache, actively reloads the requested directory, and verifies it with a direct remote listing. If local writes are still queued, the result states that the verified remote snapshot does not yet include those uploads.

Right-click a connection card for Open, Refresh, Transfers, and Log actions. Settings can register Refresh and Transfers commands in Windows Explorer, macOS Finder Quick Actions, and Nautilus, Nemo, or KDE file managers on Linux. The commands point back to the same SSH MountMate executable; no helper program is installed. A short-lived file-manager process forwards its request to the running app over authenticated loopback IPC and exits.

The Rust application keeps a native system-tray icon on Windows, a menu-bar item on macOS, and an AppIndicator on supported Linux desktops. Closing the main window hides it without stopping mounts or transfer monitoring. The tray menu can restore the main window, open Transfers, mount or unmount all connections, and explicitly exit the interface. Exit asks for confirmation when uploads are active or cloud state is unknown. Native SFTP and OpenSSH mounts can continue after the GUI exits; interactive shared SSH depends on the app-managed session and may lose its transport when the application exits.

Capacity Display

For mounted connections, SSH MountMate shows used and total capacity on each card. It first tries to read the remote directory's Lustre project ID with lfs project -d and its quota with lfs quota -p. If that query fails, Lustre is unavailable, or there is no nonzero hard block limit, the app tries the filesystem capacity reported by the local mountpoint, then rclone about, and finally a non-interactive remote df -Pk query.

When Lustre project quota data is available, the hard block limit (blimit) is the displayed total and the capacity percentage is calculated against it. The block soft limit (bquota) is shown as a warning marker and in the card text; reaching or passing it changes the bar to the warning color. The soft limit is used for display and warning purposes, so exceeding it does not make the app treat the hard capacity as full. Whether writes continue after the soft limit depends on Lustre's grace and enforcement policy.

Interactive connections reuse their existing verified shared SSH session for the Lustre and df queries. Other supported profiles need a working non-interactive system SSH login; native SFTP's saved passwords and key passphrases are not passed to ssh. Password-based native connections without an imported or app-managed SSH profile skip these SSH queries.

Settings

The Settings window contains:

  • dependency checks
  • program update check
  • mount log access
  • transfer center and file-manager command registration
  • language selection
  • login startup mount option
  • rclone VFS cache root
  • VFS cache mode
  • max cache size
  • max cache age
  • minimum free space
  • write-back delay
  • directory cache time
  • read buffer size
  • simultaneous cached-file uploads

Each setting option has a ? help icon in the GUI. Hover the icon to see what the option does. Batch mount and unmount concurrency are fixed internally at 4 and 8 workers.

Login startup uses the current user's Windows Run key, a macOS LaunchAgent under ~/Library/LaunchAgents/, or a Linux XDG autostart entry. It calls the Rust application's headless --mount-startup entrypoint after login to mount the connections selected for login startup. Interactive shared SSH connections are excluded because they require an app-managed login session. The older --mount-startup-all option remains a compatibility alias for --mount-all and attempts all saved connections.

Building From Source

Install the Rust toolchain declared in rust-toolchain.toml and the GUI development libraries required by your operating system.

Run from the repository root:

cargo build --release --package ssh-mountmate

The executable is written to target/release/. Release packaging downloads and verifies the platform-specific rclone binary, so use the release workflow or the corresponding native operating system to produce distributable packages.

Development

Run the GUI from source:

cargo run --package ssh-mountmate

Useful checks:

cargo fmt --all --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-features
cargo run --package ssh-mountmate -- --version
cargo run --package ssh-mountmate -- --licenses

License

SSH MountMate's application code is released under the MIT License. See LICENSE.

Release builds bundle rclone. rclone is distributed under the MIT License. See THIRD_PARTY_NOTICES.md, licenses/rclone-COPYING.txt, or the in-app Settings -> View licenses window.

Bundled Rust dependency notices are listed in THIRD_PARTY_NOTICES.md and licenses/.

About

A SSH/SFTP drive mounter powered by rclone and OpenSSH config.

Resources

Contributing

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages