rp346
September 30, 2019, 5:46pm
1
I am trying to redirect all HTTP to HTTPS with following configuration
But when I open http url it isn't getting redirect to https.
traefik.toml
## static configuration
[global]
checkNewVersion = true
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[providers]
[providers.kubernetesCRD]
[providers.file]
directory = "/etc/traefik/providers/"
watch = true
[log]
level = "INFO"
[accessLog]
[api]
insecure = true
dashboard = true
debug = true
[metrics]
[metrics.prometheus]
buckets = [0.1,0.3,1.2,5.0]
addEntryPointsLabels = true
addServicesLabels = true
entryPoint = "web"
[ping]
entryPoint = "web"
[certificatesResolvers]
[certificatesResolvers.letsencrypt]
[certificatesResolvers.letsencrypt.acme]
email = "admin@domain.com"
caServer = "https://acme-v02.api.letsencrypt.org/directory"
storage = "acme.json"
[certificatesResolvers.letsencrypt.acme.dnsChallenge]
provider = "route53"
delayBeforeCheck = 0
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
dynamic.toml
## dynamic configuration
[web.routers]
[web.routers.https-redirect]
entryPoints = ["web"]
middlewares = ["https-redirect"]
rule = "HostRegexp(`{host:.+}`)"
service = "api@internal"
[web.middlewares]
[web.middlewares.https-redirect.redirectScheme]
scheme = "https"
permanent: true
What change I need here ?
zespri
September 30, 2019, 6:31pm
2
It's either incomplete configuration, or it's wrong: it never references your dynamic.toml
file.
rp346
September 30, 2019, 7:02pm
3
As per traefik/docs/content/providers/file.md at master · traefik/traefik · GitHub I have following in traefik.toml
[providers]
[providers.kubernetesCRD]
[providers.file]
directory = "/etc/traefik/providers/"
watch = true
Directory /etc/traefik/providers/
has dynamic.toml
Is it wrong ?
zespri
September 30, 2019, 7:18pm
4
Sorry about that I missed it. Anything in the logs?
[web.routers]
does not look right, I mean the web
prefix. That's not something traefik
would be aware of. This what dynamic configuration should look like.
lnxbil
October 1, 2019, 6:36am
5
Easiest method I found for a catch-all-redirect from http to https is this setup:
rp346
October 1, 2019, 6:04pm
6
@lnxbil @zespri
I tried following config which didn't not work.
## dynamic configuration
[http.routers]
[http.routers.HTTPSRedirect]
entryPoints = ["web"]
rule = "PathPrefix(`/`)"
middlewares = ["HTTPSRedirect"]
service = "HTTPSRedirect"
priority = 1
[http.middlewares]
[http.middlewares.HTTPSRedirect.redirectScheme]
scheme = "https"
permanent = true
[http.services]
[http.services.HTTPSRedirect.loadBalancer]
[[http.services.HTTPSRedirect.loadBalancer.servers]]
url = "http://localhost/"
There is no error in the traefik container.
rp346
October 1, 2019, 7:01pm
8
@ldez
Tried following config, still didn't work
## dynamic configuration
[http.routers]
[http.routers.redirecttohttps]
entryPoints = ["web"]
rule = "HostRegexp(`{host:.+}`)"
middlewares = ["httpsredirect"]
service = "noop"
[http.middlewares]
[http.middlewares.httpsredirect.redirectScheme]
scheme = "https"
[http.services]
[http.services.noop.loadBalancer]
[[http.services.noop.loadBalancer.servers]]
url = "http://192.168.0.1"
zespri
October 1, 2019, 7:08pm
9
I also tried your config and it does.
Since you are using kubernetes, I suspect that you did not do that part of configuration properly. Could be that your request simply never makes to traefik.
Could you please post your curl command you are using to test, the output of it, your IngressRoutes and your kubernetes manifest for traefik in the cluster.
rp346
October 1, 2019, 7:30pm
10
manifest I used for deploy Traefik V2
resources.yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- middlewares
verbs:
- get
- list
- watch
- apiGroups:
- traefik.containo.us
resources:
- ingressroutes
verbs:
- get
- list
- watch
- apiGroups:
- traefik.containo.us
resources:
- ingressroutetcps
verbs:
- get
- list
- watch
- apiGroups:
- traefik.containo.us
resources:
- tlsoptions
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: kube-system
name: traefik-ingress-controller
deployments.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: traefik-conf
namespace: kube-system
data:
traefik.toml: |
## static configuration
[global]
checkNewVersion = true
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[providers]
[providers.kubernetesCRD]
[providers.file]
directory = "/etc/traefik/providers/"
watch = true
[log]
level = "INFO"
[accessLog]
[api]
insecure = true
dashboard = true
debug = true
[metrics]
[metrics.prometheus]
buckets = [0.1,0.3,1.2,5.0]
addEntryPointsLabels = true
addServicesLabels = true
entryPoint = "web"
[ping]
entryPoint = "web"
[certificatesResolvers]
[certificatesResolvers.letsencrypt]
[certificatesResolvers.letsencrypt.acme]
email = "admin@domain.com"
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
storage = "/etc/traefik/storage/acme.json"
[certificatesResolvers.letsencrypt.acme.dnsChallenge]
provider = "route53"
delayBeforeCheck = 0
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
dynamic.toml: |
## dynamic configuration
[http.routers]
[http.routers.redirecttohttps]
entryPoints = ["web"]
rule = "HostRegexp(`{host:.+}`)"
middlewares = ["httpsredirect"]
service = "noop"
[http.middlewares]
[http.middlewares.httpsredirect.redirectScheme]
scheme = "https"
[http.services]
[http.services.noop.loadBalancer]
[[http.services.noop.loadBalancer.servers]]
url = "http://192.168.0.1"
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: traefik
namespace: kube-system
labels:
app: traefik
spec:
selector:
matchLabels:
app: traefik
minReadySeconds: 5
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
terminationGracePeriodSeconds: 30
hostNetwork: true
containers:
- name: traefik
image: traefik:v2.0.0
env:
- name: AWS_REGION
valueFrom:
configMapKeyRef:
name: aws-config
key: aws_region
- name: AWS_HOSTED_ZONE_ID
valueFrom:
configMapKeyRef:
name: aws-config
key: aws_hosted_zone_id
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: aws-secret
key: access_key
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: aws-secret
key: secret_key
ports:
- name: web
containerPort: 80
- name: websecure
containerPort: 443
- name: admin
containerPort: 8080
securityContext:
privileged: true
volumeMounts:
- mountPath: /etc/traefik/traefik.toml
name: traefik-config
subPath: traefik.toml
- mountPath: /etc/traefik/providers/dynamic.toml
name: traefik-config
subPath: dynamic.toml
- mountPath: /etc/traefik/storage/
name: traefik-storage
volumes:
- name: traefik-config
configMap:
name: traefik-conf
- name: traefik-storage
hostPath:
path: /tmp/traefik
type: DirectoryOrCreate
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: whoami
namespace: kube-system
labels:
app: whoami
spec:
replicas: 1
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: containous/whoami
ports:
- name: web
containerPort: 80
service.yaml
---
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: kube-system
spec:
ports:
- protocol: TCP
name: web
port: 80
targetPort: 80
- protocol: TCP
name: admin
port: 8080
targetPort: 8080
- protocol: TCP
name: websecure
port: 443
targetPort: 443
selector:
app: traefik
---
kind: Service
apiVersion: v1
metadata:
name: traefik-external
namespace: kube-system
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app: traefik
ports:
- name: web
protocol: TCP
port: 80
targetPort: 80
- name: websecure
protocol: TCP
port: 443
targetPort: 443
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: kube-system
spec:
ports:
- protocol: TCP
name: web
port: 80
selector:
app: whoami
ingressroutes.yaml
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-admin
namespace: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.dev.domain.ca`)
kind: Rule
services:
- name: traefik
port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-admin-tls
namespace: kube-system
spec:
entryPoints:
- websecure
routes:
- match: Host(`traefik.dev.domain.ca`)
kind: Rule
services:
- name: traefik
port: 8080
tls:
certResolver: letsencrypt
domains:
- main: test.domain.ca
sans:
- "*.test.domain.ca"
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-notls
namespace: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(`test.domain.ca`) && PathPrefix(`/notls`)
kind: Rule
services:
- name: whoami
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-tls
namespace: kube-system
spec:
entryPoints:
- websecure
routes:
- match: Host(`test.domain.ca`) && PathPrefix(`/tls`)
kind: Rule
services:
- name: whoami
port: 80
tls:
certResolver: letsencrypt
domains:
- main: test.domain.ca
sans:
- "test.domain.ca"
- "*.test.domain.ca"
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-notls2
namespace: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(`dev.domain.ca`) && PathPrefix(`/notls`)
kind: Rule
services:
- name: whoami
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-tls2
namespace: kube-system
spec:
entryPoints:
- websecure
routes:
- match: Host(`dev.domain.ca`) && PathPrefix(`/tls`)
kind: Rule
services:
- name: whoami
port: 80
tls:
certResolver: letsencrypt
domains:
- main: dev.domain.ca
sans:
- "dev.domain.ca"
- "*.dev.domain.ca"
and curl output
curl http://test.domain.ca/notls
Hostname: whoami-6bd5c965c9-xt4kh
IP: 127.0.0.1
IP: 10.2.23.104
RemoteAddr: 10.2.23.76:47402
GET /notls HTTP/1.1
Host: test.domain.ca
User-Agent: curl/7.54.0
Accept: */*
Accept-Encoding: gzip
X-Forwarded-For: 133.132.131.13
X-Forwarded-Host: test.domain.ca
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: ip-10-2-23-76.us-west-2.compute.internal
X-Real-Ip: 133.132.131.13
zespri
October 1, 2019, 9:30pm
11
To me it looks, like what you are observing is because of this piece:
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-notls
namespace: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(`test.domain.ca`) && PathPrefix(`/notls`)
kind: Rule
services:
- name: whoami
port: 80
This matches, it does not contains the redirect so here you go. You other rule in dynamic.toml
is probably not even checked, since this one (above) matched before.
I'm not sure about the matching order, would not be surprised if it's non-deterministic and/or not guaranteed.
Does this make sense?
rp346
October 1, 2019, 9:38pm
12
I updated ingress routes to following, still no redirect.
ingressroutes.yaml
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-admin
namespace: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.test.domain.ca`)
kind: Rule
services:
- name: traefik
port: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-admin-tls
namespace: kube-system
spec:
entryPoints:
- websecure
routes:
- match: Host(`traefik.test.domain.ca`)
kind: Rule
services:
- name: traefik
port: 8080
tls:
certResolver: letsencrypt
domains:
- main: test.domain.ca
sans:
- "*.test.domain.ca"
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-notls
namespace: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(`test.domain.ca`)
kind: Rule
services:
- name: whoami
port: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-tls
namespace: kube-system
spec:
entryPoints:
- websecure
routes:
- match: Host(`test.domain.ca`)
kind: Rule
services:
- name: whoami
port: 80
tls:
certResolver: letsencrypt
domains:
- main: test.domain.ca
sans:
- "test.domain.ca"
- "*.test.domain.ca"
---
zespri
October 1, 2019, 9:45pm
13
Sorry, could you please explain why the change that you've made should change the outcome? To me it looks like it still has the same problem, more or less: http://test.domain.ca/notls
will match Host(`test.domain.ca`)
as well as Host(`test.domain.ca`) && PathPrefix(`/notls`)
, so I would expect no change, and this is what you reported. Is there another change that I missed?
rp346
October 2, 2019, 2:43pm
14
It worked after removing IngressRoute which were created for entryPoints: web
ingressroutes.yaml
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-admin
namespace: kube-system
spec:
entryPoints:
- websecure
routes:
- match: Host(`traefik.test.domain.ca`)
kind: Rule
services:
- name: traefik
port: 8080
tls:
certResolver: default
domains:
- main: test.domain.ca
sans:
- "*.test.domain.ca"
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: kube-system
spec:
entryPoints:
- websecure
routes:
- match: Host(`test.domain.ca`)
kind: Rule
services:
- name: whoami
port: 80
tls:
certResolver: default
domains:
- main: test.domain.ca
sans:
- "*.test.domain.ca"
---