Catégories
Blog Open-source Planet-libre Reseau Systeme

Sécuriser son blog WordPress #2

Dans ce deuxième billet, nous allons aborder la pierre angulaire de la sécurisation de votre site/blog: la sécurisation du couple infernal Apache/PHP.

Bien qu’il existe d’autres serveurs Web (par exemple le très rapide NGinx ou le très simple Cherokee), Apache reste, à ce jour, le plus répandu. Un des reproche que l’on peut lui faire est sa lourdeur de configuration. Cette lourdeur et l’utilisation de fonctions pas forcement utiles à votre site peut rapidement entraîner des failles de sécurité. Nous allons donc détailler la sécurisation du serveur Web ainsi que celle du moteur de langage PHP qui est utilisé par WordPress.

Je vous rappelle que cet article est découpé en plusieurs billets (vous êtes en train de lire le #2):

Cette série de billets a été co-écrite avec Jérémie Marguerie étudiant à EPITA (merci à lui !).

Serveur Web Apache

Sécuriser l’installation par défaut d’Apache2

Apache est développé en tenant compte de la sécurité mais dévoile, dans le header HTTP, son identité (son nom et son numéro de version) à chaque client qui se connecte. Ne pas divulguer ces informations permet d’éviter aux scripts kiddies de connaitre directement les failles connues pour la version d’Apache utilisée et peut compliquer le travail des crackers.

Pour cacher ces informations aux clients HTTP, il suffit d’éditer le fichier /etc/apache2/conf.d/security et d’y ajouter/modifier les variables suivantes:

ServerTokens Prod
ServerSignature Off
TraceEnable On

Module de securité IDS pour Apache

Il existe dans Apache un module optionnel nommé ModSecurity2 qui permet de détecter et de protéger son serveur contre des attaques touchant vos applications Web (notamment les « SQL injections », « cross-site scripting », « path traversal attacks »…).

On commence par l’installation de mod-secure:

sudo aptitude install libapache2-mod-security2

Par défaut, aucune règle n’est appliquée. Il faut donc partir du fichier de configuration qui est donné en exemple:

sudo cp /usr/share/doc/mod-security-common/examples/modsecurity.conf-minimal /etc/apache2/conf.d/mod-security.conf

On édite ensuite le fichier /etc/apache2/conf.d/mod-security.conf:

# Basic configuration options
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off

# Handling of file uploads
# TODO Choose a folder private to Apache.
SecUploadDir /tmp/
SecUploadKeepFiles Off

# Debug log
SecDebugLog /var/log/apache2/modsec_debug.log
SecDebugLogLevel 0

# Serial audit log
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus ^5
SecAuditLogParts ABIFHZ
SecAuditLogType Serial
SecAuditLog /var/log/apache2/modsec_audit.log

# Maximum request body size we will
# accept for buffering
#SecRequestBodyLimit 131072
SecRequestBodyLimit 8192000

# Store up to 128 KB in memory
SecRequestBodyInMemoryLimit 131072

# Buffer response bodies of up to
# 512 KB in length
SecResponseBodyLimit 524288

# Verify that we’ve correctly processed the request body.
# As a rule of thumb, when failing to process a request body
# you should reject the request (when deployed in blocking mode)
# or log a high-severity alert (when deployed in detection-only mode).
SecRule REQBODY_PROCESSOR_ERROR « !@eq 0 » \
« phase:2,t:none,log,deny,msg:’Failed to parse request body.’,severity:2 »

# By default be strict with what we accept in the multipart/form-data
# request body. If the rule below proves to be too strict for your
# environment consider changing it to detection-only. You are encouraged
# _not_ to remove it altogether.
SecRule MULTIPART_STRICT_ERROR « !@eq 0 » \
« phase:2,t:none,log,deny,msg:’Multipart request body \
failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_SEMICOLON_MISSING}, \
IQ %{MULTIPART_INVALID_QUOTING}' »

# Did we see anything that might be a boundary?
SecRule MULTIPART_UNMATCHED_BOUNDARY « !@eq 0 » \
« phase:2,t:none,log,deny,msg:’Multipart parser detected a possible unmatched boundary.' »

On relance ensuite Apache pour prendre en compte le plugin:

sudo /etc/init.d/apache2 restart

Ce module contient un ensemble d’expressions rationnelles dont l’objectif est de bloquer les requêtes jugées dangereuses. Il bloquera une partie des tentatives de piratage. C’est  tout de même une barrière de protection faillible mais qui peut empêcher l’exploitation de certaines failles. Dans tout les cas, cela n’empêche pas le développeur de coder correctement, en prenant en compte la sécurité au moment du développement des sites.

Module anti DOS

Nous allons installer le module Apache mod_evasive qui permet d’atténuer les attaques DOS faite en utilisant le protocole HTTP en bloquant les adresses IP des clients trop gourmand, c’est à dire ceux qui demandent trop rapidement des pages webs.

Contrairement à ce que l’on peut lire sur certains sites, ce module ne protège pas des DDOS, seulement des DOS (lire ici une explication des attaques DOS et DDOS). Autrement dit, il bloque les reqêtes venant d’une adresse IP (DOS).

Si un très grand nombre d’IPs font une seule requête : votre serveur sera saturé et le mod_evasive n’aura pas servi (DDOS). Bloquer les DDOS est très difficile car les requêtes sont difficilement reconnaissables des requêtes autorisées.

On commence par installer le module:

sudo aptitude install libapache2-mod-evasive

On édite le fichier /etc/apache2/conf.d/mod-evasive:

<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 2
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
</IfModule>

C’est la configuration par défaut qui va bloquer pendant 10 secondes (DOSBlockingPeriod) les requêtes HTTP venant de l’adresse IP source si une des assertions suivantes est vérifiée:

  • il y a plus de 2 requêtes (DOSPageCount) sur la même page dans un intervalle de 1 seconde (DOSPageInterval)
  • il y a plus de 50 requêtes (DOSSiteCount) sur l’ensemble du site dans un intervalle de 1 seconde (DOSSiteInterval)

On relance ensuite Apache pour prendre en compte le plugin:

sudo /etc/init.d/apache2 restart

Sécurisation du moteur PHP

PHP est un langage interprété, largement utilisé pour générer dynamiquement des pages HTML. C’est le langage utilisé par le moteur de CMS WordPress. La génération des pages de votre blog se faisant directement sur votre serveur, il est important de protéger l’environnement d’exécution des scripts PHP.

Il est donc conseillé d’utiliser suphp. Il est relativement facile à installer et permet d’exécuter vos scripts PHP sous un utilisateur autre que www-data et donc protéger votre système.

Cela permet aussi de servir plusieurs sites internet sur un même serveur. Si un pirate atteint un site, il ne pourra pas toucher aux autres.

Ce module fournit aussi la possibilité de disposer d’un fichier PHP.ini par site web, et offre donc plus de flexibilité que l’installation standard de PHP.

La sécurité a néanmoins un coup: la performance. Attendez vous à des pertes de performances sur vos applications. Dans le cas d’une application codée correctement et d’un serveur non surchargé, cette perte devrait cependant être minime.

Il est également possible de désactiver certaines fonctions sensible de PHP (system, exec…) en éditant le fichier php.ini (voir exemple dans l’étape n°3 de ce billet).

Pour installer  suPhp sur votre serveur je vous conseille la lecture de cet article. (si vous voulez/devez faire cohabiter deux versions de PHP, par exemple la 4 et la 5, vous pouvez également consulter ce billet).

Conclusion (temporaire)

On dispose donc maintenant d’un système et d’un serveur Web sécurisé. Il ne reste plus qu’à attendre la suite de cette série de billets pour s’attaquer à la sécurisation du moteur de blogging WordPress.

Catégories
Blog Open-source Planet-libre Reseau Systeme

Sécuriser son blog WordPress #1

Il n’y a rien de plus rageant que de se faire pirater son blog. En plus de réduire à néant notre amour propre, cela peut avoir, dans le cas d’une indisponibilité prolongée, des impacts non négligeables sur le « saint » référencement dans gOOgle et donc sur le trafic sur votre site (je suis bien placé pour en parler…).

Après avoir détaillé l’installation d’un blog WordPress sur un serveur VPS Gandi Ubuntu Server puis optimiser ce dernier en 12 étapes, nous allons donc aborder des techniques permettant de protéger votre blog WordPress hébergé sur un serveur dédié ou virtuel (mais un bon nombre de ces techniques sont aussi applicables sur n’importe quel site Internet). Il faut garder à l’esprit que cela ne garantira en rien une protection efficace à 100%. Si une personne compétente décide de pirater votre site, il y a de fortes chances qu’elle réussisse. Par contre, ces techniques vous protégeront sûrement d’une grande majorité des attaques lancées via des « script kiddies« .

Cet article va être découpé en plusieurs billets (vous êtes en train de lire le #1):

Cette série de billets a été co-écrite avec Jérémie Marguerie étudiant à EPITA (merci à lui !).

Sécurisation du système d’exploitation

C’est la base de votre infrastructure. Ici, pas la place pour des systèmes d’exploitations (OS) de comique. Il faut du lourd, du sûr, du solide, du stable, du libre: c’est-à-dire une distribution GNU/Linux ou BSD.

Pour les serveurs Web, j’utilise FreeBSD ou Ubuntu Server, selon mon humeur. Comme je le répète assez souvent il vaut mieux choisir un système d’exploitation que l’on maîtrise bien. En discutant avec des “experts”, vous aurez autant de sons de cloches que d’OS…

Dans la suite de ce billet, nous travaillerons sur la sécurisation d’un serveur sous Ubuntu Server 10.04 LTS, ces méthodes sont applicables facilement sur une Debian (et toute autre distribution Debian like).

Pense bête lors de l’installation

Lors de la configuration des partitions du disque dur de votre serveur, ne tombez pas dans la facilité en faisant une partition unique qui contiendra le système, les application et vos données sur un même volume logique.

Séparer intelligemment les répertoires de son système permet de cloisonner les données et simplifie la ré-installation d’un système. Au minimum, il est conseillé de séparer au moins les partitions suivantes:

  • / (~ 5 Go)
  • /boot (~ 100 Mo)
  • /var (~ 12 Go)
  • /home (Tout l’espace restant)
  • /var/tmp (Voir plus bas)
  • /tmp (Voir plus bas)

Dans notre cas, l’idée est de ne pas stocker nos sites sur /var/www mais sur /home, qui contient tout l’espace.

Le répertoire /var, dédié principalement aux logs, pourra alors se remplir sans impacter votre arborescence principale sur / ou vos comptes sur /home.

Surveiller l’espace utilisé sur vos partition est important, une partition pleine empêcherait vos logs de s’écrire ou vos sites de fonctionner correctement. Le programme logwatch (décrit plus bas) vous fournit un récapitulatif de l’espace disque utilisé, il est donc utile pour surveiller ce point.

Utilisation de tmpfs

Sous les systèmes GNU/Linux, on a deux dossiers temporaires: /tmp et /var/tmp. Passer ces dossiers “World Writable” (c’est à dire que n’importe quel utilisateur/processus de votre système peut écrire et lire dans ces répertoires) en tmpfs (disque RAM). Il faut que votre serveur dispose d’une quantité de mémoire RAM conséquente car une partie de celle-ci sera utilisée pour stocker les fichiers temporaires.

Pour mettre en place tmpfs sur un système de fichier (/tmp dans cet exemple), éditez le fichier /etc/fstab et ajouter la ligne suivante :

tmpfs        /tmp     tmpfs        defaults,user_xattr          0    0

Je vous conseil de mettre tmpfs en place pour les répertoires /tmp, /var/tmp et /dev/shm. La rêgle pour savoir síl faut le mettre en place est « sur tous les répertoires dont le données sont volatiles ». Ainsi, /var/lock devrait en faire partie, sauf que certains programmes, mal codé, n’apprécient pas que ce dossier soit vidé.

L’idée derrière l’utilisation de la RAM est de rendre ces répertoire très rapides. Le stockage sur RAM limite aussi intrinsèquement leur taille, que le noyau gère automatiquement pour étendre ou diminuer la taille de ces partitions en fonction des besoins du système.

Mise à jour du système

C’est un des principe de base de la sécurité de votre système informatique (malheureusement aussi un des plus rébarbatif):

« Toujours avoir un système et des applications à jour. »

Pour m’aider dans cette lourde tache, j’utilise l’application cron-apt qui permet de vérifier automatiquement si des mises à jours sont disponibles. Si c’est le cas, le logiciel peut envoyer un mail et optionnellement, mettre à jour le système pour vous.

Installation de cron-apt:

sudo aptitude install cron-apt

Il faut ensuite configurer votre adresse mail dans le fichier /etc/cron-apt/config. Par défaut cron-apt s’exécute automatiquement tout les matins à 4h00.

Voici un exemple de mail envoyé:
Pour les machines sous Fedora, il existe une fonction équivalente directement dans Yum (lire ce billet pour plus d’informations).

Tuning de la sécurité

Configurer les paramètres de sécurité réseau par défaut dans le fichier  /etc/sysctl.conf.

Vous pouvez vous inspirer des billets suivants pour effectuer cette configuration:

Protection contre les « forks bombs »

Une attaque par « forks bombs » est de type DOS (Deny Of Service) qui utilise la commande système fork. Pour se protéger de telle attaque et limiter leurs impacts sur le reste du système,  il faut éditer le fichier /etc/security/limits.conf et y ajouter les lignes suivantes (en adaptant « username » à vos besoins):

username soft nproc        300

username hard nproc        350

username soft nice         0

username hard nice         0

username soft priority     5

username hard priority     5

username –    maxlogins    10

Ces limitations empêchent un utilisateur de se logguer plus de 10 fois sur la machine (en SSH notamment), de lancer plus de 350 processus simultanément (empêche les forks-bombs) et met une priorité faible a ses tâches par défaut (haute priorité < 0, normal 0, basse priorité > 0).

Source: http://www.cyberciti.biz/tips/linux-limiting-user-process.html

Firewall

Ne laisser passer que les flux réseaux utiles à l’utilisation de votre serveur par les utilisateurs (HTTP / HTTPs) et l’administration (SSH).

Concernant le protocole SSH, on lit souvent qu’il faut changer le port d’écoute du daemon SSHd (par défaut TCP/22). Mise à part le bloquage de certains scripts automatique, je ne pense pas que cette sécurité soit suffisante. En effet, un simple scan de votre machine avec Nmap permettra de retrouver facilement le port d’écoute.

Une solution plus efficace pour protéger cette porte d’entrée sur le serveur est d’utiliser la technique du “portknockers”. Avant de s’ouvrir, on doit taper à la porte de notre serveur en  envoyant une séquence de requêtes vers des ports prédéfinis. Par exemple avant de ce connecter en SSH sur le port TCP/22, il faudra envoyer “taper à la porte” des ports 2222, 3333 et 4444.

Le programme knockd permet de configurer facilement un “portknockers” sur son serveur Linux: https://help.ubuntu.com/community/PortKnocking

Fail2Ban analyse les logs de votre système et bloque automatiquement les indésirables au niveau du firewall iptables, ce qui est très efficace. Vous pouvez aussi bloquer manuellement des plages d’IPs considérées comme “malfaisantes”, il m’est arrivé de bloquer un pays entier cas de nombreux tentatives de piratage provenaient de ce site, et qu’aucun visiteur en provenance de ce pays ne viennent sur mes sites (bon c’est vrai cela fait un peu censure :)).

A installer à partir des sources:

sudo aptitude install fail2ban

Le fichier de configuration par défaut est /etc/fail2ban/jail.conf. Vous pouvez notamment y configurer les adresses IP à ignorer (par exemple l’adresse IP publique ou le nom d’hôte de votre propre box):

ignoreip = 127.0.0.1 home.mondomaine.com

Et également ajouter ou modifier les prisons (jail) pour des services spécifiques. Par exemple pour le serveur pure-ftpd:

#

# FTP servers

#


[pure-ftpd]

enabled = true

port = ftp,ftp-data,ftps,ftps-data

filter = pure-ftpd

logpath = /var/log/messages

maxretry = 6

Pour aller plus loin dans la configuration de fail2bna, vous pouvez lire ce billet.

Autres idées en vrac

  • instaurer des quota disk stricts par utilisateur (quotatool) : très utile pour éviter de bloquer tous ses sites à cause d’un script mal codé.
  • empecher le reboot par syskey /etc/inittab : intéressant mais peu utile, une personne avec un accès physique à votre serveur peut de toute façon faire à peu prêt tout ce qu’elle veut.
  • utiliser rsyslog pour envoyer les logs sur un serveur distant, sans accès de modification/suppression de logs de préférence : permet d’analyser les actions d’un pirate après détection du piratage (un pirate ne peut pas effacer toutes les traces laissées par les tentatives de piratage infructueuses). Un peu cher à mettre en place pour un site perso.

Les commentaires sont ouverts pour nous faire partager votre expérience dans la sécurisation de vos sites Internet.

Sources ayant servies à la rédaction de ce billet: