Wednesday, January 3, 2024

When you really need access your two 3D printers outside your double NAT'd network you don't want to bother contacting the ISP about.

 I really like the idea of Octoprint(Link). There is something about a microservice, with a web front-end, that runs in a docker container, you can use to solve a very specific problem. It feels like putting in the last piece in a puzzle. I feel more complete after installing it.

In this case, I own Prusa MK3S+ 3D printer. An awesome printer I have extruded many miles of plastic  over many hours of run time. But it does not come with any WiFi capabilities at all. Loading it with models to print requires writing to an sd card and sneaker-netting it all the way across the room. Obviously, it's not ideal.

Octoprint solves this little challenge of mine. By plugging the printer into a raspberry pi, then configuring and launching Octoprint, I can upload my gcode files, and even start the printer without ever leaving my chair. I still have to get up when the print is finished, but that can be a project for another day. It also has the added functionality of managing the various uploads, camera feeds, stats, metrics, and a whole host of plugins. It's really great software.

 


Hosting multiple Printers


But I had a problem. I inherited a second Prusa, and Octoprint does not support multiple printers. Which I found odd, considering its mascot is an octopus.... But I digress.

Other than using a different software package that supported multiple printers, my only option was to host multiple instances of the Octoprint docker container. Each container would have to have it's own unique port number, and I would just have to remember which is which. I did this for a while, and it worked well enough. But eventually, I found the use of ports as the discriminator to be ugly. I have a domain name configured for services running on the raspberry pi, and it was a shame to have to remember to a fix a port number each time. 


My solution to this is a pretty simple NGINX reverse proxy that routes traffic to the correct octoprint instance based on the URL path instead of the port.

An example of the system architecture



can be seen here:



The config file is pretty straight forward also:



Nginx is super cool.

Accessing Externally

I really wanted to access these printers from outside my network. For no other reason than because a friend of mine got a Bambu and he could do it. But also if I'm running a long print, being able to checkup on the camera feed and and progress is pretty nifty.

Unfortunately, my ISP double NATs me, which means I don't have the option to host locally and setup port forwarding on my router(But who wants to deal with dynamic DNS any way?), so I had to come up with another way.

I've long been a proponent of over complicating things. And my solution is very much that. I built what I'm going to refer to as a "reverse jump server". Effectively it's an EC2 instance running in AWS, with an actively maintained SSH tunnel initiated from the raspberry pi. With remote port forwarding. This allows the EC2 instance to host the port externally, and traffic is then forwarded through the tunnel back to the internal network.

It works like a dream.

To manage these tunnels, I built an ASP.NET microservice (This is our THIRD microservice mentioned in this post). It acts as an SSH client, connecting to the ssh server, and actively maintains the tunnel. Reconnecting/logging errors as they come up. (The code for this service can be found here: https://github.com/jqt3of5/reverse-jump-server)


No comments:

Post a Comment