Skip to main content

SSH tunnel server + agent with reverse port forwarding

Project description

ssh-tunnel-gateway

Single Python package that ships both the server and agent CLIs.

Install

On the gateway server host:

pip install ssh-tunnel-gateway

On each agent host:

pip install ssh-tunnel-gateway

Quick Start (ProxyJump)

  1. On the gateway server host, start server:
API_KEY="change-me" ssh-tunnel-server
  1. On the agent host, start agent:
ssh-tunnel-agent --api-key change-me --endpoint http://<gateway_host>:12000 --reverse-bind-host 127.0.0.1
  1. Get port_b from the agent side:
  • Foreground mode prints a log line with port_b.
  • Session file is always written to ${STATE_DIR}/session.json (default ./data/session.json):
cat ./data/session.json

Get only port_b:

python3 -c 'import json; print(json.load(open("./data/session.json"))["port_b"])'
  1. Add user SSH config (~/.ssh/config):
Host GWServer
    HostName <gateway_public_ip_or_dns>
    User <gateway_ssh_user>
    Port 22

Host AgentServer
    HostName localhost
    User <agent_ssh_user>
    Port <port_b_from_agent_session_json>
    ProxyJump GWServer
  1. Connect:
ssh AgentServer

Server Usage

Foreground:

API_KEY="change-me" ssh-tunnel-server

Systemd mode:

API_KEY="change-me" ssh-tunnel-server -d

Agent Usage

Foreground:

ssh-tunnel-agent --api-key change-me --endpoint http://server:12000

If --agent-id is not provided, agent generates a UUID once and caches it locally for future restarts. Agent writes current session info (including port_b) to ${STATE_DIR}/session.json by default.

Default reverse bind host is 127.0.0.1 (gateway loopback) for ProxyJump style access. Use --reverse-bind-host 0.0.0.0 only if you intentionally want direct public access to port_b. If not set, agent follows the server-provided reverse bind host.

Systemd mode:

ssh-tunnel-agent -d --api-key change-me --endpoint http://server:12000

In -d mode, register/startup failures exit immediately so systemd can restart the unit.

Systemd Usage

Server unit (/etc/systemd/system/ssh-tunnel-server.service):

[Unit]
Description=ssh-tunnel-gateway server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=gw-tunnel
WorkingDirectory=/opt/ssh-tunnel
EnvironmentFile=/etc/ssh-tunnel/server.env
ExecStart=/usr/local/bin/ssh-tunnel-server -d
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Example server env (/etc/ssh-tunnel/server.env):

API_KEY=change-me
SERVER_PORT=12000
SSH_USER=gw-tunnel
AUTHORIZED_KEYS_PATH=/home/gw-tunnel/.ssh/authorized_keys
AGENT_REVERSE_BIND_HOST=127.0.0.1

Agent unit (/etc/systemd/system/ssh-tunnel-agent.service):

[Unit]
Description=ssh-tunnel-gateway agent
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/ssh-tunnel
EnvironmentFile=/etc/ssh-tunnel/agent.env
ExecStart=/usr/local/bin/ssh-tunnel-agent -d
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Example agent env (/etc/ssh-tunnel/agent.env):

API_KEY=change-me
API_URL=http://<gateway_host>:12000
SSH_HOST=<gateway_host>
SSH_PORT=22
LOCAL_TARGET_HOST=127.0.0.1
LOCAL_TARGET_PORT=22

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable --now ssh-tunnel-server
sudo systemctl enable --now ssh-tunnel-agent

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ssh_tunnel_gateway-0.1.3.tar.gz (13.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ssh_tunnel_gateway-0.1.3-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

File details

Details for the file ssh_tunnel_gateway-0.1.3.tar.gz.

File metadata

  • Download URL: ssh_tunnel_gateway-0.1.3.tar.gz
  • Upload date:
  • Size: 13.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for ssh_tunnel_gateway-0.1.3.tar.gz
Algorithm Hash digest
SHA256 98ab9f625485007dc8173c61287b597a67ab7c2f66d0d2191eb445422006e4ee
MD5 3231de0b367e4f69e20495ead8432024
BLAKE2b-256 05972f33757cd8708c176a0d6567b8cf80efc7f0c2a981fe9a4f8a6975e462da

See more details on using hashes here.

File details

Details for the file ssh_tunnel_gateway-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for ssh_tunnel_gateway-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 00bd0ebc73d55c386454dd26f1f847d58a003924477d60f4dbe0db87ce9012b2
MD5 2af3ec0cdf53841f34e04efb9a5a9ba2
BLAKE2b-256 89a757200c8aff241c6b696800e67ef553dcf3cbe7509f84f5ae18579256f4f6

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page