On an Octoprint instance, what is actually listening on port 5000?

Hi,
I have a general question about Octoprint regarding what is actually listening on port 5000. Note I am running it on an ubuntu-server-19.04 box, not an rpi with Octopi so there is no haproxy involved. The reason I ask is because I would like to access it from the public internet by forwarding ports 80 & 443 on my Linksys WRT3200ACM router running OpenWrt to a dedicated Nginx reverse proxy server on my network. That connection will be over SSL https with a cert I got from letsencrpyt using a domain name I have. This means any incoming connections from the public internet will have to go through the reverse proxy with an http auth first in order to get to any of my self-hosted web services.

So the question is, is there a way to make an SSL connection from my reverse proxy server, directly to port 5000 of the Octoprint instance on a separate server (no localhost connection to port 5000)? That's why I'm asking how or what software (or I guess programming language) is making it possible to listen on that port 5000 for Octoprint so maybe I could use a SSL certificate for that connection also. If not, I will just use an SSH tunnel but just wanted to ask out of curiosity. And I know I probably don't need encryption over my internal network but it is over wifi and mostly I just like tinkering with network stuff for fun.

Thanks for your help!
Rob

Definitely possible...

What does this show you?

sudo netstat -napl | grep :5000

I'm on a pi, it shows me

tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN      441/python2
tcp        0      0 127.0.0.1:56532         127.0.0.1:5000          ESTABLISHED 596/haproxy
tcp        0      0 127.0.0.1:5000          127.0.0.1:56532         ESTABLISHED 441/python2

Which means that process 441 is binded to 127.0.0.1 (so not accessible from external servers)

if check what is that, I'll get:

ps -ewHf | grep 4[4]1
pi         441     1  0 11:19 ?        00:02:15   /home/pi/oprint/bin/python2 /home/pi/oprint/bin/octoprint serve --host=127.0.0.1 --port=5000

So you can have that binding to other IPs and listening on other ports...

Mine shows:

sudo netstat -napl | grep :5000

tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN      17260/python2
tcp6       0      0 :::5000                 :::*                    LISTEN      17260/python2

ps -ewHf | grep 5000

octopri+ 17260     1  2 Oct04 ?        01:35:30   /home/octoprint_user/venvs/vir_octoprint-1/bin/python2 /home/octoprint_user/venvs/vir_octoprint-1/bin/octoprint serve --config /home/octoprint_user/.octoprint/config.yaml --basedir /home/octoprint_user/.octoprint --port=5000

Ok yeah thanks, that makes sense now that I see that. It's a python socket listening to whatever port you execute octoprint on and bound to 0.0.0.0

Does octoprint have any ssl functionality built-in with the ssl python module? If not, does anyone know what would be involved in using pythons built-in ssl TLS/SSL wrapper for socket objects to add it to octoprint myself as a project?

Thanks!
Rob

Nothing built-in that I know of. With the OctoPi image the ssl is achieved through the haproxy frontend, and the connection still is tunneled/nat'd to port 5000 on the backend.You could achieve the same thing I'm sure using nginx.

Ok yeah, I'm using ssh port forwarding now for the connection between octoprint and the Nginx reverse proxy which are on seperate computers. Maybe I'll take a look at the source code and see if there's anythings about ssl around the web socket so https can be used.

Doing a little more research it seems that certbot would be your friend as it automatically configures nginx for you. Here's a couple of links of a couple of different approaches. If you take those approaches along with the config examples linked before you should be able to come up with a working example, specifically using a sub-folder of the domain you are already configuring for letsencrypt.

Those are very good links for people to follow and I'm pretty sure I read them a couple weeks ago lol. I have the outside ssl connection coming from the internet to my nginx reverse proxy all working well and also from the nginx reverse proxy server to my octoprint server machine using an ssh port forward. That all works as expected and fine but I was trying to see if I could also use an ssl connection instead of an ssh tunnel between the nginx reverse proxy and my octoprint sever machine.

I combed through the octoprint code and I actually was able to find the code that starts the octoprint server. It uses a python web framework called Tornado. After looking at the Tornado docs a little it seems it is no problem to use SSL with Tornado applications. It is simple enough to add the python code to start the server with SSL but not sure how that would affect the javascript etc. but I am going to try just for fun. Any comments on this would be appreciated. Thanks everyone!

I forgot to post back but I figured it out, never say never! I dug into the code and was able to add arguments to the CustomHTTPserver tornado server for an an SSL certificate to be used. It works great! I can access OctoPrint using https://192.168.x.x:5000 now and connect it to my nginx reverse proxy server instead of an ssh tunnel. A lot easier and cleaner I think. Here is the magic code to make it work:

Server File: src\octoprint\server_init_.py

server_kwargs = dict(max_body_sizes=max_body_sizes,
		                     default_max_body_size=self._settings.getInt(["server", "maxSize"]),
		                     xheaders=True,
		                     trusted_downstream=trusted_downstream)
		
server_kwargs.update(dict(ssl_options={"certfile":"ssl/certs/example.com/fullchain.pem",
	            						       "keyfile":"certs/example.com/privkey.pem"}))
1 Like