Metadata-Version: 2.4
Name: ssh-tunnel-gateway
Version: 0.1.4
Summary: SSH tunnel server + agent with reverse port forwarding
License-Expression: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: fastapi>=0.110
Requires-Dist: uvicorn[standard]>=0.29
Requires-Dist: requests>=2.31
Requires-Dist: cryptography>=41

# ssh-tunnel-gateway

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

## Install

On the gateway server host:

```bash
pip install ssh-tunnel-gateway
```

On each agent host:

```bash
pip install ssh-tunnel-gateway
```

## Quick Start (ProxyJump)

1. On the gateway server host, start server:

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

2. On the agent host, start agent:

```bash
ssh-tunnel-agent --api-key change-me --endpoint http://<gateway_host>:12000 --reverse-bind-host 127.0.0.1
```

3. 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`):

```bash
cat ./data/session.json
```

Get only `port_b`:

```bash
python3 -c 'import json; print(json.load(open("./data/session.json"))["port_b"])'
```

4. Add user SSH config (`~/.ssh/config`):

```sshconfig
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
```

5. Connect:

```bash
ssh AgentServer
```

## Server Usage

Foreground:

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

Systemd mode:

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

## Agent Usage

Foreground:

```bash
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:

```bash
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`):

```ini
[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`):

```bash
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`):

```ini
[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`):

```bash
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:

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