Operational guide — what to do, step by step, to get the most out of SSHBorg on Android and iOS. Where the iOS app differs, a note marked iOS says so.
Tap the + button on the hosts screen to add a new server (on iOS it opens a short menu: choose Add Host).
ubuntu, root, deploy).On the first connection SSHBorg shows you the server's fingerprint and asks you to accept it. This is a security check: it ensures you are connecting to the right machine and not to an impostor. You should verify the fingerprint matches the one shown by your server admin or obtained via a trusted channel before accepting.
Once accepted, the fingerprint is stored locally. If it changes on a future connection, SSHBorg will warn you — this could indicate a server rebuild, a key rotation, or a man-in-the-middle attack.
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
When the server list grows, you can organize hosts into collapsible, color-coded groups — for example Production, Home lab, Clients.
On iOS a group can also be created on its own, from the + button → New group.
Colors can be picked from the quick swatches or, on Android, mixed freely with the gradient color picker — on iOS the swatches are the choice. A host can also have its own color — set it in the host editor, right below the group — which overrides the group color and works for ungrouped hosts too.
Hosts without a group stay at the top of the list, and if you never create a group the list looks and behaves exactly as before.
Choose how the list is arranged in Settings → Host list order:
In the first three modes the groups stay in alphabetical order, so the section headers never move and only the hosts inside them are rearranged. In manual order the groups can be moved as well.
To rearrange, pick Manual, then open the menu of a host or of a group header — the ⋮ button (… on iOS), a long press, or the Menu key on an Android TV remote — and use Move up / Move down. A host only moves inside its own section: to put it in another group, change the group in the host editor. Switching to manual keeps exactly the order that was on screen at that moment, so nothing jumps, and hosts added later go to the end of their section.
The SFTP file manager lets you browse, upload, download, rename, and delete files on your server directly from your phone. Open it from the hosts screen with Files in a host's menu.
Tap a folder to open it. Use the back arrow or tap any segment of the path bar to jump up the directory tree. A tap on a file opens what you can do with it: download, open in the editor, rename, delete.
Symbolic links are shown with a small link icon badge. Tapping a symlink navigates to its target: if it points to a directory you enter it, if it points to a file it behaves like a regular file.
Tap the upload button (↑) to pick one or more files from your phone's storage. The upload starts immediately and progress is shown at the top of the screen.
Tap the download icon at the right of a file's row to download it at once. To download an entire folder, tap the download icon next to it — SSHBorg will download the entire directory tree and save it under the Downloads folder on your phone.
If a file already exists at the destination, a dialog will ask you whether to overwrite, skip the file, or cancel the entire transfer.
Tap Select items in the toolbar to enter selection mode, then tick the items you want. The toolbar shows actions for the current selection:
Choose Cut in a file's or a folder's menu — or several at once with Select items — then open the destination folder and tap Paste in the bar that appears above the list. The move is done by the server itself: nothing is downloaded and nothing is uploaded, so a file of any size moves instantly.
If the destination already holds that name, SSHBorg asks before touching anything. A file can be replaced or kept alongside the existing one; two folders with the same name can only be kept side by side, because no SFTP server can merge folders — mv refuses as well. Moving between two different disks on the server is also refused: a move is a rename, and a rename cannot cross filesystems. That needs a copy, which SSHBorg does not do yet.
Tap a file to open its menu and choose Open in editor to change it directly on the server. Nothing is stored on the phone: the file is read into memory, edited, and written straight back.
The file goes back as it came. Its character encoding is detected and used again when saving, LF or CRLF line endings are preserved, a file that ended without a newline still does, and the permissions stay as they were. If the encoding was read wrong, tap it in the bar at the bottom of the editor and choose another — the list only offers encodings that can reproduce this file's bytes exactly, so a wrong choice can look wrong on screen but cannot damage the file.
Saving writes to a temporary file beside the original and renames it into place, so a connection lost halfway cannot leave a half-written file on the server.
Files open up to 4 MB, whatever their length: only the lines on screen are drawn, so a file of megabytes scrolls like a short one. Above that the terminal is the answer, with nano or vi, and it has no limit at all.
Configuration files are coloured — comments, strings, numbers, keys, section headers, shell variables and XML tags — from the file's name or, when the name says nothing, from the shape of its contents: shell scripts, nginx and sshd style directives, INI, YAML, JSON and XML. Prose, notes and logs are deliberately left plain, where colour would only be noise. Colouring is appearance alone and never changes a byte.
A file that is not text opens in the hex editor: offsets on the left, the bytes in the middle, the printable characters on the right, and a keypad for the hex digits. Tap a byte and type two digits to replace it. Values change but the length never does, so every offset in the file stays where it was. Open in hex in a file's menu opens any file this way, and a text file mistaken for binary — one with a stray NUL byte in it — can still be opened as text from the same dialog.
Key-based authentication is more secure than passwords and does not require you to remember or type anything after setup.
Tap the key icon at the top of the hosts screen to open SSH Keys, then generate a new key. SSHBorg supports:
Give the key a meaningful name (e.g. my-vps or work-server) so you can identify it later.
After generating a key, tap it to see the public key. Copy it and paste it into the server's ~/.ssh/authorized_keys file for the user you want to log in as.
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "ssh-ed25519 AAAA...yourcopiedkey..." >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
PubkeyAuthentication yes in /etc/ssh/sshd_config. This is the default on most distributions, but some hardened images disable it.
Turn on Settings → Security → Encrypt sensitive data to store private keys and saved host passwords encrypted with a key held in the device's secure hardware — the Android Keystore, or the Keychain on iOS. It stays off until you enable it; the security tip shown at first launch points to it.
Encrypted data is bound to the device and to this installation of the app: after uninstalling, the stored keys cannot be recovered, and you would generate new ones and authorize them on your servers again. Together with an app lock, this is strongly recommended if you keep sensitive server credentials on your phone.
A key protected by a passphrase asks for it once, when you import it, and is then stored unlocked: the passphrase itself is never written to the device. A passphrase is usually reused somewhere else, while a private key is worth only itself — and a key stored next to its own passphrase would not be protected by it anyway. What protects it here is the app's private storage, Encrypt sensitive data, and the app lock. A key imported by an earlier version was stored still encrypted and cannot authenticate; the key list marks those, and they have to be imported again.
Two encrypted formats the app cannot open: an OpenSSL container (BEGIN ENCRYPTED PRIVATE KEY) and PuTTY's .ppk. The import says so rather than taking the key half-way. Decrypt it with the tool that created it and import it again — working on a copy, never on your only file:
ssh-keygen -p -N "" -f id_ed25519_copy
openssl pkcs8 -in key.pem -out key_plain.pem
PuTTYgen converts a .ppk from Conversions → Export OpenSSH key.
.ppk, also the older PEM encryption (Proc-Type: 4,ENCRYPTED), which ssh-keygen -m PEM writes when given a passphrase. Decrypt such a key and import it again.
SSHBorg shows a suggestion bar above the keyboard while you type in the terminal. Suggestions are drawn from the shell history of the user you connected as.
When a terminal session opens, SSHBorg reads the shell history file from the remote server. It tries the following locations in order:
~/.bash_history — default for Bash shells~/.zsh_history — default for Zsh (also checked as $HISTFILE if set)~/.local/share/fish/fish_history — for Fish shell usersThe first file that exists and is readable is used. As you type, commands are filtered in real time and shown as chips in the suggestion bar. Tap a chip to insert the command.
No suggestions appear
~/.bashrc:
HISTFILE=~/.bash_history
HISTSIZE=10000
HISTFILESIZE=20000
~/.zshrc:
HISTFILE=~/.zsh_history
HISTSIZE=10000
SAVEHIST=10000
setopt APPEND_HISTORY SHARE_HISTORY
Suggestions are from the wrong user
sudo su - root (or switch to another user with su), the suggestion bar still shows the history of the original login user, not of root. This is because SSHBorg reads the history file before the shell starts, using the credentials you connected with.
root (if your server allows it).
The terminal responds to a few touch gestures beyond typing:
Full-screen apps. Programs that take over the whole screen — tmux, vim, nano, less — have no scrollback of their own, so while one is running the view stays on the live screen instead of drifting into the shell output underneath it.
To scroll inside them, the application has to handle the scrolling itself. In tmux, add set -g mouse on to ~/.tmux.conf: a swipe then scrolls the history of the pane under your finger. The same goes for any program that accepts mouse input, such as vim with set mouse=a. With screen, check that altscreen on is set in ~/.screenrc — on many systems it is off by default, and screen then draws over the ordinary scrollback.
Under Settings → Terminal you can adapt the terminal to your needs:
When the soft keyboard is open, a row of shortcut buttons appears above it. Scroll the bar sideways to reach all the keys.
Ctrl and Alt are sticky toggles — tap one, then tap a letter key to send the combination. They reset automatically after the next keystroke.
The spellcheck icon toggles the keyboard between terminal mode and word mode. In terminal mode (default) autocorrect and word suggestions are disabled — ideal for commands and file paths. In word mode the keyboard behaves like a normal text field, with suggestions and autocorrect enabled. Useful when typing natural language over SSH, for example with Claude Code or other interactive tools.
On Android, word mode is also what makes voice typing work. The keyboard's microphone key needs a real text field to write into, so dictation produces nothing in terminal mode — switch to word mode before dictating.
Scroll the bar to the right to reach F1 through F12.
The bar comes in several layouts. Tap the ⇄ key on the bar to switch: the keys make room for the list of available bars, tap one and you are done — the choice is remembered. You can also pick and manage bars in Settings → Terminal → Extra key bar → Customise.
/ - | ~ and the arrows in keyboard order (← ↑ ↓ →).ESC / - Home ↑ End PgUp over Tab Ctrl Alt ← ↓ → PgDn.To build your own, duplicate a preset (the ⋮ menu next to it, or a long press on iOS) or create a new bar. The editor shows the bar exactly as it will look: tap a key to select it, then use the buttons below to move it left or right, to another row, change it, add a key after it or remove it. Each row can either scroll (keys keep their natural width) or fill the screen width (up to about nine keys per row on a phone). Up to three rows; the key size is adjustable.
Besides the usual keys, a custom bar can hold text keys: any text, sent as typed — a single |, a sudo prefix, or a whole command. Use \n for Enter, \t for Tab and \e for Escape, so ls -la\n becomes a one-tap macro. Two more action keys are available: pin keeps the bar visible with the keyboard closed, keyboard shows or hides the keyboard.
Custom bars are included in the settings backup. On Android TV everything works with the remote: the editor's keys and buttons are all reachable with the D-pad.
SSH agent forwarding lets the keys stored in SSHBorg be used to authenticate further connections made from inside the remote server — for example, to git clone a private repo, or to hop to a second machine.
When adding or editing a host, enable the Agent forwarding toggle. SSHBorg will act as an SSH agent for that session.
The server must allow agent forwarding. Check /etc/ssh/sshd_config:
AllowAgentForwarding yes
This is the default on most systems. After changing it, restart the SSH daemon:
sudo systemctl restart sshd
If you also connect to this server from a laptop or desktop, you can configure forwarding persistently in your local ~/.ssh/config:
Host myserver
HostName 203.0.113.42
User ubuntu
ForwardAgent yes
Some older servers — network appliances, embedded devices, or systems running outdated OpenSSH versions — only support cipher algorithms that modern SSH clients no longer advertise by default.
When you enable the Allow Legacy Ciphers toggle in the host settings, SSHBorg appends the following additional algorithms to the negotiation list:
aes128-cbc, aes192-cbc, aes256-cbc, 3des-cbcdiffie-hellman-group14-sha1, diffie-hellman-group-exchange-sha1, diffie-hellman-group1-sha1ssh-dss (DSA 1024-bit)The server always negotiates the strongest algorithm both sides support, so enabling this option does not weaken connections to modern servers — the legacy algorithms are only used when the server cannot offer anything better.
ssh-dss host keys are not available: the SSH library the app is built with no longer includes DSA, so a server whose only host key is DSA cannot be reached from an iPhone or iPad, even with this option on.
SSH is a live TCP connection between your phone and the server. If the connection is interrupted — even for a second — the session and everything running inside it is lost.
Mobile networks are particularly prone to connection drops for several reasons:
A terminal multiplexer runs a persistent session on the server, completely independent of your SSH connection. If the connection drops, the session and everything running inside it keeps going. When you reconnect, you re-attach and find everything exactly as you left it.
This is the single most useful habit for anyone managing servers from a phone.
tmux is available on most modern Linux distributions and is the recommended choice.
# Start a new named session
tmux new -s work
# Detach from the session (leave it running)
Ctrl+B, then D
# List running sessions
tmux ls
# Re-attach to a session
tmux attach -t work
# Re-attach to the most recent session
tmux attach
screen is older but available on virtually every Unix system, including minimal server images where tmux may not be installed.
# Start a new named session
screen -S work
# Detach from the session
Ctrl+A, then D
# List running sessions
screen -ls
# Re-attach to a session
screen -r work
tmux attach || tmux new -s maintmux attach || tmux new -s main to your ~/.bashrc or ~/.zshrc on the server so that a multiplexer session starts automatically every time you log in via SSHBorg.
A jump host (also called a bastion host) is an intermediate server you must pass through to reach a target server that is not directly accessible from the internet. SSHBorg supports single and multi-hop jump chains natively.
If you need to jump through more than one intermediate server (e.g. internet → bastion → dmz → target), create an entry for each hop and chain them:
The equivalent setup in a desktop ~/.ssh/config looks like this:
Host bastion
HostName bastion.example.com
User admin
ForwardAgent yes
Host target
HostName 10.0.1.50
User ubuntu
ProxyJump bastion
ForwardAgent yes
With this config, ssh target on your laptop transparently jumps through the bastion.
SSHBorg lets you keep several SSH terminal sessions and SFTP file manager sessions open at the same time, even to different servers.
tmux or screen on the server side if you want them to survive even if the SSH connection drops.
Choose how the app is protected in Settings → Security → App lock: None (default), Biometric only (fingerprint or face unlock), Device lock (the device PIN, pattern, or password, alongside biometrics), or an in-app PIN or passphrase. When a lock is active, SSHBorg requires authentication before showing any host, credential, or session data. If authentication is refused, or you cancel it, the app stays on its own lock screen with a button to try again — it does not close, so the sessions you had open are still there when you unlock.
The in-app PIN or passphrase works on any device, even without biometric hardware or a system screen lock — which makes it the right choice on an Android TV. Changing or removing it asks for the current one first. There is no way to recover it if forgotten: you would have to clear the app's data or reinstall, so keep a backup of your hosts.
You can set an inactivity timeout — after that long in the background the app locks automatically.
By default SSHBorg blocks screenshots and screen recording to prevent sensitive terminal content from leaking via the recent-apps screen or screen capture tools.
If you need to take a screenshot (e.g. to share a terminal output), you can temporarily disable screenshot protection in Settings → Security → Allow screenshots.
With Encrypt sensitive data turned on (see SSH Keys), passwords and private keys are stored encrypted with a key held in the Android Keystore — hardware-backed on Android 10+ — or, on iOS, in the Keychain, restricted to this device. Credentials are never written to external storage or transmitted anywhere.
Each piece above is useful on its own. Together they are as tight as the app gets, and it takes a couple of minutes:
A key generated on the phone has never existed anywhere else: there is no older copy of it that might already have leaked, and nothing to clean up on another machine. One key per device also means that losing the phone costs you one line in authorized_keys — remove it and your other devices keep working, which is why the name is worth choosing well.
What none of this can do: if the phone itself is compromised, that key is compromised with it, whatever protects it on disk. A passphrase on the key would not save it either — anything able to read the app's storage can also read what you type. That is why SSHBorg asks for a key's passphrase once, when importing it, and stores the key unlocked instead of keeping the passphrase (see SSH Keys).
SSHBorg can export and import host configurations and app settings as a JSON file. This lets you transfer your server list to another device or keep a portable backup of your setup.
Go to Settings → Backup → Export backup. Choose where to save the file using the system file picker. The file is named sshborg_backup.json by default (sshborg-backup-date.json on iOS).
Go to Settings → Backup → Import backup. Select the .json file you previously exported (or created manually). SSHBorg merges it with the existing host list:
keyLabel, if one exists; otherwise the field is ignored.The export file is a plain JSON object. You can also create it by hand to bulk-import a server list from another source.
{
"version": 7,
"exported_at": "2026-05-14T10:00:00Z",
"groups": [
{ "name": "Production", "color": -1754827, "position": 0 }
],
"hosts": [
{
"label": "My VPS",
"hostname": "203.0.113.42",
"port": 22,
"username": "ubuntu",
"agentForwarding": false,
"jumpMode": "simple",
"jumpHosts": null,
"jumpHostIdList": null,
"portForwardings": null,
"sftpStartMode": "last",
"sftpStartDir": null,
"sftpShowHidden": false,
"allowLegacyCiphers": false,
"position": 0,
"lastConnected": 1757404800000,
"connectCount": 12,
"keyLabel": "My VPS key",
"group": "Production"
}
],
"settings": {
"night_mode": 0,
"scrollback_lines": 2000,
"terminal_font_size": 13,
"terminal_color_scheme": 0,
"double_tap_action": 0
}
}
The optional settings object holds your app preferences and is written automatically on export; you can leave it out when creating the file by hand.
label — display name shown in SSHBorg. Used as the unique key for merging on import. Required.hostname — server address or IP (IPv4 or IPv6). Required.port — SSH port. Defaults to 22.username — login user. Required.agentForwarding — true to enable SSH agent forwarding. Defaults to false.jumpMode — "simple" (use the jumpHosts text) or "host_list" (use SSHBorg internal host IDs). Use "simple" when creating the file manually.jumpHosts — comma-separated jump hosts in [user@]host[:port] format. Only used when jumpMode is "simple".portForwardings — newline-separated local port-forwarding rules in SSH -L syntax, e.g. "8080:localhost:8080".sftpStartMode — SFTP starting directory: "last" (remember last visited), "fixed" (always use sftpStartDir), "home" (server home). Defaults to "last".sftpStartDir — path to use when sftpStartMode is "fixed".sftpShowHidden — true to show hidden files (dotfiles, names starting with ".") in the SFTP browser for this host. Defaults to false.allowLegacyCiphers — true to enable the legacy cipher algorithms described above. Defaults to false.keyLabel — name of the SSH key this host uses. On import, if a key with this name exists it is linked to the host; otherwise the field is ignored. The key itself is never included in the backup.group — name of the group the host belongs to. Groups are listed in the top-level groups array with their name and color (ARGB as a signed 32-bit integer). If a host references a group that is not in the array, it is created automatically with a default color — so you can omit the array entirely when writing the file by hand.color — optional per-host color (ARGB as a signed 32-bit integer). It overrides the group color.position — place of the host in the manual list order, counted inside its own section (the ungrouped block, or one group). Omit it and the host is appended at the end. Groups carry a position of their own in the groups array.lastConnected — time of the last connection, in milliseconds since the Unix epoch. Feeds the "recently used" order.connectCount — how many terminal sessions were opened to this host. Feeds the "most used" order.label, hostname, and username are optional. Omitted fields fall back to their defaults.
SSHBorg runs on Android TV and Google TV. It works with the remote's D-pad, but because it is a text-heavy app, a physical keyboard makes a real difference.
To rename, delete, edit, duplicate or download from a row, open its menu: press the remote's Menu (options) key on the focused row, or hold OK (long-press). OK by itself runs the primary action, not the menu.
A physical keyboard — USB or Bluetooth (Android TV supports both) is strongly recommended, and effectively required for the terminal. With one, text fields and the shell behave normally.
Without one, the on-screen keyboard still handles short entries: focus a field, press OK to open it, type, and press the keyboard's OK / Go to confirm — on the password prompt this connects directly. Entering shell commands with the on-screen keyboard, however, is impractical.
A TV usually has no fingerprint reader or screen lock, so protect the app with the built-in PIN or passphrase lock (Settings → Security) — it works entirely with the remote or a keyboard. See App Security.
SSHBorg is free software, released under the GNU General Public License v3. Its source code is on GitHub, for both the Android and the iOS app. It uses the following libraries, each under its own licence:
None of them connects to anything on its own: the only addresses SSHBorg contacts are the servers you tell it about, and sshborg.com when you tap a link. There are no analytics libraries, no advertising libraries and no trackers of any kind.