acme staging environment shows invalid certificate - kubernetes

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.

Related

Cluster-issuer secret wont replicate with multiple ingress

I was under the impression that the main point of cluster-issuer is that its namespaced and doesn't have to be recreated across different resources, in general there could be one main cluster-issuer that will manage all ingresses across the cluster.
From what I am seeing the cluster-issuer can only create one secret and if its in use by one ingress the second wont wont be created properly cause its already taken.
Is there anyway to create one cluster-issuer to manage all ingresses across the cluster?
Code included below
Cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-grafana
namespace: cert-manager
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: foo#gmail.com
privateKeySecretRef:
name: letsencrypt-grafana
solvers:
- selector:
dnsZones:
- "foo.com"
dns01:
route53:
region: eu-central-1
hostedZoneID: foo
accessKeyID: foo
secretAccessKeySecretRef:
name: aws-route53-creds
key: password.txt
Ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-ingress
namespace: loki
annotations:
cert-manager.io/cluster-issuer: letsencrypt-grafana
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "125m"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts:
- grafana.foo.com
secretName: letsencrypt-grafana # < cert-manager will store the created certificate in this secret.
rules:
- host: grafana.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: loki-grafana
port:
number: 80
i would recommend creating the wildcard certificate using issuer/clusterissuer.
So you will be having the single secret with wildcard cert so you can use that across all ingress.
As you are already using DNS verification it will work well, as wildcard not supports the HTTP
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: test123#gmail.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- selector:
dnsZones:
- "devops.example.in"
dns01:
route53:
region: us-east-1
hostedZoneID: Z0152EXAMPLE
accessKeyID: AKIA5EXAMPLE
secretAccessKeySecretRef:
name: route53-secret
key: secret-access-key
---
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: le-crt
spec:
secretName: tls-secret
issuerRef:
kind: Issuer
name: letsencrypt-prod
commonName: "*.devops.example.in"
dnsNames:
- "*.devops.example.in"
Read my full article : https://medium.com/#harsh.manvar111/wild-card-certificate-using-cert-manager-in-kubernetes-3406b042d5a2
Ingress & secret example
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
certmanager.k8s.io/issuer: "letsencrypt-prod"
certmanager.k8s.io/acme-challenge-type: dns01
certmanager.k8s.io/acme-dns01-provider: route53
name: ingress-resource-tls
namespace: default
spec:
rules:
- host: "hello.devops.example.in"
http:
paths:
- backend:
serviceName: hello-app
servicePort: 8080
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- "hello.devops.example.in"
secretName: tls-secret
#Harsh Manvar while I do appreciate your anwser I found something that is a better suit for my needs.
Cert-manager documentation contains multiple options to sync secrets across namespaces
The one I chose was reflector. The steps to install are included in the documentation but just for the sake of service i'll post here aswell
Requirements: Helm
Installation:
helm repo add emberstack https://emberstack.github.io/helm-charts
helm repo update
helm upgrade --install reflector emberstack/reflector
Setup:
Add the following annotation to your secret reflector.v1.k8s.emberstack.com/reflection-allowed: "true", it should look like the following
apiVersion: v1
kind: Secret
metadata:
name: source-secret
annotations:
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
Done! Your secret should be replicated within all namespaces. For multiple ingress configurations within the same namespace you could edit your ingress.yaml like this
Ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: jenkins
annotations:
cert-manager.io/cluster-issuer: letsencrypt-global
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "125m"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts:
- jenkins.foo.com
- nginx.foo.com
secretName: letsencrypt-global # < cert-manager will store the created certificate in this secret.
rules:
- host: jenkins.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jenkins
port:
number: 80
- host: nginx.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80

Microk8s/Kubernetes does not use the Let's Encrypt auto-generated certificate

Having the following k8s config:
---
kind: Namespace
apiVersion: v1
metadata:
name: test
labels:
name: test
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: test-depl
spec:
selector:
matchLabels:
app: test-app
template:
metadata:
labels:
app: test-app
spec:
containers:
- name: test-app
image: jfsanchez91/http-test-server
---
apiVersion: v1
kind: Service
metadata:
namespace: test
name: test-svc
spec:
selector:
app: test-app
ports:
- name: test-app
protocol: TCP
port: 80
targetPort: 8090
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
namespace: test
name: letsencrypt-cert-issuer-test-staging
spec:
acme:
email: email#example.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-cert-issuer-test-staging
solvers:
- http01:
ingress:
class: public
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
namespace: test
name: letsencrypt-cert-issuer-test-prod
spec:
acme:
email: email#example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-cert-issuer-test-prod
solvers:
- http01:
ingress:
class: public
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: ingress-routes
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: "letsencrypt-cert-issuer-test-prod"
spec:
tls:
- hosts:
- test.example.com
secretName: tls-secret
rules:
- host: test.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-svc
port:
number: 80
The Let's Encrypt certificate is being issued and stored in tls-secret correctly.
But then when I try to open test.example.com I get an invalid certificate (the K8s default certificate) NET::ERR_CERT_AUTHORITY_INVALID.
Common Name (CN): Kubernetes Ingress Controller Fake Certificate
Organization (O): Acme Co
Q: How can I configure Ingress correctly to use the Let's Encrypt certificate?
Q: Is there anything else I should configure?
UPDATE: tls-secret type (kubernetes.io/tls):
$ kubectl -n test describe secrets tls-secret
Name: tls-secret
Namespace: test
Labels: <none>
Annotations: cert-manager.io/alt-names: test.example.com
cert-manager.io/certificate-name: tls-secret
cert-manager.io/common-name: test.example.com
cert-manager.io/ip-sans:
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: ClusterIssuer
cert-manager.io/issuer-name: letsencrypt-cert-issuer-test-prod
cert-manager.io/uri-sans:
Type: kubernetes.io/tls
Data
====
tls.key: 1679 bytes
tls.crt: 5599 bytes
I'd recommand setting the certificate your self in order to have more control on subdomains to include and renewal policy
kubectl -n $NAMESPACE apply -f certificate.yaml
For example, for a DNS hosted on Azure DNS zone
#certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cert-wildcard
spec:
duration: 2160h # 90d
renewBefore: 360h # 15d
secretName: cert-wildcard
issuerRef: #from issuer.yaml
name: letsencrypt-prod
kind: ClusterIssuer
commonName: domain.com # go to domaine, go to certificate, go to Details, go to Common Name
dnsNames: #list of all different domains associeted with the certificate
- domain.com
- sub.domain.com
acme:
config:
- dns01:
provider: azure-dns
domains:
- domain.com
- sub.domain.com

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 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

Cert-managed with wilcard and Cloudflare DNS, stuck at 'OrderCreated'

I'm trying to get cert-manager and letsencrypt working for a wildcard domain. I've pointed the wildcard A host to the load balancer IP (GKE). Here is the secret and issuer:
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-key
namespace: cert-manager
type: Opaque
data:
apikey: BASE_64_ENCODED_API_KEY
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
namespace: cert-manager
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: EMAIL
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- dns01:
cloudflare:
email: EMAIL
apiKeySecretRef:
name: cloudflare-api-key
key: apikey
and here is my ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: apps-ingress
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-staging
spec:
tls:
- hosts:
- "*.sampledomain.com"
secretName: letsencrypt-staging
rules:
- host: phpmyadmin.sampledomain.com
http:
paths:
- backend:
serviceName: phpmyadmin
servicePort: 8081
The events are stuck at 'OrderCreated'. On checking the logs:
E0817 08:42:45.872348 1 base_controller.go:189] cert-manager/controller/challenges "msg"="re-queuing item due to error processing" "error"="Cloudflare API Error \n\t Error: 9103: Unknown X-Auth-Key or X-Auth-Email" "key"="default/letsencrypt-staging-3055668421-0"
There was a typo in my email address :|