Installation d’un blog WordPress sur un VPS Gandi

Date: 25/08/2010 | Catégories: Blog,Open-source,Web | Tags: ,,,,,,

Comme vous le savez, je me suis fait hacké mon site pendant les "grandes vacances". Cette petite contrariété m'a fait faire dans l'urgence une chose que j'avais planifier depuis un certain moment: la migration du Blog de Nicolargo sur un serveur privé virtuel de Gandi.

Nous allons donc voir dans ce billet comment installer, sécuriser et optimiser une blog WordPress sur une serveur privé virtuel !

Commencons par le commencement

Il faut d'abord choisir les performances initiales du serveur virtuel. J'ai utilisé le serveur que j'avais créé il y a quelques mois. C'est l'entrée de gamme, c'est à dire 1 part correspondant aux spécifications suivantes:

  • 1/64ème des capacités globales du serveur, soit environ 1 GHz
  • 1/64ème des 16 Go de mémoire du serveur, soit 256 Mo de RAM garantie avec un burst possible à 2 Go (+512 Mo de Swap)
  • 1/64ème des capacités réseau, soit 5 Mbits dédiés
  • 1/64ème du disque réservé au serveur, soit 5 Go de disque data (+3 Go pour le système)

Comme nous allons le voir plus tard cette configuration n'est pas adapté pour un blog avec un trafic relativement important (environ 1 00 000 pages vues par mois) . Je suis donc rapidement passé à la configuration suivante:

Nous disposons donc d'un accès SSH (root) sur le serveur,. Après une mise à jour du système d'ecploitation (Ubuntu Server 9.04) nous pouvons enfin commencer les choses sérieuses...

Installation du serveur Web Apache

On commence par installer le serveur:

sudo aptitude install apache2 php5 libapache2-mod-php5 php5-curl

Puis on active les modules qui vont nous permettre d'optimiser les performances de WordPress:

sudo a2enmod deflate

sudo a2enmod headers

sudo a2enmod rewrite

sudo a2enmod expires

Il est également possible d'adapter la configuration des processus Apache (nombre de process, nombre maximal de client par process..) en modifiant le fichier /etc/apache2/apache2.conf:

<IfModule mpm_prefork_module>

StartServers 5

MinSpareServers 5

MaxSpareServers 10

MaxClients 40

MaxRequestsPerChild 2000

</IfModule>

StartServers permet de configurer le nombre de processus Apache lancés au démarrage.

MinSpareServers et MaxSpareServers donnent respectivement le nombre minimum et maximum de processus Apache selon les besoins.

MaxClients permet de configurer le nombre de clients (au sens session TCP) pouvant se connecter simultanément à un processus Apache. Pour des sites dynamiques (comme WordPress) il est plutôt conseillé de ne pas avoir une valeur trop élevée afin d'éviter les swap mémoire sur disque.

Une solution proposée sur ce blog pour calculer la valeur MaxClients est la suivantes: Il faut d'abord regarder combien de mémoire prend un processus apache2 (par exemple avec la commande top), puis diviser la mémoire système disponible par cette valeur. Par exemple, pour un serveur disposant de 1 Go de RAM (1000 Mo) et dont chaque processus Apache occupe 25 Mo, on a le calcul suivant:

MaxClients = 1000 / 25 = 40

Enfin MaxRequestsPerChild permet de définir le nombre maximal de requête qu'un processus peut prendre en charge avant d'être tué. Il est conseillé de mettre une valeur différente de 0 (le processus n'est alors jamais tué) pour éviter qu'une processus ne consomme trop de mémoire si un problème arrive.

On passe ensuite aux directives KeepAlive qui permette de configurer finement le temps de vie des sessions TCP. Pour un site dynamique comportant un nombre important d'images et de JS (comme mon blog), les valeurs suivants sont un bon point de départ:

# KeepAlive: Whether or not to allow persistent connections
KeepAlive On
# MaxKeepAliveRequests: The maximum number of requests to allow
MaxKeepAliveRequests 200
# KeepAliveTimeout: Number of seconds to wait for the next request
KeepAliveTimeout 5
# Timeout: The number of seconds before receives and sends time out.
Timeout 50

Enfin on relance le serveur pour que la configuration soit prise en compte:

sudo /etc/init.d/apache2 restart

Installation de MySQL

On commence par installer le serveur MySQL:

sudo aptitude install mysql-server

Puis on créé une base de donnée et un compte utilisateur associé qui va servir pour WordPress:

mysql -u adminusername -p

mysql> CREATE DATABASE databasename;

Query OK, 1 row affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON databasename.* TO "wordpressusername"@"hostname"

-> IDENTIFIED BY "password";

Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;

Query OK, 0 rows affected (0.01 sec)

mysql> EXIT

On peut optimiser la base de donnée en éditant le fichier /etc/mysql/my.cnf:

query_cache_type = 1

query_cache_limit = 2M

query_cache_size = 32M

Ne pas oublier de relancer le serveur MySQL pour prendre en compte les modifications.

Installation de WordPress

Depuis le hack de mon blog, j'ai décidé de travailler directement avec la version SVN de WordPress afin de disposer au plus vite des patchs de sécurité. Une fois de le répertoire racine de votre site Web (/home/nicolargo/web/blog dans mon cas), il faut saisir la commande suivante:

svn co http://core.svn.wordpress.org/trunk/ .

On ajoute ensuite la ligne suivante dans le fichier .htaccess afin de rendre invisible les sous répertoires .svn:

RewriteRule ^(.*/)?\.svn/ - [F,L]

Puis on finalise l'installation en suivant la fameuse installation de WordPress en 5 minutes.

Il est ensuite conseillé de supprimer le fichier wp-admin/install.php (qui ne servira plus une fois l'installation faite):

rm wp-admin/install.php

Sécurisation de WordPress

Cette sécurisation passe par deux étapes. Une première est de protéger le blog à l'aide du fichier .htaccess. La seconde est d'installer des plugins de sécurité qui vont nous permettre de faire régulièrement des audits sur notre serveur.

Pour le fichier .htaccess, j'utilise la base suivante:

# MAIN

RewriteEngine On

ServerSignature Off

Options All -Indexes

Options +FollowSymLinks


# SVN protect

RewriteRule ^(.*/)?\.svn/ - [F,L]


# Secure .htaccess

<Files .htaccess>

Order Allow,Deny

Deny from all

</Files>


# Secure wp-config.php

<Files wp-config.php>

Order Deny,Allow

Deny from all

</Files>


# FILTER REQUEST

<IfModule mod_rewrite.c>

RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule . /index.php [L]

</IfModule>


# BEGIN Expire Header

<FilesMatch "\.(ico|jpg|jpeg|png|gif|js|css|swf)$">

ExpiresDefault "access plus 2 hours"

</FilesMatch>


On passe ensuite à l'installation des plugins de sécurité suivants:

Le premier (Secure WordPress) permet d'effectuer simplement et automatiquement une liste d'actions essentielle à la sécurité de votre site:

Le second (WP Security Scan) effectue régulièrement un scan de l'arborescence de votre site et remonte dans l'interface d'administration de WordPress les fichiers modifiés.

Optimisation de WordPress

Pour l'optimisation des performance du blog, je me base sur l'indispensable plugin W3 Total Cache. Bien qu'il ne se limite pas qu'a cela, il permet de mettre facilement en place un système de cache ou les pages sont directement gérées en mémoire RAM plutôt qu'en lecture sur le disque dur. J'ai choisi de coupler W3 Total Cache avec Memcached (un cache mémoire sous licence libre).

L'installation de Memcached est des plus simple:

sudo aptitude install libcache-memcached-perl memcached

Si votre serveur est protégé par un Firewall (ce que je conseille évidemment...), il ne faut pas oublier d'ajouter la règle suivante:

iptables -A OUTPUT -p tcp --destination 127.0.0.1 --dport 11211 -j ACCEPT

La configuration de W3 Total Cache se fait via l'onglet Performance / General settings:

Une dernière optimisation consiste à installer le plugin WP-DBManager et de suivre régulièrement (tout les mois environ) les procédures d'optimisation (onglet Database).

Test et validation

Pour tester les performances de votre serveur, vous pouvez utiliser la commande suivante:

ab -t 30 -c 5 http://votreblog.com/

L'information intéressante se trouve sur la ligne:

Requests per second:    159.46 [#/sec] (mean)

Il est également important de surveiller les paramètres suivant: charge CPU, mémoire RAM disponible, accès disque et réseau. Gandi propose pour cela une interface d'administration Web avec un système de sonde permettant de remonter des alertes par mail ou même d'augmenter dynamiquement le nombre de part lors d'un pic de trafic.

Personnellement, je surveille mon serveur via Nagios mais cela sera le sujet d'un prochain billet...