sish 4.0.0
Overview
This guide covers how to launch and verify sish 4.0.0 on Ubuntu 24.04 from SecureAnyCloud on Amazon EC2. It is one version in the SecureAnyCloud Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace. You pick it as the software version when you subscribe and launch. The listing's guide hub describes the other VPN, proxy and remote access servers in the listing.
sish is an open source, self-hosted alternative to services such as ngrok. It runs its own SSH server. A developer on any machine with a standard OpenSSH client runs ssh -p 2222 -R myapp:80:localhost:8080 <your-sish-host>, and the web app listening on port 8080 of their laptop becomes reachable as https://myapp.<your-domain>/ and http://myapp.<your-domain>/. No special client software is needed. sish is a headless service with no web console to log in to.
What you get
- The current upstream release, unmodified. This image ships sish 4.0.0, the upstream release binary for Linux x86-64. The build pins the release tarball's SHA-256 checksum (the value upstream publishes) and the binary's own checksum. The build record is in
/usr/local/share/doc/sish/BUILD-PROVENANCE.txt. - No open tunnelling and no default key. Authentication is forced on, and only public keys are accepted (no passwords). The image ships with no authorized key at all. Each instance's first boot generates its own tunnel key (the key that may open tunnels), sish's own SSH host key, and a TLS certificate for the tunnel domain, so no two instances share a key.
- Works out of the box. First boot reads the instance's public IPv4 address from the instance metadata service and uses
<public-ip>.sslip.ioas the tunnel domain. This is a free public wildcard DNS name that resolves to that address, sohttps://myapp.<public-ip>.sslip.io/works with no DNS setup. One command switches to your own domain. - HTTPS by default. sish terminates TLS on port 443 with the per-instance certificate, which is an end-entity certificate for the domain and its wildcard, not a certificate authority. You verify the certificate by its fingerprint, or replace it with a certificate from your own CA.
- Hardened service.
sishruns as an unprivileged sish user that owns and can write no file. The service has only the capability to bind ports 80 and 443, a read-only system, a private/tmpand a restricted set of system calls. Its admin and service web consoles are off. - No route to instance metadata. sish is blocked from the EC2 instance metadata service at the system level. Tunnel clients cannot use sish to reach it either:
ssh -L/ssh -Wthrough sish reach only other clients' named tunnels, never an arbitrary address. - Raw TCP forwards stay private. A client's
ssh -R <port>for a port other than 80 and 443 is bound on the instance's loopback address only, on a port of 1024 or above. A tunnel client can never open a port on the instance's network interfaces or a privileged port.
Prerequisites
- An AWS account and permission to launch EC2 instances
- An EC2 key pair in the Region you launch in
- An OpenSSH client on each machine that will open tunnels (macOS, Linux and Windows 10/11 include one)
Recommended instance type: m5.large. A tunnel server for a small team runs comfortably on t3.small or larger.
Connecting to your instance
Version Operating system SSH user
sish 4.0.0 on Ubuntu 24.04 Ubuntu 24.04 LTS ubuntu
Port Protocol Purpose Who should reach it
22 TCP SSH administration of the instance (the system SSH server) Your administrators
2222 TCP sish's own SSH server: tunnel clients connect here with ssh -R The machines that open tunnels
80 TCP HTTP to your tunnels (http://<name>.<domain>/) Whoever should use your tunnelled apps
443 TCP HTTPS to your tunnels (https://<name>.<domain>/) Whoever should use your tunnelled apps
Launch the instance
Option A: AWS Marketplace console
- Open the SecureAnyCloud Hardened WireGuard VPN & VPN, Proxy and Remote Access AMIs listing on AWS Marketplace. Choose View purchase options, then Subscribe. One subscription covers every version in the listing.
- When the subscription is active, choose Launch your software.
- Choose One-click launch from AWS Marketplace, or Launch from EC2 Console for the full launch wizard. In Version, choose sish 4.0.0 on Ubuntu 24.04, then choose your Region.
- Pick an instance type and your key pair.
m5.largeis recommended. The software charge is $0.04 per vCPU per hour. - Configure the security group. The listing's default group opens 22, 2222, 80 and 443. Restrict port 22 to your own IP address, and restrict port 2222 to the machines that will open tunnels.
- Choose a subnet that gives the instance a public IPv4 address, which the default
sslip.iodomain needs. Leave the metadata defaults, because the image already requires IMDSv2. Then choose Launch.
Option B: AWS CLI
Run this command on your own workstation. It creates a security group, then launches the instance. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and replace the VPC, subnet, key pair and CIDR ranges with your own:
SG=$(aws ec2 create-security-group --group-name sish \
--description "sish tunnel server" --vpc-id vpc-0123456789abcdef0 \
--query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 2222 --cidr <your-client-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 80 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 443 --cidr 0.0.0.0/0
aws ec2 run-instances \
--image-id ami-0123456789abcdef0 \
--instance-type m5.large \
--key-name my-key-pair \
--security-group-ids "$SG" \
--subnet-id subnet-0123456789abcdef0 \
--associate-public-ip-address \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=sish}]'You do not need --metadata-options, because the AMI already requires IMDSv2. To keep the same tunnel domain across stop and start, associate an Elastic IP address and run sudo sish-set-domain --default once afterwards (see Step 8).
Connect and read the instance details
Connect as ubuntu with the key pair you chose:
ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>First boot finishes within a minute of launch. It generates the tunnel key, the host key and the TLS certificate, writes the configuration for this instance's domain, starts sish, and waits for ports 2222, 80 and 443.
The details are in /root/sish-credentials.txt, which only root can read. The file holds fingerprints and URLs, not key material:
sudo cat /root/sish-credentials.txt# sish 4.0.0 - written by sish-firstboot on this instance. No key material is stored in this file.
# Tunnel key (private half): /root/sish-tunnel-key (0600 root). Copy it to your client machine, then shred it here.
# Open a tunnel:
ssh -p 2222 -i <key> -R myapp:80:localhost:8080 203.0.113.10.sslip.io -> https://myapp.203.0.113.10.sslip.io/
# Self-test:
sudo sish-selftest Change the domain:
sudo sish-set-domain tunnels.example.com
# Guide: https://secureanycloud.com/stacks/sish-4-0-0/ SISH_DOMAIN=203.0.113.10.sslip.io SISH_HOST=203.0.113.10 SISH_SSH_PORT=2222 SISH_TUNNEL_KEY_FILE=/root/sish-tunnel-key SISH_TUNNEL_KEY_FINGERPRINT=SHA256:q8T2n0kXc4Vd7mR1hZ5yLwE9aJ3uB6sPfG0tKxNcY2E SISH_HOST_KEY_FINGERPRINT=SHA256:Hk4wP9sQ2bV7nL1xR6tY3mC8dF0gJ5aZ2eU4iO7kWq0 SISH_TLS_CERT_SHA256=3A:91:5C:0E:7D:22:B8:4F:61:A0:9E:3D:C7:58:14:F2:6B:0D:93:E8:5A:27:C1:4E:80:BF:36:D9:72:1A:E5:0C SISH_EXAMPLE_HTTPS_URL=https://myapp.203.0.113.10.sslip.io/ SISH_EXAMPLE_HTTP_URL=http://myapp.203.0.113.10.sslip.io/Your values differ, because every instance has its own domain, keys and certificate.
Confirm sish is running
systemctl is-active sish sish-firstboot
sudo ss -Htlnp | awk '{print $4, $6}'active active 127.0.0.54:53 users:(("systemd-resolve",pid=368,fd=17)) 127.0.0.53%lo:53 users:(("systemd-resolve",pid=368,fd=15)) 0.0.0.0:22 users:(("sshd",pid=888,fd=3),("systemd",pid=1,fd=86)) [::]:22 users:(("sshd",pid=888,fd=4),("systemd",pid=1,fd=87)) *:80 users:(("sish",pid=6466,fd=8)) *:2222 users:(("sish",pid=6466,fd=3)) *:443 users:(("sish",pid=6466,fd=9))sish owns ports 2222, 80 and 443. The system SSH server keeps port 22 for administration, and nothing else listens on the network.
Run the self-test
The self-test opens a real tunnel through sish on the instance itself, using the tunnel key. It fetches the tunnel over HTTPS (verified against the per-instance certificate) and over HTTP. It also checks that an unknown key is refused, that only public-key authentication is offered, and that ssh -W through sish reaches neither the metadata service nor the instance's own SSH server:
sudo sish-selftest[sish-selftest] host key pinned; tunnel https://selftest3f0a12.203.0.113.10.sslip.io/ answers over TLS with the per-instance certificate, and over HTTP [sish-selftest] served certificate fingerprint = /etc/sish/ssl/sish.crt [sish-selftest] ssh -W through sish reaches a client's named alias (control) but neither the metadata service nor the instance's own SSH server [sish-selftest] an unauthorized key is refused [sish-selftest] password and keyboard-interactive authentication are not offered (publickey only) SELFTEST_OKCopy the tunnel key to your workstation
Run this command on your workstation. It copies the instance's tunnel key, which is the key that may open tunnels, into a file that only you can read:
umask 077 ssh -i ~/.ssh/my-key-pair.pem ubuntu@<SISH_HOST> 'sudo cat /root/sish-tunnel-key' > ~/.ssh/sish-tunnel-key ssh-keygen -l -f ~/.ssh/sish-tunnel-keyThe fingerprint ssh-keygen prints must equal SISH_TUNNEL_KEY_FINGERPRINT in the credentials file. Keep this key private, because anyone who holds it can open tunnels on your server.
When the key is safely on your workstation, you can remove the server's copy. The authorized public half stays in /etc/sish/pubkeys/:
sudo shred -u /root/sish-tunnel-keyTo let other people or machines open tunnels, give each one its own key instead of sharing this one. See Step 7.
Open your first tunnel
On your workstation, start any local web app, for example on port 8080. Then run:
ssh -p 2222 -i ~/.ssh/sish-tunnel-key -R myapp:80:localhost:8080 <SISH_DOMAIN>The first time you connect, SSH shows sish's host key fingerprint. Accept it only if it equals SISH_HOST_KEY_FINGERPRINT in the credentials file. sish then prints the URLs of your tunnel.
While the SSH session stays open, https://myapp.<SISH_DOMAIN>/ and http://myapp.<SISH_DOMAIN>/ serve your local app to anyone who can reach ports 80 and 443. Press Ctrl+C to close the tunnel. Add -N to run without a session, and add -o ServerAliveInterval=30 to keep long-lived tunnels open through NAT devices.
Browsers warn about the certificate because it is self-signed. Compare the fingerprint that the browser shows (SHA-256) with SISH_TLS_CERT_SHA256, or install a CA-issued certificate as shown in Step 8. Do not add the self-signed certificate to a trust store. On the instance, this command prints the fingerprint of the certificate that sish actually serves:
openssl s_client -connect 127.0.0.1:443 -servername myapp.<SISH_DOMAIN> </dev/null 2>/dev/null | openssl x509 -noout -fingerprint -sha256sha256 Fingerprint=3A:91:5C:0E:7D:22:B8:4F:61:A0:9E:3D:C7:58:14:F2:6B:0D:93:E8:5A:27:C1:4E:80:BF:36:D9:72:1A:E5:0CAuthorize more keys
sish accepts the OpenSSH public keys in the files in /etc/sish/pubkeys/ and notices new files within seconds, without a restart. To let a colleague open tunnels, ask for their public key (for example id_ed25519.pub), copy it to the instance, and install it:
sudo install -o root -g sish -m 0640 your-laptop.pub /etc/sish/pubkeys/your-laptop.pubTo revoke a key, delete its file from /etc/sish/pubkeys/. sish refuses that key within seconds. Tunnels that the key already has open stay up until they disconnect, and sudo systemctl restart sish ends every open tunnel. List the authorized keys and their fingerprints:
sudo sh -c 'for k in /etc/sish/pubkeys/*.pub; do ssh-keygen -l -f "$k"; done'Use your own domain
To serve tunnels under a domain of your own, create two DNS records that point at the instance's public IP address. An Elastic IP address keeps the address stable. The records are tunnels.example.com and the wildcard *.tunnels.example.com. Then run:
sudo sish-set-domain tunnels.example.comThis re-renders /etc/sish/config.yml for the new domain, generates a new self-signed certificate for tunnels.example.com and *.tunnels.example.com, updates /root/sish-credentials.txt and restarts sish. The tunnel key, the host key and every authorized key are kept.
sudo sish-set-domain --default returns to <public-ip>.sslip.io. Also run it after the public IP address changes, for example after you associate an Elastic IP address.
To use a certificate from your own certificate authority or a public CA, obtain a certificate that covers the domain and its wildcard. Then replace the self-signed pair and restart sish:
sudo install -o root -g sish -m 0644 your-fullchain.pem /etc/sish/ssl/sish.crt
sudo install -o root -g sish -m 0640 your-privkey.pem /etc/sish/ssl/sish.key
sudo systemctl restart sishKeep the file names sish.crt and sish.key. With public CAs such as Let's Encrypt, a wildcard certificate requires the DNS-01 challenge.
TCP forwards and aliases (optional)
Consider a forward for a port other than 80 and 443, for example a database on your laptop:
ssh -p 2222 -i ~/.ssh/sish-tunnel-key -N -R 5432:localhost:5432 <SISH_DOMAIN>sish binds this forward on 127.0.0.1 only, on a random free port between 1024 and 65535. It prints the forward as TCP: <domain>:<port>, but in this image that port is not reachable from the network. Reach it from the instance itself, or through the system SSH server (ssh -L). sish never binds a tunnel client's port on the instance's network interfaces or below 1024. To list the listeners that sish holds right now, run:
sudo ss -Htlnp | grep '"sish"'A named alias (-R mydb:5432:localhost:5432) creates no port at all. Another authorized client connects to it with ssh -p 2222 -i <key> -W mydb:5432 <SISH_DOMAIN>. Aliases are the only thing a client's ssh -L or ssh -W can reach through sish.
To publish raw TCP ports to the network, change tcp-address in /usr/local/lib/sac/sish-config.yml.template and /etc/sish/config.yml, restart sish, and open the port range in the security group. Do this only if every key holder should be able to open public ports on this instance.
Logs
sudo journalctl -u sish-firstboot --no-pager -o cat | tail -3 systemctl status sish --no-pager | head -5sish runs in the foreground under systemd, so its messages go to the journal (sudo journalctl -u sish). It logs SSH login attempts with the client address and public key, the tunnels opened and closed, and the connections made to those tunnels.
How the secure start works
sish.service starts only when first boot has written /var/lib/sac/data/sish-ready. Before each start, a preflight check runs as root. It confirms that:
- The configuration is rendered for a real domain.
- Public-key authentication is forced, the consoles are off, and raw TCP forwards stay on loopback.
/etc/sish/keysholds exactly the per-instance host key.- At least one key is authorized.
- The TLS certificate is an end-entity certificate.
- Nothing under
/etc/sishis writable by anyone but root.
If a check fails, sish does not start. Run the check against the current configuration:
sudo /usr/local/sbin/sish-preflight && echo preflight OKpreflight OKSecurity recommendations
- Restrict port 2222 to the networks your tunnel clients connect from, and port 22 to your administrators.
- Give each person or machine its own key in
/etc/sish/pubkeys/, and delete a key's file when it should stop working. Remove/root/sish-tunnel-keyfrom the server when you have copied it. - Remember that a tunnel publishes a local service to anyone who can reach ports 80 and 443. Protect the app itself with its own login, or restrict ports 80 and 443 in the security group to the people who should use it.
- Keep the instance patched. Ubuntu security updates install automatically every day. To update sish itself, launch a newer version from the listing.
Support and licensing
sish is free software under the MIT License. The licence text and the build record are in /usr/local/share/doc/sish/. The source of this release is at https://github.com/antoniomika/sish/tree/v4.0.0.
sish is developed by Antonio Mika and contributors (https://github.com/antoniomika/sish). SecureAnyCloud is not affiliated with or endorsed by the sish project.
For help with this image, contact SecureAnyCloud support through the AWS Marketplace listing.
Deploy on AWS
Launch sish 4.0.0 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com