viktak
July 18, 2023, 3:10pm
1
Dear All,
I'm new to Traefik, and have done a lot of reading before attempting to install it for my VPS. Now I am at a stage where all the services that I need are exposed. However, I cannot get the main domain to redirect (anywhere). I would like to redirect it to another site.
In the DEBUG log I can see, that all the subdomains are getting SSL certificates (if they need), but if I visit mydomain.com or www.mydomain.com I get a similar error:
time="2023-07-18T17:58:29+03:00" level=debug msg="Serving default certificate for request: \"www.mydomain.com\""
time="2023-07-18T17:58:29+03:00" level=debug msg="http: TLS handshake error from 172.68.62.27:56516: remote error: tls: unknown certificate authority"
My server is behind Cloudflare, but I don't think that is an issue as all the subdomains work correctly.
This is my docker-compose.yml
:
version: "3"
services:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
networks:
- mynet
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /etc/localtime:/etc/localtime:ro
- ./data:/etc/traefik
- ./ssl-certs:/ssl-certs
- ./logs:/var/log/traefik
labels:
- traefik.enable=true
- traefik.http.routers.traefik.entrypoints=websecure
- traefik.http.routers.traefik.rule=Host(`traefik.mydomain.com`)
- traefik.http.routers.traefik.tls=true
- traefik.http.routers.traefik.tls.certresolver=production
- traefik.http.services.traefik.loadbalancer.server.port=8080
- traefik.http.routers.catchall.entrypoints=websecure
- traefik.http.routers.catchall.rule=HostRegexp(`{host:.+}`)
- traefik.http.routers.catchall.priority=1
- traefik.http.routers.catchall.tls.certresolver=myresolver
- traefik.http.services.catchall.loadbalancer.server.port=80
- traefik.http.routers.catchall.middlewares=redirectall
- traefik.http.middlewares.redirectall.redirectregex.regex=.*
- traefik.http.middlewares.redirectall.redirectregex.replacement=https://anotherdomain.com
networks:
mynet:
external: true
Finally, here is my traefik.yml
:
global:
checkNewVersion: true
log:
level: DEBUG
format: common
filePath: /var/log/traefik/traefik.log
api:
dashboard: false
insecure: false
entryPoints:
web:
address: :80
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: :443
certificatesResolvers:
staging:
acme:
email: letsencrypt@mydomain.com
storage: /etc/traefik/certs/acme.json
caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
httpChallenge:
entryPoint: web
production:
acme:
email: letsencrypt@mydomain.com
storage: /etc/traefik/certs/acme.json
caServer: "https://acme-v02.api.letsencrypt.org/directory"
httpChallenge:
entryPoint: web
providers:
docker:
exposedByDefault: false
file:
directory: /etc/traefik/configuration
watch: true
What am I missing?
See simple Traefik example , redirect at the bottom.
You should first check that your router works, maybe with a whoami target service, then add the middleware. You could use HostSNI(`*`)
for websecure catchall rule.
viktak
July 19, 2023, 6:26am
3
I'm afraid I don't quite understand what you mean. I had a look at the example you have shown (in fact, I had been experimenting with it before), and while it works as it is (well, I added tls
to it), it didn't get me any closer to the solution.
Entering whoami.mydomain.com
works fine, but www.whoami.mydomain.com
fails with the following error in the browser (Brave, incognito mode):
This site can’t provide a secure connection www.whoami.mydomain.com uses an unsupported protocol.
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
Also, what do you mean by:
You could use HostSNI(
*)
for websecure catchall rule.
I like the idea of a catchall rule... but where do I put it?
<thanks for sticking with me on this issue!>
viktak
July 19, 2023, 8:37am
4
I managed to redirect the main domain like this:
# Redirecting main domain
- "traefik.http.routers.domain.entrypoints=websecure"
- "traefik.http.routers.domain.rule=Host(`mydomain.com`)"
- "traefik.http.routers.domain.tls.certresolver=production"
- "traefik.http.routers.domain.middlewares=domain"
- 'traefik.http.middlewares.domain.redirectregex.regex=^https://mydomain.com/(.*)'
- 'traefik.http.middlewares.domain.redirectregex.replacement=https://google.com/$${1}'
- "traefik.http.middlewares.domain.redirectregex.permanent=false"
This is now working as expected. Is this the preferred way to do it, though?
Also, this only redirects the main domain, but not all the "non-existing" subdomains.
Traefik uses a router
to match a route, then applies middleware
, to finally forward via service
.
traefik.http.routers.domain.rule=HostSNI(`*`)
is a catchall for https/TLS connections.
This requires that you use a wildcard cert, so that Traefik knows what domains to get a cert for, and also that browsers will not show "invalid cert".
And you need to update your current RegEx to match any domain.
viktak
July 19, 2023, 10:01am
6
I'm happy to use a wildcard certificate, but where do I set it? And how do I make sure that this catchall router only forwards the "unknown" subdomains?
viktak
July 19, 2023, 10:05am
7
If I replace my - "traefik.http.routers.domain.rule=Host(
mydomain.com)"
line with your suggestion traefik.http.routers.domain.rule=HostSNI(
*)
then the main domain redirection stops working with 404 page not found
and all unknown subdomains fail with Invalid SSL certificate
.
As I stated before
This requires that you use a wildcard cert, so that Traefik knows what domains to get a cert for, and also that browsers will not show "invalid cert".
Either you specify all used domains with Host() || Host() || ...
or you use a wildcard cert, either by buying one or using LetsEncrypt with dnsChallnge (doc ).
viktak
July 19, 2023, 3:07pm
9
I've been trying to get this working all day long, with no luck.
I have now this in my traefik.yml
:
certificatesResolvers:
production:
acme:
email: letsencrypt@mydomain.com
storage: /etc/traefik/certs/acme.json
caServer: "https://acme-v02.api.letsencrypt.org/directory"
dnsChallenge:
provider: cloudflare
delayBeforeCheck: 0
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
and this in docker-compose.yml
:
- traefik.http.routers.http_catchall.rule=HostRegexp(`{any:.+}`)
- traefik.http.routers.http_catchall.entrypoints=web,websecure
- traefik.http.routers.http_catchall.middlewares=default_host
- traefik.http.middlewares.default_host.redirectregex.regex=^https://(.*)?mydomain.com(.*)$$
- traefik.http.middlewares.default_host.redirectregex.replacement=https://google.com
- traefik.http.middlewares.default_host.redirectregex.permanent=false
- traefik.http.routers.wildcard.tls=true
- traefik.http.routers.wildcard.tls.certresolver=production
- traefik.http.routers.wildcard.tls.domains[0].main=mydomain.com
- traefik.http.routers.wildcard.tls.domains[0].sans=*.mydomain.com
Still, no luck. All the subdomains defined work well, the main domain redirects correctly as well. But an undefined subdomain, like blah.mydomain.com
gives me a 404 page not found
error.
In the logs I can't see any error:
time="2023-07-19T18:04:20+03:00" level=info msg="Traefik version 2.10.3 built on 2023-06-19T16:18:54Z"
time="2023-07-19T18:04:20+03:00" level=info msg="Starting provider aggregator aggregator.ProviderAggregator"
time="2023-07-19T18:04:20+03:00" level=info msg="Starting provider *file.Provider"
time="2023-07-19T18:04:20+03:00" level=info msg="Starting provider *traefik.Provider"
time="2023-07-19T18:04:20+03:00" level=info msg="Starting provider *docker.Provider"
time="2023-07-19T18:04:20+03:00" level=info msg="Starting provider *acme.ChallengeTLSALPN"
time="2023-07-19T18:04:20+03:00" level=info msg="Starting provider *acme.Provider"
time="2023-07-19T18:04:20+03:00" level=info msg="Testing certificate renew..." providerName=production.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"
time="2023-07-19T18:04:20+03:00" level=info msg="Starting provider *acme.Provider"
time="2023-07-19T18:04:20+03:00" level=info msg="Testing certificate renew..." providerName=staging.acme ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory"
Routers need a rule to be matched, routers.wildcard
probably does nothing.
Assign your certresolver to websecure entrypoint.
See simple Traefik example .
viktak
July 20, 2023, 7:28am
11
ok, I think I understand this, and it makes sense:
So I changed my config like this, I even put in priority
:
- traefik.http.routers.http_catchall.priority=999999
- traefik.http.routers.http_catchall.rule=HostRegexp(`{any:.+}`)
- traefik.http.routers.http_catchall.entrypoints=websecure
- traefik.http.routers.http_catchall.middlewares=default_host
- traefik.http.middlewares.default_host.redirectregex.regex=^https://(.*)?mydomain.com(.*)$$
- traefik.http.middlewares.default_host.redirectregex.replacement=https://google.com
- traefik.http.middlewares.default_host.redirectregex.permanent=false
- traefik.http.routers.http_catchall.tls=true
- traefik.http.routers.http_catchall.tls.certresolver=production
- traefik.http.routers.http_catchall.tls.domains[0].main=mydomain.com
- traefik.http.routers.http_catchall.tls.domains[0].sans=*.mydomain.com
Now I am getting Too many redirects
in the browser, for any request.
That does not make sense, when you redirect the browser to an external domain, like you show in your config. This usually just happens when you redirect to the same server and enter an endless loop.
viktak
July 21, 2023, 6:57am
13
After a lot more research, I am finally starting to begin to understand how Traefik works.
I managed to get the desired behavior with the following setup:
I removed all shenanigans from docker-compose.yml
, and added the following to the dynamic config:
routers:
domainRouter:
entrypoints:
- websecure
rule: "Host(`mydomain.com`)"
service: dummy
middlewares:
- domain
tls:
certresolver: production
catchAllRouter:
entrypoints:
- websecure
middlewares:
- catchAll
rule: "PathPrefix(`/`)"
service: dummy
priority: 1
tls:
certresolver: production
domains:
- main: "mydomain.com"
- sans: "*.mydomain.com"
middlewares:
domain:
redirectregex:
regex: "^https://mydomain.com/(.*)"
replacement: "https://mydomain.com/${1}"
permanent: true
catchAll:
redirectregex:
regex: "^.*$"
replacement: "https://mydomain.com/${1}"
permanent: false
This accomplishes the following:
The main domain is redirected to a custom URL
Any subdomain that is not explicitly defined in docker label rules get redirected to another custom domain.
@bluepuma77 thank you for nudging me in the right direction!
1 Like
system
Closed
July 24, 2023, 6:57am
14
This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.