can't get a trusted certificate from Let's encrypt using cert-manager - kubernetes

I am setting up my first K8s cluster in Linode LKE and I have problem getting a trusted certificate from Lets Encrypt. firefox shows unsecure connection with certificate name "Kubernetes Ingress Controller Fake Certificate".
I can't figure out what is missing and how can I troubleshoot this.
Here is my ClusterIssuer and Ingress definitions. I tried the staging and the production acme urls but I couldn't get a trusted certificate.
`
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
email: example#gmail.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: letsencrypt-staging
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tb-https-loadbalancer
namespace: thingsboard
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
cert-manager.io/cluster-issuer: "letsencrypt-staging"
spec:
ingressClassName: nginx
tls:
- hosts:
- testing.com
secretName: letsencrypt-staging
rules:
- host: testing.com
http:
paths:
...

Related

ALB Ingress Controller, Terminating TLS via AWS ACM. How to go End-To-End?

We currently use the AWS ALB Ingress Controller to front out ingress, and terminate SSL using a certificate from AWS ACM. This work fine.
Is there a way, to also encrypt the traffic from the Load balancer to the cluster?
Here is what I attempted
Install/Configure Cert Manager
Add a TLS Secret to the Ingress
Change the ingress annotation to set the backend protocol to HTTPS alb.ingress.kubernetes.io/backend-protocol: HTTPS
This... results in a 502 gateway error
here is my current, working ingress, with only the relevant parts still shown.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
alb.ingress.kubernetes.io/backend-protocol: HTTP
alb.ingress.kubernetes.io/certificate-arn: real-cert-arn
alb.ingress.kubernetes.io/group.name: public.monitor
alb.ingress.kubernetes.io/group.order: "40"
alb.ingress.kubernetes.io/healthcheck-path: /
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
alb.ingress.kubernetes.io/load-balancer-name: monitoring-public-qa
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-FS-1-2-Res-2020-10
cert-manager.io/cluster-issuer: cert-manager-r53-qa
kubernetes.io/ingress.class: alb
spec:
rules:
- host: goldilocks.qa.realdomain.com
http:
paths:
- backend:
service:
name: goldilocks-dashboard
port:
name: http
path: /*
pathType: ImplementationSpecific
tls:
- hosts:
- goldilocks.qa.realdomain.com
secretName: goldilocks-qa-cert
status:
loadBalancer:
ingress:
- hostname: real-lb-address.us-gov-west-1.elb.amazonaws.com
my (staging) cert exists, and appears fine.
[ec2-user#ip-10-17-2-102 ~]$ kubectl get cert -n goldilocks goldilocks-qa-cert -o yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: goldilocks-qa-cert
namespace: goldilocks
ownerReferences:
- apiVersion: networking.k8s.io/v1
blockOwnerDeletion: true
controller: true
kind: Ingress
name: goldilocks-dashboard
uid: 2494e5be-e624-471b-afd3-c8d56f5dc853
resourceVersion: "81003934"
uid: d494a1ec-7509-474e-b154-d5db8ceb86c0
spec:
dnsNames:
- goldilocks.qa.realdomain.com
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: cert-manager-r53-qa
secretName: goldilocks-qa-cert
usages:
- digital signature
- key encipherment
status:
conditions:
- lastTransitionTime: "2023-02-08T16:06:56Z"
message: Certificate is up to date and has not expired
The fact I can not figure out what to google to find this answer, leads me to think that I'm attempting to do something weird? I understand I could just terminate the TLS on the pod, but I didn't want to rely on the lets encrypt to provide me good/valid certs, I just want the traffic encrypted.

kubectl get certificates : No resources found using cert-manager

I don't undestand why i can't get certificates on K8S using cert-manager
I installed cert-manager : https://github.com/cert-manager/cert-manager/releases/download/v1.7.1/cert-manager.crds.yaml
I created ClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
email: user#example.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: example-issuer-account-key
solvers:
- http01:
ingress:
class: nginx
I created ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-staging
spec:
rules:
- host: mytest.example.fr
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp
port:
number: 80
tls:
- hosts:
- mytest.example.fr
secretName: letsencrypt-staging
But when i try to get an certificate i get 'no resources found'
Any idea ?
Thank you for your help
If you don't want to create kind certificate you can use
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: cluster-issuer-name
namespace: development
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: harsh#example.com
privateKeySecretRef:
name: secret-name
solvers:
- http01:
ingress:
class: nginx-class-name
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx-class-name
cert-manager.io/cluster-issuer: cluster-issuer-name
nginx.ingress.kubernetes.io/rewrite-target: /
name: example-ingress
spec:
rules:
- host: sub.example.com
http:
.
. #Path and service configs
.
.
tls:
- hosts:
- sub.example.com
secretName: secret-name
ingress will call clusterisser and it will auto-create certificate for you.
Update ingress resources as per need if you are higher version 1.18 or above
Notes
Make sure you are using the URL https://acme-v02.api.letsencrypt.org/directory in clusterissue or else you will get fake certificate in browser.
For refrence you can read more here :
https://stackoverflow.com/a/55183209/5525824
Make sure also you ingress pointing to proper clusterissuer if
you have created new.
Also don't use same privateKeySecretRef:name: secret-name you
need to delete it or use the new name as fake certificate
now stored in that secret so.
Certificates are not created automatically by cert-manager.
You have to create a YAML yourself. And use the issuer name that you have already created
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: my-certificate
namespace: default
spec:
secretName: set-a-new-name-here
issuerRef:
name: letsencrypt-staging
kind: ClusterIssuer
commonName: mytest.example.fr
dnsNames:
- mytest.example.fr

cert-manager: no configured challenge solvers can be used for this challenge

I followed this instruction to set up a cert manager on my EKS cluster https://cert-manager.io/docs/tutorials/acme/ingress/.
here is my ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/issuer: "letsencrypt-staging"
spec:
tls:
- hosts:
- '*.test.com'
secretName: test-tls
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-service
port:
number: 80
Here is the issuer. I just copied the config from the instruction
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: info#test.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
class: nginx
After deployment, I found the certificate ready state is false
kubectl get certificate
NAME READY SECRET AGE
test-tls False test-tls 2m45s
Then I followed this to troubleshoot https://cert-manager.io/docs/faq/troubleshooting/
I ran kubectl describe certificaterequest <request name>, found error Waiting on certificate issuance from order test-tls-xxx: "pending"
then ran kubectl describe order test-tls-xxx, found error
Warning Solver 20m cert-manager Failed to determine a valid solver configuration for the set of domains on the Order: no configured challenge solvers can be used for this challenge.
Any idea why it couldn't determine a valid solver? how do I test if solver is working?
It's not working due you are using the staging URL in cluster issuer to verify the image.
Please try with the Production URL.
here a simple and proper example of Clusterissuer and ingress YAML (do note you were trying with staging API https://acme-staging-v02.api.letsencrypt.org/directory if possible use the production server address so it works properly with all browsers)
Example:
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: cluster-issuer-name
namespace: development
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: harsh#example.com
privateKeySecretRef:
name: secret-name
solvers:
- http01:
ingress:
class: nginx-class-name
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx-class-name
cert-manager.io/cluster-issuer: cluster-issuer-name
nginx.ingress.kubernetes.io/rewrite-target: /
name: example-ingress
spec:
rules:
- host: sub.example.com
http:
paths:
- path: /api
backend:
serviceName: service-name
servicePort: 80
tls:
- hosts:
- sub.example.com
secretName: secret-name
Note : When you are trying again please try deleting the old objects like ingress, Clusterissuer first.
Issuer vs ClusterIssuer
An Issuer is a namespaced resource, and it is not possible to issue
certificates from an Issuer in a different namespace. This means you
will need to create an Issuer in each namespace you wish to obtain
Certificates in.
If you want to create a single Issuer that can be consumed in multiple
namespaces, you should consider creating a ClusterIssuer resource.
This is almost identical to the Issuer resource, however is
non-namespaced so it can be used to issue Certificates across all
namespaces.
Ref : https://cert-manager.io/docs/concepts/issuer/
Wildcard cert
You can use as per requirement, if you are using issuer you can update the ingress annotation line like
cert-manager.io/issuer: issuer-name
If you are trying to get the wildcard * certificate you won't be able to get it using HTTP auth method
solvers:
- http01:
ingress:
class: nginx-class-name
instead of this you have to use the DNS-auth method for wildcard cert.
solvers:
- dns01:
cloudDNS:
project: my-project
serviceAccountSecretRef:
name: prod-clouddns-svc-acct-secret
key: service-account.json
Read more at : https://cert-manager.io/docs/configuration/acme/dns01/
Ref article to get the wildcard cert : https://medium.com/#harsh.manvar111/wild-card-certificate-using-cert-manager-in-kubernetes-3406b042d5a2

cert-manager letsencrypt issuing invalid certs

I followed this tutorial to serve a basic application using the NGINX Ingrss Controller, and cert-manager with letsencrypt.
I am able to visit the website, but the SSL certificate is broken, saying Issued By: (STAGING) Artificial Apricot R3.
This is my ClusterIssuer:
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-issuer
namespace: cert-manager
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: my-email#example.com
privateKeySecretRef:
name: letsencrypt-issuer
solvers:
- http01:
ingress:
class: nginx
And the Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress-dev
namespace: my-app
annotations:
cert-manager.io/cluster-issuer: letsencrypt-issuer
spec:
tls:
- secretName: echo-tls
hosts:
- my-app.example.com
rules:
- host: my-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-dev
port:
number: 80
LetsEncrypt staging is for testing, and does not issue certificates that are trusted by browsers. Use the production LE URL instead https://acme-v02.api.letsencrypt.org/directory

acme staging environment shows invalid certificate

I have created a staging environment with cert-manager as the following:
---
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
email: stage#example.io
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: privateKeySecretRef
solvers:
- dns01:
digitalocean:
tokenSecretRef:
name: digitalocean-dns
key: access-token
selector:
dnsNames:
- "*.dev.svc.databaker.io"
- "*.stage.svc.databaker.io"
---
and have created a certifcate for the wildcard domain *.dev.svc.databaker.io:
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: dev-cert-staging
namespace: dev
spec:
secretName: secretName
issuerRef:
name: letsencrypt-staging
kind: ClusterIssuer
commonName: "*.dev.svc.databaker.io"
dnsNames:
- "*.dev.svc.databaker.io"
at the end, an ingress object:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-staging
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
name: dashboard
namespace: dev
spec:
rules:
- host: dashboard.dev.svc.databaker.io
http:
paths:
- backend:
serviceName: dashboard
servicePort: 80
path: /
tls:
- hosts:
- '*.dev.svc.databaker.io'
secretName: secretName
When I call the page https://dashboard.dev.svc.databaker.io/, it shows me:
The question is, if it is right, that it shows an invalid certificate?
It's right, staging is for testing certificate creation and has a very high limit on certificate issues.
Use production cert-issuer for even your dev environments but it's limited so make sure you're not spamming certs.