View Source Handling Astarte certificates
Astarte heavily requires SSL in a number of interactions, even though this can be bypassed with
ssl: false
.
In general, there are two alternative scenarios when dealing with certificates:
- you already purchased SSL certificates for your domains,
- you want your certificates to be handled by Let's Encrypt through cert-manager.
The two alternative procedures for securing your Astarte deployment are outlined in the following sections.
use-your-own-certificates
Use your own certificates
If you already own certificates for your domains, all it's needed is creating a TLS secret in the
namespace in which Astarte resides. Assuming that the certificate and key are saved respectively as
cert.pem
and privkey.pem
, simply run:
$ kubectl create secret tls astarte-tls-cert -n astarte \
--cert=cert.pem --key=privkey.pem
use-let-s-encrypt-certificates-with-cert-manager
Use Let's Encrypt certificates with cert-manager
The process of obtaining a TLS certificate from Let's Encrypt is handled by cert-manager using a cluster issuer. The issuer will query the Let's Encrypt API and handles the challenge to confirm that you are the right owner of the specified domain. Two types of challenges are supported, namely DNS01 and HTTP01.
Ensure all the prerequisites are satisfied and that both cert-manager and the NGINX ingress controller are deployed within your cluster. If you haven't installed them yet, you can do it with these simple commands:
- install cert-manager:
$ helm repo add jetstack https://charts.jetstack.io $ helm repo update $ kubectl create namespace cert-manager $ helm install \ cert-manager jetstack/cert-manager \ --namespace cert-manager \ --version v1.7.0 \ --set installCRDs=true
- install NGINX ingress controller:
$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx $ helm repo update $ helm install ingress-nginx ingress-nginx/ingress-nginx -n ingress-nginx \ --set controller.service.externalTrafficPolicy=Local \ --create-namespace
http01-challenge
HTTP01 Challenge
The current section outlines the procedure for setting up a ClusterIssuer to solve the HTTP01 challenge.
Find the external IP assigned to the ingress controller
Knowing the external IP of the NGINX ingress controller is crucial for solving the HTTP01 challenge.
You can find the external IP under the EXTERNAL-IP
field when inspecting the output of the
following command:
$ kubectl get svc -n ingress-nginx ingress-nginx-controller
Configure your DNS
Once the external IP of the ingress controller is known, make sure all your Astarte domains point to the NGINX Ingress controller IP. In particular, the list of the domains is:
api.your-domain.example.com
dashboard.your-domain.example.com
(if deployed)broker.your-domain.example.com
Create a ClusterIssuer
Define a ClusterIssuer and save it as cluster-issuer.yaml
:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@email.com
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
ingress:
class: nginx
Then, apply the resource with the following:
$ kubectl apply -f cluster-issuer.yaml
Create a Certificate resource
Once the ClusterIssuer has been created, add a Certificate
resource in the Astarte namespace
referencing the ClusterIssuer
, and save it as certificate.yaml
:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: astarte-default-ingress-certificate
namespace: astarte
spec:
dnsNames:
- <your-dns.names>
secretName: astarte-tls-cert
issuerRef:
name: letsencrypt
kind: ClusterIssuer
Then, apply the Certificate
resource:
$ kubectl apply -f certificate.yaml
Wait the HTTP challenge to complete
As soon as the HTTP challenge completes, a Kubernetes secret of type kubernetes.io/tls
called
astarte-tls-cert
will be created in the astarte
namespace. Now you can reference the TLS secret
in both the Astarte and AstarteDefaultIngress resources where required.
dns01-challenge
DNS01 challenge
The current section describes the procedure for setting up a ClusterIssuer
to use Google CloudDNS
to solve the DNS01 challenge. Therefore, when needed, the rest of this section will make use of the
gcloud CLI
.
If your Astarte deployment is hosted by another cloud provider, please refer to the cert-manager specific documentation.
Define a DNS Zone for your project
First, ensure that a DNS Zone is already defined for your project. If this requirement is not satisfied, this page provides guidance for the creation of the DNS Zone for a project hosted on Google Cloud. If your cluster is hosted by any other cloud provider, please ensure to follow the needed steps to fulfill the requirement.
Set up a Service Account with privileges of DNS Administrator
To set up a service account with privileges of DNS Administrator, run the following command:
$ PROJECT_ID=<your-project-id>
$ gcloud iam service-accounts create dns01-solver --display-name "dns01-solver"
$ gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:dns01-solver@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/dns.admin
Create a Service Account secret
To access the service account, cert-manager uses a key stored in a Kubernetes Secret. Therefore, create a key and download it as a json file:
$ gcloud iam service-accounts keys create key.json \
--iam-account dns01-solver@$PROJECT_ID.iam.gserviceaccount.com
and create a secret named clouddns-dns01-solver-svc-acct
in the cert-manager
namespace from the
key.json
file:
$ kubectl create secret generic -n cert-manager \
clouddns-dns01-solver-svc-acct \
--from-file=key.json
Create a ClusterIssuer that uses CloudDNS
Define a ClusterIssuer
resource which uses the secret, and save it as cluster-issuer.yaml
:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns-cluster-issuer
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@email.com
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: letsencrypt-cluster-issuer-key
solvers:
- dns01:
cloudDNS:
# The ID of the GCP project
project: <your-project-id>
# This is the secret used to access the service account
serviceAccountSecretRef:
name: clouddns-dns01-solver-svc-acct
key: key.json
Apply the resource simply running the following:
$ kubectl apply -f cluster-issuer.yaml
Create a Certificate resource
Once the ClusterIssuer has been created, add a Certificate
resource in the Astarte namespace
referencing the ClusterIssuer
, and save it as certificate.yaml
:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: astarte-default-ingress-certificate
namespace: astarte
spec:
dnsNames:
- <your-dns.names>
secretName: astarte-tls-cert
issuerRef:
name: letsencrypt-dns-cluster-issuer
kind: ClusterIssuer
Thus, apply the Certificate
resource:
$ kubectl apply -f certificate.yaml
Wait the DNS challenge to complete
As soon as the DNS challenge completes, a Kubernetes secret of type kubernetes.io/tls
called
astarte-tls-cert
will be created in the astarte
namespace. Now you can reference the TLS secret
in both the Astarte and AstarteDefaultIngress resources where required.
conclusions
Conclusions
The current page describes how to handle SSL certificates for securing your Astarte instance. In particular the following use cases are analyzed:
- certificates have already been purchased and needs to be properly deployed,
- let cert-manager generate and handle certificates in the following cases:
- solving HTTP01 ACME challenges,
- solving DNS01 ACME challenges.
At the end of each procedure you will end up with a Kubernetes TLS secret, named astarte-tls-cert
,
deployed in the Astarte namespace. Reference the secret in your Astarte and AstarteDefaultIngress
resources where required to secure your Astarte deployment.