Redis 09 - Comment gérer sécurité, accès aux données et permissions avec les ACL de Redis
Comment sécuriser Redis avec des identifiants et mots de passe pour l’authentification et avec des ACL pour l’accès aux commandes et aux données. Introduction, explication et démo des ACL de Redis.
Vous pouvez trouver des liens vers les enregistrements vidéo et les supports imprimables associés à la fin de cet article.
- Vidéo
- Introduction
- Un problème de sécurité
- Limites de la solution existante
- Solution implémentée et résultats
- Revenons à notre exemple
- Supports et liens
Vidéo
Introduction
Savez-vous que Redis peut être sécurisé par des comptes avec mots de passe pour l’authentification et par des listes de controle d’accès pour les commandes et l’accès aux données ? Voyons comment fonctionnent les ACL et comment les utiliser.
Un problème de sécurité
Jusqu’à la version 6, Redis n’avait qu’un unique utilisateur anonyme par défaut, éventuellement avec un mot de passe, pour accorder les pleins pouvoirs. Cette faiblesse de sécurité n’est pas un vrai problème pour les développeurs qui aiment Redis pour sa flexibilité, ses performances et ses possibilités de manipulation et de stockage des données. Ils l’utilisent partout, dans presque toutes les entreprises. C’est un problème pour les ops et les équipes de sécurité, mais ils s’y sont habitués. Ils, vous, ne savez peut-être pas que Redis dispose de comptes nominatifs, avec des mots de passe individuels, pour l’authentification et de listes de contrôles d’accès (ACL), pour la gestion des autorisations et permissions. Redis peut être sécurisé, voyons comment cela fonctionne et comment l’implémenter avec un exemple de projet.
Limites de la solution existante
Nous disposons d’une unique base pour enregistrer les commandes et de deux microservices, un pour modifier une commande, l’autre pour générer la facture. C’est un projet, nous avons donc un développeur par microservice, David et Denis, un chef de projet, Paul, et un administrateur, Angélina. Les microservices et les personnes utilisent toutes le même compte anonyme avec son unique mot de passe. Ce simple mot de passe leur donne un accès complet aux données et aux commandes Redis. Chacun peut exécuter n’importe quelle commande, avec le droit d’écriture, sur le jeu de données.
Lorsqu’un microservice a besoin de lire et d’écrire, alors que le second n’a besoin que de lire, si le second a un bug, est corrompu ou compromis, il peut corrompre les données du premier. Si un prestataire ou un stagiaire arrive, il aura un accès complet aux données et l’unique mot de passe partagé ne sera probablement pas changé à leur départ, il faudrait aussi modifier la configuration des applications. Aucun audit n’est possible, pour vérifier qui a fait quoi. Voyons comment Redis 6 permet de gérer ce problème de sécurité.
Solution implémentée et résultats
Je suppose que les connexions à la base Redis sont chiffrées par TLS, sinon, les mots de passe circulent en clair sur le réseau.
Qu’est-ce qu’une ACL Redis
Une ACL, pour Access Control List, est une liste ordonée de règles ou ACE, pour Access Control Entries. Chaque règle accorde ou retire des privilèges à un compte nommé, sur des commandes Redis, des clés ou des channels. Le compte peut être protégé par son propre mot de passe. Comment définir des ACL ?
acl setuser <account> [rulelist]
Initialiser un compte
Un compte peut être initialisé, par la règle reset
, avec un mot de passe
obligatoire mais non défini, sans règles, et désactivé.
# Initialise le compte sans obligation de mot de passe
redis-cli acl setuser francois reset nopass
# Connexion impossible, le compte est désactivé
redis-cli --user francois --pass 'nimportequoi' quit
Désactiver un compte
Un compte peut être temporairement désactivé avec la règle off
ou activé avec
on
.
# Activation du compte
redis-cli acl setuser francois on
# La connexion est possible
redis-cli --user francois --pass 'nimportequoi' quit
# Désactivation
redis-cli acl setuser francois off
# Plus de connexion
redis-cli --user francois --pass 'nimportequoi' quit
# Réactivation pour la suite
redis-cli acl setuser francois on
Plusieurs mots de passe par compte
Les ACL peuvent affecter un ou plusieurs mots de passe pour authentifier un
compte, avec le signe >
pour un mot de passe en clair ou le signe #
pour un
mot de passe chiffré. Elles peuvent aussi invalider un des mots de passe
respectivement avec les signes <
et !
. Tous les mots de passe sont invalidés
par la règle nopass
.
# Ajout d'un mot de passe à un compte
redis-cli acl setuser francois '>mypassword'
# Plus de connexion possible sans mot de passe
redis-cli --user francois --pass 'nimportequoi' quit
redis-cli --user francois --pass mypassword quit
# Ajout d'un second mot de passe
redis-cli acl setuser francois '>mysecondpassword'
# Le premier fonctionne toujours
redis-cli --user francois --pass mypassword quit
# Le second fonctionne aussi
redis-cli --user francois --pass mysecondpassword quit
# Invalidation du premier
redis-cli acl setuser francois '<mypassword'
# Il ne fonctionne plus
redis-cli --user francois --pass mypassword quit
# Le second fonctionne toujours
redis-cli --user francois --pass mysecondpassword quit
Catégories de commandes
Les règles peuvent accorder ou révoquer des privilèges sur des catégories de
commandes, respectivement avec les signes +
et -
suivis de @
et du nom de
la catégorie.
nocommands
et allcommands
sont des synonymes de -@all
et +@all
# Réinitialiser le compte avec accès aux données
redis-cli acl setuser francois reset on '>mypassword' ~*
# La manipulation des strings est désactivée
redis-cli --user francois --pass mypassword set strkey value1
# Accorde le droit de manipuler les strings
redis-cli acl setuser francois reset on '>mypassword' +@string ~*
# Commandes de lecture et écriture sur les strings sont autorisées
redis-cli --user francois --pass mypassword set strkey value1
redis-cli --user francois --pass mypassword get strkey
# Mais pas les autres
redis-cli --user francois --pass mypassword sadd setkey value
# Ni les commandes générales
redis-cli --user francois --pass mypassword info
# Interdiction des commandes d'écriture
redis-cli acl setuser francois reset on '>mypassword' +@string -@write ~*
# Le compte ne peut plus exécuter de commandes d'écriture
redis-cli --user francois --pass mypassword set strkey value1
# Mais peut toujours lire les strings
redis-cli --user francois --pass mypassword get strkey
Restrictions d’accès aux données
Les règles peuvent limiter les données accessibles par des masques, préfixés par
le signe ~
.
# Accorder un accès global
redis-cli acl setuser francois reset on '>mypassword' +@all ~*
redis-cli --user francois --pass mypassword set mykey value1
redis-cli --user francois --pass mypassword set yourkey valuer2
redis-cli --user francois --pass mypassword set hiskey valuer3
# Limiter l'accès à mes clés et à tes clés
redis-cli acl setuser francois reset on '>mypassword' +@all ~my* ~your*
redis-cli --user francois --pass mypassword set mykey value1
redis-cli --user francois --pass mypassword set yourkey valuer2
redis-cli --user francois --pass mypassword set hiskey valuer3
Restrictions sur les commandes
Une règle peut aussi accorder ou retirer des droits sur des commandes
spécifiques avec les signes +
et -
suivis du nom de la commande.
# Accorde un droit de lecture seule sur les strings et les TTL
redis-cli acl setuser francois reset on '>mypassword' -@all +get -set +ttl -expire -del +exists ~*
# Le compte ne peut pas écrire
redis-cli --user francois --pass mypassword set strkey value1
# Ni changer les TTL
redis-cli --user francois --pass mypassword expire strkey 60
# Mais il peut consulter les valeurs
redis-cli --user francois --pass mypassword get strkey
# Et les TTL
redis-cli --user francois --pass mypassword ttl strkey
Importance de l’ordre des règles
L’ordre des règles est important. Elles sont évaluées de gauche à droite. Par exemple, une liste peut accorder les droits pour toutes les commandes sur les hash puis retirer celles qui modifient les données.
# Accès total sur les hash, en retirant les écritures
redis-cli acl setuser francois reset on '>mypassword' -@all +@hash -@write ~*
# Une écriture échoue
redis-cli --user francois --pass mypassword hset hashkey field1 value1 field2 value2
# Interdictions des écriture, puis ajout d'un accès total sur les hash
redis-cli acl setuser francois reset on '>mypassword' -@all -@write +@hash ~*
# La révocation est inutile
redis-cli --user francois --pass mypassword hset hashkey field1 value1 field2 value2
Revenons à notre exemple
Création des comptes
Nous avons besoin de six comptes protégés par mot de passe avec différentes permissions.
- orders-update : droit complet de manipuler les hash et list, limité aux clés commençant par order
- orders-invoice : accès identique, mais en lecture seule
- david : comme pour le microservice orders-invoice
- denis : comme pour david
- paul : identique au microservice orders-update pour pouvoir corriger les données
- angelina : accès aux commandes d’administration, mais pas de manipulation des donées, ni aux clés
Notre base “orders” peut révoquer les permissions sur toutes les commandes, puis accorder les permissions sur les commandes manipulant les hash et les lists, exclure les commandes dangereuses à un utilisateur “order-update” identifié par un mot de passe. Et ce, sur toutes les clés commençant par “order:”. Ce microservice pourra se connecter avec son propre identifiant et sera limité aux commandes et clé dont il a besoin.
redis-cli acl setuser order-update reset on '>order-update' -@all +@hash +@list -@dangerous ~order:*
Le microservice “order-invoice” a besoin des mêmes permissions, auxquelles on retire l’accès aux commandes d’écriture.
redis-cli acl setuser order-invoice reset on '>order-invoice' -@all +@hash +@list -@dangerous -@write ~order:*
David et Denis ont besoin des mêmes permissions en lecture seule.
redis-cli acl setuser david reset on '>david' -@all +@hash +@list -@dangerous -@write ~order:*
redis-cli acl setuser denis reset on '>denis' -@all +@hash +@list -@dangerous -@write ~order:*
Paul, comme chef de projet, doit pouvoir modifier les valeurs.
redis-cli acl setuser paul reset on '>paul' -@all +@hash +@list -@dangerous ~order:*
Enfin, Angélina a besoin d’accéder aux commandes d’administration uniquement pour éventuellement vider la base.
redis-cli acl setuser angelina reset on '>angelina' +@admin +@dangerous
Désactivation du compte anonyme par défaut
Ce compte est un compte de repli pour attribuer des permissions par défaut lorsqu’aucune authentification ne s’est produite ou a réussi. Ce compte doit être limité. La seconde exécution devrait échouer.
redis-cli acl setuser default reset +info
redis-cli acl setuser default reset +info
Il peut aussi être désactivé. Il pourra uniquement exécuter la commande AUTH
pour s’authentifier. La seconde exécution devrait échouer.
redis-cli acl setuser default off
redis-cli acl setuser default off
À partir de maintenant, le seul administrateur disponible pour changer les permissions est… Angélina.
Tests des privilèges
Le moyen le plus simple pour tester est d’exécuter le jeu de commandes suivant avec chacun des comptes. Nous testons d’abord que l’ compte peut lire et écrire des clé de type string, de type hash et de type list. Enfin, nous testons la disponibilité de la commande INFO pour connaître le nombre de clés dans la base et la commande FLUSHALL pour vider la base.
redis-cli --user angelina --pass angelina << EOF
set key value
get key
hset order:key field1name field1value field2name field2value
hgetall order:key
lpush order:key:sub value1
lpush order:key:sub value2
llen order:key:sub
lpop order:key:sub
info keyspace
flushall
info keyspace
EOF
Compte anonyme
Ce compte ne devrait pouvoir exécuter aucune de ces commandes, sauf éventuellement la commande INFO si vous avez décidé de la lui laisser.
Microservice order-update
Ce compte ne devrait pas pouvoir accéder aux clés de type STRING, can les commandes ne lui sont pas accordées et car le nom de la clé ne correspond pas à ceux autorisés. Il devrait pouvoir lire et écrire les HASH et les LIST, car il a accès à ces commandes et à ces clés. En revanche, il ne doit pas pouvoir vider la base.
Microservice order-invoice
Ce compte dispose exactement des mêmes permissions, sauf en ce qui concerne les commandes d’écriture qui doivent donc échouer. On note que la commande LPOP est une commande combinant à la fois une lecture et une écriture, pour retirer l’élément lu, et qu’elle échoue.
Développeur David
David et Denis ont les mêmes permissions que order-invoice
.
Chef de projet Paul
Paul dispose des mêmes permissions que order-update
.
Administrateur Angelina
Angélina n’a aucun droit d’exécution sur les commandes de manipulation des clés, SET, GET, HSET, HGET, LPUSH, LPOP, qui échoueront. Mais elle peut consulter le nombre d’enregistrements de la base et vider la base.
Gestion de la sécurité à l’échelle
Les applications, développeurs, chefs de projets et admins sont identifiés par leurs propre identifiants et disposent de permissions spécifiques sur les commandes et les données. Mais que se passe-t-il lorsque des microservices sont ajoutés, avec leurs bases de données, lorsque des développeurs changent de projet, lorsque les équipes recrutent, que des employés s’en vont, qu’une base Redis est ajoutée pour servir de bus de message PubSub entre tous les microservices…. Un cauchemard à maintenir, mais Redis peut aussi gérer ce type de situation avec une gestion par role (RBAC) décrite dans le prochain épisode.
Supports et liens
Lien | Description |
---|---|
Video | Enregistrement vidéo de la démonstration |