Cryptage de nos sauvegardes : atteindre la ligne d'arrivée
Publié: 2017-09-02Remarque : ce poste d'ingénierie a été rédigé par notre administrateur de base de données, Silvia Botros. Découvrez certains de ses autres messages DBA ici.
Il y a un an, SendGrid travaillait dur pour obtenir la certification SOC2. Tout le monde était impliqué. Il y avait des histoires sur presque tous les tableaux d'équipe de livraison avec une étiquette SOC2, car nous cherchions tous à être certifiés d'ici la fin du troisième trimestre. Comme vous pouvez l'imaginer, étant la personne en charge des bases de données, il y avait certainement du travail à faire pour cette partie de la pile.
Sur ma liste de tâches pour cette entreprise à l'échelle de l'entreprise, je m'assurais que nos sauvegardes étaient cryptées. Étant donné que mon domaine de connaissance concerne les outils DBA et sachant que xtrabackup de Percona prend déjà en charge le cryptage, il était prévisible que j'irais à cela comme première tentative de cette tâche.
Quelques points importants étaient dans ma ligne de mire en testant cette approche :
- De toute évidence, la sauvegarde devait être cryptée
- Les frais généraux liés à la création de la sauvegarde devaient être connus et acceptables
- La surcharge liée au déchiffrement de la sauvegarde au moment de la restauration devait être connue et acceptable
Cela signifiait que je devais d'abord pouvoir suivre la durée de mes sauvegardes.
Suivi du temps de sauvegarde
SendGrid utilise Graphite pour ses métriques d'infrastructure et bien que la grande majorité soit envoyée via Sensu, Graphite est assez simple pour envoyer des métriques directement via des lignes bash - très pratique puisque les scripts de sauvegarde sont en bash. Notez que l'envoi direct de métriques à Graphite n'est pas super évolutif, mais comme ces sauvegardes s'exécutent au plus une fois par heure, c'était bien pour mes besoins.
Cette partie s'est avérée relativement facile.
Pour expliquer ce qui s'est passé dans cette dernière ligne, j'envoie à Graphite le chemin de la métrique que j'envoie (assurez-vous qu'elle est unique), la valeur de la métrique, puis l'heure actuelle au format d'époque. Netcat est ce que j'ai décidé d'utiliser pour plus de simplicité, et je lui donne un délai d'attente de 1 seconde car, sinon, il ne se fermera jamais. L'`URL graphite` est notre point de terminaison DNS pour Graphite dans le centre de données.
Maintenant que j'avais une base de comparaison, nous étions prêts à commencer à tester les méthodes de chiffrement.
Suite à la documentation détaillée de Percona sur la façon de procéder, j'ai commencé par créer une clé. Si vous lisez attentivement cette page de documentation, vous réaliserez peut-être quelque chose.
Cette clé doit être transmise directement à l'outil de sauvegarde, et c'est la même clé qui peut déchiffrer l'instantané. C'est ce qu'on appelle le cryptage symétrique et il est, de par la nature de cette même clé dans les deux sens, moins sûr que le cryptage asymétrique. J'ai décidé de continuer à tester pour voir si la simplicité en fait toujours une approche viable.
Des tests avec de très petites bases de données, quelques centaines de Mo, ont été concluants. L'outil fonctionne comme prévu et documenté, mais il s'agissait davantage d'un test fonctionnel et la vraie question était "quelle est l'ampleur de la pénalité de chiffrement sur nos plus grandes bases de données ?" Les instances les plus héritées de SendGrid avaient atteint des tailles allant de 1 à 2 To à une seule bête de 18 To. Ce que j'allais utiliser pour les petites instances devait également être opérationnellement acceptable sur les plus grandes.
C'est là que les tests et les benchmarks sont devenus intéressants
Mon premier sujet de test d'une taille considérable est une base de données que nous avons qui est de 1 To sur disque. Très rapidement, j'ai rencontré un problème inattendu. Avec des paramètres de cryptage minimaux (1 thread, tailles de bloc par défaut), j'ai vu les sauvegardes échouer avec cette erreur :
À l'époque, ces bases de données utilisaient 512 Mo comme taille de fichier du journal des transactions, et il s'agit d'un cluster assez occupé, de sorte que ces fichiers tournaient presque toutes les minutes. Normalement, cela serait perceptible dans les performances de la base de données, mais il était principalement masqué par la merveille des disques SSD. On dirait que ne pas définir de threads de cryptage parallèles (lire : utiliser un) signifie que nous passons tellement de temps à crypter les fichiers `.ibd` que les rouleaux de journalisation innodb sous nous faisaient la pause de sauvegarde.
Alors, essayons à nouveau avec un certain nombre de threads de chiffrement. Dans un premier temps, j'ai essayé avec 50 threads. L'astuce ici est de trouver le point idéal du cryptage rapide sans rivaliser avec le processeur. J'ai également augmenté la taille des `ib_logfiles` à 1 Go chacun.
Ce fut un test plus réussi que j'étais heureux de laisser infuser pendant la nuit. Pour les premières nuits, les choses semblaient bonnes. Il était temps de faire une sauvegarde qui ne grossit pas trop, mais la charge moyenne de la boîte pendant le processus de sauvegarde montrait définitivement les étapes supplémentaires.
Cependant, lorsque je suis passé au test des restaurations, j'ai constaté que le processus de restauration des mêmes sauvegardes, après l'ajout du cryptage, était passé de 60 à 280 minutes, ce qui signifie une pénalité sévère pour notre temps de récupération promis en cas de catastrophe.
Nous devions ramener cela à un délai plus raisonnable.
C'est là que le travail d'équipe et les solutions plus simples aux problèmes ont brillé. Un des membres de notre équipe InfoSec a décidé de voir si cette solution pouvait être simplifiée. Il a donc fait quelques tests supplémentaires et est revenu avec quelque chose de plus simple et de plus sûr. Je n'avais pas encore appris gpg2 et c'est donc devenu un exercice d'apprentissage pour moi aussi.
La bonne chose à propos de gpg2 est qu'il prend en charge le cryptage asymétrique. Nous créons une paire de clés où il y a des parties privées et publiques. La partie publique est utilisée pour chiffrer tout flux ou fichier que vous décidez d'alimenter gpg2 et le secret privé peut être utilisé pour déchiffrer.
La modification de nos scripts de sauvegarde pour ajouter un cryptage distillé à cela. Certains arguments ont été supprimés pour faciliter la lecture :
D'autre part, lors de la restauration d'une sauvegarde, nous devons simplement nous assurer qu'une clé secrète acceptable se trouve dans le trousseau de clés de l'hôte, puis utiliser cette commande :
Étant donné que j'étais également nouveau sur gpg2, cela est devenu une opportunité d'apprentissage pour moi. Colin, notre formidable membre de l'équipe InfoSec, a continué à tester les sauvegardes et les restaurations à l'aide de gpg2 jusqu'à ce qu'il confirme que l'utilisation de gpg2 présentait de nombreux avantages par rapport à l'utilisation de la compression intégrée de xtrabackup, notamment :
- C'était asymétrique
- Sa gestion secrète pour le décryptage est relativement facile à faire pivoter (plus à ce sujet ci-dessous)
- Il est indépendant des outils, ce qui signifie que tout autre type de sauvegarde qui n'utilise pas xtrabackup pourrait utiliser la même méthode
- Il utilisait plusieurs cœurs lors du décryptage, ce qui nous donnait de meilleurs temps de restauration
Toujours place à l'amélioration
Un domaine où je vois encore une marge d'amélioration est la façon dont nous gérons le secret qui peut décrypter ces fichiers. Pour le moment, nous les avons dans notre solution de gestion des mots de passe d'entreprise, mais les obtenir à partir de là, puis les utiliser pour tester les sauvegardes est un processus manuel. La prochaine étape de notre plan consiste à implémenter Vault by Hashicorp et à l'utiliser de manière transparente et sur les hôtes désignés, extraire la clé secrète pour le déchiffrement, puis la supprimer de l'anneau local afin qu'elle soit facilement disponible pour les tests automatisés et toujours protégée.
En fin de compte, nous avons obtenu que toutes nos sauvegardes de base de données soient conformes à nos besoins SOC2 à temps sans sacrifier les performances de sauvegarde ou le SLA de reprise après sinistre. J'ai eu beaucoup de plaisir à travailler sur cette mission avec notre équipe InfoSec et j'en suis sorti en apprenant de nouveaux outils. De plus, il est toujours agréable lorsque la solution la plus simple finit par être la plus adaptée à sa tâche.