Adding SSL certificate to ingress controller vs adding it to ingress resource - ssl

Ingress controller deployment.yml
spec:
containers:
- args:
- /nginx-ingress-controller
- --default-backend-service=stratus/nginx-ingress-default-backend
- --election-id=ingress-controller-leader
- --ingress-class=nginx
- --configmap=ingress-controller-leader-nginx
- --enable-ssl-passthrough
Ingress resource.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: 'REPOSITORY_NAME'
namespace: service
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-passthrough: "false"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
tls:
- hosts:
- "xyz-development.com"
- secretName: ingress-secret-tls
rules:
- host: "xyz-development.com"
http:
paths:
- path: /service/
backend:
serviceName: 'REPOSITORY_NAME'
servicePort: 8080
the secret consists of a signed certificate with the CN as xyz-development.com
endpoint : xyz-development.com/service/swagger-ui.html
If I try to access the endpoint with the above config, I end up with "Your connection is not private" error.
But if I modify the ingress controller deployment.yml to
spec:
containers:
- args:
- /nginx-ingress-controller
- --default-backend-service=stratus/nginx-ingress-default-backend
- --election-id=ingress-controller-leader
- --ingress-class=nginx
- --configmap=stratus/ingress-controller-leader-nginx
- --enable-ssl-passthrough
- --default-ssl-certificate=service/ingress-secret-tls
Then the site is secure with my valid certificate.
Is this expected behaviour?
Even if the default ssl certificate flag is removed in the controller, shouldn't the secret mentioned in the ingress resource.yml be used?
Any other pointers or better practice would be appreciated

There's a minor typo in your manifest that's causing the first option to fail; it should not be a new element in the array of .spec.tls entries:
- secretName: ingress-secret-tls # wrong
secretName: ingress-secret-tls # correct

When you getting connection is not private, are you hitting the URL https://xyz-development.com/ or using an IP address instead? If you are using an IP address, NGINX will not load that TLS certificate, it might load other default certificate (kubernetes fake certificate if you are running on k8s)
And when you add that configuration into ingress controller directly, that will become your default TLS certificate, so whatever domain name that you are using, it will give you that certificate.

Related

Traefik IngressRoute is not accepting TLS certificates

I have set up a TLS kubernetes secret which is operating normally on the non-traefik workloads.
When I try to use it to one of my ingress routes the certificate seems to have not been applied and the "TRAEFIK DEFAULT CERT" is assigned.
Below is my IngressRoute .yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: example
namespace: example-ns
spec:
entryPoints:
- websecure
routes:
- match: Host(`example.com`)
kind: Rule
services:
- name: example-svc
port: 9090
tls:
secretName: example-tls
Found it!
Indeed issue was related with passing the TLS Store to both namespaces and traefik pod logged the below:
level=error msg="Default TLS Stores defined in multiple namespaces: [example traefik]" providerName=kubernetescrd
I removed the TLS store from the "example" namespace and everything worked fine!

Kubernetes Ingress can't find SSL secret created by CertManager

I have been trying to genereate an SSL certificate from Let's Encrypt to my domain but cert-manager creates the secret and adds a random suffix, causing the NGINX ingress controller to not be able to find it:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/issuer: scaleway
kubernetes.io/tls-acme: "true"
spec:
rules:
- host: <DOMAIN>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-svc
port:
number: 80
tls:
- hosts:
- <DOMAIN>
secretName: tls-cert
Here is the error in the NGINX logs :
Error obtaining X.509 certificate: no object matching key "default/tls-cert" in local store
Error getting SSL certificate "default/storek8s.igesa.it": local SSL certificate default/storek8s.igesa.it was not found. Using default certificate
The secret is always created like this :
NAME TYPE DATA AGE
...
tls-secret-fjrm5 Opaque 1 60m
How do I disable adding the random suffix for the secret generated by Ingress ? Is there any workaround to solve this ?
At the moment I have too little information to give an exact answer. Are you for example using this Helm chart, what values does your values.yaml contain, and how did you setup your issuer?
Also, I know that tls secrets created by cert-manager should be of type kubernetes.io/tls and not Opaque as is the case in your situation. So there is definitly something going wrong there.

How can I use Cert manager letsencrypt-prod in my kubernetes service?

I have 4 yaml file
Deployment.yaml
Service.yaml
Ingress.yaml
issuer.yaml
I want to use letsencrypt-prod for my service for certification . But it doesn't work.
When I use to be sure ingress is working or issuer is working both of them are done!
kubectl get ing
kubectl get issuer
But when I run:
kubectl get cert
Cert is not readt during 2 days . Like below:
it creates problem like below. certification is not binding mandrakee.xyz.Mandrakee.xyz looks still not secure! how can I make my website secyre via cert manager?
Deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-deployment
spec:
replicas: 1
selector:
matchLabels:
app: echo-server
template:
metadata:
labels:
app: echo-server
spec:
containers:
- name: httpapi-host
image: jmalloc/echo-server
imagePullPolicy: Always
resources:
requests:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
Service.yaml:
apiVersion: v1
kind: Service
metadata:
name: echo-service
spec:
ports:
- name: http-port
port: 80
targetPort: 8080
selector:
app: echo-server
Ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: ambassador
cert-manager.io/issuer: letsencrypt-prod
name: test-ingress
spec:
tls:
- hosts:
- mandrakee.xyz
secretName: letsencrypt-prod
rules:
- host: mandrakee.xyz
http:
paths:
- backend:
service:
name: echo-service
port:
number: 80
path: /
pathType: Prefix
issuer.yaml:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: ykaratoprak#sphereinc.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- dns01:
digitalocean:
tokenSecretRef:
name: digitalocean-dns
key: ce28952b5b4e33ea7d98de190f3148a7cc82d31f030bde966ad13b22c1abc524
If you have setup your issuer correctly, which you have assured us, you will see in your namespace a pod belonging to cert manager. This creates a pod that will validate that the server requesting the certificate resolves to the DNS record.
In your case, you would need to point your DNS towards your ingress.
If this is done successfully, then the next stage of debugging is to validate that both 443 and 80 can be resolved. The Validation Pod created by Cert Manager uses port 80 to validate the communication. A common mistake people make is assuming that they will only use port 443 for ssl and disable 80 for security reasons to find out later that letsencrypt can't validate the hostname without port 80.
Otherwise, the common scenario is that cert-manager is installed in the namespace cert-manager and so you should check the logs of the manager. This will provided a limited amount of logs and can be sometimes cryptic to finding the remedy to your issues.
To find the direct error, the pod spawned by cert-manager in the namespace you have deployed the ingress is a good place to focus.
A test I would run is to setup the ingress with both 80 and 443, if you use your domain from your browser you should get some invalid kubernetes generic certificates response on the port 443 and just "Not Found" on port 80. If this is successful, it rules out the limitation I have mentioned before.

oauth2_proxy not asking for authentication

I am trying to setup oauth2_proxy on kubernetes to secure one of my single page application and I am using github as the authentication provider. I found this link useful and I followed this for doing my setup.
[https://alikhil.github.io/2018/05/oauth2-proxy-for-kubernetes-services/]
I have created an application on github and used my DNS Name in place of the HomePageURL and CallBackURL (https://auth.example.com replaced with https://example.com) because I do not have TLS secrets generated for auth.example.com. Rather I have TLS certificates generated for example.com because this domain belongs to me. I was getting error in nginx-controller that the certificate belongs to example.com and not to auth.example.com as these URLs have been used in defining the example Ingress and oauth proxy ingress and this was the basis for me to do the before mentioned chang.
My Ingresses looks like this
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: oauth2-proxy
annotations:
kubernetes.io/tls-acme: "true"
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: oauth2-proxy
servicePort: 4180
path: /oauth2
tls:
- hosts:
- example.com
secretName: oauth-proxy-tls
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: oauth-main-ingress
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
ingress.kubernetes.io/auth-url: https://example.com/oauth2/auth
ingress.kubernetes.io/auth-signin: https://example/oauth2/start?rd=https://$host$request_uri$is_args$args
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: example-service
servicePort: 80
path: /
tls:
- hosts:
- example.com
secretName: tls-secret
I want that whenever I click example.com it should display page for github authentication but in my case its directly giving the response which a service should give after successful authentication. I am not being asked to provide credentials. Also, I am getting error in my ingress controller logs as 7 controller.go:753] Error obtaining Endpoints for Service "default/oauth2-proxy": no object matching key "default/oauth2-proxy" in local store
Also, I tried replacing using nginx.ingress.kubernetes.io/auth-url: http://oauth2-proxy.oauth-proxy.svc.cluster.local:4180/oauth2/auth as mentioned in the link but it did not work for me. Can some one explain why is oauth2_proxy not asking for authentication and ingress is serving the requests directly without asking for authentication?
The annotation declared in the oauth-main-ingress yaml is incorrect.
As per the kubernetes/nginx-ingress documentation the annotation for external auth-url should be
nginx.ingress.kubernetes.io/auth-url: http://<oauth-service-url>
instead of
ingress.kubernetes.io/auth-url: http://<oauth-service-url>

Kubernetes: TLS on an Ingress; hosts using wrong certificate

I want to secure my K8s application with TLS. I've generated 2 SSL certificates with Let's Encrypt: one for kamerbaas.nl and one for gateway.kamerbaas.nl. I created two secrets from the files tls.crt and tls.key for each domain.
The YAML file of my Ingress is as follows:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gateway-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- gateway.kamerbaas.nl
secretName: gateway.kamerbaas.nl
- hosts:
- kamerbaas.nl
secretName: kamerbaas.nl
rules:
- host: gateway.kamerbaas.nl
http:
paths:
- path: /*
backend:
serviceName: kb-gateway
servicePort: 80
- host: kamerbaas.nl
http:
paths:
- path: /*
backend:
serviceName: kb-frontend
servicePort: 80
The catch: When I go to https://gateway.kamerbaas.nl, it works; it's showing a green lock. When I go to https://kamerbaas.nl however, it says it's not secure, since it's trying to use the certificate of gateway.kamerbaas.nl.
I've ruled out the possibility that it's a cache issue, and I've ensured that I didn't mix my certificate files up. I'm 100% sure the secrets are right.
Why is kamerbaas.nl trying to use the certificate of gateway.kamerbaas.nl?
Ps. gateway.kamerbaas.nl has a node-express server running with HTTPS. I've loaded my certificates there as well. kamerbaas.nl has a node server without https, could that be the problem? I'm guessing it doesn't matter, since my Ingress rules only points to port 80 of my services, which is the port for unsecured HTTP.