Reverse proxy configuration examples

I'd like to share my traefik example configuration, as i'm running many docker containers on a separate raspberry and using traefik there as a reverse proxy with basic authentication for access to octopi (for the Octoapp). This is stored as a traefik file configuration. I also added a ratelimit of averaged 3 requests per second and 10 for a burst of time (traefik docs doesn't specify the timeframe what a "burst of time" is).

http:
  middlewares:
    octopi_auth:
      basicAuth:
        users:
          - "octopi:bcrypt_hash"
    octopi_rate_limit:
      rateLimit:
        average: 3
        burst: 10

  routers:
    octopi:
      rule: "Host(`octopi.example.com`)"
      entryPoints:
        - "websecure"
        - "web"
      service: "octopi_service"
      middlewares:
        - "octopi_auth"
        - "octopi_rate_limit"
      tls:
        certResolver: letsencrypt


  services:
    octopi_service:
      loadBalancer:
        servers:
          - url: "http://octopi.internal.local"
        passHostHeader: true

Hi,

I've got my Nginx reverse proxy all setup and working with the webcam location as well, but am concerned that anyone can access my webcam externally by going to https://myserver.com/webcam/?action=stream. Is there a way to block external access to the /webcam location while still allowing it to work with Octoprint while using Octoprint externally?

Yes, quite simple actually: Don't make your OctoPrint instance accessible on the public and hostile internet where every script kiddie with a Kali Linux instance can find you on Shodan and then attempt to break in or launch a fun DDOS attack on you. See also this post. Use a VPN. At the very least use basic auth and access restriction by IP.

1 Like

I tried the HAproxy config, but I get this error:

The 'reqadd' directive is not supported anymore since HAProxy 2.1. Use 'http-request add-header' instead.

Simply replacing the string "reqadd" with "http-request add-header" does not work. Any ideas?

1 Like

Leaving this here as I hadn't seen reference to it after going through each post and testing/trying to get my reverse proxy working as it solved my issues:
After setting up a nginx reverse proxy (npm) last week with a basic configuration I was able to access all my instances/resources fairly easily, or resolve issues via its gui quickly, except for connecting to my octoprint server, running on a raspberry pi with a fairly stock OctoPi image.
It would hang after logging in while "connecting to server", the octoprint logs showed my connection, the error in Chrome was regarding a websocket connection error.
The reverse__proxy_test url was green across the board for http & https connections directly to octoprint as well as via the reverse proxy.
The fix I found in other post in the forums: "struggling to get reverse proxy working"
Enabling CORS under Settings > API and returning the npm configuration to "stock" (scheme:https forward port:443, Websockets, block common exploits, force ssl, http/2 support, HSTS enabled & shts subdomains all checked) is all that was needed and I was able to connect without issue.

1 Like

Has anyone set this up with a Microsoft IIS server as the proxy? I've been having a really tough time getting this one to work and I have many sites setup so I can't change to nginx or others.

Has anyone managed to configure lighttpd as a reverse proxy?

@foosel

I'm not sure how to request this change in the first post, but after a train ride from a forum post to an issue to a PR on custom HTTPS ports with nginx, an issue was solved that documentation would help with. In the nginx example provided, if a user has a custom HTTPS port, the CSRF cookie name is displayed using port 443 due to the host header being passed as just a hostname. It would be nice to have noted, specific for nginx, that the only apparent way to run a custom port is to set this header:

proxy_set_header X-Forwarded-Host $host:12345;

If interested, here is the PR that led to this: Remove custom port from CSRF cookie suffix by Fmstrat · Pull Request #4741 · OctoPrint/OctoPrint · GitHub

Thanks!

For anyone who comes along and is trying to get haproxy to work with a redirect...

At the time I posted this, all of the documentation I could find tells you to do this:

backend octoprint
        acl needs_scheme req.hdr_cnt(X-Scheme) eq 0

        reqrep ^([^\ :]*)\ /octoprint/(.*) \1\ /\2
        reqadd X-Scheme:\ https if needs_scheme { ssl_fc }
        reqadd X-Scheme:\ http if needs_scheme !{ ssl_fc }
        reqadd X-Script-Name:\ /octoprint
        option forwardfor
        server octoprint1 127.0.0.1:5000
        errorfile 503 /etc/haproxy/errors/503-no-octoprint.http

There are also posts telling you that because haproxy has been updated, you have to replace reqrep/reqadd => http-request.

Perhaps you'll start off like I did, trying to modify the latest default provided by OctoPi

backend octoprint
        acl needs_scheme req.hdr_cnt(X-Scheme) eq 0

        http-request replace-path ^([^\ :]*)\ /(.*) \1\ /\2
        http-request add-header X-Scheme https if needs_scheme { ssl_fc }
        http-request add-header X-Scheme http if needs_scheme !{ ssl_fc }
        option forwardfor
        server octoprint1 127.0.0.1:5000
        errorfile 503 /etc/haproxy/errors/503-no-octoprint.http

Perhaps you'll be like me, and naively change it to:

http-request replace-path ^([^\ :]*)\ octoprint/(.*) \1\ /\2

It'll connect to the OctoPrint login page, but it'll just loop at the login page. The proxy test page will show proper server values, but a blank space for all the client values. The help will send you here, to this page, which as of the time of writing was outdated.

If you know/learn how to read the haproxy log file, you'll see the GET requests don't have the server:port number prepended, and that you've written your replace-path incorrectly. Perhaps because you were like me, and had no idea what you were doing.

Here's a version that works for me, which perhaps might be helpful to someone:

backend octoprint
        acl needs_scheme req.hdr_cnt(X-Scheme) eq 0

        http-request replace-path /octoprint/(.*) /\1

        http-request add-header X-Script-Name /octoprint
        http-request add-header X-Scheme https if needs_scheme { ssl_fc }
        http-request add-header X-Scheme http if needs_scheme !{ ssl_fc }
        option forwardfor
        server octoprint1 127.0.0.1:5000
        errorfile 503 /etc/haproxy/errors/503-no-octoprint.http

You mean what was mentioned in this post?

In fairness I would agree that the original post ought to be updated with the correct configuration for Haproxy 2.x and 1.x separately due to the breaking changes.

1 Like

All of the previous example code had a very different replacement regex for octoprint vs the web cam backends.

It was not at all obvious to me how to write that post replacement given the default version provided by OctoPi that I was starting with, and none of the existing posts (including the one you linked) provided working code.

That post is a wiki node :wink:

I'm not especially familiar with whatever I need to be familiar with for that to mean anything to me.

Can you suggest a resource that can explain to me what that means? Perhaps one that would make it clear what I should have done differently?

wiki posts are directly editable.so I think the idea was to edit the original, adding an haproxy 2 section maybe.

1 Like

Ah. Must be some sort of minimum post count or something, because I don't have an edit button.

It's ironic, because I would totally have quietly edited the OP but I can't because I have been quiet.

I am running HAProxy and the post with the full config file worked for me on Ubuntu 22.04. When I tried to add other pages written the same way as the web cam they are ‘not found’.l. Have Plex, home assistant, etc. etc. all on same server and would like to add this same convenience for everything as I am losing track of port numbers in my head. What am I missing?

Hello @Scott_Vanlandingham !

If you seeking for concrete help and trouble shooting, please open a new thread in Get Help Networking and provide all the information that is asked for.

My Bad! Will do!

1 Like