If you intend to make your OctoPrint instance reachable via the internet through something like a port forward, you should protect it one level above OctoPrint, so that really only you and those you trust can access it and your webcam (which is not served by OctoPrint, only embedded).
Note
The safest way would be to forgo the port forward all together and instead setup and use a VPN. You could also utilize a cloud access plugin such as PolarCloud or maybe a messenger plugin like Telegram.
If all of that is not an option, feel free to read on.
If you are running haproxy in front of OctoPrint anyhow (as shipped on OctoPi and recommended), an easy way way to accomplish this is setting up HTTP Authentication.
This can be done by defining a custom user list and limiting access to your OctoPrint instance to accounts defined in this list:
Open /etc/haproxy/haproxy.cfg in your favourite text editor. You'll need to use sudo here, otherwise you won't be able to write your changes to disk! Example: sudo nano /etc/haproxy/haproxy.cfg
Define a new user list:
userlist OctoPrintUsers
user myuser insecure-password mypassword
Note: Instead of providing the password in plain text, it would be safer to create a hashed version and use that. For that you'd need to sudo apt install whois, then hash your password via mkpasswd -m sha-512 and then use the result in haproxy.cfg as password instead of insecure-password:
userlist OctoPrintUsers
user myuser password mypasswordhash
Define a new access control list (ACL) based on this user list in the frontend section:
acl ValidOctoPrintUser http_auth(OctoPrintUsers)
Tell haproxy to prompt for authentication if the ACL doesn't match:
http-request auth realm OctoPrint if !ValidOctoPrintUser
Verify that the userlist and frontend sections in your file should now look somewhat like this:
userlist OctoPrintUsers
user mypasswd insecure-password mypassword
frontend public
bind *:80
bind 0.0.0.0:443 ssl crt /etc/ssl/snakeoil.pem
option forwardfor except 127.0.0.1
acl Auth_OctoPrintUsers http_auth(OctoPrintUsers)
http-request auth realm OctoPrint if !Auth_OctoPrintUsers
use_backend webcam if { path_beg /webcam/ }
default_backend octoprint
errorfile 503 /etc/haproxy/errors/503-no-octoprint.http
Save it and exit the editor.
Restart haproxy: sudo service haproxy restart. The next time you try to open OctoPrint, you'll be prompted to authenticate by your browser.
A more sophisticated version of this could also only prompt for authentication if the request originates outside your trusted home network.
Starting with OctoPrint 1.3.7, you'll also have the option to log into your OctoPrint account through the Basic Authentication header, meaning that if you have the same username/password combos configured in both haproxy and OctoPrint, you won't have to login twice.
I would very much likte to know how to accomplish this "A more sophisticated version of this could also only prompt for authentication if the request originates outside your trusted home network."
I have tried to google it but come up short.
Edit:
I managed to do this via a workaround. By creating two separate front ends, one binds to 443 (with basic auth) and the other to 80 (without basic auth) I could expose 443 over internet and connect to 80 locally. Not the most elegant solution but it solves my problem.
First, I moved the "acl ..." and the "http-request auth..." lines from the frontend to the default backend. Then, I made a complete copy of the original default backend with a different name. Finally, I added the following line to the fronend to use the new unsecure backend from the local network: "use_backend octroprint_unsecure if { hdr_beg(host) -i 192.168 }"
So, the relavent sections of my haproxy.cfg now looks like the following:
And for whatever it's worth, I've actually changed the default ports and only forwarded the SSL through my firewall (i.e. not on 443, 80, 88, 8080, etc.).
Starting with OctoPrint 1.3.7, you'll also have the option to log into your OctoPrint account through the Basic Authentication header, meaning that if you have the same username/password combos configured in both haproxy and OctoPrint, you won't have to login twice.
Is this still true? I've configured haproxy as described, and have the same user/password configured, but I'm still getting a second login prompt.
To accomplish a HTTP-Authentication only for connections from outside your LAN, I really would not suggest to use the solution with two different backends which you can find here (https://printoid.net/access-octoprint-from-the-internet/) or in the post by @akovar above.
As far as I understand, this solution would only protect the backend octoprint while backend webcam stays unprotected from inside and outside your LAN.
In other words, everybody that knows the IP address and port of your OctoPrint could see your webcam's stream on http://IP:Port/webcam/.
A safer as well as much easier solution to prompt for authentication only for requests from outside your network would be something like
The key is in 192.168.0.0/24 which defines all IP addresses from 192.168.0.0 to 192.168.0.255 - find more about it here: https://en.wikipedia.org/wiki/Subnetwork