SSH Proxy — Tips & Tricks

Strategy and pitfalls for SSH Proxy: bind addresses, GatewayPorts, DNS leaks, autossh, host keys for services, agent forwarding and alternatives.

Back to overview: SSH Proxy · Open the live tool: www.jpkc.com/tools/ssh-proxy/

SSH Proxy takes the flag order off your hands — the strategic decisions stay with you. This page collects what matters in practice. The technical groundwork is in the manual.

The tool only builds — you read and verify

SSH Proxy opens no connection and runs nothing. It produces text. Treat every output as a template: read it (the Explanation table helps), keep an eye on the yellow warnings below the output, adjust hosts and ports, and test in a safe environment before putting anything into production. The warnings don't block anything — the command is generated regardless — but they flag exactly the spots where a tunnel will fail later or open up more than you meant it to. The disclaimer at the foot of the page says it plainly — misconfigured tunnels can expose internal services.

Bind address: 127.0.0.1 vs. 0.0.0.0

The most important security decision lives in the bind:

  • Local Forward binds to 127.0.0.1 by default — the forwarded port is reachable only from your own machine. Leave it that way unless you deliberately need LAN access; any non-loopback bind address (such as 0.0.0.0 or a LAN IP) earns you a warning from the tool.
  • Remote Forward leaves the bind empty by default — the port then listens only on the server's loopback interface. It only goes public with the Public on the server (GatewayPorts) switch, which fills in 0.0.0.0. And even that only takes effect if the server has GatewayPorts clientspecified; without that setting, SSH silently binds to loopback no matter what you specify. If you expect external access and get none, the missing server setting is almost always to blame (see the troubleshooting tab, Channel open failed).
  • Dynamic / SOCKS belongs on 127.0.0.1 as well. A SOCKS port on a public address is an open proxy for anyone who can reach your machine — the tool warns about that too.

SOCKS5: avoid DNS leaks

A common stumble with ssh -D: the tunnel is up, but DNS queries still go through your local resolver — so the far side sees your proxied traffic, but your provider sees which domains you resolve.

  • When testing with curl, use --socks5-hostname (not --socks5) — then the SOCKS server resolves the name. That's exactly the variant the tool writes into the test line below the ssh -D command.
  • For command-line tools, the Proxy Settings generator takes care of it: with Proxy Type SOCKS5 it writes proxy URLs as socks5h://… — the h sends name resolution through the tunnel as well, so even internal host names behind the server resolve.
  • In Firefox, set network.proxy.socks_remote_dns = true.
  • The troubleshooting tab (DNS resolution not going through SOCKS proxy) offers OS-specific diagnostics.

Keep KeepAlive, use autossh for permanence

The KeepAlive options (ServerAliveInterval=60, ServerAliveCountMax=3) are pre-ticked for a reason: without them SSH often notices a dead tunnel very late. Leave them on.

For tunnels that should always be up, KeepAlive alone isn't enough — it only detects the drop, it doesn't rebuild. That's what Auto-Reconnect is for:

  • autossh is the more robust route, but needs the program of that name (apt install autossh, brew install autossh, pkg install autossh — the tool adds the right command as a comment). There's no autossh on Windows; choose Windows (OpenSSH) as the OS and the tool generates a PowerShell loop automatically.
  • The retry loop needs no extra software but has no health checks. Note: the tool removes -f here, because the loop has to see ssh exit, and sets ExitOnForwardFailure=yes — otherwise an ssh without its forward would just keep running and the loop would never restart it. On Linux and macOS, start such a script with nohup ./script.sh >/dev/null 2>&1 & so it survives logging out.

autossh with -M 0 relies entirely on the KeepAlive options to detect a dead tunnel. Switch KeepAlive off and the tool points that out — keep the two together.

Several tunnels? Script instead of hand-juggling

Once you're juggling more than one or two tunnels, the Management Script generator pays off: a script with start/stop/status/restart/list and PID management beats starting them by hand and hunting with ps — and start, stop, restart and status optionally take a tunnel name, so you can restart just one. Auto-reconnect adds watch, which restarts dead tunnels at the interval you set; with Health check, health (in the Bash variant) tests whether the local ports really accept connections. To bring everything up at boot, combine it with Autostart Setup (systemd's Restart=always is more robust here than a @reboot cron). Best leave the log path at its default ~/.local/state/ssh-tunnels — a regular user usually can't write under /var/log.

Services don't ask: prepare the host key and your SSH key

Everything that runs without a terminal — the Autostart Setup services and the tunnels of the Management Script — starts ssh with BatchMode=yes. That's deliberate: a service waiting for a password prompt or the question "Are you sure you want to continue connecting?" would otherwise hang invisibly. The flip side: you need to sort out two things first.

  • Accept the host key once by hand — as exactly the user the service runs as: ssh deploy@db-server.example.com, check the fingerprint, confirm.
  • Use a key without a passphrase, or an agent.

For systemd, also fill in Run as User — otherwise the tunnel runs as root and looks for known hosts and keys in /root/.ssh.

ForwardAgent is a risk — ProxyJump is the answer

In the SSH Config, ForwardAgent yes is deliberately flagged as a security risk: anyone with root on the destination host can use your forwarded agent to wield your keys. If all you really need is a hop through a bastion host, use ProxyJump (-J) instead — it tunnels the connection through without exposing the agent. The key for the hops comes from your local agent; that's why the Jump Host generator puts an ssh-add in front of the command when you set an identity file.

Host keys are a similar story: StrictHostKeyChecking no doesn't belong in production, because it also waves through a changed server key without complaint. That's why the Trust new host keys automatically switch in the SSH Config sets StrictHostKeyChecking accept-new: new hosts are stored on first contact, but a key that changes later is still rejected — the convenience without the hole.

ControlMaster for many fast connections

When tools like Ansible, rsync or git open many SSH connections in a row to the same host, connection multiplexing saves noticeable time: the first connection becomes the "master", and later ones share it. In the SSH Config you enable this via ControlMaster auto plus ControlPath/ControlPersist. The reference tab explains the management commands (ssh -O check/exit) — and remember to create the socket directory first: mkdir -p ~/.ssh/sockets && chmod 700 ~/.ssh/sockets. The tool also writes that command as a comment above the block. On Windows it won't help: the OpenSSH client there doesn't support connection sharing.

When an SSH tunnel is the wrong tool

SSH tunnels are ideal for quick, ad-hoc access to a single service through an existing SSH server. For other needs there are better means — the reference tab compares them: WireGuard for full network access, ngrok / Cloudflare Tunnel for public-facing endpoints without your own server, Teleport for zero-trust access with an audit trail, Tailscale / ZeroTier for a mesh across many devices. SSH tunnels are also TCP only — if you need UDP, use a VPN such as WireGuard; for roaming-friendly interactive sessions, mosh is the better choice.

Combining with other JPKCom tools

  • IP Tools — check bind addresses, networks and private ranges before you put them into a forward or a NO_PROXY list.
  • DNS, SSL, Redirect & URL — verify that the target host resolves and is reachable before you start debugging the tunnel.
  • Generator — strong passwords for services that sit at the far end of the tunnel.

The full feature reference is in the manual, concrete walkthroughs in the examples. You can try it all in the tool.