TheSpaghettiDetective / OctoPrint-Obico

GNU Affero General Public License v3.0
136 stars 42 forks source link

[BUG] In Premium/Basic mode, mpeg streaming is streamed on 127.0.0.1:8080, rather than 0.0.0.0:<port specified in Octoprint> #173

Open puterboy opened 2 years ago

puterboy commented 2 years ago

In Premium/Basic mode, flask is used to restream the native h.264 stream to mpeg so that the stream can be viewed in Octoprint. However, the stream is launched on 127.0.0.1:8080 (on the Octoprint server) which is generally not viewable from the Octoprint client (whether in a browser or app) that generally runs on another IP address.

This is not a problem in the OctoPI all-in-1 distro since haproxy is used to expose the stream to 0.0.0.0:8080 and thus be visible externally, but this prevents the restream from working if you install Octoprint manually on another RPI distro such as Raspbian.

Now you can require users to install haproxy (or another proxy server) or even to SSH tunnel the port but installing additional SW or kludges shouldn't be necessary to get Octoprint/Obico working. That's not to say there are not valid other reasons to install a proxy, just that it shouldn't be necessary.

Similarly, using Octoprint/Obico which can be installed as user-space programs (without even requiring root) shouldn't require a specific underlying distro (Octopi) but rather should work with minimal install effort on any distro.

Luckily, the solution is very simple. In webcam_stream.py, change the two instances of: 'webcam_server_app.run(port=8080, threaded=True)' to: 'webcam_server_app.run(host='0.0.0.0', port=8080, threaded=True)

It may also be necessary to change some of the references in the code to 127.0.0.1 to 0.0.0.0 -- though not sure if that is always necessary -- especially for the ones that are really just checking if the port is free (e.g., 'wait_for_port('127.0.0.1', 8080)')... but there could be subtleties.

Finally. the restream should be done on the port specified in Octoprint settings (under "Webcam & Timelapse") since Octoprint does not restrict the webcam to port 8080. This can easily be fixed by getting the port from webcam.settings.get and parsing the port.

All very trivial changes!

kennethjiang commented 2 years ago

This is not a bug. Listening on 0.0.0.0 when 99% of the users don't need it is an unnecessary security risk.

You can optionally change it to a feature request to make the address configurable. If it turns out to be popular among Obico users, we will be happy to prioritize it.

puterboy commented 2 years ago

I am very thankful for your leadership in this project, but I respectfully disagree for the following reasons:

The bottom line is that Obico will not work except in the most limited situation of browsing from your PI unless you either set the port to 0.0.0.0 or proxy it there.

If using a proxy is a prerequisite for using the Obico plugin with Octoprint, then that requirement should be clearly highlighted in the plugin page and documentation should point to how to configure a proxy. The average user shouldn't be expected to spend hours browsing and hacking the code to figure this out.

Of course, I am all for making this a parameter and indeed included it on my more general feature request (https://github.com/TheSpaghettiDetective/OctoPrint-Obico/issues/171) to allow for more user configuration rather than frustrating hard-coding of common parameters that may work for some or even most users but not all.

Indeed, for such a large and sophisticated project (and kudos to you and your team!), I am quite surprised by the lack of what would seem to be simple configurability -- and instead assuming everybody uses/wants the same web port (8080), the same FPS, the same resolution, etc. What if you already have a web service running on 8080 (a very common secondary http port)? What if your RPI bogs down at the fixed fps rate? etc.

kennethjiang commented 2 years ago

We actually changed from listening to 0.0.0.0 to 127.0.0.1 in 3c02063a03011854e80d4554a0300c13488f22c7 because multiple users have brought this up as a security concern.

Feel free to submit a PR if you feel strongly about it. I'll happily review and merge.

cp2004 commented 2 years ago

I would agree with @kennethjiang here, since the vast majority of OctoPrint users do run with a reverse proxy & the webcam server set to 127.0.0.1, that should be the default. Defaults should be suitable for the majority of users, not what your individual use case is. Configurable yes, default to 127.0.0.1. Installing Obico should not come with the unexpected extra ports streaming to the world, it should be explicitly configured.

puterboy commented 2 years ago

I don't care what the default is - just it should be configurable.

Also, if your RPI is "streaming to the world" then you have much bigger security problems than streaming and I would be concerned about your LAN setup.

Most users clearly don't need a reverse proxy as they probably mostly view things on their own LAN -- they just happen to have inherited a reverse proxy implementation if they used the out-of-the-box Octopi distro. After all, Octoprint itself doesn't require a reverse proxy and the standard DIY install of mjpeg-streamer streams to 0.0.0.0 so in compatible mode you will likely be streaming to 0.0.0.0 anyway.

Plus as mentioned above, if your LAN is not secure then bolting on a reverse proxy is not going to make your LAN secure.

The issue for me is that the docs pretty much flatly say that it may be difficult-to-impossible to get Obico to work with Octoprint if you don't use the Octopi distro. That's actually not true and it's only true (in part) because of this setting. Obico actually will work automagically even in the "advanced" (non-compatible) mode by just installing the plugin provided that the stream is not forced to 127.0.0.1 (and that you don't have the camera busy with another streaming process such as mjpeg-stream). And if you have mjpeg-stream working, then it will default automagically to "compatible" mode.

Parenthetically, if you are blindly using the Octopi distro you probably are not particularly secure unless you configure the basic, open Linux settings to be more secure -- many users may have a secure "reverse proxy" in an open Linux environment with default user PI and password raspberry :)

I don't really care which port setting is default -- but there is no reason that running the Obico plugin should require a proxy just because the Octopi distro happens to use one -- especially since most Obico users are probably hobbyists working on their own internally secure LAN.

Ideally, this setting would be configurable in the UI along with other very basic settings such as choice of port, resolution, frame rate, etc.

kennethjiang commented 2 years ago

The issue for me is that the docs pretty much flatly say that it may be difficult-to-impossible to get Obico to work with Octoprint if you don't use the Octopi distro. That's actually not true and it's only true (in part) because of this setting. Obico actually will work automagically even in the "advanced" (non-compatible) mode by just installing the plugin provided that the stream is not forced to 127.0.0.1 (and that you don't have the camera busy with another streaming process such as mjpeg-stream). And if you have mjpeg-stream working, then it will default automagically to "compatible" mode.

Your understanding above is not accurate. Please take a look at the code to better understand how streaming works in Obico (it's arguably complicated) so that you can contribute to the discussion more effectively.

puterboy commented 2 years ago

With all due respect, I think I do understand the code reasonably well, I just probably didn't explain myself well :)

That being said, the only point I was really trying to make is that Obico will work out-of-the-box even in "advanced mode" (including restreaming via flask to without any special configuration so long as:

  1. The camera is not busy -- e.g., you don't have an independent mjpeg-streamer process already using the camera
  2. Flask is not limited to streaming on 127.0.0.1

This is a good thing at least from the Octoprint perspective since the average Octoprint user should expect that most if not all plugins should "just" work without requiring a specific PI distro, advanced configuration external to Octoprint, or other not well-documented 3rd party programs (like proxies). And the basic documentation (https://obico.io/docs/user-guides/octoprint-plugin-setup/) appropriately makes the plugin seem accessible and easy without mentioning the need for a proxy or any other complexity.

I say this as a fan and supporter of Obico and one who wants to make it as accessible to the masses