Mysql – Cryptage SSL des connexions sous Debian Jessie

16 janvier 2017 | Posted in Réseau, Securisation | By

Pour plusieurs raisons propres, vous devez ouvrir votre serveur mysql vers l’extérieur. Vous trouverez de nombreux tutoriels afin de le faire. Mais ici, nous allons voir comment sécuriser vos communications entre le client et le serveur rendant ainsi impossible d’intercepter par sniffage un mot de passe ou le résultat de vos requêtes.
Il serait gênant de devoir expliquer à vos clients que leurs informations personnelles sont entre les mains de hackers malins.

Pre-requis

Serveur Debian 8 jessie dont l’ip sera 192.168.0.1
le package mysql-server installé

Information Importante

La documentation de mysql 5.5 décrit la manière de sécuriser les connexions, vous trouverez aussi de nombreux tutoriels décrivant les processus. Néanmoins, ces dernières ne fonctionnent pas sous Debian 8 à cause d’openssl. La version actuelle d’openssl sous jessie est la 1.0.1t alors que lors de l’écriture des tutoriels officiels, la version était 0.9.8. Il en découle une différence dans les protocoles PKS. La procédure décrite ci dessous en tient compte.

Ouvrir les connexions distantes

En premier lieu, nous allons modifier le fichier /etc/my.cnf afin de dire à mysql d’ouvrir son port 3306 vers l’extérieur.

sed -i '/bind-address/ s/^/# /' /etc/mysql/my.cnf
service mysql restart

Il faut maintenant faire deux choses.
La première : vérifiez que vous n’avez pas déjà un utilisateur ayant pour attribut un host % (signifiant que vous acceptez des connexions de partout) et la deuxième, de savoir créer un utilisateur.

mysql -u root -p

puis dans le shell mysql on commence par vérifier

select user,host from mysql.user;
sortie bash mysql requete
Comme on peut le voir, pas d’utilisateur ouvert vers l’extérieur.

On créé maintenant un utilisateur ssl_user provenant de l’adresse 192.168.0.10.

CREATE USER "ssl_user"@"192.168.0.10" IDENTIFIED BY "mot_de_passe";
GRANT SELECT, SHOW DATABASES ON *.* TO "ssl_user"@"192.168.0.10" REQUIRE SSL;
FLUSH PRIVILEGES;

On vérifie le tout :
select user,host,ssl_type from mysql.user;
sortie bash mysql requete
On peut voir le champ ssl_type avec la valeur ANY qui montre que l’utilisateur sssl_user accepte n’importe quel type de chiffrement ssl.

Création et déploiement des certificats SSL

Nous allons en premier lieu vérifier que votre serveur mysql est bien compilé avec le support SSL. Normalement, si vous êtes passé par les dépôts, pas de soucis à se faire

toujours depuis le shell mysql tapez :
show variables LIKE "%ssl%";
sortie bash mysql requete

Comme vous pouvez le voir, on est en etat DISABLED.
Jusque là rien d’anormal, si vous aviez eu NO à la place cela vous indiquerait alors que votre serveur Mysql n’est pas compilé avec openssl.

Géneration des certificats

Personnellement, je range mes certificats dans le même dossier que la configuration mysql


cd /etc/mysql && mkdir MysqlCertif
cd MysqlCertif

Nous allons y stocker les certificats de l’autorité de certification, du serveur et du client.

Autorité de certification


openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 1825 -key ca-key.pem > ca-cert.pem

On génère donc une clé de 2048 bits (le maximum légal en France, perso je mets plus …) valable 1825 jours soit 5 ans.

Certificat serveur


openssl req -newkey rsa:2048 -days 1825 -nodes -keyout serverMysql-key.pem > serverMysql-req.pem
openssl x509 -req -in serverMysql-req.pem -days 1825 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > serverMysql-cert.pem
openssl rsa -in serverMysql-key.pem -out serverMysql-key.pem

Certificat Client


openssl req -newkey rsa:2048 -days 30 -nodes -keyout clientMysql-key.pem > clientMysql-req.pem
openssl x509 -req -in clientMysql-req.pem -days 30 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > clientMysql-cert.pem
openssl rsa -in clientMysql-key.pem -out clientMysql-key.pem

j’ai modifié la validité du certificat client à 30 jours afin de vous montrer que vous pouvez donner ainsi une date de péremption et bloquer la connexion au bout de 30 jours

Cela évite aussi de laisser traîner des certificats valides dans la nature trop longtemps.

on fini en mettant les certificats avec les droits mysql

chown -R mysql:mysql /etc/mysql/MysqlCertif

Configuration du serveur mysql

Editez le fichier /etc/mysql/my.cnf

dans la section [mysqld] ajoutez :

ssl-ca=/etc/mysql/MysqlCertif/ca-cert.pem
ssl-cert=/etc/mysql/MysqlCertif/serverMysql-cert.pem
ssl-key=/etc/mysql/MysqlCertif/serverMysql-key.pem

Il ne reste plus qu’à redémarrer le service

service mysql restart

Vérifions maintenant que tout fonctionne :

Dans la console mysql :
show variables LIKE "%ssl%";

sortie bash mysql requete serveur ok

On a bien la confirmation que tout est ok.

Configuration cote client

En premier lieu, il faut récupérer les fichiers pour le certificat client

Les fichiers à transmettre sont :

  • /etc/mysql/MysqlCertif/ca-cert.pem
  • /etc/mysql/MysqlCertif/clientMysql-cert.pem
  • /etc/mysql/MysqlCertif/clientMysql-key.pem

Pour le client, vous avez deux manières de vous connecter.

Soit en ligne de commandes :
mysql -u ssl_user -p -h 192.168.0.1 --ssl-ca=/etc/mysql/MysqlCertif/ca-cert.pem --ssl-cert=/etc/mysql/MysqlCertif/clientMysql-cert.pem --ssl-key=/etc/mysql/MysqlCertif/clientMysql-key.pem

Soit directement dans le fichier my.cnf du client sous la section [client] :

éditez le fichier my.cnf

vim /etc/mysql/my.cnf

ssl-ca=/etc/mysql/MysqlCertif/ca-cert.pem
ssl-cert=/etc/mysql/MysqlCertif/clientMysql-cert.pem
ssl-key=/etc/mysql/MysqlCertif/clientMysql-key.pem

redémarrer le service

service mysql restart

on teste la connexion :

mysql -u ssl_user -p -h 192.168.0.1

Si tout fonctionne en tapant \s dans la console mysql on aura :

Que voit t’on la dedans? Première chose, le SSL fonctionne car on a le Cipher in use is DHE-RSA-AES256-SHA, la deuxième chose, je vous laisse la deviner et la mettre en commentaire.

Vérifier la sécurité

On pourrait s’arrêter là, mais on va aller un peu plus loin en regardant de plus près ce que l’on a avec mysql 5.5

dans votre console mysql :

SHOW GLOBAL STATUS where Variable_name like "Ssl%";

sortie bash mysql requete option global

On voit donc que la version ssl est TLSv1, ce qui est une bonne chose.
Le cipher est calé sur DHE-RSA-AES256-SHA ce qui est bon aussi.

Maintenant il faudra passer sous mysql 5.7 pour pouvoir modifier les valeurs et forcer par exemple le serveur en TLSv1.2.

Conclusion

Voila vos connexions extérieures cryptées.
Le cryptage de la connexion va un peu consommer de ressources mais d’après plusieurs benchmark cela est minime. Vous aurez par contre une latence augmentant proportionnellement avec le nombre de connexion actives.
Autre désavantage à prendre en compte, certains logiciels, sondes de monitoring ne fonctionnent pas avec une connexion cryptée ssl.

Read More...

Avoir et installer un certificat SSL https gratuitement

16 janvier 2017 | Posted in Non classé, Réseau, Securisation | By

Toujours dans l’optique d’améliorer la sécurité de votre site, vous avez pensé acheter un certificat. Mais un certificat, cela a un coût… Payer une rente annuelle pour sécuriser un flux smtp, ftp ou autres avec un certificat authentifié est hors de vos moyens.
Mais ça, c’etait avant, maintenant grâce à letsencrypt, à vous les certificats SSL valides mais sans assurance sur les transactions financières. Ils sont donc parfait pour un site ou un service non e-commerce.

Comment ca marche ?

Afin de délivrer le certificat, letsencrypt vérifie que le nom de domaine est bien relié à l’ip déclarée dans le dns. Pour cela, il monte un mini serveur http pour effectuer une connexion au service afin d’authentifier la demande de certificat. C’est pour cela que lors de la génération ou le renouvellement d’un certificat il faut arrêter apache.

Pré-requis

Si vous copier-coller mes virtualhosts, avoir installé chronolog.
Les sites sont placés dans le dossier /var/www avec comme architecture de dossier :

  • log
  • tmp
  • html

Installation

Il faut commencer par installer letsencrypt sur son serveur, la procédure est différente entre Debian 7 et une Debian 8. La Debian 8 permet maintenant l’utilisation du package.

Debian 7

On choisi d’installer le script certbot directement dans le dossier /var/ice/script/shell/

cd /opt/
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto

Debian 8

Il faut commencer par activer les backports de debian

echo "deb http://ftp.debian.org/debian jessie-backports main" >> /etc/apt/sources.list
apt-get update
apt-get install certbot -t jessie-backports

Générez vos certificats

Pour info : on peut générer plusieurs certificats en une ligne en ajoutant des -d nomdedomaine.com
Remplacer évidemment nomdedomaine.com par la valeur du nom de domaine sans les www pour les racines.

Debian 7

cd /opt/
./certbot-auto certonly --standalone -d nomdedomaine.com --pre-hook "/etc/init.d/apache2 stop" --post-hook "/etc/init.d/apache2 start"

Debian 8

certbot certonly --standalone -d nomdedomaine.com --pre-hook "service apache2 stop" --post-hook "service apache2 start"

Renouvellement des certificats

Debian 7

cd /opt/
./certbot-auto renew --pre-hook "/etc/init.d/apache2 stop" --post-hook "/etc/init.d/apache2 start"

Debian 8

certbot renew --pre-hook "service apache2 stop" --post-hook "service apache2 start"

Configuration apache

on utilise deux mods

a2enmod headers
a2enmod ssl

le mode ssl gère les multi ssl avec une ip

ATTENTION :

Header always set Strict-Transport-Security envoie une commande via le header au navigateur qui va pendant le temps exprimé, forcer le navigateur à passer en HTTPS, même si vous avez désactivé le https ou mis un htaccess après. Cela reste dans le cache du navigateur.

Exemple de virtualhost


ServerName www.site.fr
ServerAlias site.fr
DocumentRoot /var/www/www.site.fr/html
LogLevel warn

ErrorLog « |/usr/bin/cronolog /var/www/www.site.fr/log/%Y/%m/error_log »
CustomLog « |/usr/bin/cronolog /var/www/www.site.fr/log/%Y/%m/access_log » combined
TransferLog « |/usr/bin/cronolog /var/www/www.site.fr/log/%Y/%m/transfer_log »

php_admin_value auto_prepend_file none
php_admin_value open_basedir /var/www/www.site.fr:/tmp
php_admin_value upload_tmp_dir /var/www/www.site.fr/tmp
php_admin_value session.save_path /var/www/www.site.fr/tmp

SetEnv AWSTATS_FORCE_CONFIG www.site.fr

SSLEngine On
SSLCertificateKeyFile /etc/letsencrypt/live/www.site.fr/privkey.pem
SSLCertificateFile /etc/letsencrypt/live/www.site.fr/cert.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.site.fr/chain.pem

SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite          ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA

SSLHonorCipherOrder on
SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
SSLCompression Off

# HSTS (mod_headers est requis, 15 768 000 secondes = 6 mois)
Header always set Strict-Transport-Security « max-age=15768000

Virtualhost pour debian 6


ServerName www.site.fr
ServerAlias site.fr

DocumentRoot /var/www/www.site.fr/html

LogLevel warn

ErrorLog « |/usr/bin/cronolog /var/www/www.site.fr/log/%Y/%m/error_log »
CustomLog « |/usr/bin/cronolog /var/www/www.site.fr/log/%Y/%m/access_log » combined
TransferLog « |/usr/bin/cronolog /var/www/www.site.fr/log/%Y/%m/transfer_log »

php_admin_value auto_prepend_file none
php_admin_value open_basedir /var/www/www.site.fr:/tmp
php_admin_value upload_tmp_dir /var/www/www.site.fr/tmp
php_admin_value session.save_path /var/www/www.site.fr/tmp

SetEnv AWSTATS_FORCE_CONFIG www.site.fr

SSLEngine on

SSLCertificateKeyFile /etc/letsencrypt/live/www.site.fr/privkey.pem
SSLCertificateFile /etc/letsencrypt/live/www.site.fr/cert.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.site.fr/chain.pem

<FilesMatch « \.(cgi|shtml|phtml|php)$ »>
SSLOptions +StdEnvVars

SSLOptions +StdEnvVars

BrowserMatch « .*MSIE.* » \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0

on active et on recharge apache

a2ensite www.site.fr.conf
apache2ctl graceful

Lexique commande

certonly : pour la création de certificat
renew : Pour le renouvellement
–dry-run : mode test
-q : mode silencieux sans sortie dans le shell
–force-renewal : pour forcer le renouvellement même si il n’est pas encore temps de le renouveler.
–email : pour spécifier un email différent de celui par défaut généré lors de la première utilisation
–rsa-key-size : taille de la clé RSA par défaut 2018
–pre-hook : Pour lancer une commande avant que certbot fasse l’action
–post-hook : Pour lance une commande après que certbot ait fonctionné.

Cas spécial pour les os non supportés.

L’astuce est valable si vous avez deux serveurs dont un avec une Debian. Il suffit de bouger les dns sur le serveur pouvant générer le certificat et de générer les fichiers.
Recopier les certificats dans le dossier /etc/letsencrypt sur la machine d’origine. Attention n’utilisez pas cette technique pour un service critique.

Test

Pour vérifier que votre serveur apache, votre virtualhost et votre certificat marchent correctement, rien de plus simple, il suffit de se rendre à cette adresse :

https://www.ssllabs.com/ssltest/

Et voila le résultat :

resultat test ssl site

Inconvénient

Il y a néammoins un inconvénient avec letsencrypt, les certificats sont valables que 2 mois … Il faut penser à renouveler vos certificats.

J’ai pour cela une astuce : nous allons utiliser le crontab et y mettre cette commande.


30 3 10 * * ./certbot-auto renew --pre-hook "/etc/init.d/apache2 stop" --post-hook "/etc/init.d/apache2 start"

Conclusion

Maintenant vous avez un site en https et en plus A+ d’après qualys et sans avoir débourser d’argent.

 

Read More...

Installation du waf modsecurity d’apache et reverse proxy

13 juin 2015 | Posted in Securisation | By

Par tous les moyens, vous cherchez à protéger votre réseau. Vous déployez un firewall pour bloquer les accès et les protéger de l’anti-spoofing, un fail2ban contre le brut force, rkhunter et compagnie, mais comment sécuriser les sites web que vous hébergez ??? Êtes-vous sûr que leur développement respecte les règles de l’art, qu’ils sont bien patchés avec les versions à jour… Il existe pourtant des solutions. Explorons ensemble la mise en place d’un web applicatif firewall appelé entre-amis WAF.

WAF le firewall pour vos applications web

Le principe du WAF est assez simple, un WAF se place entre internet et votre application web. Il va intercepter toutes les requêtes http pour les analyser suivant des règles de filtrage permettant de repérer les attaques et de les bloquer.
Il existe plusieurs modèles de WAF, nous allons ici mettre en place le module d’apache modsecurity. Vous pouvez bien sûr mettre directement votre waf sur votre serveur où sont les sites internets, mais ici je vais vous montrer comment mutualiser un WAF.

Schema waf mutualisé

schéma de flux pour infrastructure serveur web protégé par un waf

 

Explication de l infrastructure réseaux WAF

J ai choisi de mettre le serveur WAF sur un esxi pour plusieurs raison. D abord c est un serveur qui doit pouvoir évoluer suivant notre datacenter, une machine virtuelle offre cette flexibilité. Ensuite j ai fait le choix de donner une interface réseaux sur le WAF pour chaque serveur web que protégera le WAF. J ai donc une interface pour l administration et une pour chaque serveur web soit ici 3 en tout.
Pourquoi sommes toutes une interface par serveur web. Et bien tout simplement parce que cela m apporte de nombreux avantages de configurations je trouve. Pour le proxy je peux tout rediriger par l ip et non par le nom de domaine. Très utilie lorsque l’on a un serveur web hébergeant plusieurs nom de domaine.

 

Installation du WAF et du PROXY

On part d’une debian 7 fron scratch.

On commence par installer le serveur web apache et le modsecurity et le mod proxy

apt-get install apache2 libapache2-modsecurity libapache2-mod-proxy-html

On active tout le monde

a2enmod mod-security
a2enmod headers
a2enmod proxy_html
a2enmod proxy_http

 

Réglons tout de suite un bug de load de module. Si vous ne le faites pas vous aurez cette erreur dans votre /var/log/error.log


[Thu Jul 10 12:54:10 2014] [warn] proxy: No protocol handler was valid for the URL /. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.
[Thu Jul 10 12:54:10 2014] [warn] proxy: No protocol handler was valid for the URL /favicon.ico. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.

Il suffit de faire ceci :

ln -s /etc/apache2/mods-available/proxy_http.load /etc/apache2/mods-enabled/proxy_http.load

Paramétrage Modsecurity

on paramètre modsecurity

cd /etc/modsecurity
mv modsecurity.conf-recommended modsecurity.conf

On l’édite

vim /etc/modsecurity/modsecurity.conf

On active complètement modescurity

SecRuleEngine DetectionOnly

en

SecRuleEngine On

Puis rajouter juste après

SecDefaultAction "phase:2,log,auditlog,deny,status:403,tag:'SLA 24/7'"
SecServerSignature "Serveur Sécurisé"

Modifiez

SecPcreMatchLimit 1000
SecPcreMatchLimitRecursion 1000

En

SecPcreMatchLimit 2000
SecPcreMatchLimitRecursion 2000

Enfin

SecDataDir /tmp/

En

SecDataDir /var/cache/modsecurity/

Dé-commentez

SecDebugLog /var/log/apache2/modsecurity-debug.log
SecDebugLogLevel 3

et pour activer des règles on ajoute

Include /etc/modsecurity/activerules/*.conf

Attention l’include ne marche pas de manière récursive il faut toujours spécifier tous les répertoires ou vous avez des règles à charger.

Trouvez des règles pour le modsecurity

Par défault le modsecurity ne comporte pas de règle il faut en installer dans le dossier /etc/modsecurity/activerules/.

Il existe plusieurs sources gratuites ou payantes. Voici quelques liens.

A vous de faire votre choix.

En annexe un petit document à lire pour vous

http://www.ssi.gouv.fr/uploads/IMG/cspn/anssi-cspn-cible_2010-05fr.pdf

Configuration du Proxy

Pour rappel, nous avons détourné le flux http (port 80) allant sur le serveur web1 (192.168.1.40) vers le serveur waf sur son interface 192.168.1.4.

Il faut donc maintenant via apache rediriger le flux sur le serveur web1 grâce au mod_proxy

vim /etc/apache2/sites-available/web1.conf
<VirtualHost 192.168.1.4:80>

ServerAdmin webmaster@localhost
ProxyRequests Off
ProxyPreserveHost On
#ProxyHTMLExtended On

#SetOutputFilter INFLATE;proxy-html;DEFLATE
ProxyPass / http://192.168.1.40/
ProxyPassReverse / http://192.168.1.40/
ProxyTimeout 60
</Virtualhost>

On active le virtualhost et on recharge


a2ensite web1.conf
apache2ctl graceful

Modification des logs sur les serveurs Web

Si vous regardez les logs de votre serveur web, vous n’aurez plus que l’ip de l’interface du waf. Pour cela, il faut modifier le LogFormat afin qu’il reprenne en compte l’ip de l’internaute.

Éditez le fichier apache2.conf

vim /etc/apache2/apache2.conf

Commenter la ligne

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

ce qui donne

#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

et ajoutez en dessous

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

Il suffit maintenant d’appliquer le tout

apache2ctl graceful

Conclusion

Nous venons de rajouter une couche en plus pour la protection de votre infrastructure, de plus nous l’avons centralisé en un endroit, ce qui facilite l’entretien. N’oubliez pas que sans les règles un WAF ne sert à rien, il faut donc les mettre à jour régulièrement.

Read More...