PortPatch is a portable desktop application that represents your computer and SSH servers as nodes. Draw a directed edge from the place that accepts a connection to the place that should receive the traffic. Closing the window keeps active routes running in the system tray.
Current version: 0.4.2 - MIT License
- A free-form node graph for your computer and multiple SSH servers
- Drag node cards to arrange the map; hold
Ctrland drag one node onto another to create a directed route - Pan the routing map by dragging its background and zoom around the mouse pointer with the wheel
- Parallel routes between the same nodes are separated into distinct curved lanes
- Private keys in
~/.sshare detected locally when adding a server - Local-to-remote, remote-to-local, and remote-to-remote TCP relays
- SOCKS5 routes in either direction
- Listen on your computer and use a remote server as the egress
- Listen on a remote server and use your computer as the egress
- Listen on server A and use server B as the egress
- Private key, password, SSH Agent, and Pageant authentication
- Persistent interface sizing from 80% to 125%
- SHA-256 SSH host-key verification and pinning
- Per-route start and stop controls with exponential-backoff reconnection
- Active connection counts, byte counters, errors, and retry status
- Password and key-passphrase protection through Electron
safeStorage(Windows DPAPI, macOS Keychain, or a Linux secret service such as GNOME Keyring or KWallet) - Close to tray, start all, stop all, and quit controls
- Optional launch at sign-in (Windows Login Items or a Linux XDG autostart entry)
- Optional restoration of only the routes that the user explicitly left active
PortPatch is distributed without an installer.
- Windows: one portable
.exe; run it directly from any folder - Linux: one AppImage; run
chmod +x PortPatch-<version>-linux-x86_64.AppImageonce, then execute it directly - No administrator access is required for normal use
- Application settings and encrypted credentials remain in the operating system's per-user application-data directory. They are not written beside the executable. This keeps the executable movable and allows it to run from read-only locations.
Both the Windows executable and the Linux AppImage are published on every tagged release; see Current limitations for exactly what has and has not been verified on Linux, and architecture.md for the underlying findings, including a deliberate sandboxing trade-off in the AppImage build.
Download the latest release for your platform from GitHub Releases: PortPatch-<version>-windows-x64-portable.exe or PortPatch-<version>-linux-x86_64.AppImage. No Node.js, pnpm, installation, or administrator access is required. A .sha256 checksum file is published alongside each release asset, and new releases include GitHub build-provenance attestations. Verification instructions are in releasing.md.
git clone downloads the source code, not compiled release files. Cloning is intended for contributors who want to build or modify PortPatch.
| Goal | Route |
|---|---|
Use an LLM on a GPU server at localhost:8000 from your computer |
My Computer 127.0.0.1:18000 -> GPU Server 127.0.0.1:8000 using TCP |
Let a remote server use an LLM on your computer at localhost:8000 |
Server 127.0.0.1:18000 -> My Computer 127.0.0.1:8000 using TCP |
| Browse sites that are reachable only from a server | My Computer 127.0.0.1:1080 -> Server egress using SOCKS5 |
| Give an offline server access through your computer's network | Server 127.0.0.1:1080 -> My Computer egress using SOCKS5 |
| Connect a port on server A to a service on server B | Server A bind:port -> Server B host:port using TCP |
When a server uses a SOCKS5 route, configure the relevant program to use the proxy:
export ALL_PROXY=socks5h://127.0.0.1:1080
curl https://example.comFor a browser, configure 127.0.0.1:1080 as its SOCKS5 proxy and enable proxy-based DNS resolution when available.
- Download the portable executable for your platform from GitHub Releases and run it. On Linux, mark the AppImage executable first (
chmod +x). - Select
Add server, then enter the SSH address, user, and authentication method. For private-key authentication, PortPatch silently selects a recognized key from~/.ssh; openPrivate key optionsonly when you need another file or a passphrase. SSH Agent mode uses keys already unlocked in Windows OpenSSH Agent/Pageant, or in anssh-agentreachable throughSSH_AUTH_SOCKon Linux. - Select
Test connection, verify the SHA-256 host-key fingerprint, and trust it only if it is correct. PortPatch does not send a password or private key before this confirmation. - Hold
Ctrland drag the node that should accept connections onto the node that should receive the traffic. Drag withoutCtrlto rearrange nodes, drag the background to pan, and use the mouse wheel to zoom. - Enter the two ports in the compact editor on the new edge. Open
Advancedonly when you need to change addresses, route type, exposure consent, or reconnection behavior. - Close the window to keep routes running in the system tray. Use the tray menu, or the power-icon Quit button in the top bar, to quit completely; use the Quit button specifically if your Linux desktop does not display the tray icon (see Current limitations).
Select the ? button at any time to review the map controls.
By default, closing the window keeps active routes running. Open PortPatch again from its system tray icon, or use the tray menu to stop routes and quit the application. If the tray icon is unavailable, run the same portable executable or AppImage again to bring the existing window back.
The SSH server must permit the required forwarding through AllowTcpForwarding. A restrictive server may return an error such as administratively prohibited. Its GatewayPorts policy also controls the actual exposure of remotely bound ports.
The default local bind address, 127.0.0.1, accepts connections only from the same computer. Non-loopback local listeners and every remote-node listener require explicit exposure consent. An SSH server with GatewayPorts yes can expose even a requested 127.0.0.1 listener on every interface, so review the server configuration and firewall. The current SOCKS5 listener does not provide user authentication.
Node.js and pnpm are required.
pnpm install
pnpm icons
pnpm test
pnpm startRegenerate the README demos with pnpm demo and pnpm demo:tray.
Build the portable Windows executable:
pnpm dist:winThe output is written to release/PortPatch-<version>-windows-<arch>-portable.exe.
Build the Linux AppImage (must be built and tested on Linux):
pnpm install
pnpm dist:linuxThe output is written to release/PortPatch-<version>-linux-<arch>.AppImage. Running the resulting AppImage, or pnpm icons/pnpm start, may fail with a setuid_sandbox_host error inside containers or sandboxes that disable unprivileged user namespaces; set ELECTRON_DISABLE_SANDBOX=1 in that case (packaging itself, i.e. pnpm dist:linux, does not need it, since it never launches Electron).
Each edge is modeled as two operations instead of an SSH command string:
- Open a TCP listener on the source node.
- For each connection, dial the target from the destination node and relay both streams.
When the source is remote, PortPatch uses SSH forwardIn. When the target is remote, it uses SSH forwardOut. The same model therefore handles conventional local and reverse forwarding as well as server-A-to-server-B routing. See the architecture document for details.
- Only TCP and SOCKS5 CONNECT are supported; UDP is not supported.
- Each server must currently be reachable directly over SSH from the computer running PortPatch. ProxyJump import is planned for a later version.
- PortPatch relays both SSH streams for remote-to-remote routes, so the application must remain running.
- SOCKS5 is a per-application proxy, not a VPN or transparent TUN interface for all server traffic.
- Windows executables are not Authenticode-signed and may trigger a Microsoft Defender SmartScreen warning. PortPatch does not use a self-signed certificate because it would not establish a trusted publisher identity on another computer.
- The Linux AppImage builds and runs, and has been confirmed working by a person on real Ubuntu 24.04/GNOME/X11 hardware, but not yet on any other distribution, KDE, or a Wayland session; see architecture.md for the underlying findings on sandboxing and tray behavior.
- On GNOME, the system tray icon requires the "AppIndicator and KStatusNotifierItem Support" extension. It ships pre-installed on Ubuntu but is not enabled by default in every session, and is not installed at all on stock Fedora Workstation; without it, the tray icon is silently never shown. With the extension active, the icon has been confirmed to render correctly (see architecture.md). Use the top bar Quit button (or the tray menu, if visible) to fully close PortPatch either way.
- If no Linux secret-storage backend (GNOME Keyring/libsecret or KWallet) is available, PortPatch blocks saving new passwords and key passphrases instead of using Electron's weak
basic_textpersistence. Installgnome-keyring(or KWallet on KDE), or use SSH Agent authentication.

