senan kelly

diy ngrok

2019/12/12

if you:

then, you can create your own 👌

step 1, the server

setup your traefik 1.x frontends/backends. in my case, i wanted t-1.my.domain and t-2.my.domain. two always available endpoints for whatever machine to connect to, which will be routed to a service running on my laptop.
of course you could extend this config to as many tunnels as you like:

# traefik.toml

[file]
[backends]
[backends.t-1]
[backends.t-1.servers.t-1]
url = "http://localhost:51401"
[backends.t-2]
[backends.t-2.servers.t-2]
url = "http://localhost:51402"
[frontends]
[frontends.t-1]
backend = "t-1"
passHostHeader = true
[frontends.t-1.routes.t-1]
rule = "Host:t-1.my.domain
  [frontends.t-2]
backend = "t-2"
passHostHeader = true
[frontends.t-2.routes.t-2]
rule = "Host:t-2.my.domain"

for the frontends, i picked a high enough local ports that they hopefully won’t clash with any other service running on the server.

i’m also doing a passHostHeader = true for each backend, so that the request headers for the local proxied-to services have the public frontend hosts instead of localhost.

to make the public t-*.my.domain possible for my home server, i’ve setup DNS similar to:

A      my.domain    <home_ip>
CNAME  *.my.domain  my.domain

and a DDNS client updating the A record, and 80/443 forwarded.

acme should be configured, giving you TLS for a proper ngrok alternative.

step 2, the client

it’s as simple as

ssh -N -R '<traefik_backend_port>:localhost:<local_service_port>' <your_box>

for every tunnel you want to create. no need for any extra binaries like with ngrok

so in my case, if i want to show a friend a web server i have running at http://localhost:5454 by the more friendly and secure address https://t-1.my.domain, it would be:

ssh -N -R '51401:localhost:5454' my-box

where 51401 matches the frontend in the traefik.toml

much better :)