Expose local SSH servers to the public internet via aitun TCP tunnel with SSH-over-TLS routing. Each subdomain gets its own SSH endpoint on port 22 with perf...
---
name: sshtunnel
description: Expose local SSH servers to the public internet via aitun TCP tunnel with SSH-over-TLS routing. Each subdomain gets its own SSH endpoint on port 22 with perfect isolation via SNI. Perfect for AI agents that need to provide remote SSH access behind NAT/firewall.
metadata:
openclaw:
requires:
bins:
- python3
envVars:
- name: AITUN_SERVER
required: false
description: "AiTun server address (default: aitun.cc:6639)"
install:
- kind: uv
package: aitun
bins: [aitun]
emoji: "๐ฅ๏ธ"
homepage: https://aitun.cc
clawhub: https://clawhub.ai/ctz168/sshtunnel
---
# SSH Tunnel - Remote SSH Access via SSH-over-TLS
## When to Use
Use this skill when:
- You need to access a remote machine via SSH that is behind NAT, firewall, or a private network
- You want to expose a local SSH server so a colleague or client can connect remotely
- You are running SSH in a container or VM that has no public IP and need to make it reachable
- You want to provide temporary SSH access for pair programming, debugging, or server maintenance
- You need to connect to a development machine from another location without VPN or port forwarding
- Multiple users each need their own SSH endpoint on the same server port
Do NOT use this skill when:
- The SSH server already has a public IP and is directly reachable
- You only need to transfer files (use sendfile instead)
- You want to expose an HTTP service (use aitun-tunnel instead)
## Instructions
### Step 1: Install aitun
```bash
pip install aitun
```
Or verify it is already installed:
```bash
which aitun || pip show aitun
```
### Step 2: Ensure SSH server is running locally
Verify the local SSH daemon is running and accessible:
```bash
# Check if sshd is running
ps aux | grep sshd
# Or check if port 22 is listening
ss -tlnp | grep :22
# Test local SSH connection
ssh localhost echo "SSH OK"
```
If sshd is not running, install and start it:
```bash
# Ubuntu/Debian
sudo apt install openssh-server -y
sudo systemctl start sshd
# CentOS/RHEL
sudo yum install openssh-server -y
sudo systemctl start sshd
# macOS (usually pre-installed)
sudo systemsetup -setremotelogin on
```
### Step 3: Create a TCP tunnel for SSH
SSH uses TCP port 22. Use aitun's `--tcp-ports` flag to forward this port. TCP forwarding requires an auth token (register at https://aitun.cc):
```bash
aitun -p 22 --tcp-ports 22 -k YOUR_TOKEN &
AITUN_PID=$!
sleep 3
```
The output will show:
```
[TCP] ssh -> localhost:22 (subdomain: yourname.t.aitun.cc:22)
```
### Step 4: Configure SSH ProxyCommand
On the **remote client machine** (the one connecting TO your SSH server), add this to `~/.ssh/config`:
```
Host *.t.aitun.cc
ProxyCommand aitun ssh-proxy %h %p
```
This tells SSH to route connections through `aitun ssh-proxy`, which wraps SSH in TLS with the correct SNI for subdomain routing.
### Step 5: Connect remotely
From any machine with aitun installed:
```bash
# Direct SSH โ just like a normal server!
ssh user@yourname.t.aitun.cc
# With SSH key
ssh -i ~/.ssh/id_rsa user@yourname.t.aitun.cc
# With verbose output for debugging
ssh -v user@yourname.t.aitun.cc
```
### Step 6: Clean up
When done, stop the tunnel:
```bash
kill $AITUN_PID 2>/dev/null
```
## How SSH-over-TLS Works
aitun v4.7.0 uses **SSH-over-TLS** for perfect multi-tenant SSH on shared ports:
```
ssh user@acer.t.aitun.cc
โ
ProxyCommand: aitun ssh-proxy wraps SSH in TLS (SNI=acer.t.aitun.cc)
โ
Server terminates TLS, sees SNI โ routes to "acer" tunnel
โ
Decrypted SSH stream โ tunnel client โ localhost:22
```
**Why TLS?** SSH is a plaintext protocol that doesn't send hostname information. Without TLS, there's no way to tell which subdomain an SSH connection is targeting. By wrapping SSH in TLS, we get SNI (Server Name Indication) which tells the server exactly which subdomain to route to.
**Result:** Every subdomain can have its own SSH on port 22 โ no conflicts, no ambiguity, no `--tcp-default` needed.
## Advanced Usage
### Forward Multiple Ports (SSH + MySQL)
```bash
aitun -p 22 --tcp-ports 22,3306 -k YOUR_TOKEN &
AITUN_PID=$!
sleep 3
```
### SSH into a Container
```bash
# If SSH is running in a Docker container on a non-standard port
aitun -p 2222 --tcp-ports 2222 -k YOUR_TOKEN &
# Then connect (add port to ssh config):
ssh -p 2222 user@yourname.t.aitun.cc
```
### Use with SSH Config (Recommended)
Add to `~/.ssh/config` on the remote client:
```
Host *.t.aitun.cc
ProxyCommand aitun ssh-proxy %h %p
Host my-remote-dev
HostName yourname.t.aitun.cc
User username
IdentityFile ~/.ssh/id_rsa
```
Then simply:
```bash
ssh my-remote-dev
```
### One-off SSH without Config
If you don't want to modify ssh config:
```bash
ssh -o "ProxyCommand=aitun ssh-proxy %h %p" user@yourname.t.aitun.cc
```
## CLI Reference
The `aitun` command (installed via `pip install aitun`) accepts these flags:
| Flag | Description |
|---|---|
| `-p PORT` | Local service port (default: 8080) |
| `-k TOKEN` | Auth token for registered subdomain (required for TCP forwarding) |
| `--host HOST` | Local service address (default: localhost) |
| `--tcp-ports PORTS` | TCP forwarding ports, comma-separated (e.g., `22,3306`; requires `-k`) |
| `--p2p` | Enable P2P direct connection (default: enabled) |
| `--no-p2p` | Disable P2P, force server relay mode |
| `--daemon` | Run as background daemon |
| `--stop` | Stop running daemon |
**Subcommand:**
| Command | Description |
|---|---|
| `aitun ssh-proxy <host> [port]` | SSH ProxyCommand โ wraps SSH in TLS for SNI routing |
## Notes
- TCP forwarding (required for SSH) requires a registered account and `-k` token โ free tunnels do not support TCP
- Register at https://aitun.cc to get an auth token
- All traffic is encrypted end-to-end: SSH inside TLS inside the aitun tunnel
- **ProxyCommand is required** โ plaintext SSH is not supported. Add `ProxyCommand aitun ssh-proxy %h %p` to your `~/.ssh/config`
- If the requested port (e.g., 22) is occupied on the server, a port from the 7000-7999 range will be automatically assigned
- P2P mode reduces latency for SSH sessions; use `--no-p2p` only if P2P connection fails
- For security, ensure your SSH server uses key-based authentication (disable password auth if possible)
- Consider using fail2ban or similar tools to protect against brute-force attacks on your SSH server
- The tunnel stays active as long as the aitun process runs; use `--daemon` for persistent background operation
- Subdomains remain active for 30 days of inactivity; use heartbeat to renew
don't have the plugin yet? install it then click "run inline in claude" again.