Trouble configuring ssl-redirect on Kubernetes Ingress - ssl

I have configured an ingress on a kubernetes cluster from Google Cloud. I followed the instructions as is on this doc.
My manifest:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-proxy
annotations:
ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- hosts:
- foo.bar.com
secretName: foo-bar-secret
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: foo-bar-service
servicePort: 80
path: /*
From the documentation, it specifies that ssl-redirect
is by default true if tls is configured but it doesn't work. I've also tried to set force-ssl-redirect to true(default is false), still no luck.
I'm confused if there is actually a bug or I'm doing something wrong, because when I run kubectl describe ing web-proxy, it displays that annotations were set:
Annotations:
force-ssl-redirect: true
[...]
Any suggestions?
EDIT 1:
I was using the 1.8.3.gke.0 version but when I upgraded to 1.8.4.gke.0 this seems to have solved the problem.
I'll keep this post updated while I test more annotations(like: nginx.ingress.kubernetes.io/from-to-www-redirect)

Related

Kubernetes cert-manager certificate is created but can not get vertified

I am working on a DO kubernetes cluster and install ingress nginx and argocd on it, All seems fine and I can easily use the ingress as long as they are accessing the services via http.
I have also installed certmanager and here are the main files regarding my ingress, certificate and issuer:
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rancher-demo
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
certmanager.k8s.io/cluster-issuer: "letsencrypt-production"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- {sub-domain}
secretName: ssl-cert-production
rules:
- host: {sub-domain}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rancher-demo
port:
number: 80
Issuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
namespace: default
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: {my-email}
privateKeySecretRef:
name: letsencrypt-production
solvers:
- selector: {}
http01:
ingress:
class: nginx
Certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ssl-cert-production
namespace: default
spec:
secretName: ssl-cert-production
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: {sub-domain}
dnsNames:
- {sub-domain}
I went through some other samples on github and questions on stackoverflow and unfortunetly I can not figure out where I am doing it wrong.
Thank you in advance for your attentions
I finally managed to fix the issue, what I have done was as follow:
creating a new kubernete instance
installing cert-manager manaully
installing ingress-nginx manaully
creating the issuer (waiting for it to complete)
creating deployment and cluster
creating ingress config for my application
creating the certificate (waiting for it to complete)
I was working on ArgoCD and had to first do these setups myself before handling CD with Argo. It was my own fault that I did not properly go through their documentations. The order is important, but the way I sat up Argo, it was provisioing everything in parallel so for example certificate was being provision before ingress be up or issuer be in place
Also for anyone who is interested in a detailed version please checkout the github repo I created below:
https://github.com/mehdiamenein/cert-manager-nginx-ingress-do
I hope this can be helpful to someone else as well :)
Huge thanks to marcel.dempers for his wonderful video https://www.youtube.com/watch?v=hoLUigg4V18
and many thanks to #justin and #harsh-manvar for their comments

How can I make one route public in kubernetes ingress with auth-url set?

I am playing a little bit with path-based routing via Kubernetes ingresses (we use Nginx ingress). We have one service up and running behind authentication via external service like the one in the first snippet. This service is already used by other services in our ecosystem, however, as the development progresses, the service now has management API and we need to turn off the authentication for specific paths. According to this answer, this is not possible for basic auth and, according to what I have tried (second snippet), it is not possible for authentication via external service either. Is there any other way to allow specific paths without authentication without completely rearchitecting ingresses and domains/paths?
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: path-based-routing-1
annotations:
kubernetes.io/tls-acme: "true"
kubernetes.io/ingress.class: nginx-external
nginx.ingress.kubernetes.io/auth-url: http://authorizer.dev.svc.cluster.local
spec:
tls:
- hosts:
- 'routing.example.com'
secretName: routing.example.com
rules:
- host: 'routing.example.com'
http:
paths:
- path: /
backend:
serviceName: path-based-routing-1
servicePort: 80
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: path-based-routing-2
annotations:
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/auth-type: ""
kubernetes.io/ingress.class: nginx-external
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- 'routing.example.com'
secretName: routing.example.com
rules:
- host: 'routing.example.com'
http:
paths:
- path: /management-api
backend:
serviceName: path-based-routing-2
servicePort: 80

Reverse proxy a site with SNI support using kubernetes nginx-ingress

I am setting a reverse proxy using kubernetes nginx-ingress, but I don't know how to add nginx parameters to the configuration, specifically: proxy_ssl_server_name. How do I set ingress parameters in yaml configurations?
I already tried using the server-snippet annotation, but it seems like it's not adding the parameter to the nginx.conf file in the cluster pods.
Here is the current code for the reverse proxy:
kind: Service
apiVersion: v1
metadata:
name: formstack
namespace: serves
spec:
type: ExternalName
externalName: fluidsignal.formstack.com
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: formstack
namespace: serves
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/upstream-vhost: "fluidsignal.formstack.com"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
tls:
- hosts:
- fluidattacks.com
secretName: fluidattacks-cert
rules:
- host: fluidattacks.com
http:
paths:
- backend:
serviceName: formstack
servicePort: 443
path: /forms(.*)
After setting up the proxy, I get a 502 Bad Gateway error from Nginx. After looking at the pods logs, I see I'm getting the following openssl error: SSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:SSL alert number 40, which is why I want to add the parameter I mentioned before.
I just figured out that I was indeed using the right annotation: nginx.ingress.kubernetes.io/server-snippet,
But I needed to add an extra parameter: proxy_ssl_name
Adding the following code fixed the problem:
nginx.ingress.kubernetes.io/server-snippet: |
proxy_ssl_name fluidsignal.formstack.com;
proxy_ssl_server_name on;
Everything seems to be working fine now :D

TLS setup on K8S Ingress with Traefik

I have a setup that is not too much different than the user guide for use with k8s. For some reason I can only access http://app.minikube and not https://app.minikube.
Can someone look at my setup and see what I am obviously missing?
apiVersion: v1
kind: Service
metadata:
name: myapp
labels:
app: myapp
spec:
ports:
- name: http
port: 80
targetPort: 7777
selector:
app: myapp
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myingress
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: app.minikube
http:
paths:
- path: /
backend:
serviceName: myapp
servicePort: http
tls:
- secretName: mytls
FYI, according to the Traefik user guide, the hosts definition in tls is unneeded, which is why I left it out.
The field hosts in the TLS configuration is ignored. Instead, the domains provided by the certificate are used for this purpose. It is recommended to not use wildcard certificates as they will match globally)
You're missing the hosts section:
tls:
- hosts:
- my-host.example.com
secretName: my-secret

Google Container Engine - How to update L7 ingress to load new TLS certificate?

I am using the standard L7 load balancing ingress on Google Container Engine. I have installed it through the following ingress definition:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: l7-ingress-{{environment}}
spec:
tls:
- secretName: web-secret
backend:
serviceName: web
servicePort: 80
Now, my question is, how do I ensure that the TLS certificate is updated once the secret web-secret changes? AFAICT, it currently stays the same even though the underlying secret changes.
Apparently, the L7 ingress doesn't currently monitor the TLS secret for changes. But a PR to solve this has been merged, so it should only be a matter of time.
My experience to workaround this is to delete and create the ingress, but making sure you specify the IP in the YAML you pass to kubectl create -f:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dev-ing
spec:
tls:
- secretName: tls-sekret
rules:
- host: tryout.example.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
status:
loadBalancer:
ingress:
- ip: 130.211.n.n
I couldn't find any documentation stating that this is the way to ensure you will get the same IP, but for me it worked. Use with caution on production systems where you can not afford to loose the IP!
I just tried a simple apply on an edited secret, and yes it worked. The web console and gcloud compute ssl-certificates list reported the change right away, and the load balancer started serving it up in about 10 minutes. It would be nice to have this officially documented! Especially because there are other corners of k8s where changes to secrets aren't automatically picked up, like deployments, so we don't take it for granted.
The Google L7 loadbalancer does exchange the underlying certificate if updated. You have to apply the correct annotations:
Secret
apiVersion: v1
kind: Secret
data:
tls.crt: xxx
tls.key: xxx
metadata:
name: tls-secret
type: kubernetes.io/tls
Ingress
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: dev-ing
annotations:
# Do not forget this annotation
kubernetes.io/ingress.class: "gce"
spec:
tls:
- hosts:
- tryout.example.com
secretName: tls-secret
backend:
serviceName: nginx
servicePort: 80
The exchange happens somehow in the background, be aware of the time it takes (5-15 minutes).