Administration Hadoop multitenant avancée - protection de Zookeeper
5 juil. 2017
Ne ratez pas nos articles sur l'open source, le big data et les systèmes distribués, fréquence faible d’un email tous les deux mois.
Zookeeper est un composant critique au fonctionnement d’Hadoop en haute disponibilité. Ce dernier se protège en limitant le nombre de connexions max (maxConns=400). Cependant Zookeeper ne se protège pas intelligemment, il refuse les connexions une fois le seuil atteint. Dans ce cas les composants cœur (HBase RegionServers/HDFS ZKFC) ne pourront plus initialiser une connexion et le service sera alors dégradé voir indisponible !
Or il est très facile de faire une attaque de type DoS sur Zookeeper. D’autre part ces attaques sont souvent involontaires. Il suffit qu’un développeur manque de vigilance et lance un code custom qui ouvre des sessions zookeeper en boucle sans les fermer. Dans ce cas zookeeper est compromis, et l’ensemble des composants avec lui.
Solutions
Plusieurs contournements peuvent être mis en place, indépendamment ou conjointement.
Utilisation des Observers
Les observers sont des nœuds zookeepers particuliers :
- Ils ne participent pas au Quorum
- Ils se synchronisent sur les nœuds participants
- Ils transfèrent les requêtes en écriture sur les nœuds participants
Ils permettent donc d’augmenter le nombre de nœuds sans ralentir le processus d’élection.
Utilisation de iptables
Il est possible de se protéger des DoS externes via iptables. En effet nous pouvons limiter le nombre de connexions sur le port de zookeeper (2181) par adresse IP. Cela permet de mettre une limite inférieure au maxConns de Zookeeper et ainsi bloquer une adresse particulière sans bloquer l’accès depuis une autre machine.
Exemple
Imaginons la topologie de cluster suivante :
- 3 edge nodes :
edge1.adaltas.com, edge2.adaltas.com edge3.adaltas.com
- 3 master nodes :
master1.adaltas.com, master2.adaltas.com, master3.adaltas.com
- n worker nodes : n’interviennent pas dans ce cas
- Ces machines se situent dans le sous réseau :
10.10.10.0/24
On utilise les masters nodes comme le quorum électif et les edges comme observers pour monter en charge.
NB : le nombre pair de nœuds n’est pas un problème, seul 3 sont participants
Configuration Zookeeper
On met en place ces configurations (/etc/zookeeper/conf/zoo.cfg) :
Sur les noeuds master :
clientPort=2181
maxClientCnxns=200
peerType=participant
server.1=master1.adaltas.com:2888:3888
server.2=master2.adaltas.com:2888:3888
server.3=master3.adaltas.com:2888:3888
server.4=edge1.adaltas.com:2888:3888
server.5=edge2.adaltas.com:2888:3888
server.6=edge3.adaltas.com:2888:3888
Sur les noeuds edge :
clientPort=2181
maxClientCnxns=200
peerType=observer
server.1=master1.adaltas.com:2888:3888
server.2=master2.adaltas.com:2888:3888
server.3=master3.adaltas.com:2888:3888
server.4=edge1.adaltas.com:2888:3888
server.5=edge2.adaltas.com:2888:3888
server.6=edge3.adaltas.com:2888:3888
Sur les nœuds master, on interdit la communication avec des machines externes sur le port 2181 (seul le réseau local est autorisé) via la règle iptables suivante :
-A INPUT -m state --state NEW -m tcp -p tcp -s 10.10.10.0/24 --dport 2181 -j ACCEPT
Ainsi ces instances zookeeper ne sont accédées que par nos services et processus internes.
Sur les nœuds edges, on limite la communication avec des machines externes sur le port 2181 à 100 connexions simultanées par IP via la règle :
iptables -A INPUT -p tcp --syn --dport 2181 -m connlimit --connlimit-above 100 --connlimit-mask 32 -j REJECT --reject-with tcp-reset
Configuration Hadoop
Pour les services Hadoop (HDFS ZKFC, HBase Master, etc), on spécifie la chaine de connexion suivante :
master1.adaltas.com:2181,master2.adaltas.com:2181,master3.adaltas.com:2181
Pour les configurations “clientes” (Containers YARN, hbase client, applications tierces, etc.) on spécifie la chaîne :
edge1.adaltas.com:2181,edge2.adaltas.com:2181,edge3.adaltas.com:2181
Ainsi, lorsqu’un job ou une application externe se lance, ce dernier ne peut pas saturer le quorum et ne compromet pas l’état du cluster.
Aller plus loin, silotage des nœuds observers
Si une application externe “frauduleuse” utilise la chaine edge1.adaltas.com:2181,edge2.adaltas.com:2181,edge3.adaltas.com:2181
alors il est possible qu’elle sature les 3 nœuds observers. Ainsi, bien que le cluster reste stable, certains services seront indisponibles, puisque les clients ne pourront plus consulter Zookeeper.
On peut limiter l’impact de la saturation des observers en décomposant la chaîne en plusieurs sous-chaînes que l’on spécifiera dans les configurations clientes. Exemple :
- Chaîne 1 :
edge1.adaltas.com, edge2.adaltas.com
- Chaîne 2 :
edge1.adaltas.com, edge3.adaltas.com
- Chaîne 3 :
edge2.adaltas.com, edge3.adaltas.com
Ainsi si la chaîne 1 est saturée, edge3 reste disponible. Les applications ciblant la chaîne 2 et 3 ne seront donc pas bloquées.