Lors du déploiement d'un projet Web, la mise en œuvre d'un certificat SSL est un défi commun auquel chaque ingénieur est susceptible de faire face - et je ne fais pas exception.
Généralement, les startups optent pour des certificats gratuits comme ceux de Let's Encrypt. Cependant, ceux-ci s'accompagnent de limitations et d'inconvénients à prendre en compte, qui sont détaillés sur le site Web du fournisseur de certificats .
Examinons de plus près les problèmes que j'ai personnellement rencontrés avec les certificats gratuits :
Ayant régulièrement rencontré ces problèmes, j'ai développé une configuration de solution personnalisée qui utilise les certificats Let's Encrypt. Dans cet article, je vais partager mes découvertes et les leçons que j'ai apprises en cours de route.
Récemment, je me suis concentré sur une pile technologique spécifique et j'aimerais discuter d'une solution d'infrastructure basée sur un cluster Kubernetes dans le contexte d'un fournisseur de cloud Azure. Bien que cert-manager soit une solution populaire dans ce domaine, je préfère l'installer via Helm pour plus de commodité.
Alors, sans plus tarder, plongeons directement dans :
helm repo add jetstack https: //charts.jetstack.io
helm repo update kubectl apply -f https: //github.com/jetstack/cert-manager/releases/download/v1.6.1/cert-manager.crds.yaml
helm install cert-manager jetstack/cert-manager -- namespace cert - manager -- create - namespace -- version v1 . 6 . 1
Ensuite, nous pouvons créer un ClusterIssuer en utilisant le fichier YAML suivant :
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-cluster-issuer
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: p…[email protected] #your e-mail
privateKeySecretRef:
name: letsencrypt-cluster-issuer
solvers:
- http01:
ingress:
class: nginx
À l'avenir, il existe deux options pour mettre en œuvre les certificats :
Explorons les deux options.
Dans le premier scénario, mes fichiers YAML ressemblaient à ceci :
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: myservice2 namespace : test
Spec : duration : 2160h
renewBefore : 72h
dnsNames : - myservice2 . mydomain . org # you resources
secretName : myservice2 - tls
issuerRef : name : letsencrypt - cluster - issuer
kind : ClusterIssuer
Il est à noter que seul le "secretName: myservice2-tls" a été mentionné dans l'entrée dans la section TLS pour un service particulier.
Soit dit en passant, le fichier YAML contient des paramètres utiles, tels que :
Si vous êtes plus à l'aise avec la console, permettez-moi de vous fournir une vue complète du certificat à titre d'exemple.
kubectl describe certificates <cert name > -n <namespace name >
Alors, qu'avons-nous au final ?
Personnellement, j'ai trouvé que la gestion des certificats Let's Encrypt via Ingress était plus fiable et pratique, c'est pourquoi je l'utilise depuis peu. Avec cette approche, en plus du secretName et du nom d'hôte dans la section TLS, il vous suffit de spécifier des annotations dans le fichier YAML d'entrée.
annotations : cert-manager .io/cluster-issuer: "letsencrypt-cluster-issuer" cert-manager .io/renew-before: 72h
Et voilà, la magie de tout ça ! Les certificats sont désormais automatiquement réémis, avec une période tampon de trois jours avant leur expiration dans cet exemple. Il convient de noter que, dans le cas de Let's Encrypt, la période par défaut est de 90 jours.
Cependant, en raison des limitations des certificats gratuits de Let's Encrypt, notre équipe a finalement envisagé le besoin d'un certificat complet qui pourrait protéger non seulement notre domaine mais également les sous-domaines. Alors que nous continuions à développer notre projet sur Azure, nous avons constaté qu'Azure Key Vault fournissait un emplacement pratique pour stocker ces certificats. Nous utilisons l'utilitaire akv2k8s dans notre cluster Kubernetes. Si cela vous intéresse, je vous encourage à en savoir plus .
Une fois que vous avez obtenu un certificat dans Azure, l'étape suivante consiste à l'ajouter à Azure Key Vault (AKV). Bien que ce processus soit relativement simple, la vérification de la propriété du domaine peut être un peu délicate. Cependant, une fois toutes les étapes de confirmation terminées avec succès, le certificat apparaîtra dans la section "Secrets" du coffre de clés.
L'un des principaux avantages de cette approche est le renouvellement automatique des certificats. Le certificat sera réédité et mis à jour dans AKV après un an, et il se synchronisera automatiquement avec le secret dans Kubernetes.
Pour que le cluster Kubernetes utilise le certificat acquis, vous devez lui accorder certaines autorisations et droits d'accès.
Pour ce faire, vous devez d'abord obtenir l'identityProfile.kubeletidentity.objectId du cluster. Vous pouvez le faire en utilisant la commande suivante :
az aks show -g < RG > -n < AKS_name >
Le groupe de ressources (RG) est l'emplacement où le cluster est stocké et AKS_name est le nom de votre cluster.
Après avoir obtenu le identityProfile.kubeletidentity.objectId, vous devez le copier. Ensuite, ajoutez la valeur à la commande pour accorder les autorisations d'accès aux secrets :
az keyvault set-policy --name < name AKV > --object-id < get from first step value > --secret-permissions get
Ensuite, vous pouvez procéder à l'installation de akv2k8s, qui peut être effectuée via Helm ou d'autres méthodes préférées, comme décrit dans le guide d'installation .
En suivant la documentation officielle , vous pouvez ensuite synchroniser votre certificat Azure Key Vault avec Secret dans un espace de noms Kubernetes particulier. Voici mon fichier YAML :
apiVersion: spv.no/v1 kind: AzureKeyVaultSecret metadata: name: wildcard-cert #any name namespace : default
spec : vault : name : SandboxKeyVault # name you keyvault in Azure
object : name : name_object_id # name object id from Azure AKV this cert
type : secret
output : secret : name : wildcard - cert # any name for secret in your namespace
type : kubernetes . io / tls
chainOrder : ensureserverfirst # very important values !!!
Permettez-moi de souligner l'importance de la dernière ligne, car elle a joué un rôle crucial dans la résolution d'un problème que j'ai rencontré. Au départ, j'ai réussi à télécharger le certificat dans Kubernetes, mais cela n'a pas fonctionné comme prévu. Il a fallu du temps pour diagnostiquer le problème.
Il s'est avéré que lors de l'exportation d'un certificat PFX à partir du Key Vault, le certificat du serveur est parfois positionné à la fin de la chaîne au lieu du début où il devrait être. Cela peut entraîner des problèmes lorsqu'il est utilisé avec des paramètres tels que ingress-nginx, car le certificat ne se charge pas et revient par défaut à sa valeur d'origine. Cependant, en définissant le chainOrder pour assurer le serveur en premier, le certificat de serveur est placé en premier dans la chaîne.
En examinant de plus près le certificat, j'ai découvert que la chaîne était disposée dans l'ordre suivant :
Après avoir abordé les aspects techniques et les configurations, revenons sur les particularités des certificats Azure.
Azure propose deux options pour commander un certificat, toutes deux fournies par GoDaddy :
Nous avons opté pour ce dernier, en espérant qu'il protégerait l'ensemble de nos applications et services. Cependant, il y avait quelques nuances.
Le certificat Azure Wildcard protège uniquement les sous-domaines de premier niveau. Par exemple, si nous avons un domaine nommé mydomain.com , le certificat ne couvrira que les sous-domaines de premier niveau sous la forme .mydomain.com .
Par conséquent, le certificat fonctionnera pour des ressources telles que service1.mydomain.com, service2.mydomain.com, service3.mydomain.com , mais il ne couvrira pas service1.test.mydomain.com ou mail.service1.mydomain.com .
Quelles options avons-nous alors?
Il est peu probable que la première option soit pratique, car le nombre de sous-domaines, en particulier ceux du deuxième niveau, peut être énorme. Ainsi, payer un certificat wildcard pour chaque sous-domaine ( .service1.mydomain.com, *.dev.mydomain.com… ) n'est pas la solution la plus raisonnable.
En ce qui concerne la deuxième option, j'ai eu une longue conversation avec l'équipe de support Azure à ce sujet, passant par toutes les étapes de déni, de frustration et de colère, pour finalement réaliser que la capacité SAN pour les certificats n'a pas encore été implémentée.
Jusqu'à la fin, j'avais espéré qu'un tel problème ne se produirait jamais sur Azure. En revanche, leur concurrent, AWS Amazon, propose des certificats via leur AWS Certificate Manager (ACM) qui prend en charge jusqu'à 10 noms de sujet alternatifs, y compris les caractères génériques. Il vous permet de créer 10 sous-domaines avec un caractère générique (*), et même de demander une augmentation de quota sur AWS jusqu'à 100k.
Pour conclure, je vais partager comment vous pouvez utiliser des certificats avec le service Front Door sur Azure.
Pour moi, Azure Front Door (AFD) est une passerelle globale et évolutive qui exploite le réseau périphérique mondial de Microsoft pour diriger le trafic entrant vers les points de terminaison appropriés, qui peuvent être des applications ou des services Web. Fonctionnant au niveau de la couche HTTP/HTTPS (couche 7), Front Door achemine les demandes des clients vers un serveur d'applications disponible à partir du pool. Le côté serveur de l'application peut être n'importe quel service accessible sur Internet, qu'il soit hébergé à l'intérieur ou à l'extérieur d'Azure.
Un exemple du site Web de documentation https://docs.microsoft.com/
Azure Front Door est un outil pratique qui vous permet d'équilibrer et de proxy le trafic entrant accédant aux applications et services distribués dans le monde entier. Il offre une gamme de fonctionnalités, notamment la possibilité de lier diverses règles en configurant le gestionnaire de règles, les stratégies de jointure et les paramètres de pare-feu. Je ne m'attarderai pas trop sur les spécificités du service AFD dans cet article mais me concentrerai plutôt sur les particularités du service des certificats.
Comme vous pouvez vous y attendre, le trafic entrant vers Azure Front Door peut être http ou https . Si vous choisissez https , vous avez trois options : générer un certificat sur le service Azure Front Door lui-même, charger votre propre certificat ou synchroniser votre certificat existant avec Azure Key Vault. Pour autoriser le service Front Door à accéder au coffre de clés, vous devez configurer les autorisations nécessaires.
Je recommande d'utiliser la dernière option et de sélectionner la dernière version du certificat pour éviter d'avoir à le renouveler ou le régénérer manuellement. En connectant le certificat d'AKV, tout restera à jour automatiquement.
Cette configuration vous donnera le résultat suivant :
Voici une autre particularité lors de la direction du trafic d'Azure Front Door vers AKS.
La gestion du trafic http n'est pas un problème, mais il y a un détail subtil à garder à l'esprit lors de la configuration d'un pool de ressources et de la spécification de l'adresse IP externe du cluster AKS. Assurez-vous de laisser le champ "en-tête de nœud de composant serveur" vide pour vous assurer qu'il est automatiquement rempli avec les valeurs qui ont été saisies dans le champ "IP ou nom de nœud".
Supposons que vous ayez un certificat générique de domaine attaché via AKV qui est utilisé à la fois par le service Front Door et vidé dans le cluster AKS via akv2k8s. Le nom d'hôte de l'interface (et l'enregistrement CNAME dans DNS) pour toutes vos applications et services accessibles via Front Door sera le suivant :
Cela permettra à tous les services au format *.mydomain.com de fonctionner correctement. Une fois que vous avez terminé cette configuration, vous êtes prêt.
Dans certains scénarios, la redirection du trafic d'Azure Front Door vers AKS via https peut être plus avantageuse. Pour garantir le bon fonctionnement d'Azure Front Door dans les paramètres du pool de serveurs, il est crucial de spécifier un nom DNS correspondant à votre cluster AKS , qui est lié au SNI et aux vérifications de l'état. Sinon, la configuration ne fonctionnera pas.
Dans mon cas, aucun nom n'était attribué à mes clusters AKS, je n'avais que des services qui fonctionnaient auparavant directement mais devaient fonctionner via Azure Front Door. Pour résoudre ce problème, j'ai dû créer un nom DNS distinct pour le cluster AKS, configurer DNS et configurer un service distinct avec un certificat attaché à l'entrée. Ce n'est qu'alors que je pourrais rediriger le trafic https vers les clusters AKS et m'assurer qu'il fonctionne correctement pour tous les services disponibles.
Il est important de prendre en compte les mesures de sécurité lors de la configuration de l'autorisation de connexion pour AKS. Pour garantir une connexion sécurisée, vous pouvez limiter l'autorisation de se connecter à AKS uniquement à partir d'adresses IP Azure Front Door dans le groupe de sécurité réseau pour AKS (comme illustré dans l'image ci-dessous).
De plus, vous pouvez configurer l'entrée AKS pour accepter les connexions exclusivement à partir de votre en-tête Azure Front Door par ID à l'aide du paramètre X-Azure-FDID .
1. Azure ne fournit pas d'informations complètes sur les fonctionnalités et les inconvénients de leurs certificats. Cependant, il convient de mentionner qu'ils nous ont rapidement remboursés pour le certificat acheté.
2. Au cours de notre processus de développement, nous continuons à utiliser Let's Encrypt. Bien qu'il ait ses limites, ce n'est pas le pire choix disponible.
3. Si votre projet nécessite plusieurs sous-domaines avec différents niveaux de ressources, vous pouvez envisager les certificats « Wildcard (également appelé multidomaine) avec SAN » de fournisseurs tiers. Ces certificats peuvent être importés dans Azure et utilisés à leur plein potentiel.
4. Lorsqu'il est configuré correctement, Azure Front Door est un excellent service. Je le recommande fortement.
Écrit par Pavel Shapurau, ingénieur principal DevOps, Social Discovery Group