How to properly set up Syncthing GUI with Nginx?

Hi all! Basically the title: I am configuring a NixOS home lab, and I have all the services behind Nginx. The server is also running Headscale, and the connections to the services (except Headscale) are only accepted from the tailnet. This works for other services, but I really have troubles in making the Syncthing GUI work in this way. What I ended up with is this configuration, that works:

{
  services.syncthing = {
    enable = true;
    openDefaultPorts = true;

    # Accept from everyone, not just localhost
    guiAddress = "0.0.0.0:8384";
    # To avoid hard-coding it or setting it via GUI
    guiPasswordFile = "/var/secrets/syncthing-admin-pass";
    settings.gui = {
      user = "syncthing";
    };
  };

  # Only accept connections from the VPN
  networking.firewall.interfaces."tailscale0".allowedTCPPorts = [ 8384 ];

  services.nginx.virtualHosts."syncthing.my-domain.net" = {

    useACMEHost = "my-domain.net"; # Use my wildcard SSL certificate
    forceSSL = true;

    locations."/" = {
      proxyPass = "http://127.0.0.1:8384";
      proxyWebsockets = true;

      extraConfig = ''
        allow 100.64.0.0/10;
        allow 127.0.0.1;
        deny all;

        client_max_body_size 50000M;
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
        send_timeout 600s;
      '';
    };
  };

  services.headscale.settings.dns.extra_records = [
    { name = "syncthing.${pubDomain}";  type = "A"; value = "100.64.0.1"; } # The tailnet IP of the NixOS server
  ];

}

But I have some questions:

  1. If I change
guiAddress = "0.0.0.0:8384";
# to =>
guiAddress = "127.0.0.1:8384";

I get

HTTP/2 403 - Host check error
  1. In the Syncthing wiki about using Nginx, it’s recommended to use these options:
location /syncthing/ {
  proxy_set_header        Host $host;
  proxy_set_header        X-Real-IP $remote_addr;
  proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header        X-Forwarded-Proto $scheme;

  proxy_pass              http://localhost:8384/;

  proxy_read_timeout      600s;
  proxy_send_timeout      600s;
}

But if use them as the extraConfig of the Nginx virtualHost (instead of the one I used), I get

HTTP/2 400 - Bad Request

What’s going on? Shouldn’t the “usual” reverse proxying work (as in scheme)? And why do I get these errors? Are the recommended Nginx options wrong? Thanks!


                                                          +----------------------------------------------------+
                                                          |    +----------------+         +---------------+    |
      +---------------+                                   |    |                |         |               |    |
      |               |       +----------------------+HTTPS on |                | localhost               |    |
      |   Client      |------>|    Tailscale VPN     |----+--->|  Nginx         |-------->|  Syncthing    |    |
      |               |       +----------------------+subdomain|                | connection              |    |
      +---------------+                                   |    |                | port 8384               |    |
                                                          |    |                |         |               |    |
                                                          |    |                |         |               |    |
                                                          |    +----------------+         +---------------+    |
                                                          |                                                    |
                                                          |             NixOS home lab                         |
                                                          |                                                    |
                                                          |                                                    |
                                                          +----------------------------------------------------+

This is because the guiAdress = "127.0.0.1:8384" will make the GUI socket accept connections only from 127.0.0.1 aka localhost.