Redirect HTTP to HTTPS on localhost - traefik

I want to have a dev setup on my local machine to more easily test new versions of my programm - it's a server/client application. The client does need SSL and so I want to have traefik as a proxy to the (local) server which will use a self signed certificate.
I managed to get a connection without SSL but as soon as I enable HTTPS / Redirecting, traefik only responses with "backend not found" "/" 0ms.
The SSL certificate is valid according to my browsers.
Here is my setup:
traefik.toml
[docker]
watch = true
exposedByDefault = false
logLevel = "DEBUG"
defaultEntryPoints = ["https", "http"]
[accessLog]
[traefikLog]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
ca = "etc/traefik/ca.cert.pem"
certFile = "/etc/traefik/dev-cert.pem"
keyFile = "/etc/traefik/dev-key.nopass.pem"
# API definition
[api]
entryPoint = "traefik"
dashboard = true
docker-compose.yaml
version: '3'
services:
edv-reverse-proxy:
image: traefik
container_name: edv-reverse-proxy
expose:
- 8080
ports:
- 80:80
- 443:443
- 8080:8080
volumes:
- ./traefik/dev-cert.pem:/etc/traefik/dev-cert.pem
- ./traefik/dev-key.nopass.pem:/etc/traefik/dev-key.nopass.pem
- ./traefik/ca.cert.pem:/etc/traefik/ca.cert.pem
- ./traefik/traefik.toml:/etc/traefik/traefik.toml
- /var/run/docker.sock:/var/run/docker.sock
networks:
- proxy
whoami:
image: emilevauge/whoami
expose:
- 80
labels:
- traefik.enable=true
- "traefik.frontend.rule=Host:whoami.test"
- traefik.port=80
networks:
- proxy
networks:
proxy:
external: true
/etc/hosts
127.0.0.1 whoami.test
If I disable the whole entrypoints section I can connect to the service with whoami.test like expected. I tried a lot of different settings which didn't seem to have any effect.
So if anyone knows how to solve this I would be really glad!

Fields order is important in toml:
logLevel = "DEBUG" # <---
defaultEntryPoints = ["https", "http"] # <---
[accessLog]
[traefikLog]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[[entryPoints.https.tls.certificates]]
ca = "etc/traefik/ca.cert.pem"
certFile = "/etc/traefik/dev-cert.pem"
keyFile = "/etc/traefik/dev-key.nopass.pem"
# API definition
[api]
entryPoint = "traefik"
dashboard = true
[docker]
watch = true
exposedByDefault = false

For a traefik v2.1 default router http to https redirect you can do the following:
traefik:
image: traefik:v2.1
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- 80:80
- 443:443
labels:
- "traefik.enable=true"
### Default HTTP Router
- "traefik.http.routers.default-http2https.rule=HostRegexp(`{subdomain:[a-z,0-9]+}.example.com`)"
- "traefik.http.routers.default-http2https.entrypoints=http"
- "traefik.http.routers.default-http2https.middlewares=https-redirect#file"
### SSL
- "traefik.http.routers.frontend.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.frontend.entrypoints=https"
- "traefik.http.routers.frontend.tls.certresolver=example.com"
- "traefik.http.routers.frontend.tls.domains[0].main=example.com"
- "traefik.http.routers.frontend.tls.domains[0].sans=*.example.com"
- "traefik.http.routers.frontend.service=api#internal"
I found the solution here: https://docs.traefik.io/routing/routers/#rule

Related

Localtunnel with Traefik and ssh

I'm looking for a solution with Traefik to do my own Ngrok alternative.
I have multiple a home assistant with the Autossh plugin installed on an another server and would like to access to it by entered the url : home-assistant.server.com
Authssh is configured with the remote forwarding port : 44400:localhost:8123, on ssh port (22).
I found this Traefik configuration (Traefik V1) but would like to use Traefik V2.
I obtain a Bad gateway with my new Traefik configuration.
Do you have any idea to resolve it ? Thanks.
Here, my Traefik V2 configuration :
traefik.toml
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[api]
[providers.docker]
endpoint = "unix:///var/run/docker.sock"
[providers.file]
filename = "/etc/traefik/services.toml"
[certificatesResolvers.mycertificate.acme]
email = "contact#server.com"
storage = "acme.json"
[certificatesResolvers.mycertificate.acme.httpChallenge]
entryPoint = "http"
services.toml
[http]
[http.services]
[http.services.nas]
[http.services.nas.loadBalancer]
[[http.services.nas.loadBalancer.servers]]
url = "http://localhost:44400"
docker-compose.yml
version: '3.7'
services:
reverse-proxy:
restart: always
image: traefik:chevrotin
ports:
- "443:443"
- "80:80"
volumes:
- /srv/traefik.toml:/etc/traefik/traefik.toml
- /srv/services.toml:/etc/traefik/services.toml
- /var/run/docker.sock:/var/run/docker.sock
- /srv/acme.json:/acme.json
labels:
- traefik.http.routers.nas.entrypoints=https
- traefik.http.routers.nas.rule=Host(`home-assistant.server.com`)
- traefik.http.routers.nas.service=nas#file
- traefik.http.routers.nas.tls=true
- traefik.http.routers.nas.tls.certresolver=mycertificate

Traefik 2.0: How to configure `traefik.frontend.rule=Host:example.com`?

I just attempted to upgrade my existing pretty simple Traefik setup to 2.0.
I am using Docker as a provider.
I am running the containers with docker-compose. This is my docker-compose config:
version: "3.5"
services:
traefik:
image: traefik:v2.0-alpine
read_only: yes
ports:
- 80:80
- 443:443
volumes:
- type: bind
source: /var/run/docker.sock
target: /var/run/docker.sock
- type: bind
source: ./traefik.toml
target: /traefik.toml
- type: bind
source: ./acme.json
target: /acme.json
networks:
- traefik
example:
image: example.com/example/example
labels:
- "traefik.enable=true"
- "traefik.frontend.rule=Host:example.com"
- "traefik.docker.network=traefik"
networks:
- traefik
This is my traefik.toml:
defaultEntryPoints = ["http", "https"]
[Global]
sendAnonymousUsage = true
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[acme]
email = "ssl#example.com"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
onDemand = false
acmeLogging = true
[acme.tlsChallenge]
[docker]
exposedByDefault = false
This setup works fine with Traefik 1.7.
With Traefik 2.0 I observe two issues, looking at the ACME log:
Unable to obtain ACME certificate for domains traefik-example-deployment
Unable to obtain ACME certificate for domains example-example-deployment
Traefik is apparently exposing both containers. It should only expose the example container.
Traefik is ignoring the traefik.frontend.rule=Host:example.com label.
I suspect this might be due to configuration format changes in Traefik 2.0. However, although I looked through the 2.0 documentation, I was unable how the correct configuration looks.
Routers¶
To update the configuration of the Router automatically attached to the container, add labels starting with traefik.routers.{name-of-your-choice}. and followed by the option you want to change. For example, to change the rule, you could add the label traefik.http.routers.my-container.rule=Host(my-domain).
Every Router parameter can be updated this way.
As Mentioned in Doc - https://docs.traefik.io/v2.0/providers/docker/
change the labels: to
services:
my-container:
# ...
labels:
- traefik.http.routers.my-container.rule=Host(`my-domain`)
To tell Traefik not to expose Container - add - traefik.enable=false
As traefik Expose containers by default through Traefik. If set to false, containers that don't have a traefik.enable=true label will be ignored from the resulting routing configuration.
exposedByDefault (Optional, Default=true)¶

How to make content to show on both www and non-www urls using traefik

Thank you for showing interest and I was in a hurry. Any help would be great.
At present users were not able to reach www.example.com but they can reach example.com.
Either one of them is fine:
1) Accepts all traffic from WWW and non-www urls and serve same content.
2) Redirect users from WWW to non-www url to display content.
Note: Let's Encrypt is used
My present config is
traefik.toml
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.dashboard]
address = ":8080"
[entryPoints.dashboard.auth]
[entryPoints.dashboard.auth.basic]
users = ["admin:key"]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
regex = "^https://www.(.*)"
replacement = "https://$1"
permanent=true
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[api]
entrypoint="dashboard"
[acme]
email = "mail#gmail.com"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
[acme.httpChallenge]
entryPoint = "http"
[[acme.domains]]
main = "*.example.com"
sans = ["example.com"]
[[acme.domains]]
main = "*.example1.com"
sans = ["example1.com"]
[docker]
domain = "example.com"
watch = true
network = "proxy"`
docker-compose.yml:
version: '2'
services:
traefik:
image: traefik
restart: always
command: --docker
ports:
- 80:80
- 443:443
networks:
- proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- $PWD/traefik.toml:/traefik.toml
- $PWD/acme.json:/acme.json
container_name: trefik
environment:
DO_AUTH_TOKEN: TOKEN
labels:
- traefik.frontend.rule=Host:monitor.example.com
- traefik.port=8080
example1:
image: wordpress:4.7.5-apache
restart: always
environment:
WORDPRESS_DB_PASSWORD: something
labels:
- traefik.backend=example1
- traefik.frontend.rule=Host:example1.com
- traefik.docker.network=proxy
- traefik.port=80
networks:
- internal
- proxy
depends_on:
- mysql
example:
image: tutum/apache-php
restart: always
labels:
- traefik.backend=example
- traefik.frontend.rule=Host:example.com, www.example.com
- traefik.docker.network=proxy
- traefik.port=80
networks:
- internal
- proxy
Edit #1:
Your config Redirects:
http://example.com => [no redirect]
https://www.example.com => [timeout]
http://www.example.com => [timeout]
http://example.com => [no redirect]
My Config Redirects:
http://example.com => https://example.com:443/
https://www.example.com => [timeout]
http://www.example.com => [timeout]
http://example.com => https://example.com:443/
You cannot use redirect entrypoint and regex at the same on the same entrypoint.
Please note that regex and replacement do not have to be set in the redirect structure if an entrypoint is defined for the redirection (they will not be used in this case).
https://docs.traefik.io/v1.7/configuration/entrypoints/#redirect-http-to-https
The wildcard certficates cannot be obtain with the HTTP challenge: https://docs.traefik.io/v.7/configuration/acme/#wildcard-domains
You have to use the DNS challenge https://docs.traefik.io/v1.7/configuration/acme/#dnschallenge (edited)
and before you ask: you cannot use both (HTTP challenge and DNS challenge) at the same time.
Edit
I will illustrate the redirections with 2 simple configurations (self-signed certificates instead of acme but it's the same thing).
Those 2 configurations works without any changes, you only need to do docker-compose up.
Note that redirection has no influence on the HTTP challenge (ACME).
Strip www and HTTPS redirection
The goal:
$ curl --insecure -L http://www.whoami.docker.localhost
# http://www.whoami.docker.localhost -> https://whoami.docker.localhost
$ curl --insecure -L https://www.whoami.docker.localhost
# https://www.whoami.docker.localhost -> https://whoami.docker.localhost
$ curl --insecure -L http://whoami.docker.localhost
# http://whoami.docker.localhost -> https://whoami.docker.localhost
$ curl --insecure -L https://whoami.docker.localhost
# https://whoami.docker.localhost -> https://whoami.docker.localhost
I. Example without TOML: (docker-compose.yml)
version: "3"
services:
reverseproxy:
image: traefik:v1.7.8
command:
- --logLevel=INFO
- --defaultentrypoints=http,https
- --entrypoints=Name:http Address::80 Redirect.Regex:^http://(?:www\.)?(.+) Redirect.Replacement:https://$$1 Redirect.Permanent:true
- --entrypoints=Name:https Address::443 TLS Redirect.Regex:^https://www\.(.+) Redirect.Replacement:https://$$1 Redirect.Permanent:true
- --docker
- --docker.domain=docker.localhost
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
whoami:
image: containous/whoami
labels:
- "traefik.frontend.rule=Host:whoami.docker.localhost"
II. Example with TOML: (docker-compose.yml + traefik.toml)
version: "3"
services:
reverseproxy:
image: traefik:v1.7.8
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/traefik.toml
whoami:
image: containous/whoami
labels:
- "traefik.frontend.rule=Host:whoami.docker.localhost"
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
regex = "^http://(?:www\.)?(.+)"
replacement = "https://$1"
permanent = true
[entryPoints.https]
address = ":443"
[entryPoints.https.redirect]
regex = "^https://www\\.(.+)"
replacement = "https://$1"
permanent = true
[entryPoints.https.tls]
[api]
[docker]
domain = "docker.localhost"

Traefik - cannot show dashboard

Treafik redirecting works like charm!
How can I configure the Traefik dashboard to be shown?
I have an "A"-record pointing to my domain and a CNAME record "monitor" pointing to the same domain. Is this correct?
My first attempt was this docker-compose.yml file. It contains also a Spring Boot application listening at 8080:
version: '3'
services:
traefik:
image: traefik:latest
container_name: traefik
command: --api --docker
restart: always
networks:
- geosolutionsnet
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/ec2-user/traefik/traefik.toml:/traefik.toml
- /home/ec2-user/traefik/acme.json:/acme.json
ports:
- "80:80"
- "443:443"
labels:
- "traefik.docker.network=geosolutionsnet"
- "traefik.enable=true"
- "traefik.frontend.rule=Host:monitor.xyz.nl"
- "traefik.port=8080"
- "traefik.protocol=http"
#- "traefik.frontend.headers.STSSeconds=15768000"
With the browser I pointed to 'monitor.xyz.nl' but I got a 404.
My second try was with:
- "traefik.frontend.rule=Host:xyz.nl;Path:/monitor"
Pointing my browser to xyz.nl/monitor ... gave again a 404.
My traefik.toml file is:
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "xyz.nl"
watch = true
exposedByDefault = false
[acme]
email = "jj#xyz.nl"
storage = "acme.json"
onHostRule = true
entryPoint = "https"
onDemand = false
[acme.tlsChallenge]
UPDATE:
Using the CNAME traefik that is mapped to domain xyz.nl/traefik results in a 404 error.
Using the CNAME 'monitor' pointing to the (A-record) domain I get the same result. I think that is normal because I configured the host match via a pathprefix.
In the Docker compose I added to the traefik part port 8080:8080.
Then, the Traefik dashboard was shown by navigating to port 8080. Important is to navigate via 'http' and NOT 'https'.
The next improvement is by using HTTPS so that no unfriendly people can visit the Traefik dashboard.
docker-compose.yml
services:
traefik:
image: traefik:latest
container_name: traefik
restart: always
networks:
- geosolutionsnet
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/ec2-user/traefik/traefik.toml:/traefik.toml
- /home/ec2-user/traefik/acme.json:/acme.json
ports:
- "80:80"
- "443:443"
labels:
- "traefik.docker.network=geosolutionsnet"
- "traefik.enable=true"
- "traefik.frontend.rule=Host:xyz.nl;PathPrefix:/monitor" # <----
- "traefik.port=8080"
treafik.toml
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[api]
[docker]
domain = "xyz.nl"
exposedByDefault = false
[acme]
email = "jj#xyz.nl"
storage = "acme.json"
onHostRule = true
entryPoint = "https"
onDemand = false
[acme.tlsChallenge]
I recommend to not mix CLI args and TOML for the same section (ex: --docker and [docker])

How to add proper labels in docker for SSL?

I have managed to setup Traefik to to work with my docker swarm and for HTTP requests it works great. However, I don't know how to setup SSL for some of my containers. I will be using letsencrypt for generating certificates.
traefik.toml (partial)
defaultEntryPoints = ["https","http"]
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
[acme]
email = "acme#example.com"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
caServer = "https://acme-staging.api.letsencrypt.org/directory"
docker-compose.yml
version: '3'
services:
web:
...
deploy:
labels:
- "traefik.enable=true"
- "traefik.frontend.rule=Host:example.com,www.example.com"
- "traefik.docker.network=public"
- "traefik.frontend.entryPoints=http"
- "traefik.backend=service_web"
In this configuration, my application never reaches SSL because my containers do not have SSL entryPoint setup. If I change "traefik.frontend.entryPoints" to "https", Letsencrypt gets called (LE givges error because of staging but that doesn't matter to me at this moment).
My biggest problem is that, I still don't know how to convert traefik TOML config into docker-compose labels. For example, Traefik docs explain entrypoints but I have bunch of services that live under different domains. Some have SSL, some do not have SSL; therefore, I want to be able to set up both http and https entryPoints, http to https redirects etc. using only docker-compose.
Also, once I am able to set entrypoints in docker-compose, do I need to keep the [entryPoints] block in traefik.toml?
Ahoi!
Requirements: Local-Persist Volume Plugin:
https://github.com/CWSpear/local-persist (otherwise the Volume Driver has to be changed)
The Network for Traefik has to be pre-created: "docker network create proxy -d overlay"
(1) Fire Up Traefik:
version: "3"
services:
traefik:
image: traefik
#command: --consul --consul.endpoint=consul:8500
#command: storeconfig --consul --consul.endpoint=consul:8500
networks:
- proxy
ports:
- 80:80
- 443:443
#- 8080:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- traefikdata:/etc/traefik/
deploy:
#replicas: 3
replicas: 1
placement:
constraints: [node.role == manager]
update_config:
parallelism: 1
delay: 45s
monitor: 15s
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 10
window: 60s
volumes:
traefikdata:
driver: local-persist
driver_opts:
mountpoint: /data/docker/proxy
networks:
proxy:
external: true
Important Note: When using ACME and you'd like to scale the Traefik (like here 3), you have to use Consul or ETCD as a "storage" for the Config.
You do not use Consule or ETCD if you just use one Instance of Traefik.
With a normal Certificate ETCD & Consul is never required.
(2) Mount traefik.toml
logLevel = "WARN"
debug = false
defaultEntryPoints = ["http", "https"]
[entryPoints]
[entryPoints.http]
address = ":80"
compress = false
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
#Letsencrypt
[acme]
email = "admin#berndklaus.at"
storage = "traefik/acme/account"
entryPoint = "https"
onHostRule = true
onDemand = true
#[[acme.domains]]
# main = "yourdomain.at"
# sans = ["sub1.yourdomain.at", "www.yourdomain.at"]
#[[acme.domains]]
# main = "anotherdomain.at"
#[web]
#address = ":8080"
[docker]
domain = "docker.localhost"
watch = true
swarmmode = true
The uncommented Part is not mandatory
(3) Start any Service
version: '3'
services:
nginx:
image: nginx
deploy:
labels:
- "traefik.port=80"
- "traefik.docker.network=proxy"
- "traefik.frontend.rule=Host:sub1.yourdomain.at"
- "traefik.backend=nginx"
- "traefik.frontend.entryPoints=http,https"
replicas: 1
networks:
proxy:
aliases:
- nginx
volumes:
- html:/usr/share/nginx/html
environment:
- NGINX_HOST=sub.yourdomain.at
- NGINX_PORT=80
#command: /bin/bash -c "envsubst < /etc/nginx/conf.d/mysite.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
networks:
proxy:
external: true
default:
driver: overlay
volumes:
html:
driver: local-persist
driver_opts:
mountpoint: /data/docker/html
Some more examples: https://github.com/Berndinox/compose-v3-collection