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:

Catégories
Blog Open-source Planet-libre Web

Le blog de Nicolargo a son application IOS

Mon ami Nicolas Richasse vient de finaliser la première version de l’application du « Blog de Nicolargo » pour iPhone, iPod et iPad. Cette application est d’ores et déjà téléchargeable gratuitement sur l’Apple Store. (voir ici la page officielle de l’application pour plus d’informations).

Vous devez trouver plutôt causasse le fait que ce blog dispose d’une application pour iPhone (axe du mal propriétaire) plutôt que pour Android (les gentils libristes)…

La raison principale est assez simple. Nicolas Richasse m’a proposé de développer gratuitement cette application pour « se faire la main » sur le développement d’application sous IOS. Disposant d’un iPhone 4 à la maison, je n’ai donc pas hésité longtemps (si une âme généreuse veut faire la même chose sous Android je suis preneur :)).

Cependant notre « bon coté de la force » nous a poussé à réfléchir à un modèle plus en accord avec nos convictions. Après quelques discussions avec lui, nous avons donc décidé de proposer l’application sous licence GPL v2.

Elle sera disponible au téléchargement et librement « adaptable » à votre blog dans quelques temps (sur une forge qu’il nous reste à identifier). Nicolas souhaite juste avoir un peu de temps et de recul sur l’application pour proposer une code documenté et facile à forker pour d’autres blogs sous WordPress..

Il faut donc considérer l’application IOS du Blog de Nicolargo comme une démonstration de ce code open-source.

A télécharger, tester puis commenter sans modération !


Que pensez-vous de cette initiative ?

Etes-vous intéressé pour développer un « fork » de cette application pour votre blog ?

Souhaitez vous participer au développement de l’application « core » pour l’améliorer  ?

A vos commentaires…

PS: l’application est bien entendu gratuite. Si vous voulez soutenir Nicolas Richasse  dans son développement vous pouvez acheter son application iNumber qui reprend grosso modo la règle des chiffres de l’émission des chiffres et des lettres.

Catégories
Blog Open-source Planet-libre Web

Booster votre site n’est pas qu’un truc de geek

Depuis la généralisation des accès hauts débits sur Internet, la rapidité de chargement d’un site est devenu un critère important à prendre en compte dès la phase de conception.

Les moteurs de recherche (Google, Yahoo, Bing…) incluent dans leurs algorithmes la vitesse d’affichage de votre site. Ainsi, Google considère qu’une page est lente si elle met plus de 4.97 secondes pour se charger. La rapidité de chargement aura donc un impact plus ou moins important (difficile d’avoir des chiffres précis) sur le référencement de votre site.

Une étude a montrée qu’un utilisateur venant sur votre site à partir d’un moteur de recherche aura une patience d’environ 4 secondes. Au delà de cette valeur le taux d’abandon devient important.

Bref, vous l’avez compris, le temps de chargement des pages est un paramètre tout aussi important que le design quand vous mettez un site en ligne.

Je me suis penché sur ce sujet lors de conception de la nouvelle version du blog de Nicolargo. Il en ressort quelques billets ciblés sur les problèmatiques de performances des blogs WordPress (basée sur des solutions libres bien sûr :)):

Au niveau des outils de tests, le Web fourmille de service en ligne. Attention lorsque vous faite vos tests de choisir des URL représentatives (pas seulement un test sur votre Home page qui ne représente que 1% de vos visiteurs…). Personnellement, j’utilise surtout:

  • GTMetrix qui permet d’automatiser le test de votre site en calculant automatiquement les valeurs Y-Slow, Page Speed.
  • WebWait: très utile pour tester les modifications que vous faites sur votre site et en mesurer l’impact en terme de vitesse de chargement.
  • Apache Benchmark (ab pour les intimes): un outil libre sous licence Apache permettant de tester la montée en charge de votre site (c’est à dire comment votre site va réagir quand beaucoup d’utilisateurs vont le consulter simultanément). Un exemple de ligne de commande que j’utilise en local sur mon serveur:

ab -t 30 -c 5 http://blog.nicolargo.com/2010/10/booster-votre-blog-wordpress-avec-varnish.html

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

Time per request:       8.649 [ms] (mean)

Time per request:       1.730 [ms] (mean, across all concurrent requests)

Transfer rate:          329.82 [Kbytes/sec] received

Et vous blogueurs, webmasters, comment prenez-vous en compte la problématique de rapidité d’affichage de vos pages ?

Catégories
Open-source Planet-libre Web

Booster votre blog WordPress avec Varnish

Varnish est un accélérateur de sites Web fonctionnant sur le principe d’un reverse proxy. Varnish va prendre en charge les requêtes HTTP venant de vos visiteurs et communiquer avec votre serveur Web en ne demandant la création des pages Web seulement quand cela est nécessaire.

C’est un projet open-source sous licence FreeBSD.

Installation

Sur un Ubuntu Server (ou une distribution Debian « like »), l’installation se résume à la commande suivante. Vous aurez ainsi la version standard maintenu par les dépôts:

sudo aptitude install varnish

Pour disposer d’une version plus récente et seulement sous Ubuntu, vous pouvez utiliser les lignes de commande suivantes:

curl http://repo.varnish-cache.org/debian/GPG-key.txt | sudo apt-key add –

sudo echo « deb http://repo.varnish-cache.org/ubuntu/ $(lsb_release -s -c) varnish-2.1 » >> /etc/apt/sources.list

sudo aptitude update

sudo aptitude  install varnish

Nous allons donc dans un premier temps tester Varnish sur la configuration initiale de notre serveur Web (qui comprend dans mon exemple deux sites virtuels sous Apache). Cette configuration de test permettra de tester les performances de Varnish sans aucun impact sur vos sites (les visiteurs continueront à passer directement par votre serveur Web Apache). Enfin, si les tests sont concluants, nous modifierons la configuration finale pour que vos visiteurs transitent de manière transparente par Varnish.

Configuration de test

Varnish appelle backend les serveurs Web qu’il doit accélérer. Il est possible de définir un ou plusieurs backends par serveur Varnish.

Ainsi, si l’on souhaite accélérer le site http://blog.nicolargo.com qui est hébérgé sur un serveur, il faut saisir la configuration suivante dans le fichier /etc/varnish/default.vcl (configuration librement inspiré de la documentation officielle sur comment optimiser son blog WordPress avec Varnish) avec une gestion du cache sur les requête POST, pas de cache pour la zone admin, gestion des cookies de Google Analytics.

Vous pouvez télécharger la configuration Varnish VCL complète pour WordPress ici.

#

# Varnish 3 configuration for WordPress

#

# On Debian OS: /etc/varnish/default.vcl

#

# Nicolas Hennion (aka) Nicolargo

#

# Set the default backend (Nginx server for me)

backend default {

# My Nginx server listen on IP address 127.0.0.1 and TCP port 8080

.host = "127.0.0.1";

.port = "8080";

# Increase guru timeout

# http://vincentfretin.ecreall.com/articles/varnish-guru-meditation-on-timeout

.first_byte_timeout = 300s;

}

# Forbidden IP ACL

acl forbidden {

"41.194.61.2"/32;

"192.54.144.229"/32;

}

# Purge ACL

acl purge {

# Only localhost can purge my cache

"127.0.0.1";

"localhost";

}

# This function is used when a request is send by a HTTP client (Browser)

sub vcl_recv {

# Block the forbidden IP addresse

if (client.ip ~ forbidden) {

error 403 "Forbidden";

}

# Only cache the following sites

#if ((req.http.host ~ "(blog.nicolargo.com)") || (req.http.host ~ "(blogtest.nicolargo.com)")) {

if ((req.http.host ~ "(blog.nicolargo.com)")) {

set req.backend = default;

} else {

return (pass);

}

# Compatibility with Apache format log

if (req.restarts == 0) {

if (req.http.x-forwarded-for) {

set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;

} else {

set req.http.X-Forwarded-For = client.ip;

}

}

# Normalize the header, remove the port (in case you're testing this on various TCP ports)

set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");

# Allow purging from ACL

if (req.request == "PURGE") {

# If not allowed then a error 405 is returned

if (!client.ip ~ purge) {

error 405 "This IP is not allowed to send PURGE requests.";

}

# If allowed, do a cache_lookup -> vlc_hit() or vlc_miss()

return (lookup);

}

# Post requests will not be cached

if (req.request == "POST") {

return (pass);

}

# --- WordPress specific configuration

# Did not cache the RSS feed

if (req.url ~ "/feed") {

return (pass);

}

# Blitz hack

if (req.url ~ "/mu-.*") {

return (pass);

}

# Did not cache the admin and login pages

if (req.url ~ "/wp-(login|admin)") {

return (pass);

}

# Remove the "has_js" cookie

set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");

# Remove any Google Analytics based cookies

set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");

# Remove the Quant Capital cookies (added by some plugin, all __qca)

set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");

# Remove the wp-settings-1 cookie

set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");

# Remove the wp-settings-time-1 cookie

set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");

# Remove the wp test cookie

set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");

# Are there cookies left with only spaces or that are empty?

if (req.http.cookie ~ "^ *$") {

unset req.http.cookie;

}

# Cache the following files extensions

if (req.url ~ "\.(css|js|png|gif|jp(e)?g|swf|ico)") {

unset req.http.cookie;

}

# Normalize Accept-Encoding header and compression

# https://www.varnish-cache.org/docs/3.0/tutorial/vary.html

if (req.http.Accept-Encoding) {

# Do no compress compressed files...

if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {

remove req.http.Accept-Encoding;

} elsif (req.http.Accept-Encoding ~ "gzip") {

set req.http.Accept-Encoding = "gzip";

} elsif (req.http.Accept-Encoding ~ "deflate") {

set req.http.Accept-Encoding = "deflate";

} else {

remove req.http.Accept-Encoding;

}

}

# Check the cookies for wordpress-specific items

if (req.http.Cookie ~ "wordpress_" || req.http.Cookie ~ "comment_") {

return (pass);

}

if (!req.http.cookie) {

unset req.http.cookie;

}

# --- End of WordPress specific configuration

# Did not cache HTTP authentication and HTTP Cookie

if (req.http.Authorization || req.http.Cookie) {

# Not cacheable by default

return (pass);

}

# Cache all others requests

return (lookup);

}

sub vcl_pipe {

return (pipe);

}

sub vcl_pass {

return (pass);

}

# The data on which the hashing will take place

sub vcl_hash {

hash_data(req.url);

if (req.http.host) {

hash_data(req.http.host);

} else {

hash_data(server.ip);

}

# If the client supports compression, keep that in a different cache

if (req.http.Accept-Encoding) {

hash_data(req.http.Accept-Encoding);

}

return (hash);

}

sub vcl_hit {

# Allow purges

if (req.request == "PURGE") {

purge;

error 200 "Purged.";

}

return (deliver);

}

sub vcl_miss {

# Allow purges

if (req.request == "PURGE") {

purge;

error 200 "Purged.";

}

return (fetch);

}

# This function is used when a request is sent by our backend (Nginx server)

sub vcl_fetch {

# For static content strip all backend cookies

if (req.url ~ "\.(css|js|png|gif|jp(e?)g)|swf|ico") {

unset beresp.http.cookie;

}

# A TTL of 30 minutes

set beresp.ttl = 1800s;

return (deliver);

}

# The routine when we deliver the HTTP request to the user

# Last chance to modify headers that are sent to the client

sub vcl_deliver {

if (obj.hits > 0) {

set resp.http.X-Cache = "cached";

} else {

set resp.http.x-Cache = "uncached";

}

# Remove some headers: PHP version

unset resp.http.X-Powered-By;

# Remove some headers: Apache version & OS

unset resp.http.Server;

return (deliver);

}

sub vcl_init {

return (ok);

}

sub vcl_fini {

return (ok);

}

Le port d’écoute par défaut de Varnish est  TCP/6081 (défini dans le fichier /etc/default/varnish).

Si vous avez un Firewall (iptables) sur votre serveur, il faut penser à ajouter la règle suivante:

iptables -A OUTPUT -p tcp –dport 6081 -j ACCEPT

On relance Varnish pour prendre en compte la configuration:

sudo service varnish restart

Si tout marche bien, vos sites doivent s’afficher avec les URL: http://www.nicolargo.com:6081 et http://blog.nicolargo.com:6081 (à remplacer par vos sites hein, faite pas les boulets…).

Tests sur le site statique

Test local sur le site statique (avec uniquement des éléments statiques page HTML & images). La configuration donnée ci-dessous ne montre pas l’optimisation pour ce site.

Test sur une page statique (HTML simple) sans Varnish:

ab -t 30 -c 5 http://www.nicolargo.com/

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

Time per request:       7.6 [ms] (mean)

Test sur une page statique (HTML simple) avec Varnish:

ab -t 30 -c 5 http://www.nicolargo.com:6081/

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

Time per request:       7.6 [ms] (mean)

Sur notre site Web statique, on n’a donc pas de gain au niveau de la capacité maximale de montée en charge du serveur Apache (Requests per second). Ce qui est normal vu qu’Apache n’a pas grand chose à faire pour servir ce genre de page. Par contre on observe une occupation mémoire moindre pendant le test avec Varnish (environ 10% de moins).

Tests sur le site dynamique (WordPress)

Test en local sur le site Web dynamique (WordPress, déjà optimisé en suivant ce tutoriel).

Test sur la page index d’un blog WordPress sans Varnish:

ab -t 30 -c 5 http://blog.nicolargo.com/

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

Time per request:       8.5 [ms] (mean)

Test sur la page index d’un blog WordPress avec Varnish:

ab -t 30 -c 5 http://blog.nicolargo.com:6081/

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

Time per request:       1.5 [ms] (mean)

Sur notre site dynamique, la valeur ajoutée de Varnish est importante car on a ici un gain de plus de 488% en terme de nombre de requêtes simultanées que votre serveur peut fournir. Sur une page dynamique un peu plus lourde (par exemple un billet avec beaucoup de commentaires), le gain peut alors monter jusqu’à 650%.

Attention, cela ne veut pas dire que votre blog va s’afficher 488% plus vite avec Varnish mais « seulement » que votre serveur pourra accepter 488% de requêtes simultanées maximales en plus.

Configuration finale

Une fois votre site accéléré validé, il faut passer Varnish en production. Les actions suivantes sont à effectuer.

Configurer le serveur Apache hébergeant votre blog pour écouter sur un port différent du port TCP/80 (par exemple TCP/8080). Sous Ubuntu Server, on commence par modifier le fichier /etc/apache2/ports.conf pour lui demander d’écouter les requêtes HTTP sur le port 8080 en lieu et place du port 80:

NameVirtualHost *:8080

Listen 8080

On modifie ensuite le fichier de configuration de nos sites /etc/apache2/site-enabled/virtualhosts: (notez bien la modification du port :8080 et l’utilisation du format de log varnishcombined)

# WWW

<VirtualHost *:8080>

DocumentRoot /var/www/www

ServerName nicolargo.com

ServerAlias www.nicolargo.com

ServerAdmin contact@pasdespam.com

CustomLog /var/log/apache2/www-access.log varnishcombined

ErrorLog /var/log/apache2/www-error.log

</VirtualHost>

# BLOG

<VirtualHost *:8080>

DocumentRoot /var/www/blog

ServerName blog.nicolargo.com

ServerAdmin contact@pasdespam.com

CustomLog /var/log/apache2/blog-access.log varnishcombined

ErrorLog /var/log/apache2/blog-error.log

</VirtualHost>

On configurer le serveur Apache pour loguer les adresses sources et non pas l’adresse du serveur Varnish. Il suffit pour cela d’ajouter la ligne suivante dans le fichier /etc/apache2/apache2.conf:

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

La configuration d’Apache est maintenant fini, il faut alors configurer Varnish pour écouter sur le port TCP/80 et changer la configuration du « backend » en éditant la section suivante du fichier /etc/default/varnish:

DAEMON_OPTS= »-a :80 \

-T localhost:6082 \

-f /etc/varnish/default.vcl \

-S /etc/varnish/secret \

-p thread_pool_add_delay=2 \

-p thread_pools=4 \

-p thread_pool_min=200 \

-p thread_pool_max=4000 \

-p cli_timeout=25 \

-p session_linger=100 \

-s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G »

On change ensuite la configuration de Varnish pour pointer les backends vers le port 8080:

backend blog {

.host = « blog.nicolargo.com »;

.port = « 8080 »;

}

La dernière chose à faire si votre serveur est protégé par un Firewall IpTables est de modifier la règle ajoutée dans le premier chapitre de ce billet et d’y ajouter une nouvelle règle pour une éventuelle administration locale de Varnish à l’aide de l’utilitaire varnishadm:

iptables -A OUTPUT -p tcp –dport 8080 -j ACCEPT

iptables -A OUTPUT -p tcp –dport 6082 -s 127.0.0.1 -j ACCEPT

On prend en compte la configuration finale en relancant les deux processus (Apache et Varnish):

sudo service apache2 restart

sudo service varnish restart

A partir de ce moment là, toutes les requêtes HTTP de vos visiteurs seront d’abord prise en compte par Varnish (sur le port TCP/80) puis ensuite, si nécessaire, par votre serveur Apache (TCP/8080).

Ecrire les logs sur le disque

Update du 22/02/2012

Par défaut, Varnish n’écrit pas les logs dans un fichier. Pour forcer Varnish à générer des fichiers de logs au format NSCA dans le sous répertoire /var/log/varnishnsca, nous allons utiliser le daemon VarnishNSCA (installé en même temps que Varnish). Il faut commencer par vérifier que script de lancement du daemon VarnishNSCA (/etc/init.d/varnishnsca) ne contient pas un bug, comme c’est le cas dans ma version 3.0.2:

Remplacer la ligne suivante dans le fichier /etc/init.d/varnishnsca:

DAEMON_OPTS= »-a -w ${LOGFILE} -D -P $PIDFILE} »

par

DAEMON_OPTS= »-a -w ${LOGFILE} -D -P ${PIDFILE} »

Puis forcer le lancement du daemon en modifiant le fichier /etc/default/varnishnsca:

VARNISHNCSA_ENABLED=1

On peut ensuite lancer le daemon:

sudo service varnishnsca start

Il est alors possible d’analyser ce fichier avec vos outils de stats favoris. Par exemple en ligne de commande avec GoAccess:

goaccess -f /var/log/varnish/varnishncsa.log

Quelques commandes utiles

  • varnishlog: Affichage du log du daemon Varnish.
  • varnishstat: Affichage des statistiques d’utilisation de Varnish.
  • varnishhist: Affiche un historique sous forme de graphe des requêtes faites à votre serveur Varnish.
  • varnishadm: une interface d’administration locale de Varnish

Vous pouvez également consulter la documentation en ligne à l’adresse suivante.

Catégories
Blog Open-source Planet-libre

Architecture pour un blog optimisé

Hier, j’ai passé une grande partie de ma journée dans les aéroports, j’en ai profité pour résumer dans un schéma quelques techniques d’optimisations que l’on peut actuellement mettre en place pour booster son blog.

Depuis que Saint Google prend en compte le temps de chargement des pages dans ses algorithmes, le sujet est devenu très à la mode. AntoineJérôme et moi même avont abordé récemment  le sujet dans nos blogs respectifs.

J’aimerai que l’on échange sur cette architecture afin que je puisse faire évoluer ce schéma.

Vous pouvez également récupérer le schéma au format Dia.

Catégories
Blog Open-source Systeme Web

12 étapes pour optimiser les performances de son blog WordPress

Lorsque l’on choisi d’héberger son blog WordPress (sur un serveur dédié ou virtuel), la problématique des performances vient assez vite sur le tapis. En effet, l’optimisation du blog permet non seulement de réduire le temps de chargement des pages (et donc d’être bien vu par seigneur gOOgle) mais également de dimensionner au plus juste son serveur: gain de temps d’un coté, gain d’argent de l’autre.

Nous allons donc dans ce billet parcourir une liste non exhaustive de techniques d’optimisations:

  • ETAPE 1: Hardware
  • ETAPE 2: Noyau Linux
  • ETAPE 3: Mise à jour du système d’exploitation
  • ETAPE 4: MemCached
  • ETAPE 5: Les modules Apache
  • ETAPE 6: Configuration d’Apache
  • ETAPE 7: XCache (PHP)
  • ETAPE 8: MySQL
  • ETAPE 9: WP-DBManager
  • ETAPE 10: W3 Total Cache
  • ETAPE 11: Thème WordPress
  • ETAPE 12: Tester/Surveiller

Les commentaires seront bien sur là pour nous faire partager vos solutions !

Le hardware

ETAPE 1) C’est un peu le serpent qui se mort la queue… En effet il est assez difficile de dimensionner le hardware d’un serveur sans avoir fait les optimisations est sans connaitre précisément le trafic du blog (surtout vrai pour les nouveaux blog).

C’est en partie pour ces raisons qui j’ai choisi un serveur VPS de chez Gandi. En effet il est possible d’augmenter ou de diminuer les « parts » affectées à son serveur de manière dynamique (une « part » correspond à une ressource CPU, mémoire et disque).

J’ai actuellement « 3 parts » sur le serveur du Blog de Nicolargo mais je m’en sers également pour d’autres besoins (je pense que pour ce blog, un serveur avec « 2 parts » suffirait largement). Pour une première expérience dans le monde du blogging, un serveur « 1 part » devrait convenir (environ 12€ HT par mois).

Je n’entrerai pas dans les discussions sur le coups relativement élevé de cette solution par rapport à un serveur dédié comme l’offre Dedibox de Online.net.

Le système d’exploitation

L’optimisation du système d’exploitation dépend bien sûr de la distribution Linux utilisée. Lors de la création de mon serveur j’ai choisi d’utiliser Ubuntu Server 8.04 que j’ai fait évolué en 9.04. Pourquoi cette distribution GNU/Linux ? Tout simplement car c’est celle que je connais le plus…

ETAPE 2 ) On commence par optimiser le noyau Linux . Je passe rapidement sur les explications. Il existe de nombreux article sur le net détaillant ces configurations. La configuration donnée est celle de mon serveur VPS (3 parts, 1 Go de RAM), elle doit être adaptée à votre configuration hardware.

Il faut éditer/modifier le fichier /etc/sysctl.conf (disponible sur GitHub):


Puis on applique:

sudo sysctl -p

Sources:

ETAPE 3) La première chose à faire quand on administre un serveur est bien entendu de le maintenir à jour au niveau des logiciels systèmes et applicatifs. Pour cela je m’aide d’un petit logiciel nommé cron-apt. Ce dernier permet de m’avertir par mail quand une mise à jour est disponible (par exemple une nouvelle version d’Apache ou une librairie PHP). En plus de corriger des failles de sécurités, les mises à jours permettent souvent d’obtenir de meilleures performances (que ce soit en rapidité ou en consommation de ressources).

L’installation est des plus simple:

sudo aptitude install cron-apt

Configuration en éditant le fichier /etc/cron-apt/config, notamment les lignes suivantes:

MAILTO= »nom@domaine.com »

MAILON= »always »

Un mail sera automatiquement envoyé à l’adresse nom@domaine.com, tout les matins à 4:00. Voici un exemple:

On peut voir qu’une mise à jour est disponible. Il ne reste plus qu’a se connecter en SSH sur le serveur et faire un:

sudo aptitude safe-upgrade

Il est possible de faire automatiquement les mises à jour mais je pense cela risqué si quelque chose se passe mal…

On critique souvent les serveurs VPS pour leurs faibles performances disque. Bien que je trouve celle des VPS Gandi plutôt acceptable (environ 6 Mo/s pour l’écriture et 24 Mo/s pour la lecture de petits fichiers type script PHP), il est intéressant de mettre en place un cache mémoire sur notre serveur. Ainsi, les applications compatibles pourront lire et écrire les données en RAM et non plus sur disque.

ETAPE 4) Nous allons donc installer MemCached, un cache mémoire libre.  On commence par installer le cache ainsi que la librairie Perl associée (qui sera utilisée par WordPress):

sudo aptitude install libcache-memcached-perl php5-memcache memcached

Par défaut, le cache écoute sur l’adresse 127.0.0.1 et sur le port TCP/11211. La taille du cache mémoire est de 64 Mo. J’ai gardé ces paramètres pour mon utilisation.

On peut obtenir des statistiques sur l’utilisation de MemCached en utilisant la commande:

# echo « stats » | nc localhost 11211

STAT pid 2806

STAT uptime 698465

STAT time 1283351366

STAT version 1.2.2

STAT pointer_size 32

STAT rusage_user 31.829989

STAT rusage_system 123.891742

STAT curr_items 12834

STAT total_items 1394993

STAT bytes 48830599

STAT curr_connections 11

STAT total_connections 16845

STAT connection_structures 31

STAT cmd_get 4012823

STAT cmd_set 1394993

STAT get_hits 2547543

STAT get_misses 1465280

STAT evictions 5694

STAT bytes_read 10561103955

STAT bytes_written 37908972470

STAT limit_maxbytes 67108864

STAT threads 1

END

Apache & PHP

On continue ensuite avec l’optimisation du serveur Apache (version 2.xx au moment de l’écriture de ce billet).

ETAPE 5) Apache se base sur un système de modules pour ajouter de nouvelles fonctions à votre serveur Web. Sous Ubuntu Server, la liste des modules actifs se trouvent dans le répertoire /etc/apache2/mods-enabled. Un petit ls dans ce répertoire vous donne donc la liste. L’optimisation consiste à supprimer les modules non utilisés. Je vous conseille la lecture de ce billet qui donne la liste des modules nécessaires au fonctionnement de WordPress. Attention, si votre serveur héberge d’autres sites Web que votre blog, il faut vérifier de ne pas supprimer un module utile…

Voici la liste de mes modules sur mon serveur:

alias.conf autoindex.conf dir.conf negotiation.load

alias.load autoindex.load dir.load php5.conf

auth_basic.load cgi.load env.load php5.load

authn_file.load dav.load expires.load rewrite.load

authz_default.load dav_svn.conf headers.load setenvif.conf

authz_groupfile.load dav_svn.load mime.conf setenvif.load

authz_host.load deflate.conf mime.load status.conf

authz_user.load deflate.load negotiation.conf status.load

ETAPE 6) On configure ensuite la manière dont les processus Apache sont lancés et gérés en mémoire et d’autres paramètres. Il faut éditer la section suivante dans le fichier /etc/apache2/apache2.conf (ou httpd.conf sur d’autre distribution GNU/Linux). Pour une description des paramètres, merci de lire le billet suivant:

<IfModule mpm_prefork_module>

StartServers 5

MinSpareServers 5

MaxSpareServers 10

MaxClients 40

MaxRequestsPerChild 2000

</IfModule>

# 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

J’ai également modifier le fichier /etc/apache2/conf.d/optimization pour gagner quelques précieux  points aux tests Yslow et Page Speed:

Header unset ETag

FileETag None

On applique la configuration en relançant Apche:

sudo /etc/init.d/apache2 restart

Sources:

ETAPE 7) WordPress se base sur le langage PHP qui est connu pour être flexible mais pas très performant. C’est pour cela qu’il est nécessaire d’installer un cache PHP sur votre serveur Web WordPress. En gros, il permet de mettre en cache le code PHP déjà compilé. J’utilise personnellement XCache.

L’installation est simple:

sudo aptitude install php5-xcache

On configure ensuite le fichier/etc/php5/conf.d/xcache.ini (à adapter à votre configuration):

xcache.size = 64M

On relance le serveur Web:

sudo /etc/init.d/apache2 restart

Source:

MySQL

Souvent décriée, MySQL reste à l’heure actuelle la base de donnée officielle supportée par le moteur de blogging WordPress. Nous allons donc étudier quelques techniques d’optimisation.

ETAPE 8) On commence par éditer le fichier de configuration /etc/mysql/my.cnf pour ajuster la taille des caches (encore une fois les valeurs sont à adapter en fonction de votre audience/configuration):

query_cache_type = 1

query_cache_limit = 2M

query_cache_size = 32M

ETAPE 9) On installe ensuite le plugin WordPress WP-DBManager. Ce dernier permet de maintenir une base de données optimisée à travers le temps. En plus des fonctions de sauvegarde (manuelle ou automatique) et de restauration de votre base de données WordPress, ce plugin permet de d’optimiser et réparer cette même base.

Source:

WordPress

ETAPE 10) L’installation standard de WordPress (la fameuse installation en 5 minutes) ne tient pas en compte de l’optimisation. Nous allons voir comment configurer l’utilisation parallèle de XCache et Memcached (préalablement installé dans les étapes n°3 et n°5). Pour cela nous allons utiliser l’indispensable plugin W3 Total Cache.

Après l’installation du plugin, il faut se rendre dans le menu Performance > General setting de la page d’administration de WordPress puis cliquer sur le bouton Compatibility check pour vérifier que XCache et Memcached sont bien détectés:

Opcode cache: XCache

Memcache extension: OK

Ensuite on configure WordPress pour utiliser Memcached en activant toutes le fonctions de cache (CDN mis à part) et en utilisant le démon Memcached. Exemple de configuration pour les pages:

Dans le menu Page cache settings j’active toutes les fonctions sauf pour les pages 404:

Dans le menu suivant (Minify settings), j’active toutes les fonctions. Cela à pour but d’optimiser les pages, css et js avant d’être envoyés vers les lecteurs (attention, certains JS n’aiment pas beaucoup ces optimisations, à tester donc…).

Enfin, dans le menu Browser Cache setting, j’active toutes les fonctions et les expires header lifetime à:

  • 3600 secondes pour JS / CSS
  • 3600 secondes pour le HTML
  • 2592000 secondes pour les autres fichiers

A l’heure actuelle, le trafic généré par mon blog ne nécessite pas l’utilisation de caches réseau répartis (CDN). Mais c’est une optimisation à prendre en compte pour les « gros » sites.

Sources:

ETAPE 11) Rien ne sert d’avoir un kernel Linux, un serveur Web, un moteur PHP et un WordPress optimisés si le thème de votre blog est mal développé. Il est important de tester ce thème et notamment les plugins utilisées. Ces derniers utilisent souvent des JavaScripts qui peuvent pénaliser fortement le temps de chargement de vos pages. Rien de tel que des mesures de type YSlow et Page Speed pour mettre en évidence ce qui ne va pas.

Sources:

Tester/surveiller son serveur

ETAPE 12) Pour tester les optimisations mise en place, j’utilise l’outil  GTMetrix qui donne les valeurs YSlow et Page Speed (avec un archivage vous permettant de voir l’évolution des performances de votre blog à travers le temps).

De manière locale et surtout pour valider la configuration de votre serveur Web (Apache dans ce document), vous pouvez utiliser la commande suivante:

ab -t30 -c5 http://blog.mondomaine.com/

La ligne intéressante donnant le nombre maximal de requête par seconde que votre blog peut supporter est la suivante:

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

A un niveau plus bas, la commande Linux netstat permet de donner pas mal d’informations sur l’état des sockets:

netstat -tan | grep ‘:80 ‘ | awk ‘{print $6}’ | sort | uniq -c

Enfin, pour surveiller l’activité de MySQL, j’utilise la commande MySqlReport.

Autres optimisations possibles

D’autres optimisations sont possibles, pour vous donner un exemple, je suis tombé l’autre jour sur le première article d’une série en cours sur le blog d’Antoine Benkemoun qui propose d’utiliser Squid pour booster les performances de votre site. C’est une technique très intéressante mais qui nécessite, pour être vraiment efficace, l’utilisation deux deux machines différentes. Une servant de reverse proxy-cache et une autre hébergeant votre blog.

Il est aussi possible de se passer du serveur Web Apache (il est vrai un peu lourd à administrer) pour se pencher vers des serveurs plus légers comme NGinx ou Cherookee. Update: Ou bien d’utiliser NGinx comme serveur Web pour les pages statiques et Apache pour les pages dynamiques (voir exemple de configuration ici). L’avantage d’une telle configuration est un gain non négligeable en terme de consommation mémoire.

Il existe un nombre incalculable d’optimisations possibles, j’espère d’ailleurs en découvrir de nouvelles dans vos commentaires…

Catégories
Blog Open-source Web

Nouveau thème pour le blog !

Après 3 ans de bons et loyaux services, le thème Largo v1 prend sa retraite bien méritée. Il laisse sa place à Largo v2 (oui je sais, ce n’est pas très original…).

Pourquoi un nouveau thème ?

Tout simplement parce que je commençais à me lasser du précédent. De plus comme Largo v1 était le premier thème WordPress que j’avais développé « from scratch » (merci encore aux tutos de Francis), il était assez difficile à administrer et à faire évoluer.

Une fois la décision de changement de thème prise, j’ai commencé à regarder ce qu’il existait sur le marché, que ce soit au niveau des thèmes gratuits et payants. Je n’ai malheureusement jamais trouvé un thème qui réponde totalement à mes besoins. N’ayant pas les moyens de le faire développer par des professionnels du Webdesign (peut être la prochaine version…), j’ai mis la main dans le clavier et la souris.

Petit tour du propriétaire

Le haut et le base du blog…

On retrouve en haut à gauche une liste de liens vers les pages statiques du blog qui évoluera selon… mes envies. Pour l’instant des liens vers:

  • la home page
  • la catégorie Open-source (le fond de commerce du blog;))
  • la « famous » page Nagios & Co avec tous les billets sur la supervision système et réseau
  • la « nouvelle » page GStreamer avec tous les billets sur ce framework multimedia
  • la page Publicité pour les annonceurs (coucou)
  • la page A propos
  • la Contact

En haut à droite, on a la liste des liens pour s’abonner au blog (c’est à dire recevoir les nouveaux billets sans forcement venir tout les jours sur le blog). Plusieurs solutions: par mail, via Facebook, par Twitter et enfin par RSS.

En bas du blog, on a le pas très original footer:

La home page (index)

On retrouve sur la page principale la liste des derniers billets avec quelques informations:

Les billets

C’est le coeur du blog, vu que ces pages représentent 95% des visites… A gauche du billet, j’ai mis en place une sidebar avec quelques informations et liens utiles aux lecteurs pour approfondir le sujet.

Au bas du billet, un menu permet de partager ou lire plus d’articles sur le sujet:

Il suffit de cliquer sur le bandeau vert pour accéder aux différents sous menus…

Enfin les commentaires se trouve après tout celà:

Conclusion

Bien que j’ai testé en interne (et avec l’aide de Nicolas aka Ritchy) le thème, il doit sûrement y avoir quelques coquilles restantes. Je compte sur vous pour me les signaler. De plus si vous avez des questions ou des remarques sur ce nouveau thème je suis également preneur !

Ce blog est fait pour vous !

PS: suite au hack du blog et à mon changement d’hébergeur, il semble que certains utilisateurs du réseau Free utilisent des DNS pointant encore sur mon ancien serveur. J’ai envoyé un mail au support de Free en espérant que le problème soit vite résolu…

Catégories
Blog Open-source Web

Installation d’un blog WordPress sur un VPS Gandi

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 !

Catégories
Blog Developpement Open-source

Un blog WordPress local pour vos développements

Envie de vous lancer dans le développement de votre propre thème WordPress ? Envie tester votre dernier plugin sur une copie de votre blog sans impact pour vos lecteurs ? Envies de tester cette fameuses version 3.0bêta de WordPress ?

Ces quelques exemples justifient l’installation en local (donc disponible même sans liaison Internet), sur votre PC GNU/Linux d’un environnement de développement de blog complet. Celui-ci se composera:

  • d’un serveur LAMP à jour (Linux, Apache, MySQL, PHP)
  • de la dernière version de WordPress
  • de votre IDE préférée (Bluefish, Eclipse, Anjuta, NetBeans, Emacs, vi…)

Catégories
Blog Developpement

Upgrade de WordPress 2.8 vers 2.9

La dernière version de WordPress vient de sortir. Elle apporte son lot d’améliorations et de nouvelles fonctionnalités (voir la liste exhaustive ici). Voici la procédure, de plus en plus simple, pour mettre à jour votre blog d’une version 2.8.x vers 2.9.

On sauvegarde

On commence bien sûr par sauvegarder l’ensemble du blog (contenue ET base de donnée), on ne sait jamais…

On met à jour

J’utilise, depuis la version 2.7 de WordPress, la procédure de mise à jour automatique, il suffit de se rendre dans le menu « Tools / Upgrade » et de cliquer sur le lien « Upgrade to WordPress 2.9 » et le tour est joué: