sish SSH Tunnel Server on AWS User Guide
Overview
This guide covers the deployment and use of sish on AWS using cloudimg AWS Marketplace images. sish is an open source, self hosted SSH tunnelling server, a drop in alternative to ngrok and serveo that you run on your own infrastructure. It runs an SSH server whose only job is forwarding and multiplexing, so anyone can expose a local service on a public URL using a command they already know: an ordinary ssh remote forward. There is no custom client to install for end users, no third party relay in the path, and no per seat SaaS bill.
The image installs sish 2.23.0 from the official prebuilt release tarball, run under systemd as a hardened service. sish's SSH tunnel ingress listens on port 2222, kept deliberately separate from the standard SSH service on port 22 that you use to manage the instance, and it terminates HTTP and HTTPS for your tunnels on ports 80 and 443. There is no web interface and no database: a single flat config file (/etc/sish/config.yml) plus the per instance key and certificate material under /etc/sish are the whole configuration.
Secure by default — no known credentials. A tunnel server that anyone can connect to is an abuse risk, so this image forces authentication on and ships an empty authorized key list. On the first boot of every instance a one shot service generates a unique SSH host identity for the server, a unique authorized tunnel key for you, and a per instance TLS certificate, then writes your private tunnel key to a root only credentials file. Only that key, plus any additional public keys you choose to add, may open a tunnel, and the server refuses to start until this per instance setup has completed — so there is never an open, unauthenticated window.
What is included:
-
sish 2.23.0 from the official prebuilt release binary, run under systemd as a hardened service (
sish.service) -
An SSH tunnel ingress on
:2222, kept separate from the management SSH service on:22, plus HTTP and HTTPS tunnel routers on:80and:443 -
Secure by default: authentication forced on, a per instance authorized tunnel key generated on first boot, and the server gated so it cannot start before that key exists
-
A per instance TLS certificate for HTTPS out of the box, with a documented one line switch to browser trusted Let's Encrypt certificates for your own domain
-
A per instance
<public-ip>.sslip.iotunnel domain so public URLs resolve with no DNS setup at all -
A shipped self test (
/opt/sish/tunnel-selftest.sh) that proves the server tunnels a real request end to end, entirely on the instance
Connecting to your instance
Connect over SSH on port 22 as the default login user for the AMI variant you launched. This is the management SSH service and is separate from sish's own tunnel ingress on port 2222.
| OS variant | SSH login user | Notes |
|---|---|---|
| Ubuntu 24.04 LTS | ubuntu |
sish.service; config at /etc/sish/config.yml; credentials at /root/sish-credentials.txt |
ssh -i /path/to/key.pem ubuntu@<public-ip>
Prerequisites
-
An AWS account and a key pair in the target region
-
Subscription to the sish listing on AWS Marketplace
-
A security group allowing TCP 22 (admin) from your address, TCP 2222 (tunnel clients) from the machines that will open tunnels, and TCP 80 and TCP 443 (public HTTP and HTTPS routers) from the audience that will reach your tunnel URLs
Recommended instance type: m5.large (2 vCPU, 8 GB RAM) is ample for a team sharing preview links and running staging or demo environments. sish is a single lightweight Go binary; larger sizes are only needed for very high concurrent tunnel volumes.
Step 1: Launch from AWS Marketplace
Search sish in AWS Marketplace, select the cloudimg listing, and click Continue to Subscribe, then Continue to Configuration and Continue to Launch. Choose the m5.large instance type, your key pair, and a security group. Configure the security group to allow TCP 22 for administration, TCP 2222 for the clients that will open tunnels, and TCP 80 and TCP 443 for the audience that will reach your public tunnel URLs.
Step 2: Verify the service is running
SSH in as ubuntu and confirm the service is active and listening. sish's tunnel ingress is on :2222 and its HTTP and HTTPS routers on :80 and :443, while the management sshd stays on :22.
systemctl is-active sish.service
sudo ss -tlnp | grep -E ':2222 |:80 |:443 |:22 '
You can confirm the installed version at any time:
/opt/sish/sish --version

Step 3: Prove the tunnel works end to end
The image ships a self test that starts a tiny local HTTP origin, opens an authenticated tunnel through sish, fetches the assigned public tunnel URL through the HTTP router, and confirms the origin's response round trips back — all on this one instance, with no external client. It then proves that an unauthenticated key is rejected.
sudo bash /opt/sish/tunnel-selftest.sh
A successful run prints round-trip OK, confirms the unauthenticated tunnel was REJECTED, and ends with SISH_SELFTEST_OK.

Step 4: Read your per instance credentials
On first boot sish generates a unique authorized tunnel key for this instance and records the details in a root only credentials file. Read it to find your per instance tunnel domain, the SSH ingress port, and the path to your private tunnel key.
sudo cat /root/sish-credentials.txt
The file records sish.domain (your per instance <public-ip>.sslip.io tunnel domain), sish.ssh_ingress_port (2222), and sish.tunnel_key_path (the path to your private tunnel key). The private key itself lives at /root/sish-tunnel-key with 0600 root:root permissions — copy it to any machine that should be allowed to open tunnels, and keep it secret.

Step 5: Open your first tunnel
From any machine that holds your tunnel key, publish a local service on a public subdomain with an ordinary ssh remote forward. Point it at your per instance domain (the sish.domain value above) and choose the subdomain you want. For example, to expose a local web app running on port 8080:
ssh -p 2222 -i /path/to/your-tunnel-key -R myapp:80:localhost:8080 <your-domain>
Your app is now reachable at http://myapp.<your-domain> and, using the per instance certificate, at https://myapp.<your-domain>. Because the default domain is <public-ip>.sslip.io, the URL resolves with no DNS setup at all.
sish also forwards raw TCP and routes TLS by SNI. Expose a TCP service on a chosen external port, or create a private alias only reachable through authenticated SSH:
ssh -p 2222 -i /path/to/your-tunnel-key -R 9000:localhost:5432 <your-domain>
Step 6: Authorize additional clients
sish watches the authorized keys directory and reloads it automatically. To let a teammate open tunnels, drop their public key into /etc/sish/pubkeys on the server; they can then open tunnels from their own machine with their matching private key.
sudo install -m 0640 teammate.pub /etc/sish/pubkeys/teammate.pub
ssh -p 2222 -i /path/to/their-tunnel-key -R demo:80:localhost:3000 <your-domain>
The image ships zero authorized keys, and only keys present in /etc/sish/pubkeys may open tunnels — an unknown key is rejected with Permission denied (publickey).

Step 7: Use a real domain with browser trusted HTTPS
The default per instance certificate is self signed, so browsers show a warning. For production, point a wildcard DNS record (for example *.tunnel.example.com) at this instance's public IP, then enable sish's on demand Let's Encrypt certificates and set your domain in /etc/sish/config.yml:
domain: "tunnel.example.com"
https-ondemand-certificate: true
https-ondemand-certificate-email: "you@example.com"
Then restart the service to pick up the new configuration:
# after pointing your wildcard DNS record at this instance and editing config.yml
sudo systemctl restart sish # applies your <your-domain> certificate settings
sish will obtain a browser trusted certificate for each tunnel subdomain on first request.
Security group and firewall
Restrict the security group to your use case:
-
TCP 22 — administration, from your address only
-
TCP 2222 — the sish SSH tunnel ingress, from the machines that will open tunnels
-
TCP 80 and TCP 443 — the public HTTP and HTTPS tunnel routers, from the audience that will reach your tunnel URLs
Because the tunnel ingress on 2222 is separate from the management SSH service on 22, you can lock administration down to your own network while still letting clients open tunnels, without ever exposing the management port more widely.
Support
cloudimg provides 24/7 technical support for this sish product by email (support@cloudimg.co.uk) and live chat. We help with deployment and first boot configuration, retrieving your per instance tunnel domain and authorized key, authorizing additional users, pointing a wildcard DNS record at the server, enabling Let's Encrypt for browser trusted HTTPS, configuring HTTP, TCP, TLS and SNI tunnels and private aliases, tuning binding, load balancing and rate limiting policies, configuring firewall and security group rules, monitoring and log inspection, and sish version upgrades. Critical issues receive a one hour average response time. For billing, subscription changes, or refund requests, contact support@cloudimg.co.uk.