Contrôle d'accès aux index ElasticSearch par certificat numérique

Sécurité de l'information
Contrôle d'accès aux index ElasticSearch par certificat numérique

ElasticSearch

ElasticSearch est une suite de solutions (ElasticSearch, LogStash, Kibana) Open Source permettant l'indexation, la transformation (ETL) et la visualisation de données structurées et non structurées. Le tout en temps-réel et en environnement distribué. ElasticSearch a été initialement développé sur la base du moteur Apache Lucene.

Ses performances, son architecture distribuée, sa "scalabilité" ou encore ses API RESTful en font une solution de choix pour traiter de gros volumes de données (des logs par exemple). Son mode de fonctionnement permet d'envisager une intégration "from-scratch" ou d'interfacer la solution avec une infrastructure de recherche déjà en place.

Ce papier n'a pas pour but d'expliquer le fonctionnement d'ElasticSearch ni même d'aborder ses multiples options de configuration, mais simplement de faire un petit retour d'expérience sur une technique de sécurisation des accès.

Deux modes de communication

Au sein d'un cluster ElasticSearch, les noeuds communiquent entre eux via un module de transport TCP natif (ports TCP 9300-9400 par défaut). Ce module de transport peut également être appelé par des API clients afin d'accéder aux données.

Ceci dit, le mode de communication privilégié pour interagir avec des composants tiers (exemple : Un serveur Web avec un formulaire de recherche) sera HTTP via des requêtes REST.

La problématique de l'ouverture d'un cluster ES sur l'extérieur

Tant que les noeuds ES restent confinés au sein d'une DMZ avec un filtrage réseau strict (ex : Solution interne pour centraliser les logs, accessible uniquement aux administrateurs), la sécurité du cluster peut être jugée suffisante.

En revanche, dès que l'on envisage l'ouverture du cluster sur l'extérieur (publication du contenu pour des utilisateurs) il devient indispensable de contrôler strictement ce qui peut être fait (indexation, recherche, suppression...).

La sécurisation dépasse largement le cadre de ce papier (est bien malin celui qui s'aventure sur ce terrain là, car les techniques de sécurisation dépendent directement de l'organisation du cluster et de la typologie des index utilisés). Je vous invite toutefois à lire les articles suivants qui introduisent les concepts de base pour sécuriser un cluster ES :

Pour résumer les thématiques abordées :

  1. Désactiver les scripts dynamiques (activés par défaut)
  2. Limiter les opérations pouvant être effectuées sur les index
  3. Prévenir les attaques DOS par saturation de ressources mémoire
  4. Positionner correctement les protections CORS (Cross Origin Ressource Sharing)
  5. Isoler les clusters

Caution

Comme n'importe quel logiciel, la configuration d'ES présente un certain nombre de vulnérabilités par défaut : tout est ouvert et tout est possible.

Par ailleurs, ES n'implémente pas directement la notion d'utilisateur.

Dès lors, toute personne capable d'effectuer une requête HTTP sur un noeud ES dispose des privilèges d'administration et peut donc effecuter n'importe quelle opération.

Des solutions existent sous forme de plugins. On trouvera  notamment le plugin salyh / elasticsearch-security-plugin (https://github.com/salyh/elasticsearch-security-plugin ) qui étend les capacités d'ES pour :

  • Authentifier les utilisateurs (Kerberos, NTLM, PKI/SSL/TLS, filtrage sur IP)
  • Effectuer un contrôle d'accès très fin sur les documents ES (AAA, SPNEGO, ACL, ...)

L'inconvénient de ce plugin (avis personnel) est qu'il s'appuie sur un serveur Tomcat embarqué dans Elasticsearch... ce qui est un peu lourd et "contre-nature" : laissons les solutions de filtrage filtrer et laissons ES indexer et rechercher à la vitesse de la lumière. Après tout, dans la plupart des configurations, contrôler les accès à ES revient à filtrer les requêtes HTTP de l'api REST, non ?

Architecture générique pour filtrer les requêtes vers ElasticSearch

Ca ne vous viendrait pas à l'idée (j'espère :) ) d'ouvrir un serveur SQL  sur Internet ? Pas plus que cela ne vous viendrait à l'idée d'exposer sur Internet une console Web (PHPMyAdmin par exemple) pour le gérer. Pourtant, c'est le fonctionnement par défaut de la suite Elasticsearch.

Exemple avec Kibana :

Kibana-Elasticsearch

Le bon sens impose (c'est ce que propose le plugin présenté ci-dessus) d'ajouter un serveur mandataire afin de filtrer les requêtes vers le cluster ES. Un tel serveur  peut facilement être déployé sur la base d'Apache ou Nginx.

Les intérêts du serveur proxy sont multiples :

  • Limitation des méthodes HTTP disponibles (ex : désactiver  les méthodes POST/DELETE)
  • Filtrage sur l'IP source
  • Authentification des utilisateurs en amont
  • Contrôle d'accès aux URI
  • Firewall applicatif pour limiter (liste blanche) très précisément la nature des requêtes envoyées à ES
  • Journalisation de tous les accès à ES
  • Et beaucoup plus si affinité...

Sur le point relatif au contrôle d'accès, il est possible de faire beaucoup de choses à moindre frais au niveau du serveur proxy, notamment contrôler finement ce que peut faire un utilisateur sur les index et éventuellement bloquer en sortie (inspection de contenu) si on détecte un document avec un index ou un tag "sensible".

Exemple de contrôle d'accès aux index par certificat numérique sous Apache

Disclaimer

L'exemple proposé ici s'appuie sur  une authentification des utilisateurs par certificat numérique et un contrôle d'accès strict aux index pour chaque utilisateur. L'intérêt de l'approche réside dans sa simplicité (pas besoin de déclarer explicitement chaque ACL sur chaque index pour chaque utilisateur).

La technique repose sur l'utilisation de modules Apache de réécriture (mod_rewrite) et de proxy (mod_proxy_http). Dans cet exemple, nous allons faire en sorte de garantir qu'un utilisateur donné (username) ne pourra accéder qu'aux index de la forme username-xxx.

Avec cette règle, toute tentative d'accès à l'interface de recherche sera filtrée par le script esfilter.pl. Ce script sera appelé avec 2 paramètres :

  • L'URL de recherche, comprenant les index demandés, les types et les arguments éventuels
  • Le nom de l'utilisateur (champ 'CN' du certificat numérique)

Côté script de filtrage, c'est assez trivial à réaliser. Voici un proof of concept, le code a été épuré et formaté spécifiquement pour l'exemple.

L'exemple propose ici un script PERL, mais il est évidemment possible d'utiliser tout autre script... et notamment ceux issus de votre Framework Django ou RoR préféré. La gestion des droits peut ainsi être effectuée depuis votre Framework et le filtre bénéficie d'un accès à votre modèle de données.

Jérémie Jourdin, Responsable R&D, Advens