Skip to content

Jump Host

A jump host (also called a bastion host or gateway server) is an intermediate SSH server that you connect through to reach a final destination. Instead of connecting directly to your target machine, ZestSSH connects to the jump host first, then tunnels through that connection to the actual server you want to work on.

This is essential when your target server is on a private network with no direct internet access. The jump host sits at the boundary — it has a public IP and can also reach the private network — and acts as a stepping stone.

Equivalent SSH command: ssh -J jumpuser@jumphost targetuser@targetserver


  • Corporate networks. Your company has a single bastion server exposed to the internet. All internal servers (databases, app servers, CI runners) are on a private VLAN. You SSH into the bastion, then through it to the internal machine.
  • Home labs. You have one public-facing server (maybe a VPS or a router with port forwarding). Behind it, several machines (Proxmox nodes, NAS, Raspberry Pi clusters) live on a 192.168.x.x network. The VPS is your jump host.
  • Cloud infrastructure. AWS, GCP, and Azure best practices recommend placing sensitive instances in private subnets. A bastion host in the public subnet is the only SSH entry point.
  • Multi-hop environments. Some networks require passing through two or more gateways to reach the final destination — for example, a DMZ host, then an internal gateway, then the target server.

When you configure a connection with a jump host in ZestSSH:

  1. ZestSSH establishes an SSH connection to the jump host using the jump host’s saved credentials (host, port, identity/key).
  2. Through that connection, ZestSSH opens a direct-tcpip channel to the target server’s address and SSH port.
  3. ZestSSH performs a second SSH handshake inside that channel, authenticating with the target server’s credentials.
  4. You get a terminal session on the target server. From your perspective, it looks and feels like a direct connection.

The entire chain is encrypted end-to-end. The jump host relays encrypted bytes but cannot see the content of your session with the target server.


Step 1: Save the jump host as a connection

Section titled “Step 1: Save the jump host as a connection”

Before you can use a server as a jump host, it must be saved in ZestSSH as its own connection.

  1. Go to the home screen and tap + to add a new connection.
  2. Enter the jump host’s details:
    • Nickname: Something clear like “Bastion” or “Gateway.”
    • Address: The jump host’s public hostname or IP.
    • Port: Usually 22.
    • Identity: Select the SSH key or credentials for the jump host.
  3. Save the connection. Optionally, test it to make sure it works.

Step 2: Configure the target server to connect via the jump host

Section titled “Step 2: Configure the target server to connect via the jump host”
  1. Add a new connection (or edit an existing one) for the target server.
  2. Scroll to the Network section.
  3. Find the Connect Via dropdown. It lists all your other saved connections.
  4. Select the jump host connection you saved in Step 1.
  5. Fill in the target server’s details:
    • Address: The target’s private IP or hostname as seen from the jump host (e.g., 192.168.1.10).
    • Port: The target’s SSH port (usually 22).
    • Identity: The SSH key or credentials for the target server (these can be different from the jump host’s credentials).
  6. Save.

When you connect to this target server, ZestSSH automatically connects to the jump host first, then tunnels through to the target.

The Connect Via dropdown includes an info button that opens an explanatory bottom sheet showing what the feature does, when to use it, and a concrete example. Tap it if you need a quick refresher while configuring.


The Connect Via / jump host feature requires ZestSSH Pro. Free tier users see a lock icon next to the Connect Via field with an upgrade prompt. All other port forwarding features remain available on the free tier.


ZestSSH supports chaining multiple jump hosts. If Server C is only reachable from Server B, which is only reachable from Server A:

  1. Save Server A as a direct connection (no Connect Via).
  2. Save Server B with Connect Via set to Server A.
  3. Save Server C with Connect Via set to Server B.

When you connect to Server C, ZestSSH connects to A, tunnels through A to B, then tunnels through B to C. Each hop adds some latency, but the chain can be as deep as needed.

Practical example:

Server A: bastion.example.com (Direct)
Server B: 10.0.1.5 (Connect Via = Server A)
Server C: 172.16.0.20 (Connect Via = Server B)

Connecting to Server C automatically chains through A and B.


Jump hosts and port forwarding work together naturally. When you add a port forward to a connection that uses a jump host, the forward operates relative to the final target server — not the jump host.

Your network layout:

Internet --> bastion.example.com --> 192.168.1.5 (target SSH server)
|
192.168.1.10 (Proxmox, port 8006)

Configuration:

  1. Bastion: saved as a direct connection.
  2. Target server (192.168.1.5): saved with Connect Via = Bastion.
  3. On the target server connection, add a Local port forward:
    • Source Port: 8006
    • Destination Host: 192.168.1.10
    • Destination Port: 8006

When you connect and start the forward, the path is:

Your browser --> localhost:8006 (your device)
|
SSH tunnel to bastion
|
SSH tunnel to 192.168.1.5
|
direct-tcpip channel to 192.168.1.10:8006

You open https://localhost:8006 in your browser and see Proxmox, even though it is two hops and a private LAN away.

You want to browse an entire private network behind a jump host. Set up a connection to any server on that network with Connect Via pointing at the jump host, then add a Dynamic (SOCKS5) forward. Your browser’s SOCKS5 proxy will route all traffic through both SSH hops and into the private network.


”Connection refused” or “Connection timed out” on the target

Section titled “”Connection refused” or “Connection timed out” on the target”
  • Verify the target’s address is correct from the jump host’s perspective. If the jump host is at bastion.example.com and the target is at 192.168.1.10, make sure the jump host can actually reach 192.168.1.10 on port 22. You can test by connecting to the jump host directly and running ssh 192.168.1.10 from its terminal.
  • Check that the target server’s SSH daemon is running and listening on the configured port.
  • The identity (SSH key or password) assigned to the target connection must be valid for the target server, not the jump host. These are separate authentication steps.
  • If the target server expects a specific username, make sure the identity in ZestSSH has the correct username configured.
  • If the jump host disconnects, all sessions and port forwards through it also disconnect. Make sure the jump host connection has appropriate keep-alive settings (the default 15-second interval usually suffices).
  • On iOS, backgrounding ZestSSH may cause the jump host connection to drop, which cascades to all dependent connections.
  • Each hop adds the latency of that link. Two hops with 50ms latency each result in approximately 100ms round-trip for the final session.
  • Enable zlib compression on the target connection if the intermediate links are bandwidth-constrained. This is configured in the Network section of the connection editor.
  • ZestSSH prevents you from selecting a connection as its own jump host. The Connect Via dropdown excludes the connection being edited.
  • Be careful not to create a loop: Server A connects via Server B, and Server B connects via Server A. ZestSSH does not currently detect multi-step circular chains, so the connection will hang.

  • Name your jump hosts clearly. Labels like “Bastion” or “VPS Gateway” make it immediately obvious which connections are jump hosts when scanning the Connect Via dropdown.
  • Set up auto-start port forwards on the target. Since the jump host connection is established automatically, port forwards with auto-activate enabled will start as soon as the full chain connects.
  • Test each hop independently first. Before setting up a chain, verify that you can connect directly to each server in the chain (where possible) to confirm credentials and network reachability.
  • Keep-alive on every hop. Ensure each connection in the chain has keep-alive enabled so idle links do not time out.