SSH session initiated from a Nerves device behind firewall

Hi,

Has anybody done and documented/blogged about the “reverse SSH proxy” or “SSH jump host” setup with a Nerves device?

I would like to set this up with a device on a 4G network. The device will be collecting some specific data but not pushing it forward in the whole capacity. If there will be a trigger I would like to send down a MQTT message to bring up a SSH tunnel and specific limits/configs for required data. But I would like to start the tunnel from a remote device side.

I was looking into NervesSSH, but couldn’t find anything there mentioning this.

Any suggestion would be appreciated.

Thanks in advance.

Tomaz

I mean, in addition to this, main purpose is to be able to manage files on /root (/data) partition. There will be a lot of files and for sure you can do a lot of this programatically, but due to the fact devices will be > 1000km away I would like to keep my options open.

To get a more clear idea I am not sure why you’d want to start an SSH tunnel rather than shove data over MQTT. Or maybe transfer it via HTTPS to something like object storage? These seem more straightforward.

But assuming you need a secure tunnel to access some private networked service to hand data to that. I guess you could install the SSH packages from buildroot and then use MuonTrap to run an SSH-command as a supervised daemon.

nerves_ssh is tooling into the SSH subsystem of Erlang to allow connecting to the device I don’t believe it has any stuff for making outbound SSH connections.

If you want something that is at least somewhat built out in Nerves I will say that Wireguard is not super hard to get rolling. You can install VintageNetWireguard and use that on the Nerves device, use the normal wireguard tooling with wg-quick on another end to set up a recipient port and all that. I think the design of wireguard actually makes it feasible to leave the tunnel “active” continuously. By default it shouldn’t be doing any keepalive so you can keep the wireguard interface/network up and just close whatever connection you used and it will be quiet (and actually disconnected) until you try to send packets again.

I think wireguard is a quicker win than SSH for this.

Yea, my post might not be best written. To elaborate a bit more. I will be getting data into my Nerves device with 2 separate streams. One getting data at 1Hz and one at 50Hz rate. Not really important, but this will be energy related data.

1Hz data will be, after some checks and processing pushed over MQTT to the cloud side.
50Hz data will be stored locally. There is a whole logging/rotation/retention/processing code for that. This data will have a retention and will be used on per request from cloud side. We’re talking about Gb’s of data, but with some slick approach it should be ok.

I will be using something like ExAws.S3 to upload this data to my Min.io (object storage) as you @lawik already suggested. I would just like to have “shell” access to a device to be able to manually intervene if needed in regards to this “file management”

Wireguard is really a good idea. Will check this as well. But just for the sake of debate, if you would have like 10k devices … what would that mean in regards to cloud side Wireguard administration? Never did Wireguards before. I expect I could wire up Wireguards with my mTLS as well?

Oh, you just want terminal access to the device? Use NervesHub. Easiest way. You get a terminal on the web and full IEx. We know it works with way more than 10k devices.

If you must have direct networking to the device to poke it, then Wireguard is probably the good choice. It uses UDP and it’s own protocol but it is PKI-based so both parties actually hold a full public/private key pair and that’s how they shake hands. You could just pack these keys in during device provisioning if you want the easiest way. Or you could add some exchange mechanism to your cloud application to set them up as needed.

I want to explore adding wireguard to NervesHub but there is no timeline for it currently.

Absolutely easiest for manual intervention is by far just using a NervesHub service and enabling the remote iex shell.

1 Like