Syncthing Relay and Disco Servers behind an Nginx Reverse Proxy

Hi Everyone
(Admin, please move to a more appropriate group if Networking & Firewalls isn’t good for this)

My company has recently setup a Syncthing solution. We are a 1 stop Ubuntu shop also… laptops, desktops, and server infrastructure. Windows doesn’t exist in this mix at all!

Head office has built a VM for Syncthing and a 2nd VM for Syncthing Relay and Disco. My sys admin has asked me to build a Nginx Reverse Proxy (in a docker container) to allow connections to both relay & disco servers on port 443.

Syncthing is on server A
Syncthing Relay is on server B
Syncthing Disco is also on server B
Nginx (docker) is also on server B
Server A & B are on the same subnet and can happily communicate to each other without any firewalls between the 2. There’s no egress firewalls on either server either.

This is proving very tricky and I’d REALLY like some tips and pointers on how best this can be done. I’ve already spent over a solid week trawling support docs on Nginx, Syncthing & docker containers.

We have public DNS setup and wildcard certificates for *.companydom.ai (not the real domain)
relay.companydom.ai resolves correctly
discover.companydom.ai also resolves correctly to their Public IP addresses.

Edge F/wall is an Ubi Dream Machine Pro (hopefully one day it’ll be a Netgate 6100 or bigger)
NAT rules enabled:
443, 8443 and 22067 are all being NAT translated to the LAN IP for the server B and are open on the internet.

We have a remote site inside a client network.The client firewall (Palo Alto) allows egress TCP:443 to anywhere. The client has kindly added egress rules to allow egress TCP:8443 and TCP:22067 from our network inside theirs. The remote Syncthing server can connect to both Relay and Disco servers from the site.

I’m having troubles with the nginx.conf.

I’ve concentrated efforts creating a secure connection from Nginx to the Relay server (TCP 22067) and have ignored the Disco server (TCP 8443) for now.

URL’s reviewed looking for a the solution

https://nginx.org/en/docs/stream/ngx_stream_core_module.html#stream

nginx -t shows the config is good

nginx.conf

worker_processes auto;

stream {
    upstream backend {
        server 172.1.2.10:22067;
        server relay.companydom.ai:22067;
       }

server {
    listen        22067;
    proxy_pass    backend;
    proxy_ssl     on;

    proxy_ssl_certificate      /etc/nginx/certs/companydom.ai.crt;
    proxy_ssl_certificate_key  /etc/nginx/certs/companydom.ai.key;
    proxy_ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
    proxy_ssl_ciphers          HIGH:!aNULL:!MD5;

    proxy_ssl_verify           on;
    proxy_ssl_verify_depth     2;
    proxy_ssl_session_reuse    on;
    }
}

A(nother) super simplified nginx.conf (again nginx -t shows the config is good)

worker_processes auto;

http {
    server {
        listen 443 ssl proxy_protocol;
     }
stream {
    listen 22067 proxy_protocol;
    }
}

remote Syncthing server connection relay://relay.companydom.ai:22067 works perfectly.
As soon as I change the remote syncthing server to use relay://relay.companydom.ai:443 the connection fails.

Not something I have ever setup or needed, maybe someone else has some advice.

Thanks Tom
Once I’ve sorted this, I’ll add details on what was executed and a copy of the nginx.conf file.

Any help from the community would be greatly appreciated.
TIA
Josho

1 Like

I have a couple things.

  1. What networking method did you deploy your nginx container with? Bridge or Host?

  2. Please replace proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2; with proxy_ssl_protocols TLSv1.2; If you want to support TLS 1.3 then add it. This is for better security.

  3. Are you able to get into the logs of the nginx container to see if any requests are being rejected or processed at all? This location is typically in /var/log/nginx

EDIT:

Oh wait. You have your listen port on the server section the same as your backend. You need to change that to 443 or a different port. Also I think the upstream module is for load balancing for round robin.

Here is what I would do for the config if it were me

server {
    listen    80;
    server_name   relay.companydom.ai;
    return 301   https://$host$request_uri;
}

server {
    listen        443 ssl;
    server_name    relay.companydom.ai;
    proxy_ssl_certificate      /etc/nginx/certs/companydom.ai.crt;
    proxy_ssl_certificate_key  /etc/nginx/certs/companydom.ai.key;
    proxy_ssl_protocols        TLSv1.2;
    proxy_ssl_ciphers          HIGH:!aNULL:!MD5;

    location / {
        proxy_pass   https://172.1.2.10:22067;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Hi xMAXIMUSx
The docker container compose file network_mode: bridge is defined.

I installed bind9-dnsutils to the nginx docker and attempted to resolve relay.companydom.ai and this is working. I can also ping the Syncthing relay server’s LAN IP and that pongs no problems.

The suggested config makes sense. The nginx daemon is listening for connections on port 443 and parsing these to the location / {context}.

I will add in an access.log and error.log to the server context to see whats coming in on port 443. When I’ve nailed this, I’ll provide an updated config. :+1:

After further digging thru the Syncthing forums, it would appear hosting a Syncthing Relay server behind a proxy (nginx or otherwise) will not work, not even using the TCP stream context in an nginx.conf

hosting a Syncthing Discovery server will function as disco servers connect on https (TCP:8443)

Syncthing Relay server CAN be discovered via using an iptables as per Syncthing Relay Server — Syncthing documentation

This means the network diagram will require the Syncthing Relay and Discovery server be separated onto different servers. Thankfully my company uses a /29 SDWAN.

xMAXIMUSx again thank you so very much for your input and proposed config! HUGELY appreciated!