tuns

Host public web services on localhost


An ngrok alternative using just SSH.

NOTICE: This is a premium pico+ service

Features #

  • A zero-install developer tool
  • Host public web services on localhost
  • Host public tcp services on localhost
  • Share your local webserver privately with another user
  • Managed sish service

Using SSH tunnels, we can forward requests to your localhost from https, wss, and tcp.

Eric connects to sish on the Internet with the command 'ssh -R eric:80:localhost:3000 tuns.sh'. Tony visits 'https://eric.tuns.sh', which connects to sish, and forwards Eric's local server to Tony.

Demo #

tuns demo

Use cases #

Think of tuns as a developer tool. It is designed for the individual developer who is looking to prototype, demo, or otherwise deploy services without the overhead of managing a production environment with TLS, HTTP reverse proxy, and provisioning cloud infrastructure.

By using tuns you get automatic and public https for local web services.

Want to prototype a web service without fully deploying it in the cloud? You can go from starting a local web service to sharing it with the world using a single SSH command.

Hosting public web services from your home has never been easier with tuns.

Docs #

We manage a completely separate doc site for all things related to sish:

Example Usage #

1# if you have a local webserver on localhost:8000:
2ssh -R dev:80:localhost:8000 tuns.sh
3# now anyone can access it at https://{user}-dev.tuns.sh

User namespace #

When creating a tunnel to tuns we always prefix the name with your username:

{user}-{name}.tuns.sh

This includes when a client is using tuns as a ProxyJump:

1ssh -R foobar:22:localhost:22 tuns.sh
2# On the client side
3ssh -J tuns.sh {user}-foobar

tunmgr #

A tunnel manager for docker services.

tunmgr automatically set's up tunnels for docker services. It utilizes Expose ports as well as DNSNames (and the container name/id) to setup different permutations of tunnels.

source code

 1services:
 2  tunmgr:
 3    image: ghcr.io/picosh/tunmgr:latest
 4    restart: always
 5    volumes:
 6      - /var/run/docker.sock:/var/run/docker.sock:ro
 7      - $HOME/.ssh/id_ed25519:/key:ro
 8    healthcheck:
 9      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
10      interval: 2s
11      timeout: 5s
12      retries: 5
13      start_period: 1s
14  httpbin:
15    image: kennethreitz/httpbin
16    depends_on:
17      tunmgr:
18        condition: service_healthy
19    # labels: # or provide tunnel names and ports explicitly
20    #   tunmgr.names: httpbin # Comma separated list of names. Can be an empty
21    #   tunmgr.ports: 80:80 $ Comma separated list of port maps. (remote:local)
22    command: gunicorn -b 0.0.0.0:80 httpbin:app -k gevent --access-logfile -

With that docker compose file httpbin will be exposed as a public service on tuns.

How do I keep a tunnel open? #

If you don't want to use tunmgr then we highly recommend using a tool like autossh to automatically restart a SSH tunnel if it exits.

1autossh -M 0 -R dev:80:localhost:8000 tuns.sh

UDP Tunneling #

Easy (-o Tunnel=point-to-point) #

Using tuns, you have the ability to tunnel UDP traffic without any external binary, meaning all using SSH. This makes use of the SSH tunneling functionality and a tun interface. To get started, you need to follow a few steps:

  1. Start some UDP service that you want to forward. For example, a simple socat echo server:

    1socat -v PIPE udp-recvfrom:5553,fork
    
  2. SSH into tuns requesting a tun interface with the information of where the service is running. This needs to be done as root. Replace local-ip-of-machines-main-interface with the ip address of the main interface for proper routing.

    1sudo ssh -w 0:0 tuns.sh \
    2  udp-forward=10000:local-ip-of-machines-main-interface:5553
    
  3. Bring the tunnel interface up and assign an ip that is link local (also as root):

    1ip link set tun0 up; ip r a 10.1.0.1 dev tun0
    
  4. Start a udp client to tuns.sh:10000. Here's one with netcat:

    1nc -u tuns.sh 10000
    

Hard (-o Tunnel=ethernet) #

You can also use an ethernet tunnel for UDP forwarding. This makes a tap interface. This is considered "hard mode" since you'll also need to handle ARP. We don't process ARP packets, but we expect you to be an expert to be able to make this work! The SRC interface MAC is 00:00:00:00:00:01, while the DST interface MAC is 00:00:00:00:00:02

  1. Start some UDP service that you want to forward. For example, a simple socat echo server:

    1socat -v PIPE udp-recvfrom:5553,fork
    
  2. SSH into tuns requesting a tap interface with the information of where the service is running. This needs to be done as root. Replace local-ip-of-machines-main-interface with the ip address of the main interface for proper routing.

    1sudo ssh -o Tunnel=ethernet -w 0:0 tuns.sh \
    2  udp-forward=10000:local-ip-of-machines-main-interface:5553
    
  3. Bring the tunnel interface up and assign an ip that is link local (also as root). You need to set the ARP entry and interface MAC as well:

    1ip link set dev tap0 address 00:00:00:00:00:02
    2ip link set tap0 up
    3ip r a 10.1.0.1 dev tap0
    4ip neigh add 10.1.0.1 lladdr 00:00:00:00:00:01 dev tap0 nud permanent
    
  4. Start a udp client to tuns.sh:10000. Here's one with netcat:

    1nc -u tuns.sh 10000
    

Create an account using only your SSH key.

Get Started
<< PREV
Pages
NEXT >>
Prose
Built by pico.sh LLC
206 E Huron St, Ann Arbor MI 48104