Importing from Other Apps
ZestSSH can import connections and keys from three sources: OpenSSH config files, PuTTY .ppk key files, and PuTTY saved sessions from the Windows registry. This page explains what each import method supports and what you should expect.
New users meet most of these on day one: the first-run onboarding offers to import your SSH config for you and can even scan your local network for servers. The rest of this page covers both that guided first-run path and the import screens you can reach any time from Settings.
First-run onboarding
Section titled “First-run onboarding”The first time you open ZestSSH with no saved connections, the app shows a short “Let’s get you connected” screen with four ways to add servers, ordered by how much they do for you:
- Import from SSH config — pull servers out of your existing
~/.ssh/config. - Scan the local network — find SSH servers on the network you are on right now.
- Restore from sync — if you already use ZestSSH, bring your servers over.
- Add one manually — enter a server’s details yourself.
You can take any of these or tap Skip for now; either way the onboarding screen does not reappear. The same four options are also available from the empty host grid, so skipping is not a one-time-only decision.
Importing your SSH config during onboarding
Section titled “Importing your SSH config during onboarding”On desktop, ZestSSH looks for ~/.ssh/config automatically (under $HOME or %USERPROFILE%) as the onboarding screen loads:
- If a config with importable hosts is found, the Import from SSH config tile is highlighted as the recommended path and shows the count, e.g. “3 servers found in your SSH config.”
- If no config is found — the normal case on mobile, where the home directory is the app’s private sandbox — the tile says so and stays disabled.
Tapping the tile opens a review screen that lists exactly what will be imported and, honestly, what was skipped and why, before anything is created. Each Host block is expanded into one connection per concrete alias, and the following directives are mapped:
| Directive | Mapped to |
|---|---|
Host (alias) | The connection label |
HostName | The host address (falls back to the alias if omitted) |
Port | The port (defaults to 22) |
User | A linked identity’s username — the identity is labelled “{alias} (imported)” and set to public-key auth when an IdentityFile is present, otherwise password |
IdentityFile | Recorded verbatim in the connection’s note (the key itself is imported separately) |
ProxyJump | Wired as the connection’s jump host, when the referenced host matches another imported alias or an already-saved connection |
The ProxyJump wiring means an imported bastion-plus-backend setup arrives already chained — see Jump Hosts for how those connections behave.
What gets skipped (and shown with its reason on the review screen):
- Wildcard-only
Hostblocks (Host *,Host prod-*) — they describe many hosts, not one, so there is nothing concrete to create. - Invalid host — a hostname that fails validation or exceeds 253 characters.
- Invalid port — a
Portvalue outside 1—65535.
For safety, IdentityFile paths containing .. (path traversal) are rejected, and every free-text field — usernames, identity-file paths, labels — is stripped of control and bidirectional/RTL spoofing characters and length-capped before it is stored, since a config file is untrusted input.
There is no limit on how many connections you can save, on any tier, so every valid host in your config is imported.
Scanning the local network
Section titled “Scanning the local network”If you do not have a config to import — or just want to see what is out there — Scan the local network discovers reachable SSH servers on the network you are currently connected to.
- Scope. ZestSSH derives a single
/24(254 addresses) from your device’s current private IPv4 address, for example192.168.1.0/24. Only private ranges are ever scanned (10.x,172.16—172.31.x,192.168.x); it will never fan out across a public range. On a cellular-only or offline device there is no scannable network, and the scan reports “No local Wi-Fi or Ethernet network detected.” - Consent first. The exact range is shown up front and nothing is probed until you tap Start scan. The scan is simply a TCP connection attempt to port 22 on each address, run with bounded concurrency and a short per-host timeout. You can Stop it at any time.
- Results. Hosts that answer on port 22 are listed with their response latency and pre-selected. Choose the ones you want and tap Add; each becomes a connection labelled by its address, on port 22.
A scan only tells you which addresses have an open SSH port — it does not discover usernames, keys, or passwords. After adding the connections, set up authentication on each one yourself.
Importing from SSH config files
Section titled “Importing from SSH config files”If you have an existing ~/.ssh/config file, you can import its connection entries into ZestSSH.
Navigate to Settings > Import > SSH Config. You can either:
- Tap Browse to pick the file from your device’s file system.
- Paste the config file contents directly into the text field.
ZestSSH parses each Host block and extracts the following directives:
| Directive | Imported | Notes |
|---|---|---|
Host | Yes | Used as the connection label |
HostName | Yes | Falls back to Host value if omitted |
Port | Yes | Defaults to 22 |
User | Yes | Username for the connection |
IdentityFile | Yes | Stored as a reference (key not auto-imported) |
ProxyJump | Yes | Stored for display; jump host support varies |
What does not import
Section titled “What does not import”The following directives are parsed by the config reader but are not converted into ZestSSH connection settings:
ProxyCommand— recognized but not mapped to a connection field.LocalForward,RemoteForward,DynamicForward— port forwarding rules are recognized by the parser but not imported as forwarding rules. You need to configure these manually in ZestSSH.ServerAliveInterval,ServerAliveCountMax— recognized but not applied.ForwardAgent— recognized but not applied.Matchblocks — parsed as separate blocks but not imported as connections.- Wildcard
Host *blocks — skipped entirely.
Validation and security
Section titled “Validation and security”The importer rejects entries with:
- Hostnames containing control characters, shell metacharacters, or exceeding 253 characters.
- Ports outside the 1-65535 range.
- Usernames containing control characters or exceeding 128 characters.
IdentityFilepaths containing..(path traversal).
If an entry is rejected, it is silently skipped. The import summary shows how many entries were successfully parsed.
Example
Section titled “Example”Given this config file:
Host prod-web HostName 10.0.1.50 Port 2222 User deploy IdentityFile ~/.ssh/deploy_ed25519
Host staging HostName staging.example.com User adminZestSSH creates two connections: “prod-web” (10.0.1.50:2222, user deploy) and “staging” (staging.example.com:22, user admin). The IdentityFile reference is stored, but you still need to import or generate the corresponding key separately in ZestSSH’s identity manager.
Importing PuTTY .ppk keys
Section titled “Importing PuTTY .ppk keys”ZestSSH converts PuTTY .ppk files (v2 and v3) to OpenSSH PEM format so they can be used for key-based authentication.
Navigate to Identities > Import Key and select your .ppk file. ZestSSH detects the PuTTY format automatically by checking for the PuTTY-User-Key-File- header.
Supported key types
Section titled “Supported key types”| Key Type | Supported |
|---|---|
ssh-rsa | Yes |
ssh-ed25519 | Yes |
| ECDSA | No |
| DSA | No |
Encrypted .ppk files
Section titled “Encrypted .ppk files”Encrypted .ppk files are not yet supported for direct import. If your .ppk file is encrypted, you have two options:
- Open the key in PuTTYgen, remove the passphrase, and save it. Then import the unencrypted
.ppkfile. - In PuTTYgen, use Conversions > Export OpenSSH key to export the key in OpenSSH PEM format. Then import the PEM file directly into ZestSSH.
Option 2 is recommended because it avoids the conversion step entirely.
How the conversion works
Section titled “How the conversion works”ZestSSH reads the public and private key blobs from the .ppk file, extracts the cryptographic parameters (modulus, exponent, etc. for RSA; seed and public key for Ed25519), and re-encodes them in OpenSSH PEM format. The converted key is then stored in ZestSSH’s secure storage, not as a file on disk.
Importing PuTTY saved sessions (Windows only)
Section titled “Importing PuTTY saved sessions (Windows only)”On Windows, ZestSSH can scan the Windows registry for PuTTY saved sessions and import them as connections.
Navigate to Settings > Import > PuTTY Sessions. ZestSSH queries the registry path:
HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SessionsFor each saved session, it reads:
HostName— the server address.PortNumber— the connection port (defaults to 22).UserName— the login username.
The session name (registry key name) becomes the connection label in ZestSSH.
What does not import
Section titled “What does not import”- Stored passwords — PuTTY does not store passwords in the registry, and neither does this importer.
- Private keys — PuTTY stores only the key file path (
PublicKeyFile), not the key data. You need to import your.ppkfile separately. - Proxy settings, tunnels, and terminal settings — these are PuTTY-specific and do not map to ZestSSH’s connection model.
- Default Settings — the
Default%20Settingssession is always skipped.
Platform restriction
Section titled “Platform restriction”This import method is only available on Windows. On other platforms, the PuTTY Sessions import screen displays a message explaining this limitation. If you need to move PuTTY sessions from a Windows machine to ZestSSH on Android or macOS, export your connections as an SSH config file or use ZestSSH’s encrypted backup feature to transfer between devices.
After importing
Section titled “After importing”After any import, review the imported connections in the home screen. Check that hostnames, ports, and usernames are correct. If the import referenced identity files, make sure the corresponding keys are also imported or generated in ZestSSH.