A robust, TUI-based Python utility for securely downloading files and folders from internal servers via an SSH Jump Host (Bastion).
This tool solves the common problem of retrieving logs, configurations, or data from private servers that are not directly accessible from the internet. It establishes a secure SSH tunnel through a Bastion host, provides a modern interactive file browser, and handles recursive downloads with real-time progress visualization.
- Bastion/Jump Host Tunneling: Automatically manages SSH Port Forwarding (Tunneling) to reach private targets.
- Interactive TUI: Navigate remote file systems using a keyboard-driven interface (powered by
questionary). - Recursive Downloads: Automatically handles nested folder structures and files.
- Rich Progress Visualization: Multi-threaded progress bars showing total operation status and individual file transfer speeds (powered by
rich). - Paramiko 3.x Compatibility: Includes a built-in "Monkeypatch" for the
AttributeError: module 'paramiko' has no attribute 'DSSKey'issue, ensuring stability on modern environments connecting to legacy servers. - Smart Authentication: Prioritizes SSH Keys/Agents and gracefully falls back to secure password prompts if keys are missing.
- Python 3.8+
- Network: SSH access to the Jump Host and network routing from the Jump Host to the Target.
It is recommended to run this tool in a virtual environment to manage dependencies cleanly.
# Clone the repo or download the script
mkdir ssh-transfer
cd ssh-transferLinux / macOS:
python3 -m venv venv
source venv/bin/activateWindows:
python -m venv venv
.\venv\Scripts\Activate.ps1Ensure you have the requirements.txt file in the folder.
pip install --upgrade pip
pip install -r requirements.txtCurrently, configuration is managed within the script headers. Open transfer.py in your text editor and modify the CONF dictionary:
CONF = {
# --- JUMP HOST (The Public Gateway) ---
'jump_host': 'bastion.example.com',
'jump_port': 22,
'jump_user': 'admin',
'jump_key': '/path/to/bastion_key.pem',
# --- TARGET HOST (The Private Server) ---
'target_ip': '10.0.0.50', # Internal IP
'target_port': 22,
'target_user': 'ubuntu',
'target_key': '/path/to/target_key.pem', # Optional
# --- BEHAVIOR ---
'start_path': '/var/log', # Where the browser starts
'local_download_dir': './Downloads', # Local save destination
'allow_agent': True, # Use local SSH Agent
}Note: If
jump_keyortarget_keyare left blank or the files are missing, the script will automatically prompt you for a password at runtime.
Once configured and your virtual environment is active:
python3 transfer.py- Arrow Keys (↑ / ↓): Navigate the file list.
- Enter: Open a directory.
.. (go up): Navigate to the parent directory.⬇️ Download this folder: Select this option to begin downloading the current directory and all its contents.
This is a common error when using newer versions of Paramiko with sshtunnel. This script automatically fixes this via a monkeypatch at runtime. No action is required.
- Check Jump Host Config: Ensure
AllowTcpForwarding yesis set in/etc/ssh/sshd_configon the Bastion server. - Check Key Permissions: SSH keys must be read-only by the user (e.g.,
chmod 600 key.pem). - Check IP Allowlisting: Ensure your local IP is allowed to connect to the Bastion.
- External Configuration: Support for
config.yamlor.envfiles to avoid editing code. - CLI Arguments: Override targets via flags (e.g.,
--target 10.0.0.5). - Upload Capability: Support for SFTP
PUToperations. - Resume Support: Ability to resume interrupted large downloads.
Distributed under the MIT License. See LICENSE for more information.