Traefik Kubernetes 301 Redirect - redirect

I have traefik installed via the helm chart.
I have a domain: example.com
It has some blog posts.
I now created a subdomain: subdomain.example.com
I have the list of my blogs urls:
/blog-1
/blog-2
Both the base domain and the subdomain are on the same cluster.
I want to have 301 redirects so that if someone tries to visit:
example.com/blog-1
they would be redirected to:
subdomain.example.com/blog-1
I do not want to direct with a wildcard just with my list of blog urls.
Thanks
Here is my middleware for redirect to https
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: https-only
namespace: exmaple
spec:
redirectScheme:
scheme: https
permanent: true
a redirect is:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-redirectregex
spec:
redirectRegex:
regex: "https://example.com"
replacement: "https://subdomain.example.com"
permanent: true
can I have multiple redirectRegex in the same middleware?
I would then just have lots of them to redirect each url

Just one redirect per middleware, but you can have as many middleware as you want.
But in this case you can use the regex:
redirectRegex:
regex: "https://example.com/(blog-1|blog-2|whatever)"
replacement: "https://subdomain.example.com/$1"

Related

Kubernetes Traefik Ingress using WebSockets sending 500's

Hello and thanks for reading!
We've been trying to setup a secure web socket via traefic to a spring webserver.
The connection is inbound to traefik via HTTP/2. The IngressRoute (HttpRouter) responsible for this endpoint is doing the SSL termination and moving the traffic to a TraefikService with scheme http.
We tried several variants, with middleware which append Headers like "X-Forwarded-Proto: https", but still the furthest we could get is as follows: The Spring WebServer did accept the connection, but it instantly got terminated with SC 500 again and no response was sent to the client.
Am I missing any configuration for the setup as described above?
Note: Traefik does not show any error logs and the Spring webservice only tells that the connection was interrupted.
Configuration snippets (commented out parts were tried before but didn't work either)
Middleware:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: wss-headers
namespace: rc
spec:
headers:
customRequestHeaders:
Connection: "keep-alive, Upgrade"
# Connection: "Upgrade"
# X-Forwarded-Proto: "https"
Upgrade: "WebSocket"
# X-Forwarded-Port: "443"
WSS ingress:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: uiserver-ws-ing
namespace: rc
spec:
tls:
secretName: tls-example.org
options:
namespace: rc
domains:
- main: example.org
sans:
- example.com
routes:
- kind: Rule
priority: 100
match: Host(`example.org`) && PathPrefix(`/ws`)
# middlewares:
# - name: wss-headers
services:
- name: uiserver-svc
namespace: rc
port: 8080
scheme: http
# scheme: h2c
Thank you & Best Regards,
Alex

How to setup basic auth in ingress for included url rules?

I have a project on k8s with 3 services, that I want to cover with basic auth, and 1 service that I'd like to be public.
In ingress 4 services devided by url rules, that have different prefixes.
I had found tutorial about basic auth setup in ingress for all rules, but not about excluded, included urls.
Unfortunately GCP Ingress does not provide basic auth authentication as this feature is specific for Nginx Ingress.
As workaround for basic auth in GCP Ingress you can use IAP. Detailed How To information can be found in Enabling IAP for GKE article.
If you would still like to use Nginx Ingress basic auth you can do it on GKE but you need specify nginx annotation.
metadata:
name: foo
annotations:
kubernetes.io/ingress.class: "nginx"
Regarding using basic auth on only one service out of four, you can createa 2 Ingress. Very similar issue was discussed in another stackoverflow thread, which contains good solution - Nginx-ingress Kubernetes routing with basic auth.
Basic Auth Ingress
First Ingress should be without annotations:
nginx.ingress.kubernetes.io/auth-type
nginx.ingress.kubernetes.io/auth-secret
nginx.ingress.kubernetes.io/auth-realm
Second Ingress should contain proper annotations and should look similar to below YAML.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: auth-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
#cert-manager.io/cluster-issuer: if you would use cert manager like letsencrypt
spec:
tls:
- hosts:
- example.com
secretName: example-tls
rules:
- host: example.com
http:
paths:
- path: /auth
backend:
serviceName: auth-service
servicePort: <auth-service-port>
Aditional information
There is an option to deny all traffic to specific path. It can be achieved by configuration-snippet annotation.
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
location /specificpath {
deny all;
}

istio redirect non-www traffic to www

I am using istioingress gateway. How can I redirect non-www traffic to www?
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
namespace: some-config-namespace
spec:
selector:
app: my-gateway-controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- uk.bookinfo.com
- eu.bookinfo.com
- www.uk.bookinfo.com
- www.eu.bookinfo.com
tls:
httpsRedirect: true # sends 301 redirect for http requests
- port:
number: 443
name: https-443
protocol: HTTPS
hosts:
- uk.bookinfo.com
- eu.bookinfo.com
- www.uk.bookinfo.com
- www.eu.bookinfo.com
tls:
mode: SIMPLE # enables HTTPS on this port
serverCertificate: /etc/certs/servercert.pem
privateKey: /etc/certs/privatekey.pem
Currently, I am able to access the website using both endpoints. But, I want to redirect all traffic from non-www to www.
Istio Gateway receives the traffic, and the routing from there will be handled by VirtualService configuration. For your non-www to www traffic routing, the same question was raised in Istio discussion forum, so that may be of your help.
https://discuss.istio.io/t/simply-redirecting-non-www-to-www/3370
As to getting all the traffic, you may want to use a wildcard in the hosts definition in the Gateway configuration (ref: https://istio.io/docs/reference/config/networking/gateway/#Server).
Have you tried redirect feature of Istio?
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: server-vs
spec:
hosts:
- mysite.com
gateways:
- my-gateway
http:
- match:
- uri:
exact: /
redirect:
uri: /
authority: www.mysite.com
Also you could have done the redirection at DNS level. But I think some domain providers don't support it. Godaddy, for example, does.

Kubernetes Service pointing to External Resource

We have an existing website, lets say example.com, which is a CNAME for where.my.server.really.is.com.
We're now developing new services using Kubernetes. Our first service /login is ready to be deployed. Using a mock HTML server I've been able to deploy two pods with seperate services that map to example.com and example.com/login.
What I would like to do is get rid of my mock HTML server, and provide a service inside of the cluster, that points to our full website outside of the server. Then I can change the DNS for example.com to point to our kubernetes cluster and people will still get the main site from where.my.server.really.is.com.
We are using Traefik for ingress, and these are the changes I've made to the config for the website:
---
kind: Service
apiVersion: v1
metadata:
name: wordpress
spec:
type: ExternalName
externalName: where.my.server.really.is.com
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: wordpress
annotations:
kubernetes.io/ingress.class: traefik
spec:
backend:
serviceName: wordpress
servicePort: 80
rules:
- host: example.com
http:
paths:
- backend:
serviceName: wordpress
servicePort: 80
Unfortunately, when I visit example.com, rather than getting where.my.server.really.is.com, I get a 503 with the body "Service Unavailable". example.com/login works as expected
What have I missed?
Following traefik documentation on using ExternalName
When specifying an ExternalName, Træfik will forward requests to the given host accordingly and use HTTPS when the Service port matches 443.
This still requires setting up a proper port mapping on the Service from the Ingress port to the (external) Service port.
I believe you are missing the ports configuration of the Service. Something like
apiVersion: v1
kind: Service
metadata:
name: wordpress
spec:
ports:
- name: http
port: 80
type: ExternalName
externalName: where.my.server.really.is.com
You can see a full example in the docs.

Kubernetes HTTPS Ingress in Google Container Engine

I want to expose a HTTP service running in Google Container Engine over HTTPS only load balancer.
How to define in ingress object that I want HTTPS only load balancer instead of default HTTP?
Or is there a way to permanently drop HTTP protocol from created load balancer? When I add HTTPS protocol and then drop HTTP protocol, HTTP is recreated after few minutes by the platform.
Ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myapp-ingress
spec:
backend:
serviceName: myapp-service
servicePort: 8080
In order to have HTTPs service exposed only, you can block traffic on port 80 as mentioned on this link:
You can block traffic on :80 through an annotation. You might want to do this if all your clients are only going to hit the loadbalancer through https and you don't want to waste the extra GCE forwarding rule, eg:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
annotations:
kubernetes.io/ingress.allow-http: "false"
spec:
tls:
# This assumes tls-secret exists.
# To generate it run the make in this directory.
- secretName: tls-secret
backend:
serviceName: echoheaders-https
servicePort: 80
You could also use FrontendConfig
HTTP to HTTPS redirects are configured using the redirectToHttps field
in a FrontendConfig custom resource. Redirects are enabled for the
entire Ingress resource so all services referenced by the Ingress will
have HTTPS redirects enabled.
The following FrontendConfig manifest enables HTTP to HTTPS redirects.
Set the spec.redirectToHttps.enabled field to true to enable HTTPS
redirects. The spec.responseCodeName field is optional. If it's
omitted a 301 Moved Permanently redirect is used.
For example
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
name: your-frontend-config-name
spec:
redirectToHttps:
enabled: true
responseCodeName: MOVED_PERMANENTLY_DEFAULT
MOVED_PERMANENTLY_DEFAULT is on of the available RESPONSE_CODE field value, to return a 301 redirect response code (default if responseCodeName is unspecified).
You can find more options here: HTTP to HTTPS redirects
Then you have to link your FrontendConfig to the Ingress, like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: your-ingress-name
annotations:
networking.gke.io/v1beta1.FrontendConfig: your-frontend-config-name
spec:
tls:
...