Self-hosting tunnel exposing local ports to the internet with custom domain
Although there are some existing solutions to expose local port to the internet, I’ve decided to use self-hosted solution. I’ve prefered this over hosted one for few reasons:
- I wanted to have some pre-configured subdomains
- I wanted those subdomains to be fixed and/or reserved just for me
- Custom domain was a nice addition
- Cost of hosted solution was just too high to justify it.
- It was just a fun exercise
Idea is simple - anyone accessing address like some_name.yourdomain.dev
will actually access your dev environment on specific port, eg. localhost:3000
. Overall cost of that will be 5$ for cheapest linode + domain cost.
How to
- Order cheap linode (or droplet in digitalocean or any other vps) to have internet-facing IP address
- Order new domain (or use any of existing you don’t exactly need any more)
- Redirect domains A records to IP address of just-ordered VPS
yourdomain.dev A 112.123.132.122
*.yourdomain.dev A 112.123.132.122
- Log in to the VPS and download this package: GitHub - hons82/go-http-tunnel: Fast and secure tunnels over HTTP/2 - it’s easiest to get it’s precompiled binary from releases page
- Skip generation of server’s certificate, use letsencrypt for that (I’m hosting my domains on route53 and following steps assume you’re as well, if not, first steps will be completelly different)
- Get domain’s zone from route53
- Create new IAM profile with folliowing policy
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "route53domains:ListDomains", "route53:ListHostedZones", "route53:ListHostedZonesByName" ], "Resource": ["*"] }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "route53:GetChange", "route53:ChangeResourceRecordSets", "route53:ListResourceRecordSets", "route53domains:GetDomainDetail" ], "Resource": ["arn:aws:route53:::hostedzone/Z01635552BLOUEU2E835A"] } ] }
- Create new IAM user and attach just-created policy
- Create set of credentials, store them in
.aws/config
file - Get certificates for the domain using certbot - install
python3-certbot-dns-route53
package and runcertbot certonly --dns-route53 -d '*.yourdomain.dev'
- Symlink generated certificate files in tunneld directory:
/etc/letsencrypt/live/yourdomain.dev/fullchain.pem
toserver.crt
and/etc/letsencrypt/live/yourdomain.dev/privkey.pem
toserver.key
- Start the
tunneld
package and profit
Overall it shouldn’t take you more than 30 minutes to set everything up.