Easily exposing your local resources with ngrok and fwd#
I bet every one of you was in a situation when you bloody needed to expose some local resource over internet. Letting a remote colleague to look at your work, delivering a demo being off-VPN, or any other reason to have your service be reachable over Internet.
And it was never easy; corporate firewalls stand on-guard ensuring you can't be agile and productive 😉
In this post I'll share with you how I glue ngrok
and fwd
tools together to make my routers management interfaces exposed over Internet in a few clicks for free.
My story will be based on the following "network-automation engineer's" requirement:
- Make router's management interfaces available over internet (SSH, Netconf, gNMI)
- Make this "exposure" process quick to set up/tear down
- Make it free of charge
In my case I am talking about management interfaces of a router, but it can be any application that relies on TCP/UDP transport that you can expose that way.
By the end of this post you will see that we deliver on all of these requirements.
You shall (not) pass#
You have a router with these shiny management interfaces. But this poor thing is so locked up...
Most of the times there are zero chances you can configure ingress access due to the myriads of elements out of your control (corp firewall being the most tricky one).
There might even not be any EVE-NG or Openstack in the picture, but this BFF9000 fella will be there, and we are about to penetrate it.
Enter ngrok#
Since opening the ports or configuring the port forwarding is not gonna help us much, we will use the reverse technique: opening the connections in the egress direction. Sending traffic in the egress direction is usually not a problem, we can leverage ngrok and expose the needed ports through it:
If you never heard of
ngrok
, I suggest you go through their website, its a very powerful tool to setup tunnels.
That way we can expose any TCP/UDP port of a machine that runs ngrok
client via publicly accessible sockets (tcp://xx.ngrok.io:<port>
) for free.
That looks like a nice idea and quite a realistic one, but not that many routers allow users to install ELF binaries and run them. This means that we can't run ngrok
client on the router itself and establish tunnels.
But we can definitely install ngrok on a machine that can reach our routers. In my case that will be the EVE-NG hypervisor/VM, since it can reach all the routers that run inside of it.
Enter fwd#
Since ngrok
is only capable of exposing the ports of the host the client runs on, we would end up with ports of the Linux host exposed, but not the router's. The missing piece is the forwarder process that will stitch the ngrok
-exposed ports of the linux host with the respective ports of the remote router.
Let's dissect this two stage process of setting the tunnels up:
- expose the local ports of the linux VM with
ngrok
. This linux VM can reach the router. - run
fwd
tool that will forward the traffic appearing on the local ports we exposed withngrok
in step 1
That way we bridge the linux ports exposed with ngrok
with the ports on the router. If that sounds confusing, lets go through the example.
socat vs fwd#
If you (as me) will experience some issues with fwd
reporting broken pipes there is an old-school alternative - socat
. As with fwd
, you can concatenate connections in the following way:
# requests coming to localhost:11122 will be forwarded to 10.2.0.11:22
socat tcp-listen:11122,reuseaddr,fork tcp:10.2.0.11:22
Practical example#
We start first with exposing the ports of the machine that runs ngrok
client and has IP reachability with our router. To expose multiple ports in a quick and easy way, I suggest you leverage the ngrok
configuration file which can resemble smth like this:
# cat ngrok.cfg
authtoken: "MYTOKEN"
log_level: warn
log: /tmp/ngrok.log
region: eu
tunnels:
gnmi_r1:
addr: 57401
proto: tcp
nc_r1:
addr: 11831
proto: tcp
ssh_r1:
addr: 11122
proto: tcp
With this configuration we command ngrok
to expose the TCP ports 57401, 831, 11122
on the linux VM.
And voilá, these ports are now Internet-reachable:
ngrok by @inconshreveable
Session Status online
Account cats_admin (Plan: Free)
Version 2.3.35
Region Europe (eu)
Web Interface http://127.0.0.1:4040
Forwarding tcp://0.tcp.eu.ngrok.io:13621 -> localhost:11831
Forwarding tcp://0.tcp.eu.ngrok.io:16704 -> localhost:57401
Forwarding tcp://0.tcp.eu.ngrok.io:19968 -> localhost:11122
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
But this won't work yet as we wanted.
ssh -p 19968 [email protected]
ssh_exchange_identification: Connection closed by remote host
As we clarified before, nothing listens on these ports, since they are not of router' but of the linux machine running ngrok
client.
There is one step left. Start the fwd
processes and stitch the local ports with the router' ports. Since fwd
cant read (yet) the configuration file, I created a dumb script:
fwd --from localhost:57401 --to 10.1.0.11:57400 &
fwd --from localhost:11831 --to 10.1.0.11:830 &
fwd --from localhost:11122 --to 10.1.0.11:22 &
Thats the missing piece to propagate our tunnels all the way to the router with IP address of 10.1.0.11
in my example. And now we're in business!
ssh:
$ ssh -p 19968 [email protected]
[email protected]'s password:
SR OS Software
Copyright (c) Nokia 2019. All Rights Reserved.
[]
A:admin@R1#
netconf:
$ ssh -p 13621 [email protected] -s netconf
[email protected]'s password:
<?xml version="1.0" encoding="UTF-8"?>
<hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<capabilities>
<capability>urn:ietf:params:netconf:base:1.0</capability>
<capability>urn:ietf:params:netconf:base:1.1</capability>
gNMI:
$ myAwesomegNMIClient -a 0.tcp.ngrok.io:16704 -u admin -p admin --insecure cap
gNMI_Version: 0.7.0
supported models:
- nokia-conf, Nokia, 19.10.R2
- nokia-state, Nokia, 19.10.R2
- nokia-li-state, Nokia, 19.10.R2
- nokia-li-conf, Nokia, 19.10.R2
Now to stop this we simply kill the fwd
processes and ngrok:
Summary#
- With
ngrok
andfwd
we have been able to expose the local router' ports with two clicks in the terminal. - The tunnels are persistent and free to use.
- Tear down process is as simple as
pkill fwd && pkill ngrok
- you can monitor established tunnels with ngrok console (free)
- you can try inlets or argo tunnels for similar capabilities
What are your ways to reach your routers in a lab, share in the comments?