mardi 29 janvier 2013

NAGIOS : Vérifier l'état du pare-feu iptables

L'environnent technique des serveurs est le suivant :
  • OS : OpenSuse 12.2
  • Supervision : NAGIOS 3.4
  • Pare-feu : iptables

0°) Introduction

L'objectif de cette article est de vous faire partager un petit outil que j'ai développé pour nos besoins propres, concernant la supervision de la prise en compte des règles d'accès à notre réseau via iptables avec NAGIOS.
Avec la politique de sécurité que nous avions choisis de mettre en place, il était nécessaire de s'assurer que nos règles étaient bien appliquées lors du démarrage de nos serveurs.
Le script est assez basique et contrôle juste le nombre de règles appliquées, déclenchant une alerte lorsque ce nombre est inférieur à un seuil prédéfini.

1°) Les motivations.

Depuis quelques années maintenant, j'ai choisi de configurer sur chacun des nos serveurs des règles de sécurité basées sur iptables. Le mise en place n'a pas été évident et la compréhension des règles a pris pas mal de temps, même en ayant une bonne connaissance du réseau et des trames IP. Mais bon, à l'arrivé nous avons un résultat qui tient la route (du moins c'est l'impression que ça donne !!!).

Seul petit bémol: une fois les règles mises au point, j'avais eu la mauvaise idée de démarrer le pare-feu au moment du boot. Et bien sur, un jour (un très mauvais jour), une erreur dans mon fichier contenant mes règles a bloqué l'ensemble des accès réseaux sur un serveur de production....
De coup, impossible d’accéder à la machine, m'obligeant à me déplacer directement en salle machine pour corriger ce problème en redémarrant le système en mode single et en désactivant le script appliquant les règles de notre pare-feu.

Pas vraiment pratique... du coup j'ai décidé d'appliquer les règles à la main après chaque démarrage. Pas très satisfaisant, mais beaucoup plus sur. Il est souvent nécessaire de faire des compromis en informatique.

2°) Dans le vif du sujet.

Malheureusement, il arrive (pas souvent, mais ça arrive) que les serveurs redémarrent (panne électrique, bug du kernel, mauvaise manipulation des techniciens,...). Du coup Il devenait nécessaire que nous soyons prévenu lorsque ces règles n'étaient pas appliquées.
Comme tous bon informaticien qui se respect, avant de ré-inventer la roue, je me suis mis à chercher un plugin plus ou moins officiel de NAGIOS. A ma grande surprise, je n'ai pas trouvé grand chose. Du moins, en restant diplomate et en modérant mes propos, je dirais que je n'ai pas trouvé de plugin qui pouvait répondre à mes attentes ou alors je n'ai pas été assez malin pour arriver à faire marcher le plugin que j'avais trouvé (check_iptables_status.sh).

Du coup, il ne me restait plus qu'à en développer un... m'inspirant malgré tout du plugin de rhoml, je suis partie sur le même principe : tester le nombre de règles appliquées et déclencher une alerte si on est en dessous d'un certain seuil.

Voici le détail des étapes pour la mise en place de ce script.
cd /usr/lib/nagios/plugins
vi check_firewall.sh
Copier le contenu

#!/bin/sh
#
# Author: Alain TOMASIAN
# Date: 25 Dec. 2012
# Description: Check if the firewall based on iptables is running
#
. /usr/lib/nagios/plugins/utils.sh
print_usage() {
echo "Usage: check_firewall.sh "
}
# Make sure the correct number of command line
IPTABLES_CMD=/usr/sbin/iptables
RESULT=`sudo $IPTABLES_CMD -L -n | wc -l`
if [ $RESULT -lt 10 ] ; then
   echo "FW CRITICAL : The firewall hasn't been started : number of  rules lines = $RESULT"
   exit $STATE_CRITICAL
elif [ $RESULT -lt 100 ] ; then
   echo "FW WARNING : May be the firewall hasn't been started : number of rules lines = $RESULT"
   exit $STATE_WARNING
else
   echo "FW OK : The firewall has been started : number of rules lines = $RESULT"
   exit $STATE_OK
fi
Le point délicat est qu'il faut autoriser l'utilisateur "nagios" à exécuter la commande "iptables". Pour cela, il est nécessaire de passer par sudo :
# sudoedit /etc/sudoers

Ajouter la ligne suivante dans la partie :
    ##
    ## User privilege specification
    ##
    nagios  ALL = (root) NOPASSWD:/usr/sbin/iptables -L -n    
et sauvegarder le fichier.

A cette phase du projet, il n'est pas vraiment facile de tester la commande avec l'utilisateur nagios, car normalement cette utilisateur n'a pas de shell valide....
Pour valider notre travail, il faut continuer la phase configuration, car le problème viendra uniquement lorsqu'on essaiera d'utiliser la commande via nrpe (dans notre cas de figure).

A présent il faut installer la commande au niveau de nrpe et au niveau de nagios.
Sur le serveur à superviser, il faut aujouter dans le fichier de configuration /etc/nagios/nrpe.cfg la ligne suivante dans la description des commandes :
    vi /etc/nagios/nrpe.cfg
    command[check_firewall]=/usr/lib/nagios/plugins/check_firewall.sh

Puis redémarrer nrpe :
    /etc/init.d/nrpe restart

Sur le serveur de supervision, il faut aujouter dans le fichier /etc/nagios/objects/commands.cfg les lignes suivantes :

    vi /etc/nagios/objects/commands.cfg
    # 'check_remote_firewall' command definition
define command { command_name check_remote_firewall command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c check_firewall } # 'check_firewall' command definition define command { command_name check_firewall command_line $USER1$/check_firewall.sh }
Faire un check de la config nagios avant de relancer le serveur :
    /etc/init.d/nagios check
Starting configuration check - passed configuration check done
    /etc/init.d/nagios restart
Shutting down Nagios           done
Starting Nagios                done


A présent, nous pouvons effectuer un test de connexion avec un check_nrpe pour valider le mode de fonctionnement :
# /usr/lib/nagios/plugins/check_nrpe -H xx.xx.xx.xx -c check_firewall
FW OK : The firewall has been started : number of rules lines = 671


Le reste n'est plus qu'une simple formalité car il faut juste configurer sur le serveur de supervision les services pour mettre un check sur les machine à superviser.
Le résultat en image :




3°) Conclusions.


Ce plugin est assez basique et nécessiterait certaines améliorations que j'apporterai peut-être si mon emploi du temp me le permet.... Mais pour l'instant il me rend un grand service en vérifiant que mes règles de sécurités soient bien appliquées.

mercredi 23 janvier 2013

Configuration SSL pour MySQL sous OpenSuse

L'environnent technique des serveurs est le suivant :
  • OS : OpenSuse 12.1
  • Base de données : MySQL Community Server 5.5.28
  • Librairie SSL : OpenSSL 1.0 

0°) Introduction.

Comme je l'ai expliqué dans mon précédent post (Serveurs physiques Versus Serveurs virtuels), nous avons migrer nos serveurs physiques vers des serveurs virtuels. Un des premiers dommages collatéral a été que l'ensemble de nos serveurs ne soient plus sur la même plage de réseau IP et que nous ne puissions plus installer une réseau privé (192.168.0.0/16) entre nos serveurs.

Bien sur, j'aurais pu mettre en place un réseau privé virtuel (VPN) pour faire transiter l'ensemble du trafic interne. Mais j'ai eu la flemme car la plus part des échanges sont fait à travers du ssh et le seul trafic en clair qui était concerné était la réplication de mes bases de données sous MySQL. Donc, je me suis lancé dans la mise en place de connexions sécurisé via SSL pour MySQL.
A priori (d'après ce que j'aivais pu lire) MySQL crypte par défaut l'échange des mots de passe lors de l'établissement d'une connexion. Par contre, une fois la connexion établie, les données transitaient en clair. Même si ces données ne revêtent pas un caractère hyper-sensible, certaines informations doivent demeurer confidentielles. Il devient alors nécessaire de crypter l'ensemble des échanges afin de pouvoir garantir la confidentialité des données échangées.

 

 1°) Dans le vif du sujet.

Pour réaliser cette mise en place, je me suis fortement inspiré de l'article "Sécurisez votre serveur MySQL sous Unix".

Même si on trouve pléthore d'articles sur le net, je vais quand même détailler les différentes étapes que effectuer car j'ai rencontré quelques difficultés qui n'ont pas été toujours simple à résoudre.

 

 1.1°) Création des certificats SSL.

Le premier travail consiste à créer les certificats qui vont être utilisés par MySQL pour le cryptage des communications entre les serveurs.
Il faut commencer par créer un premier certificat qui va nous servir à signer les 2 autres certificats (un certifcat serveur et un certificat client). C'est notre autorité de certification.  Le premier piège est qu'il est indispensable que le CN (Common Name) du certifcat de notre autorité de certification soit différent des autres certificats. Cela semble évident, mais lorsque on autosigne un certificat, on a tendance à donner le même CN. Du moins c'est ce que j'ai fait et j'ai eu énormément de mal ensuite à faire fonctionner la connexion SSL avec MySQL. Voici les lignes de commande pour la création des différents certificats :
diplodocus# cd /etc/ssl/certs
diplodocus# mkdir mysql
diplodocus# cd mysql
diplodocus# openssl req -new -x509 -keyout ca-key.pem -out ca-cert.pem -days 3600

Generating a 1024 bit RSA private key
.......................++++++
...++++++
writing new private key to 'ca-key.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:Ile de France
Locality Name (eg, city) []:PARIS
Organization Name (eg, company) [Internet Widgits Pty Ltd]:NAOS Technologies
Organizational Unit Name (eg, section) []:MySQL
Common Name (eg, YOUR name) []:www.naos.com
 
<--- ATTENTION : il est très important que le common name du CA soit différent de ceux des certificats (Voir erreur sinon en bas de page).

Email Address []:alain.tomasian@naos.com

diplodocus# openssl req -new -keyout server-key.pem -out server-req.pem -days 3600
Generating a 1024 bit RSA private key
.....++++++
..........++++++
writing new private key to 'server-key.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:Ile de France
Locality Name (eg, city) []:PARIS
Organization Name (eg, company) [Internet Widgits Pty Ltd]:NAOS Technologies
Organizational Unit Name (eg, section) []:MySQL
Common Name (eg, YOUR name) []:*.naos.com
Email Address []:alain.tomasian@naos.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:NAOS Technologies


- On signe le certificat serveur avec la clé de l'autorité de certification que l'on vient de créer :
diplodocus# openssl x509 -req -in server-req.pem -days 3600 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
Signature ok
subject=/C=FR/ST=Ile de France/L=PARIS/O=NAOS Technologies/OU=MySQL/CN=*.naos.com/emailAddress=alain.tomasian@naos.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:
Generating a 1024 bit RSA private key
...............++++++
..............................++++++
writing new private key to 'client-key.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:FR
State or Province Name (full name) [Some-State]:Ile de France
Locality Name (eg, city) []:PARIS
Organization Name (eg, company) [Internet Widgits Pty Ltd]:NAOS Technologies
Organizational Unit Name (eg, section) []:MySQL
Common Name (eg, YOUR name) []:*.naos.com
Email Address []:alain.tomasian@naos.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:NAOS Technologies


- On signe le certificat client avec la clé de l'autorité de certification que l'on vient de créer :
diplodocus# openssl x509 -req -in client-req.pem -days 3600 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
Signature ok
subject=/C=FR/ST=Ile de France/L=PARIS/O=NAOS Technologies/OU=MySQL/CN=*.naos.com/emailAddress=alain.tomasian@naos.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:


- On supprime la pass phrase sur les deux certificats :
diplodocus# openssl rsa -in server-key.pem -out server-key.pem
Enter pass phrase for server-key.pem:
writing RSA key
diplodocus# openssl rsa -in client-key.pem -out client-key.pem 
Enter pass phrase for client-key.pem:
writing RSA key

Avant de continuer, on vérifie que les certificats sont ok en passant la commande :
diplodocus# openssl verify -CAfile ca-cert.pem server-cert.pem
server-cert.pem: C = FR, ST = Ile de France, L = PARIS, O = NAOS Technologies, OU = MySQL, CN = *.naos.com, emailAddress = alain.tomasian@naos.com
error 18 at 0 depth lookup:self signed certificate
OK

Si vous avez le résultat ci-dessus, c'est que vous avez un souci. Sinon vous devriez avoir :
diplodocus# openssl verify -CAfile ca-cert.pem server-cert.pem

server-cert.pem: OK
diplodocus# openssl verify -CAfile ca-cert.pem client-cert.pem

client-cert.pem: OK

 

1.2°) Configuration du serveur MySQL.

Voilà, les certificats sont créés, il nous reste maintenant à configurer MySQL pour qu'il puisse gérer les transactions cryptées.
Dans le fichier /etc/my.cf, ajoutons dans le bloc [mysqld] les lignes suivantes :
ssl
ssl-cipher=DHE-RSA-AES256-SHA
ssl-ca=/etc/ssl/certs/mysql/ca-cert.pem
ssl-cert=/etc/ssl/certs/mysql/server-cert.pem
ssl-key=/etc/ssl/certs/mysql/server-key.pem

et dans le bloc [client], ajoutons les lignes suivantes :
ssl-ca = /etc/ssl/certs/mysql/ca-cert.pem
On redémarre le serveur MySQL :
diplodocus# /etc/init.d/mysql restart
Restarting service MySQL
Shutting down service MySQL done
Starting service MySQL done

Si tous se passe bien, on devrait avoir le résultat suivant sous la console MySQL:
diplodocus# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.28-log Source distribution
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 

mysql> SHOW VARIABLES LIKE '%ssl%';
+-----------------+-----------------------------------------+
| Variable_name   | Value                                   |
+-----------------+-----------------------------------------+
| have_openssl    | YES
                                     |
| have_ssl        | YES
                                     |
| ssl_ca          | /etc/ssl/certs/mysql/ca-cert.pem        |
| ssl_capath      | /etc/ssl/certs/mysql                    |
| ssl_cert        | /etc/ssl/certs/mysql/server-cert.pem    |
| ssl_cipher      | DHE-RSA-AES256-SHA                      |
| ssl_key         | /etc/ssl/certs/mysql/server-key.pem     |
+-----------------+-----------------------------------------+
7 rows in set (0.01 sec)

 

1.3°) Tester la connexion SSL en local.

A présent, il faut tester la connexion ssl. D'abord, nous allons tester le fonctionnement en local. Pour cela nous avons besoin de créer un utilisateur qui ne peut se connecter qu'en utilisant une connexion sécurisée.
mysql> GRANT ALL PRIVILEGES ON *.* TO 'bidon'@'localhost' IDENTIFIED BY "xxxxxxxx" REQUIRE SSL;
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges ;
Query OK, 0 rows affected (0.00 sec)

Pour tester la connexion il suffit de passer la commande suivante, pour une connexion simple :
# mysql -u bidon -p
Enter password:
ERROR 1045 (28000): Access denied for user 'test'@'localhost' (using password: YES)

On peut remarquer que la connexion échoue. Maintenant en utilisant une connexion sécurisée :
# mysql -u bidon -p --ssl-ca=/etc/ssl/certs/mysql/ca-cert.pem
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 24
Server version: 5.5.25-log Source distribution
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> quit

Et ô miracle ça fonctionne. Maintenant, tentons la connexion sécurisée depuis un serveur distant.

 

 1.4°) Tester la connexion SSL depuis un serveur distant. 

Notre serveur local est nommé "diplodocus" et le serveur distant "triceratops". Sur diplodocus il faut autoriser un utilisateur à se connecter en SSL depuis triceratops :
mysql> GRANT ALL PRIVILEGES ON bidon.* TO 'bidon'@'triceratops' IDENTIFIED BY "xxxxxxxxx" REQUIRE SSL;
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges ;
Query OK, 0 rows affected (0.00 sec)

Il faut à présent copier l'ensemble des certificats situé dans le répertoire /etc/certs/mysql/ sur le même répertoire sur triceratops :
triceratops# cd /etc/ssl/certs/mysql
triceratops# scp root@diplodocus.naos.com:/etc/ssl/certs/mysql/client-key.pem .
triceratops# scp root@diplodocus.naos.com:/etc/ssl/certs/mysql/server-cert.pem .
triceratops# scp root@diplodocus.naos.com:/etc/ssl/certs/mysql/client-cert.pem .

Un fois ce travail effecuté, il suffit de tester la connexion distante :
triceratops# mysql -u bidon -p --ssl-ca=/etc/ssl/certs/mysql/ca-cert.pem -h diplodocus
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 25
Server version: 5.5.25-log Source distribution
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> quit
Bye


Et voilà, le tour est joué...

 

2°) Analyse du trafic réseau pour valider la connexion SSL.

Mais bon comment être sur maintenant que les échanges entre le client et le serveur sont bien crypté ?
Ben, il suffit de regarder ce qui se passe sur le réseau entre les deux machine. Pour cela, j'ai trouvé sur le net un outil permettant d'analyser les paquets liés au trafic réseau MySQL sur une interface : mysqlsniffer.
Voici les étapes pour installer, compiler et utiliser mysqlsniffer (inspiré de : Utilisation de mysqlsniffer) :
diplodocus# mkdir -p /usr/local/src/mysqlsniffer
diplodocus# cd /usr/local/src/mysqlsniffer
diplodocus# wget hackmysql.com/code/mysqlsniffer.tgz
diplodocus# tar xfvz mysqlsniffer.tgz
diplodocus# gcc -O2 -lpcap -o mysqlsniffer mysqlsniffer.c packet_handlers.c misc.c

mysqlsniffer.c:26:18: fatal error: pcap.h: No such file or directory

Là, on se rend compte qu'il manque une librairie :
# zypper install libpcap-devel
# gcc -O2 -lpcap -o mysqlsniffer mysqlsniffer.c packet_handlers.c misc.c
# ls -lt

total 136
-rwxr-xr-x 1 root root 35223 Jan 22 15:50 mysqlsniffer

..............

Ensuite il faut lancer la commande et se connecter à la base distante depuis un autre console:# ./mysqlsniffer -p 3306 eth0
mysqlsniffer listening for MySQL on interface eth0 port 3306
.....................
::FRAGMENT START::
::FRAGMENT END::

......................

Les
::FRAGMENT START:: et ::FRAGMENT END:: montre que la connexion est cryptée, sinon on aurait :# ./mysqlsniffer -p 3306 eth0
mysqlsniffer listening for MySQL on interface eth0 port 3306
server > xx.xx.xx.xx.57842: ID 0 len 78 Handshake <proto 10 ver 5.5.28-log thd 18>
xx.xx.xx.xx.57842 > server: ID 1 len 80 Handshake (new auth) <user bidon db (null) max pkt 16777216>
server > xx.xx.xx.xx.57842: ID 2 len 7 OK <fields 0 affected rows 0 insert id 0 warnings 0>
xx.xx.xx.xx.57842 > server: ID 0 len 33 COM_QUERY: select @@version_comment limit 1
server > xx.xx.xx.xx.57842: ID 1 len 1 1 Fields
ID 2 len 39 Field: ..@@version_comment <type var string (253) size 19>
ID 3 len 5 End <warnings 0>
ID 4 len 20 || Source distribution ||
ID 5 len 5 End <warnings 0>
xx.xx.xx.xx.57842 > server: ID 0 len 18 COM_QUERY: SELECT DATABASE()
server > xx.xx.xx.xx.57842: ID 1 len 1 1 Fields
ID 2 len 32 Field: ..DATABASE() <type var string (253) size 34>
ID 3 len 5 End <warnings 0>
ID 4 len 1 || NULL ||
ID 5 len 5 End <warnings 0>
xx.xx.xx.xx.57842 > server: ID 0 len 5 COM_INIT_DB: bidon
server > xx.xx.xx.xx.57842: ID 1 len 7 OK <fields 0 affected rows 0 insert id 0 warnings 0>
server > xx.xx.xx.xx.44498: ID 0 len 72 Handshake <proto 10 ver 5.5.8 thd 72804>
xx.xx.xx.xx.44498 > server: ID 1 len 85 Handshake (new auth) <user bidon db bidon max pkt 1073741824>
server > xx.xx.xx.xx.44498: ID 2 len 7 OK <fields 0 affected rows 0 insert id 0 warnings 0>
xx.xx.xx.xx.44498 > server: ID 0 len 1 COM_STATISTICS
server > xx.xx.xx.xx.44498: ID 1 len 143 Uptime: 4611470 Threads: 1 Questions: 16883155 Slow queries: 1 Opens: 183 Flush tables: 1 Open tables: 152 Queries per second avg: 3.661
xx.xx.xx.xx.44498 > server: ID 0 len 1 COM_QUIT
xx.xx.xx.xx.57842 > server: ID 0 len 12 COM_QUERY: show tables
server > xx.xx.xx.xx.57842: ID 1 len 1 1 Fields
ID 2 len 86 Field: information_schema.TABLE_NAMES.Tables_in_bidon <type var string (509) size 64>
ID 3 len 5 End <warnings 0>
ID 4 len 5 End <warnings 0>
xx.xx.xx.xx.57842 > server: ID 0 len 1 COM_QUIT


Voilà, l'affaire est dans le sac.

 

3°) Conclusions

Nous voilà maintenant paré, pour mettre en place la réplication entre serveurs MySQL situés sur  réseaux différents. Il reste quand même évident que ce travail vous assure la confidentialité des données échangées, mais n'assure en aucun cas la sécurisation du serveur de base de données qu'est MySQL : c'est un autre sujet.... qui est lui lié à la mise en place d'un pare-feu et d'une vrai politique de sécurité réseau.

Quelques liens intéressant :
- Connexion sécurisée à MySQL (chicoree.fr).
- Sécurisez votre serveur MySQL sous Unix ( developpez.com).

mardi 15 janvier 2013

Serveurs physiques Versus Serveurs virtuels

0°) Introduction

L'objectif de cet article est de vous faire partager mon retour d'expérience sur la migration de l'hébergement de nos serveurs physiques vers un hébergement virtualisé.
Je me suis rendu compte à travers mes recherches que même si on parlait énormément de technologie "Cloud" et "IAAS", il n'était pas vraiment évident de si retrouver dans la jungle des offres disponibles, même pour un professionnel.
Il est possible que la problématique exposée dans cet article soit particulière et ne réponde pas à l'ensemble de vos interrogations. Mais globalement si vous gérez aujourd'hui des serveurs physiques et que vous louez une ou plusieurs baies dans une salle machine, cet article vous donnera un aperçu et surtout un exemple réussi de migration de serveurs physiques vers des serveurs virtuels.

1°) L'état des lieux

Depuis 1998, les serveurs de la société NAOS sont hébergés chez INTERNET-FR. Dans une de leurs salles machines ultra sécurisées, nous avons bénéficié pendant plus de 14 ans d'une qualité de services exceptionnelle. Que ce soit au niveau des caractéristiques techniques mises à notre disposition pour notre hébergement que de la qualité relationnelle avec les équipes techniques. A tel point qu'il ne nous était jamais venu à l'esprit de chercher une autre solution pour l'hébergement de nos serveurs.

Le seul point d'ombre à cela, c'est que nous n'avions pas accès à nos serveurs 24H/24 et 7J/7. Mais, nous avions fait avec. Les pannes étant assez rares, nous avons compensé ce léger souci d'accès par la mise en place de serveurs de secours (1 serveur de secours pour 2 serveurs en production) avec des procédures de bascule en cas de plantage, pour assurer à nos clients un taux de disponibilité le plus élevé possible. Concrétement, comme nous avions à notre disposition une plage de 32 adresses IP, nous avons attribués une adresse IP pour chaque service et une adresse IP pour chaque serveur. Ainsi, il suffisait de reconfigurer les cartes réseaux des serveurs de secours pour que les services soient relancés.

Cette stratégie avait quand même ses limites. En effet, il fallait être sûr que le serveur en panne ne soit pas redémarré, sinon des collisions et des pertes de paquets réseaux risquer de créer de gros souci si sur le même réseaux nous avions configuré la même adresse IP sur 2 cartes différentes.
Mais cela ne c'est jamais présenté.

Malheureusement, toute bonne chose a une fin. Fin Mai 2011, INTERNET-FR est racheté par la société PROSODIE. Jusque-là, pas d'affolement, même si nous nous posons pas mal de questions... L'inquiétude vient d'une annonce deux mois plus tard, mi-juin 2011 sur le rachat de PROSODIE par CAP GEMINI.  Là, nous comprenons que notre aventure avec notre hébergeur est sur sa fin....

Bon, c'est la vie....

Fataliste, même si à ce moment là, nos interlocuteurs privilégiers chez INTERNET-FR se veulent rassurants, nous entamons quand même à notre grand regret notre quête du Saint Graal : 

2°) A la recherche d'un nouvel hébergeur !

Avant d'entamer mes recherches, je fais un état des lieux des prestations que nous disposions afin d'essayer de trouver quelque chose d'approchant. Bien sur, nous avions conscience qu'il serait très difficile de retrouver l'équivalent rapport qualité/prix.
L'état des lieux fût assez rapide :
  • 6 serveurs (double alimentation 500Wx2, et oui les serveurs ne sont pas tous jeunes...)
  • 32 adresses IP
  • 2 routeurs (un réseau local + un réseau public)
  • 1 baie 42U
  • très bonne bande passante
Tant qu'à changer, autant aussi gommer les lacunes de notre précédent hébergement, donc en plus nous voulions :
  • accès à nos serveurs 24h/24 et 7j/7
  • reboot physique à distance
Voilà, YaPluKa

Je commence mes recherches en mars 2012 et elles s'avèrent très difficiles :
  1. Trouver des sociétés qui gèrent des salles machines d'hébergement sur Paris, Ile de France.
  2. Qui sont intéressées par louer 1 seule baie ou 1/2 baie.
  3. Dont le prix de la location n'est pas fonction de la consommation des ressources mais forfaitisé.
  4. Trouver des sociétés qui veulent faire un devis
  5. ...
Je me rends compte que c'est la jungle.... et j'ai énormément de mal a avoir un début de réponse, même en appelant directement les personnes. C'est assez exaspérant et surprenant. Malgré tous j'obtiens 2 devis, de la part de Céleste et de Téléhouse : un grand merci
Mais malheureusement leurs propositions ne correspondent pas à nos attentes.

Devant ce constat d'échec, nous devions changer de stratégie et commencer à penser à abandonner nos machines au profit de machines de locations chez un hébergeur. Là, du coup c'est beaucoup plus facile à trouver car les offres sur ce sujet sont pléthoriques...

3°) Dans le vif du sujet

Depuis quelques années maintenant, j'avais une position assez tranchée sur la mise en place de serveurs virtuels. Mes arguments (pour les environnement Linux) étaient les suivants :
  • Ajout d'un surcouche à l'OS : ce qui ne peut que pénaliser les performances.
  • Ajout d'un SPOF (Single Point Of Failure) : Mettre plusieurs serveurs virtuels sur une seule machine physique.
  • Démultiplication des serveurs : ce qui se traduit par l'accroissement du travail d'administration, de déploiement, de supervision, etc...
  • L'optimisation et la gestion des ressources physiques devient de plus en plus difficile et ce fait uniquement par accroissement des dites ressources...
Donc j'étais plutôt adepte d'optimiser les ressources d'une machine avec un bon OS plutôt que de multiplier l'installation de plusieurs serveurs.

Fin Septembre 2012 un événement va remettre à plat toutes mes convictions : un plantage hardware d'un serveur de production...
  • Impossible de rebooter, 
  • les délais d'intervention de mon hébergeur ont frôlé les 24h
  • la carte réseau du serveur continuait de répondre donc impossible de passer sur le serveur de secours. 
Bilan, chez NAOS on commence à se poser des questions sur l'hébergement de machines physiques. Pourquoi pas s'intéresser au marché de l'hébergement des serveurs virtuels ?
Là aussi, les offres sont pléthorique et nous avions du mal à nous y retrouver, et pourtant l'informatique c'est notre métier, je n'osais même pas imaginer si nous n'avions pas eu les compétences requises pour effectuer ce type de démarches....
Nous avions quand même une assez bonne idée de ce que nous cherchions et nous avions du mal à trouver chaussure à notre pied. Jusqu'à ce que je me rende compte en lisant mes emails, que la société GANDI (le registrar de l'ensemble de mes domaines) était un acteur assez actif dans le marché du Cloud et plus particulièrement dans le domaine du IAAS. Et, ô miracle, fin septembre 2012, GANDI annonce la mise à disposition de la distribution OpenSuse 12.1. Tous les signes étaient au vert pour faire notre choix...

Un tour d'horizon rapide du service proposé par GANDI me permet de constater dans un premier temps que cela peut répondre à nos attentes. Donc, il ne nous restait plus qu'à tester.

Et là, je commence à être assez bluffé par la simplicité et l'accessibilité du service. Comme à son habitude, GANDI travaille essentiellement sur le net. Donc, l'ensemble des opérations s'effectuent via une interface web, qui est assez simple et suffisamment ergonomique. Ce qui m'allait très bien :
  • Pas besoin d'attendre des semaines un hypothétique devis.
  • Aucun engagement dans le temps.
  • Une offre technique très claire et sans surprise.
  • Une offre financière claire et surtout très abordable.
  • ...
Le principe choisi est assez déroutant au début, mais on s'y habitue rapidement. En mode serveur, vous achetez des parts de ressources. A ce jour, une part correspond à :
  • 1 coeur
  • 512 Mo de mémoire
  • 12Go d'espace disque (SAS en Raid 10)
  • 10Mbps de bande passante

Bon, je ne vais pas décrire ici l'ensemble des avantages et des possibilités de la solution GANDI. Le mieux est de se rendre sur leur site pour le découvrir ...

De notre côté, après une quinzaine de jours de tests, nous avons complètement adopté la solution et pris la décision de migrer l'ensemble de nos services.
Avec cette expérience, j'ai remis mes convictions au goûs du jour et aujourd'hui, je commence (enfin! diront certains) à appréhender les bénéfices du cloud pour notre entreprise.

Plusieurs avantages pour nous, que je vais essayer d'énoncer et de commenter (peut-être pas de manière exhaustive) ci-dessous par degré d'importance  :

4°) Zéro serveurs physiques

Le fait de ne plus avoir de serveurs physiques, corrige deux freins majeurs dans notre mode de fonctionnement et dans nos offres de services.
Notre premier frein était lié au coût d'acquisition et de maintenance d'un serveur physiques. Lors de la mise en place de nouveaux services et/ou de propositions de nouvelles prestations, nous étions obligés :
  • d'intégrer dans nos coûts et/ou propositions, l'amortissement de l'achat des serveurs. Pour une proposition, il fallait demander à notre client, un engagement minimum de 36 mois (comptablement, c'est le délai nécessaire pour l'amortissement d'une machine). 
  • de contracter un crédit pour financer cet achat. 
  • de proposer des délais de mise en service pouvant s'étaler sur plusieurs mois (acceptation du crédit, délais de livraison des serveurs, mise en production des services, etc...).
  • de prévoir l'espace nécessaire dans notre baie d'hébergement et le cas échéant d'intégrer un coût supplémentaire de location d'une nouvelle baie.
Le second frein venait de la gestion des ressources de nos serveur et de la gestion de l'obsolescence de notre parc. Concernant l'optimisation des ressources, nous avions des serveurs qui étaient toujours surdimensionnés afin d'éviter de se retrouver sous-dimensionné après quelques mois d'exploitation. Il était très difficile après la mise en production de modifier les caractéristiques physiques d'un serveur :
  • difficulté d'accéder à la salle machine,
  • dans la majorité des cas, l'intervention nécessitait un arrêt des services,
  • risque non négligeable de générer des problèmes collatéraux suite à l'intervention.
Donc comme vous l'aurez compris, aujourd'hui, avec nos serveurs virtualisés, nous avons déporté l'ensemble des problèmes énoncés ci-dessus auprès de notre nouveau prestataire. Plusieurs gains financiers notables très rapidement:
  • réduction de notre TCO (notre coût de possession).
  • suppression de l'ensemble des contrats de maintenance hardware de nos serveurs.
  • réduction de notre facture d'hébergement.

Maintenance et  sauvegarde des données améliorés

5°) Agilité de l'entreprise.

La première conséquence évidente et mesurable induite par le choix de passer à des serveurs virtuels est d'avoir introduit une forme d'agilité dans les "futur services" que nous pourrons proposer.
En effet, la mise en production d'un serveur peut s'effectuer en quelques jours (uniquement liée à la complexité des services à installer).  Le choix de fonctionnement de notre prestataire va nous permettre de proposer à  nos clients de pouvoir s'engager sur des périodes inférieures ou égales à 12 mois.

A titre d'exemple, vous trouverez ci-dessus les délais qui ont été nécessaire pour la migration de notre serveur de supervision basé sur NAGIOS :
  • Délai d'acquisition des ressources auprès de GANDI : 1h
  • Installation d'OpenSuse 12.1 (image GANDI) : 1h
  • Configuration spécifique du serveur : 2h
  • Installation de NAGIOS et configuration des machines et services à superviser : 6h
  • Tests de validation et correction des problèmes : 5h
  • Mise en production : 1h
Soit un total d'environ 16h (deux grosses journées) de travail pour migrer un serveur NAGIOS. Honorable non ?

La deuxième conséquence concerne la gestion et l'évolution des ressources des serveurs. Bon, je n'ai pas une grosse expérience des serveurs virtualisés, mais je trouve que le concept mis en place par GANDI est assez séduisant. Concernant les ressources attribuées, vous avez les ressources propres au serveur (CPU, mémoire) et les ressources externes (carte réseau, espace disque).
Les cartes réseaux et les espaces disques sont attachés à un serveur.
Dans l'exemple ci-dessous, j'ai un serveur 3 cœurs avec 4Go de mémoire auquel est attaché une interface réseau.



Sur ce serveur, j'ai attaché 2 disques :
Un disque qui contient le système d'exploitation et un autre qui contient les données des services qui tournent sur ce serveur.
Premier avantage, en supposant que je dispose de l'espace disque nécessaire, je peux à tout moment faire un spnashot des mes disques très simplement.
Je peux aussi agrandir la taille du disque, à priori sans avoir à redémarrer le serveur. Mais je me suis rendu compte que même en effectuant un resize2fs, j'avais besoin de faire un reboot (qui ne dure que quelques secondes).
Ce qui est séduisant, c'est que je peux détacher les ressources associées à un serveur et les rattacher à un autre serveur (mais je n'ai pas encore testé). Idem pour l'interface réseau (mais je n'ai pas encore testé aussi). Ce qui ouvre des perspectives de garanties de services assez intéressantes.
Avec un peu d'organisation et de rigueur, nous allons améliorer considérablement le taux de disponibilité de nos services (même si celui si était quand même assez bon), offrir aussi des garanties plus importante sur la pérennité des données qui nous sont confiées.

Donc vous l'aurez compris, nos limites en terme de ressources seront étroitement liées à celles de notre prestataire...

6°) Conclusions.

Pour conclure, même si je suis énormément séduit pas les nouvelles perspectives qui me sont aujourd'hui offertes les services virtualisés, je suis quand même conscient que cela soulève certains nouveaux problèmes :
  • une très forte dépendance vis-à-vis de mon prestataire.
  • mes serveurs ne sont plus sur le même réseau.
  • impossible d'installer un réseau privé entre l'ensemble de mes serveurs, donc le trafic même intra-serveur passe par le réseau public.
  • accroissement nécessaire des règles de sécurité et de cryptage des données échangées entre les serveurs.
  • quid des garanties des données en cas de pertes suite à un problème grave sur l'infrastructure du prestataire ?
  • ...
Il faut malgré tous rester réaliste, aujourd'hui il est impossible d'avancer et de proposer des services innovant sans dépendre d'un prestataire... Donc le tous c'est de prévoir des plans de sorties en cas de problèmes.
Nous nous sommes déjà affranchi (du moins nous le pensons ???) des problèmes de sécurités en durcissant et en affinant les règles de nos pares-feux, et des problèmes de confidentialités d'échanges de données intra-serveurs en cryptant ces échanges via OpenSSL (cela fera l'objet d'un autre post concernant la mise en place de crytpage avec MySQL).

Pour les autres nouvelles contraintes, nous allons pour l'instant, déjà profiter des plus apporter par ces nouvelles technologies et nous essayerons dans le futur de palier aux nouveaux problèmes induits par les choix qui ont été fait.