Hi, I’m trying to run a global discovery server for my devices at home using Docker and Traefik. I set it up on my server and PC in a configuration like the below:
PC ==(https)==> Traefik (on server) ==(http)==> Syncthing-Discosvr
Syncthingthing-Discosvr is using -http
so that Traefik handles certs.
On the PC though, I always seem to get 403 Forbidden
as the error reported in the Syncthing GUI on the PC. It seems to be returned from Syncthing-Discosvr itself after looking at Traefik’s logs and trying curl -X POST https://st-ds.xxx.dev
myself (which is what Syncthing itself seems to be doing).
Here’s all the configs/logs of interest.
Syncthing-Discosvr docker-compose
snippet:
syncthing-discosrv:
image: syncthing/discosrv
container_name: syncthing-discosrv
networks:
- traefik
environment:
PUID: 1000
PGID: 1000
volumes:
- ./syncthing/DATA/syncthing-discosrv:/var/stdiscosrv
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.services.syncthing-discosrv.loadbalancer.server.port=8443"
- "traefik.http.routers.syncthing-discosrv.entrypoints=https"
- "traefik.http.routers.syncthing-discosrv.rule=Host(`st-ds.xxx.dev`)"
- "traefik.http.routers.syncthing-discosrv.tls.certresolver=cloudflarednsresolver"
command:
# Tell it to run in HTTP, otherwise it will complain that not HTTPS
- "-http"
- "-debug"
networks:
traefik:
external:
name: infra_traefik-proxy
Syncthing-Discosvr logs:
syncthing-discosrv | stdiscosrv v1.18.0 "Fermium Flea" (go1.16.5 linux-amd64) docker@syncthing.net 2021-06-21 20:53:50 UTC [noupgrade, purego]
syncthing-discosrv | Server device ID is E75BUJW-QT4SSSM-47JKLJI-TR4IBIA-6G7V7T6-2VLPZ7H-ZLKIJFE-ZBAMFQG
syncthing-discosrv | 78629a0f5f3f164f GET /?device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2
syncthing-discosrv | 380704bb7b4d7c03 GET /?device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2
syncthing-discosrv | 0866cb397916001e GET /?device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2
syncthing-discosrv | 0c697f48392907a0 POST /
syncthing-discosrv | 0c697f48392907a0 no certificates
syncthing-discosrv | 68255aaf95e94627 GET /?device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2
syncthing-discosrv | 28b621587cb3ad0b GET /?device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2
Traefik’s docker-compose
config:
version: "3.6"
services:
traefik:
image: traefik:v2.5
container_name: traefik
restart: unless-stopped
command:
- "--log.level=DEBUG"
# Turn on dashboard, configured to use Basic Auth in this contains labels
# https://docs.traefik.io/operations/dashboard/#secure-mode
- "--api.dashboard=true" # Defaults to port 8080
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
# This needs to be the FULL NETWORK NAME. If not, Traefil will sometimes work
# and sometimes give a bad gateway for containers (randomly every run)
# https://stackoverflow.com/a/46439598/2759427
- "--providers.docker.network=infra_traefik-proxy"
- "--entrypoints.http.address=:80"
- "--entrypoints.https.address=:443"
- "--entrypoints.syncthing-tcp.address=:22000"
- "--entrypoints.syncthing-udp.address=:22000/udp"
- "--certificatesresolvers.cloudflarednsresolver.acme.email=xxx@xxx.com"
- "--certificatesresolvers.cloudflarednsresolver.acme.storage=/data/acme.json"
- "--certificatesresolvers.cloudflarednsresolver.acme.caServer=https://acme-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.cloudflarednsresolver.acme.dnschallenge.provider=cloudflare"
- "--metrics.prometheus=true"
volumes:
- "/opt/batto-infra/traefik:/data"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
ports:
- "80:80"
- "443:443"
# Syncthing
- "22000:22000/tcp" # Syncing
- "22000:22000/udp" # Syncing
environment:
CF_DNS_API_TOKEN: '${CLOUDFLARE_DDNS_XXX_DEV_API_KEY}'
networks:
- traefik-proxy
labels:
- "traefik.enable=true"
#== Middlewares ==
# LAN IP only
- "traefik.http.middlewares.lan-only.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.0.0/24, 192.168.1.0/24"
# Gzip
- "traefik.http.middlewares.http-compress.compress=true"
# Basic auth
- "traefik.http.middlewares.auth.basicauth.users=$TRAEFIK_HTPASSWD"
# https redirect
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.https-redirect.redirectscheme.permanent=true"
# Global redirect all http to https
- "traefik.http.routers.http-catchall.rule=HostRegexp(`{any:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=http"
- "traefik.http.routers.http-catchall.middlewares=https-redirect"
# == Traefik Dashboard config (traefik-ception) ==
- "traefik.http.routers.api.rule=Host(`traefik.xxx.dev`) || Host(`traefik.localhost`)"
- "traefik.http.routers.api.service=api@internal"
- "traefik.http.routers.api.middlewares=lan-only,auth"
networks:
traefik-proxy:
Traefik logs sample (1 request from Syncthing to Syncthing-discosrv)
traefik | time="2021-09-22T20:43:57Z" level=debug msg="vulcand/oxy/roundrobin/rr: begin ServeHttp on request" Request="{\"Method\":\"GET\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2\",\"Fragment\":\"\",\"RawFragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept-Encoding\":[\"gzip\"],\"User-Agent\":[\"Go-http-client/1.1\"],\"X-Forwarded-Host\":[\"st-ds.xxx.dev:443\"],\"X-Forwarded-Port\":[\"443\"],\"X-Forwarded-Proto\":[\"https\"],\"X-Forwarded-Server\":[\"c448494d942d\"],\"X-Real-Ip\":[\"192.168.0.206\"]},\"ContentLength\":0,\"TransferEncoding\":null,\"Host\":\"st-ds.xxx.dev:443\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"192.168.0.206:55740\",\"RequestURI\":\"/?device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2\",\"TLS\":null}"
traefik | time="2021-09-22T20:43:57Z" level=debug msg="vulcand/oxy/roundrobin/rr: Forwarding this request to URL" ForwardURL="http://172.18.0.4:8443" Request="{\"Method\":\"GET\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2\",\"Fragment\":\"\",\"RawFragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept-Encoding\":[\"gzip\"],\"User-Agent\":[\"Go-http-client/1.1\"],\"X-Forwarded-Host\":[\"st-ds.xxx.dev:443\"],\"X-Forwarded-Port\":[\"443\"],\"X-Forwarded-Proto\":[\"https\"],\"X-Forwarded-Server\":[\"c448494d942d\"],\"X-Real-Ip\":[\"192.168.0.206\"]},\"ContentLength\":0,\"TransferEncoding\":null,\"Host\":\"st-ds.xxx.dev:443\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"192.168.0.206:55740\",\"RequestURI\":\"/?device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2\",\"TLS\":null}"
traefik | time="2021-09-22T20:43:57Z" level=debug msg="vulcand/oxy/roundrobin/rr: completed ServeHttp on request" Request="{\"Method\":\"GET\",\"URL\":{\"Scheme\":\"\",\"Opaque\":\"\",\"User\":null,\"Host\":\"\",\"Path\":\"/\",\"RawPath\":\"\",\"ForceQuery\":false,\"RawQuery\":\"device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2\",\"Fragment\":\"\",\"RawFragment\":\"\"},\"Proto\":\"HTTP/1.1\",\"ProtoMajor\":1,\"ProtoMinor\":1,\"Header\":{\"Accept-Encoding\":[\"gzip\"],\"User-Agent\":[\"Go-http-client/1.1\"],\"X-Forwarded-Host\":[\"st-ds.xxx.dev:443\"],\"X-Forwarded-Port\":[\"443\"],\"X-Forwarded-Proto\":[\"https\"],\"X-Forwarded-Server\":[\"c448494d942d\"],\"X-Real-Ip\":[\"192.168.0.206\"]},\"ContentLength\":0,\"TransferEncoding\":null,\"Host\":\"st-ds.xxx.dev:443\",\"Form\":null,\"PostForm\":null,\"MultipartForm\":null,\"Trailer\":null,\"RemoteAddr\":\"192.168.0.206:55740\",\"RequestURI\":\"/?device=Y3KJK7J-Z4CESDE-F74R563-GUHWCNT-WQOHSAT-PCEOYVM-FMBOGMT-4TV5TA2\",\"TLS\":null}"