Hello 
Before diving into the issue, let's start with a little bit of context.
I'm building my homelab with internal services and external services.
Internal services are served under their own subdomain of domain.local (dnsmasq is configured to return my homelab ip for *.domain.local)
External servies are served under thei own subdomain of domain.com
Only :80 and :443 is allowed to coming from outside and are redirected to homelab:81 and homelab:444 respectively.
Thus, I'm sure that internal services are not exposed and safe from hostname spoofing.
In Traefik, I have 4 entrypoints:
- local (:80)
- localsecure (:443)
- web (:81)
- websecure(:444)
Redirection from http (web) to https (websecure) works well:
web:
address: :81
http:
redirections:
entryPoint:
to: :443 # 443 because the redirection is done client-side and thus 443 -> 444 from outside
scheme: https
But I also have the opposite: from https (localsecure) to https (local) that doesn't work:
localsecure:
address: :443
http:
redirections:
entryPoint:
to: :80
scheme: http
(internal services cannot benefit from ssl certificate as there is no way for let's encrypt to check the challenge).
I tried every lead I have:configuration through entrypoints, routers, middlewares
I've enabled OPTL traces and verbose log but I couldn't find a solution.
Could one of you help me? 
I've must missed something
What’s the error? Browsers usually don’t like to move from https to http, once they had a secure connection.
You can use LetsEncrypt with dnsChallenge
to create TLS certs for sub-domains not available on the Internet.
What’s the error?
Sorry, I missed the most important thing... the error: a 404.
https://service.domain.local isn't bound to anything but http://service.domain.local is (hence the need of the redirection).
Browsers usually don’t like to move from https to http, once they had a secure connection.
I checked with curl directly and Traefik send the 404, there is no redirection at all
You can use LetsEncrypt with dnsChallenge
to create TLS certs for sub-domains not available on the Internet.
I could use Let's encrypt with dnsChallenge
if the domain were existing but it's not (.local
tlds are reserved and non-registrable tlds).
You do need a router
listening on an entrypoint
to apply a middleware
.
Just use an alternative domain name like service.local.example.com
.
You do need a router
listening on an entrypoint
to apply a middleware
.
Did you mean that I don't need a router? Because if so I'm aware ^^
I just tried every option I had. The code I quoted is the entrypoints configuration.
Just use an alternative domain name like service.local.example.com
Having public dns records targeting private ip addresses is considered as bad practive and even isn't supported by some ISPs... such as mine. ("Free", one of the biggest french ISPs)
Also, even if I could take another route, shouldn't this redirection work, anyway?
You should start by supplying the error, which I asked for before. Until then everyone except you has not enough information.
Enable and check Traefik debug log and Traefik access log in JSON format during requests. Also check browser developer tools network tab during requests.
You don’t need to have sub.local.example.com
in your public DNS with a private IP. You probably need to create a local.example.com
zone (without IP). Then create *.local.example.com
wildcard with LetsEncrypt dnsChallenge
. Resolve the local sub-domains to your private IPs with a hosts file or a local DNS resolver (which forwards all other requests to a public one).
You should start by supplying the error, which I asked for before. Until then everyone except you has not enough information.
I did: I get a 404 when accessing https://service.domain.local instead of having a redirection towards http://service.domain.local (redirection from https scheme to http).
Enable and check Traefik debug log and Traefik access log in JSON format during requests. Also check browser developer tools network tab during requests.
I enabled and check both (in common format though) and also enabled tracing (and exploited them with grafana tempo) and found nothing. Traefik seems to behave like there was no redirection.
Also check browser developer tools network tab during requests.
I said I used cURL, here is the output in verbose mode:
* Host service.domain.local :443 was resolved.
* IPv6: (none)
* IPv4: 192.168.1.42
* Trying 192.168.1.42:443...
* Connected to service.domain.local (192.168.1.42) port 443
* schannel: disabled automatic use of client certificate
* using HTTP/1.x
> GET / HTTP/1.1
> Host: service.domain.local
> User-Agent: curl/8.8.0
> Accept: */*
> Connection: close
>
* Request completely sent off
* schannel: remote party requests renegotiation
* schannel: renegotiating SSL/TLS connection
* schannel: SSL/TLS connection renegotiated
* schannel: server close notification received (close_notify)
< HTTP/1.1 404 Not Found
< Content-Type: text/plain; charset=utf-8
< X-Content-Type-Options: nosniff
< Date: Sun, 29 Dec 2024 10:44:01 GMT
< Content-Length: 19
< Connection: close
<
404 page not found
* Closing connection
* schannel: shutting down SSL/TLS connection with service.domain.local port 443
You don’t need to have sub.local.example.com
in your public DNS with a private IP [...]
Yes, this should work.
Share your full Traefik static and dynamic config, and docker-compose.yml
if used.
Sure 
docker-compose.yml
services:
traefik:
image: "traefik:latest"
container_name: traefik
restart: unless-stopped
networks:
- web
- observability_tracing
ports:
# external traffic is binded to specific ports
# 80 -> 81
# 443 -> 444
- "81:81"
- "444:444"
# internal traffic is supported with normal ports
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "${PWD}/acme2.json:/acme.json"
- "${PWD}/traefik.yml:/etc/traefik/traefik.yml"
- "${PWD}/conf:/etc/traefik/conf"
- "${PWD}/log:/var/log"
networks:
web:
external: true
observability_tracing:
external: true
traefik.yml
global:
checkNewVersion: true
sendAnonymousUsage: false
entryPoints:
local:
address: :80
localsecure:
address: :443
web:
address: :81
http:
redirections:
entryPoint:
to: :443
scheme: https
websecure:
address: :444
log:
level: "ERROR"
accessLog:
filePath: /var/log/traefik/access.log
addInternals: true
api:
dashboard: true
debug: true
providers:
docker:
endpoint: unix:///var/run/docker.sock
exposedByDefault: false
network: web
file:
directory: /etc/traefik/conf
watch: true
certificatesResolvers:
lets-encrypt:
acme:
dnsChallenge:
provider: <redacted>
delayBeforeCheck: "0"
email: <redacted>
storage: /acme.json
tracing:
otlp:
http:
endpoint: http://observability-tempo-1:4318/v1/traces
conf/*
(merged)
---
http:
routers:
api:
rule: Host(`traefik.domain.com`)
entryPoints:
- websecure
service: api@internal
middlewares:
- simpleAuth
tls:
certResolver: "lets-encrypt"
...
---
http:
middlewares:
simpleAuth:
basicAuth:
users:
- <redacted>
publicSimpleAuth:
basicAuth:
users:
- <redacted>
...
---
http:
middlewares:
LocalIp:
ipAllowList:
sourceRange:
- "127.0.0.1/16"
- "192.168.0.0/16"
redirect-to-http:
redirectScheme:
scheme: http
permanent: true
redirect-to-https:
redirectScheme:
scheme: https
permanent: true
...
This works with a https entrypoint
, to redirect to http:8080:
whoami2:
image: traefik/whoami:v1.10
networks:
- proxy
labels:
- traefik.enable=true
- traefik.http.routers.redir2.entrypoints=websecure2
- traefik.http.routers.redir2.rule=HostRegexp(`.+`)
- traefik.http.routers.redir2.middlewares=redir2
- traefik.http.middlewares.redir2.redirectscheme.scheme=http
- traefik.http.middlewares.redir2.redirectscheme.port=8080
- traefik.http.services.redir2.loadbalancer.server.port=80
Thanks for the repro on your side. However I unsuccessfully tried to replicate, on my side with the following:
services:
whoami:
image: traefik/whoami:v1.10
networks:
- web
restart: unless-stopped
labels:
- traefik.enable=true
- traefik.http.services.whoami.loadbalancer.server.port=80
- traefik.http.routers.whoami.rule=Host(`whoami.domain.local`)
- traefik.http.routers.whoami.entrypoints=localsecure
- traefik.http.routers.whoami.middlewares=redirect
- traefik.http.middlewares.redirect.redirectscheme.scheme=http
- traefik.http.middlewares.redirect.redirectscheme.port=8080
networks:
web:
external: true
It doesn't work if I access whoami.domain.local
the https scheme, but if I use the http scheme with port 443, it does work.
Adding a TLS section to my entrypoint fixed the issue.
my entrypoints (redirection from https to http is restored):
entryPoints:
local:
address: :80
localsecure:
address: :443
http:
tls:
certResolver: leresolver # added this
redirections:
entryPoint:
to: :80
scheme: http
and the whoami container:
services:
whoami:
image: traefik/whoami:v1.10
networks:
- web
restart: unless-stopped
labels:
- traefik.enable=true
- traefik.http.services.whoami.loadbalancer.server.port=80
- traefik.http.routers.whoami.rule=Host(`whoami.domain.local`)
- traefik.http.routers.whoami.entrypoints=local
networks:
web:
external: true
I don't understand why the tls section is required. According the doc, it overrides the default tls configuration. But the default tls configuration uses LetsEncrypt provide as well.