Remote management for OpenWRT devices without opening inbound connections
Everyone is working from home these days and needs a decent Internet connection. That's especially true if you need to do video calls and the room you want to do them has the worst WiFi coverage of the whole flat. Well, that's exactly what happened to my parents in law.
When they moved in, we knew that at some point we'll have to fix the WiFi - the ISP provided DSL/router/WiFi combo would not cut it, especially not with the shape of the flat and the elevator shaft in the middle of it: the flat is essentially a big C around said shaft. But it was good enough for email, so we postponed that. Until now.
The flat has wired Ethernet, but the users MacBook Air does not. That would have been too easy, right? So let's add another access point and hope the situation improves.
Luckily I still had a TP-Link Archer C7 AC1750 in a drawer, which I could quickly flash with a fresh OpenWRT release, disable DHCPd and configure the same SSID and keys as the main/old WiFi. But I didn't know which channels would be best in the destination environment.
Under normal circumstances, I'd just take the AP, drive to my parents in law and finish the configuration there. Nope, not gonna happen these days. So my plan was to finish configuration here, put the AP in a box and on the porch where someone can pick it up.
But this would leave me without a way to further configure the device once it has been deployed - I was not particularly interested in trying to get port forwarding configured via phone and I was pretty sure UPnP was disabled in the ISP router. Installing a Tor hidden service for SSH was one possibility, setting up a VPN and making the AP a client another. Well, or just creating a reverse tunnel with SSH!
sshtunnel
Creating a tunnel with OpenSSH is easy: ssh -R127.0.0.1:2222:127.0.0.1:22 server.example.com
will forward localhost:2222
on server.example.com
to port 22 of the machine the SSH connection originated from. But what happens if the connection dies? Adding a while true; do …; done
around it might help, but I would really like not to reinvent the wheel here!
Thankfully, somebody already invented that particular wheel and OpenWRT comes with a sshtunnel package that takes care of setting up and keeping up such tunnels and documentation how to do so. Just install the sshtunnel
package, edit /etc/config/sshtunnel
to contain a server
stanza with hostname, port and username and a tunnelR
stanza referring said server plus the local and remote sides of the tunnel and you're good to go.
config server home option user user option hostname server.example.com option port 22 config tunnelR local_ssh option server home option remoteaddress 127.0.0.1 option remoteport 2222 option localaddress 127.0.0.1 option localport 22
The only caveat is that sshtunnel
needs the OpenSSH client binary (and the package correctly depends on it) and OpenWRT does not ship the ssh-keygen
tool from OpenSSH but only the equivalent for Dropbear. As OpenSSH can't read Dropbear keys (and vice versa) you'll have to generate the key somewhere else and deploy it to the OpenWRT box and the target system.
Oh, and OpenWRT defaults to enabling password login via SSH, so please disable that if you expose the box to the Internet in any way!
Using the tunnel
After configuring and starting the service, you'll see the OpenWRT system logging in to the configured remote and opening the tunnel. For some reason that connection would not show up in the output of w
-- probably because there was no shell started or something, but logs show it clearly.
Now it's just a matter of connecting to the newly open port and you're in. As the port is bound to 127.0.0.1, the connection is only possible from server.example.com
or using it as a jump host via OpenSSH's ProxyJump
option: ssh -J server.example.com -p 2222 root@localhost
.
Additionally, you can forward a local port over the tunneled connection to create a tunnel for the OpenWRT webinterface: ssh -J server.example.com -p 2222 -L8080:localhost:80 root@localhost
. Yes, that's a tunnel inside a tunnel, and all the network engineers will go brrr, but it works and you can access LuCi on http://localhost:8080
just fine.
If you don't want to type that every time, create an entry in your .ssh/config
:
Host openwrt ProxyJump server.example.com HostName localhost Port 2222 User root LocalForward 8080 localhost:80
And we're done. Enjoy easy access to the newly deployed box and carry on.
Comments