Ngrok vs dynamic DNS for remote Linux home server access
Imagine you don’t want to expose all your Raspberry Pies fully on the Internet (probably you shouldn’t ever do that in fact) but still want to be able to reach them from outside of your home.
Imagine you want to access your NAS to schedule a download of a huge file you don’t want to download from office etc.
I do things like this on daily basis…
Here I want to present 2 successful and simple ways I use to access active network nodes remotely and my thoughts on when is one approach better than the other.
Level 1: use noip since millions already do that
I have couple of Rpi 1A, 1B and 3 (and couple of Radxa Rock Pros and a Synology, but that’s a different story altogether). Amongst other things I have my web site on one of them (https://www.milanaleksic.net) and I use noip (http://www.noip.com) to do it. The normal way is to expose a single node fully or set up your router to pass-through to ports on selected servers.
In my particular case, and since micro computers like RPi and above-mentioned RRPs are relatively cheap, I use one server as a partial DMZ, which basically means— only some ports are published. This allows me to do risky stuff on other nodes while I’m at home without endangering the rest.
Setting up thing like this is not that difficult: you just search for a suitable client from the dynamic DNS provider you use, or use some 3rd party app which supports your dynamic DNS provider.
I use for example inadyn ( https://github.com/troglobit/inadyn) since I found it to be easier to configure via Chef which I use to setup all my home nodes and laptops.
After client starts updating DNS with your host’s IP you can quickly start accessing your home server’s services exposed on your router, if you are allowed to do that of course and only if you’ve setup your router correctly.
Caveat: check if your internet provider allows you to access your home server remotely on certain ports. I’m in Belgium and Telenet here doesn’t allow ports 80,443 but Belgacom does
I used this method as a first choice since it was… logical and simple. Everyone is doing it, it can’t be wrong, right?
Dynamic DNS is perfect if you have something that constantly needs to be available on Internet (like a personal web site for example).
The only problem I see is that this approach is acceptable only on an Internet-facing node. That means: tough luck if you are connected via WiFi in a hotel or if you are behind corporate firewall for example. I’m quite sure provider/hotel will not give you an IP, thus putting IP of the endpoint of your provider in your dynamic DNS server is… pointless.
Maybe time for Level 2?
Level 2: ngrok as an über tool for the geeks
I really like using ngrok ( https://ngrok.com/). In case you don’t know what’s it about: it’s like a TeamViewer/LogMeIn, but for geeks: it allows you to not worry about not having a stable public IP. It’s like a hand that takes your host’s port, publishes it on Internet.
That’s in fact all you need, right? Exposed port should be all you need since then you can expose ssh and do everything you need!
The following tips expect some level of knowledge of Linux
You want to open VPN tunnel through that port? Here is what you need to do:
if [ "$NGROK_PORT" == "" ]; then
NGROK_PORT=$(go run ngrok_port.go -email=$NGROK_USERNAME -password=$NGROK_PASSWORD)
sudo sshuttle --auto-hosts --dns --exclude $SUBNET_HOME \
-e 'ssh -i /home/$USERNAME/.ssh/id_rsa -o \
UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
This uses an sshtunnel application that should be available as part of your Linux distribution. Probably not the fastest or the most optimal. You should use OpenVPN for that, plenty of blogs available that explain how to — it just takes more time to set it up and explain.
The ngrok_port.go is a script I made in Go language (https://golang.org) which takes your ngrok username and password as parameters, logs you in into ngrok and fetches/scraps the IP exposed on their server.
The script is as simple as it gets, which means that it doesn’t cover all possible cases: different server or different layout of the page and so on.
Ngrok free mode always has only one single tunnel allowed. If you use TCP tunnel, this script…
*Ngrok free mode always has only one single tunnel allowed. If you use TCP tunnel, this script extracts the value (since…*gist.github.com
So, these 2 scripts combined should allow you to quickly setup remote VPN connection and you are allowed to do whatever you’d like on the remote server: connect via VNC, SSH to another host, access the sites available only in that remote network etc. And all of this without support from system admins.
When you are done working with the remote host you can quickly just ssh to remote host and shutdown ngrok server which will allow you not to worry that someone might try to access your computer:
ssh 'killall ngrok'
Caveat: nothing perfect in the world is for free: ngrok comes with free plan that allows only one port to be exposed, that’s why the sshtunnel trick is so valuable: you get a lot through a single port
Is there Level 3?
Of course there is.
Although I haven’t found any problem not covered by the above-mentioned two solutions, that doesn’t mean there are no places for improvement.
If someone can’t help you with starting an ngrok server remotely you can of course use TeamViewer or LogMeIn for “quick remote access”, but that kind of defeats the entire approach since you end up mixing full desktop solution just to start a server on remote system.
I was thinking about pull daemon which would check every 15 minutes somewhere if a need exist for ngrok to be activated on the remote host. That way you keep the ngrok server active only when you really need it. From where a pull can be done is tricky: it needs to be a safe HTTPS place, either an S3 file as simplest solution or an online service, I haven’t decided which way I want to go. Probably left for another experiment when I get time🤓.
Noip or similar dynamic DNS provider is a good choice when the host is publicly reachable but you have no idea what’s the IP.
You should try to use ngrok service for other common case: quick access to a remote host behind a firewall or NAT mapping.