Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time



Keys-To-The-Tunnel (KTTT) is for when you have a lot of GitHub Developers who have added their SSH key to GitHub (e.g. here's mine) and they also are doing local development of apps that they either need to share with others via the internet or they need valid TLS certificates to test with, or both!

Check out this blog post for info, and here's a 45 second video showing these steps being taken:

  1. Make a minor edit to an app running on localhost on port 80
  2. Load the app on http://localhost
  3. Use the KTTT web GUI to get the SSH command to run
  4. Run the SSH command
  5. Connect to public URL exposing localhost over TLS

Given a list of GitHub users and a DOMAIN, the script will give each user:

  1. A login
  2. GitHub SSH key(s) put in ~/.ssh/authorized_keys
  3. Only allow SSH tunnels, no shells
  4. 2 vhosts for http and https localhost. GitHub name is a subdomain
  5. Valid SSL certificates from Let's Encrypt
  6. Instructions saved in DOMAIN

This script is hosted on GitHub.


FAQ! ;)


Right now this very narrowly scoped, so requirements are:

  1. An Ubuntu 20.04 server
  2. A public IP for the server
  3. An A record pointing to the public IP (AAAA if ya wanna be IPv6 classy)
  4. a wildcard CNAME entry pointing to the A record
  5. SSH server locked to keys only (optional, but is very good idea)

Development was done locally in lxd containers and then in Digital Ocean.


  1. SSH as root to your Ubuntu server with public IP
  2. Clone this repo with git clone
  3. cd Keys-To-The-Tunnel and create the user.txt file with your github users, one per line
  4. Optionally add a logo.svg to this directory if you want a logo to be shown on the final web page.
  5. Run the install script with ./ DOMAIN.COM EMAIL replacing DOMAIN.COM with your real domain from step 3 in Requirements and replacing EMAIL with your email which will be used to agree to Let's Encrypt TOS and to get notifications about expiring certs.
  6. Send users the URL DOMAIN.COM which now lists how to use the server


Users should go to the website you provisioned and use the list of port/URL combos and instructions there. After that, any client that can use SSH should Just Work™. This has been tested on Ubuntu and MacOS.

SSH Call

The structure of the SSH call to set up the tunnel is:


Example 1


  • user alligator-lovely
  • domain
  • port: 4555

If a user has a server running on http://localhost (implicitly port 80), they would run:

ssh -T -R 4555:

And then in a browser they could go to

Example 2

Still assuming:

  • user alligator-lovely
  • domain
  • port: 4555

If a user has a server running on https://localhost:1234, they would run:

ssh -T -R 4555:

And then in a browser they could go to - note extra -ssl in URL! This ensures the proxy server speaks SSL to your localhost.

To do

  • check for Nth run to not create users that already exist etc
  • consolidate certbot calls with "-d DOMAIN" via SAN to reduce Let's Encrypt API calls?
  • cache SSH keys on first validation to avoid subsequent API calls to GitHub to get keys again
  • add redirect for bare host 80 -> 443 with HSTS, maybe do vhost instead of using default site confs?


Deploy a server to terminate SSL and reverse proxy requests back to developer servers using accounts automatically created from GitHub users' SSH keys.







No packages published