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

Sécuriser son blog WordPress #4

Nous voici donc dans le dernier volet de notre saga sur la sécurisation d’un serveur Web hébergeant un blog WordPress. Si vous avez suivi les recommandations des billets précédant vous devriez  avoir un serveur avec un niveau de sécurité acceptable…

La perfection n’existant pas, du moins en sécurité informatique, il est nécessaire d’avoir sous la main les moyens de remonter rapidement votre serveur en cas de piratage.

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

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

Sauvegardes régulières

En effet, quelque soit les moyens que vous aller mettre en oeuvre, votre serveur ne sera jamais protégé à 100%. Il est donc essentiel d’avoir une sauvegarde récente de l’ensemble de votre blog, c’est à dire:

  • vos fichiers statiques (images, videos, fichiers de données…)
  • votre base de donnée SQL
  • une procédure (ou encore mieux un script comme celui-ci) à jour de réinstallation de votre serveur

Voici donc le détail de ces actions.

Sauvegarde des fichiers statiques

J’effectue cette sauvegarde en deux étapes.

1) La première est un backup de l’ensemble de mon répertoire Web (contenant WordPress et les fichiers statiques) sur un deuxième disque qui est attaché à mon serveur virtuel (VPS). Ainsi en cas de crash disque, les données seront disponibles localement. Attention de bien vérifier auprès de votre hébergeur que ce deuxième disque virtuel est bien sur un disque physique différent de celui sur lequel est hébergé votre blog !

J’utilise le logiciel RSnapShot pour effectuer cette tache. J’ai rédigé un billet sur le sujet que vous pouvez consulter ici.

2) La seconde étape est de copier de manière régulière (et si possible automatique) ces sauvegardes sur une autre machine. En effet, si un méchant hackeur pirate votre serveur, il y a de fortes chances qu’il s’en prenne également à vos sauvegardes locales.

Pour cela, j’utilise le service « in the cloud » Dropbox (en attendant un service équivalent basée sur des clients libres). Pour installer et utiliser Dropbox sur un serveur sans interface graphique, vous pouvez suivre cette procédure. J’archive avec une commande tar l’ensemble du répertoire WordPress puis je le copie dans un sous répertoire de ma Dropbox.

Sauvegarde de la base de donnée SQL

J’utilise le plugin WordPress WP-DBManager qui, en plus d’optimiser automatiquement ma base de donnée,  sauvegarde et envoi une archive directement sur mon adresse mail (la fréquence des expéditions est configurable).

Il est également possible d’automatiser une commande mysqldump dans votre crontab systeme et comme les fichiers statiques copier l’archive dans une copie locale et dans votre Dropbox.

Re-installation rapide de son serveur « from scratch »

Ce point est souvent négligé, à tort !

Quoi de plus long que de ré-installer et re-configurer un serveur en production sous la pression du temps… Avoir un script qui reproduit ces étapes de configuration est plus qu’utile en cas de problème : piratage ou bien panne matérielle. En cas de piratage, il faudra évidemment chercher la cause du problème et la résoudre avant de remettre son serveur en ligne et bien entendu modifier tous les mots de passes (système, WordPress, base de donnée SQL…).

Maintenance et supervision

Dans la première partie de cette série de billets, nous avons installé le logiciel cron-apt qui envoie automatiquement un mail quand des mises à jour son disponible pour votre serveur. Il faut bien sûr prendre le temps de lire ces mails et de les traiter le cas échéant.

On peut également installer le logiciel log-watch qui surveiller pour vous les fichiers de log et envoyer automatiquement un rapport par mail. J’ai personnellement laissé tombé ce type de logiciel sur mon serveur personnel car la quantité des informations remontées nécessitait trop de temps pour être interprétée . Dans le même ordre d’idée il y a également logcheck qui permet de recevoir un rapport toutes les heures sur les lignes « anormales » trouvées dans les logs.

aptitude install logcheck

Le fichier de configuration se trouve dans /etc/logcheck/logcheck.conf. La liste des fichiers de log à surveiller dans /etc/logcheck/logcheck.logfiles.

Il faut également surveiller les rootkit (petit programme permettant d’obtenir les droits d’administration de votre serveur en se basant sur des failles connues). Pour cela il faut installer un détecteur de rootkit comme  chkrootkit:

sudo aptitude install chkrootkit

Puis le lancer régulièrement (le plus simple est de le faire par crontab et d’envoyer le résultat par mail).

sudo chkrootkit

A noter que dans la version actuelle de chkrootkit (0.49). Un faux positif est détecté sous Ubuntu 10.04 LTS dans le fichier /etc/init:

Searching for Suckit rootkit… Warning: /sbin/init INFECTED

Le message est donc à ignorer jusqu’à la prochaine mise à jour.

Pour conclure ce chapitre quelques logiciels que l’on peut installer:

  • tmpreaper : vider le /tmp régulièrement
  • vérifier l’intégrité des fichiers systèmes avec Samhain (disponible dans les dépots Ubuntu).

Conclusion

Vous l’aurez compris, sécurisé son système prend du temps, consomme des performances non négligeables et demande des connaissances approfondies. C’est néanmoins une étape fondamentale pour se protéger des pirates et autres scripts automatisés qui se feront une joie de rentrer dans votre site web ou pire, votre serveur.

Les applications présentées devraient néanmoins vous permettre de limiter la casse, mais gardez à l’esprit que la plupart des attaques se faisant via votre site web, le protéger correctement reste une des meilleurs solutions existantes.

/etc/logcheck/logcheck.conf
Catégories
Blog Open-source Web

Le panier du marché libre #6

Sixième édition du marché libre. On prends son petit panier et on va glaner les liens suivants:

Bon week-end à vous !

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

Sécuriser son blog WordPress #3

WordPress n’a pas forcement bonne presse au niveau de la sécurité. Le coeur PHP du moteur WordPress est pourtant surveillé de très près et les corrections des failles sont assez rapides (voir par  exemple la publication de la version 3.0.4).

Par contre les plugins, qui sont un avantage indéniable de WordPress par rapport aux autres CMS, sont également un talon d’Achille… En effet, WordPress dispose d’une base de plugins impressionnante (plus de 12.700 au moment de l’écriture de ce billet) dont les développeurs sont plus ou moins sensibilisés à la problématique de la sécurité… Ajouter des plugins à votre blog, c’est multiplier les risques au niveau de la sécurité.

Dans ce billet, nous allons voir comment installer puis configurer WordPress pour compliquer la tache des personnes voulant attaquer votre blog.

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

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

Partir sur de bonnes bases

Nous allons détailler l’installation, la configuration initiale puis la gestion des mises à jours de WordPress.

    Installation de WordPress

    Personnellement j’utilise sur mon serveur deux versions de WordPress en parallèle.

    La première est celle du blog « de production » (celui que vous êtes en train de lire) utilise la version stable SVN (c’est à dire la 3.0.4 au jour d’aujourd’hui). J’utilise la commande suivante pour effectuer l’installation (dans le répertoire racine de mon serveur Web: /var/www/blog):

    svn co http://core.svn.wordpress.org/branches/3.0/

    La seconde, dite « de validation » me sert pour tester mon blog (thème et plugins) sur les futures versions de WordPress (3.1 par exemple). Elle n’est pas publique, seul les administrateurs peuvent y accéder. Pour installer cette version de WordPress, j’utilise la commande suivante dans un deuxième répertoire de mon serveur Web (/var/www/blogfutur):

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

    Avant de suivre la fameuse installation en 5 minutes de WordPress, je vous conseille de changer le préfixe des tables MySQL en éditant la ligne suivante dans votre fichier de configuration wp-config.php et en remplacant wp_ par une chaine aléatoire (par exemple apvbty_):

    $table_prefix  = ‘apvbty_’;

    Attention, cette manipulation est à faire seulement sur un nouveau blog. En effet, si vous avez déjà une base de donnée SQL existante il faut d’abord changer le nom du préfixe des tables dans MySQL (voir hack en fin de billet) sous peine de ne plus pouvoir accéder à vos données.

    Une fois l’installation de WordPress finalisée, nous allons commencer par fixer les droits au niveau des fichiers dans ces répertoires. En partant sur l’hypothèse ou votre serveur Web tourne sous l’utilisateur www-data et dans le répertoire /var/www/blog, j’utilise les commandes suivantes:

    chown -R www-data:www-data /var/www/blog

    find /var/www/blog -type d -exec chmod 755 {} \;

    find /var/www/blog -type f -exec chmod 644 {} \;

    chmod 640 /var/www/blog/wp-config.php

    find /var/www/blog/wp-content/themes -type d -exec chmod 775 {} \;

    find /var/www/blog/wp-content/themes -type f -exec chmod 664 {} \;

    Pour vous simplifier la vie, je vous conseille de mettre ces commandes dans un script shell afin de pourvoir rapidement les appliquer sur votre arborescence.

    Mise à jour de WordPress

    Comme nous l’avons vu, les développeurs de WordPress sont assez réactifs sur la correction des failles de sécurité. Encore faut-il que vous pensiez à mettre à jour votre instance de WordPress…

    J’utilise un script shell pour mettre à jour WordPress à partir de SVN:

    #!/bin/bash

    # Simple script pour mettre a jour WordPress

    # Test que le script est lance en root

    if [ $EUID -ne 0 ]; then

    echo « Le script doit être lancé en root: # sudo $0″ 1>&2

    exit 1

    fi

    WPPATH= »/var/www/blog »

    echo « 1) Mise a jour de WordPress »

    cd $WPPATH 2>&1 /dev/null

    CURRENTVERSION=`svn info | grep « Revision:  » | awk ‘{ print $2 }’`

    svn update

    rm $WPPATH/wp-admin/install.php

    cd – 2>&1 /dev/null

    echo « 2) Verification des droits des fichiers »

    chown -R www-data:www-data $WPPATH

    find $WPPATH -type d -exec chmod 755 {} \;

    find $WPPATH -type f -exec chmod 644 {} \;

    chmod 640 $WPPATH/wp-config.php

    find $WPPATH/wp-content/themes -type d -exec chmod 775 {} \;

    find $WPPATH/wp-content/themes -type f -exec chmod 664 {} \;

    echo « 3) Fin de la mise a jour »

    echo « En cas de pb: svn update -r$CURRENTVERSION »

    Il est possible de lancer ce script toutes les nuits (par exemple par crontab) pour éviter de se retrouver avec un blog hacké quand vous partez en congés

    Le .htaccess

    Ce fichier qui doit se trouver à la racine de votre site Web, contient des entrées utiles à la sécurité de votre site. Le mien commence par:

    # 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>

    Certains plugins ajoutent pas mal de chose dans ce fichier (notamment W3 Total Cache, le plugin d’optimisation des performances que j’ai abordé dans ce billet).

    Un peu de bon sens…

    Vous avez donc entre les mains une installation toute propre et sécurisée de WordPress, c’est normalement à partir de ce moment là que les choses se gâtent…

    On commence par l’erreur de base: ne pas utiliser un mot de passe « strong » pour le compte admin. Encore mieux, créer un nouveau compte administrateur et supprimer le compte admin par défaut.

    L’installation des plugins apportent également son lot de failles de sécurité. C’est là qu’il faut se faire violence et n’installer que les plugins indispensables au bon fonctionnement de votre blog. Il faut également veiller à mettre à jour régulièrement vos plugins (l’interface d’administration de WordPress permet de faire cela très simplement).

    Enfin vos thèmes peuvent également fragiliser votre blog en insérant des codes PHP ou JS. Si vous avez les compétences il faut faire un audit de votre thème ou au minimum utiliser des thèmes connus et validés.

    Des plugins pour la sécurité

    Parmis ces plugins, j’en utile trois dédiés à la sécurisation:

    • Secure WordPress permet d’automatiser certaines actions pour sécuriser votre blog.

    • WordPress File Monitor: Surveille les fichiers du moteur WordPress et vous alerte (par mail et/ou directement dans l’interface d’administration de WordPress) en cas de modification.
    • On peut également citer WordPress Security Scan qui permet de faire un audit de votre blog en testant notamment les droits de vos fichiers, les mots de passes, la base de données…

    Quelques hacks en bonus

    Compliquer la tache des attaques par force brute en supprimant l’indicateur (« mauvais mot de passe ») lors d’une tentative de connexion à l’interface d’administration. Il faut juste ajouter la ligne suivante à votre fichier functions.php (thème):

    add_filter(‘login_errors’, create_function(‘$a’, « return null; »));

    Si vous avez une base de données MySQL existante avec le préfixe par défaut (wp_) et que vous souhaitez le changer, il est possible de faire celà directement à la main par une requête MySQL ou alors plus simplement en utilisant le plugin WP-Security-Scan.

    Tester votre WordPress

    Pour tester la sécurité de votre blog, rien ne vaut une simulation d’attaque. Pour celà vous pouvez utiliser le logiciel libre Nikto.

    On commence par installer Nikto sur un PC client sous Ubuntu (qui va simuler l’attaque):

    sudo aptitude install nikto

    Puis on lance le test (remplacer URL par l’URL de votre blog WordPress):

    nikto -h URL

    Le rapport devrait ensuite s’afficher.

    Sources:

    Catégories
    Blog Open-source Web

    Le panier du marché libre #5

    Un très bon marché libre cette semaine, glané dans mon flux RSS, mon Twitter et un peu dans Quora que je teste depuis la fin de la semaine dernière.

    D’autres choses importantes de votre coté ?

    Catégories
    Blog Open-source Web

    11 sites pour votre veille technologique sur le libre

    Il y a quelques jours, j’ai poser la question suivante sur Twitter, Identi.ca, facebook et Quora:

     » Quels sont vos principales sources d’informations concernant les logiciels libres (sites, blogs…) ? « 

    Voici un résumé des réponses.

    Les sites spécialisés

    GCU-Squad

    Depuis plus de 10 ans, l’agrégateur de billet GCU Squad arrive encore à trouver des titres décalés 🙂 Une source indispensable pour les sysadmins :).

    >>> http://gcu.info/ <<<

    FramaBlog

    Le blog de Framasoft, LE défenseur des logiciels libres en France.

    >>> http://www.framablog.org/index.php <<<


    LinuxFR

    Le principe de ce site est le suivant. Les utilisateurs proposes des news dans le domaine des logiciels libres. Les news sont validés par une équipe avant publication assurant ainsi une sélection aux petits oignons…

    >>> http://linuxfr.org/ <<<



    Ars Technica

    Site bien connu en Anglais ayant une section open-source. Orienté grand public plutôt que geek acharnés.

    >>> http://arstechnica.com/open-source/ <<<


    Le blog de Philippe Scoffoni

    Même si Philippe est plus connu pour ces billets fleuves et philosophique sur le monde des logiciels libres, il est en plus une très bonne source d’informations pour la combo « Cloud + Open-source ». Un must have dans votre agrégateur RSS.

    >>> http://philippe.scoffoni.net/ <<<


    Webynux

    Le titre de ce blog est « L’actualité du logiciel libre », il ne pouvait pas être absent de ma sélection 🙂

    >>> http://www.webynux.net/ <<<


    NixCraft

    Un site en Anglais sur des « tips & tricks » quotidiens sur les environnements Linux et BSD.

    >>> http://www.cyberciti.biz/ <<<


    Planet-Libre

    Je ne vous fais pas l’affront de vous le présenter…

    >>> http://www.planet-libre.org/ <<<

    Les généralistes

    Numerama

    Porte parole des anti-hadopi. Il aborde également certaines actualités sur le monde des logiciels libres.

    >>> http://www.numerama.com/ <<<


    PC Inpact

    On y parle hard, soft mais aussi libre (en filtrant bien ;))

    >>> http://www.pcinpact.com/ <<<

    ZDNet

    Du sérieux, du posé… Orienté pour les entreprises.

    >>> http://www.zdnet.fr/dossier/open-source.htm <<<

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

    4 hacks pour extraire des statistiques de WordPress

    C’est le début de l’année et le moment des bilans concernant les statistiques de votre blog. Voici donc un petit billet sur quelques hacks MySQL permettant d’obtenir des statistiques à diffuser vers vos lecteurs ou à garder au chaud !

    Avant tout il faut disposer d’un accès à votre base de donnée MySQL (soit via une interface de type phpMySQL, soit directement via une ligne de commande mysql). Pour avoir vos paramètres de connexion à votre BD WordPress il suffit de regarder le fichier wp-config.php à la racine de votre répertoire Web.

    Voici l’architecture des tables de votre BD WordPress. Je ne suis plus trop un expert en requêtes MySQL (les cours datent de plus de 10 ans maintenant ;)) alors si vous voyez des améliorations dans les requêtes ci-dessous je suis preneur de commentaires.

    Nombre de billets publiés en 2010

    Cette première requête donne le nombre de billets publiés (status= »publish ») sur l’année 2010 (c’est à dire entre le 1er janvier et le 31 décembre 2010).

    mysql> SELECT COUNT(*) FROM wp_posts WHERE post_status= »publish » AND post_date BETWEEN ‘2010-01-01’ AND ‘2010-12-31’;

    +———-+

    | COUNT(*) |

    +———-+

    | 161 |

    +———-+

    1 row in set (0.00 sec)

    Nombre de commentaires pour les billets publiés en 2010

    Une requête un peu plus complexe qui somme (SUM) le nombre de commentaires pour les billets 2010.

    mysql> SELECT SUM(comment_count) FROM wp_posts WHERE post_status= »publish » AND post_date BETWEEN ‘2010-01-01’ AND ‘2010-12-31’ GROUP BY post_status;

    +——————–+

    | SUM(comment_count) |

    +——————–+

    | 1314 |

    +——————–+

    1 row in set (0.01 sec)

    Liste des 10 billets les plus commentés publiés en 2010

    On continu pas le classement (TOP 10) des nouveaux billets les plus commentés.

    mysql> SELECT post_title,comment_count FROM wp_posts WHERE post_status= »publish » AND post_date BETWEEN ‘2010-01-01’ AND ‘2010-12-31’ ORDER BY comment_count DESC LIMIT 0,10;

    +——————————————————————-+—————+

    | post_title | comment_count |

    +——————————————————————-+—————+

    | Configurer VPNTunnel sous Ubuntu | 58 |

    | Installation et test de Flumotion 0.8 | 46 |

    | Script d’installation automatique de Nagios | 42 |

    | Spideroak, un sérieux concurrent à Dropbox | 40 |

    | Utiliser Nmap pour générer vos fichiers de configuration Nagios | 38 |

    | Installation d’un serveur OpenVPN sous Debian/Ubuntu | 36 |

    | 12 étapes pour optimiser les performances de son blog WordPress | 35 |

    | Le blog de Nicolargo a son application IOS | 35 |

    | Tu fais quoi après l’installation de Firefox ? | 26 |

    | MyScreenCast, comment faire du screencast avec GStreamer | 26 |

    +——————————————————————-+—————+

    10 rows in set (0.01 sec)

    Top 10 des lecteurs ayant le plus posté de commentaires sur le blog en 2010

    Enfin une requête un peu plus complexe qui donne le classement des plus gros « commentateurs » sur le blog.

    mysql> SELECT comment_author,COUNT(comment_count) AS F01 FROM wp_comments,wp_posts WHERE comment_approved=1 AND comment_post_ID=ID AND comment_date BETWEEN ‘2010-01-01’ AND ‘2010-12-31’ GROUP BY comment_author ORDER BY F01 DESC LIMIT 0,10;+—————-+—–+

    | comment_author | F01 |

    +—————-+—–+

    | NicoLargo | 315 |

    | Albert | 22 |

    | Pierre-Yves | 18 |

    | ninja21a | 18 |

    | Mr Xhark | 15 |

    | Sylvain | 14 |

    | Christophe | 12 |

    | floppy84 | 12 |

    | Nico | 11 |

    | Guillaume | 10 |

    +—————-+—–+

    10 rows in set (0.07 sec)

    Si vous avez d’autres requêtes MySQL dans votre besace et bien faites tourner !

    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 Web

    Petit bilan de l’année 2010

    Je profite de ce premier dimanche de 2011 pour faire un petit bilan, concernant ce blog, de l’année qui vient de s’écouler.

    Tout d’abord quelques chiffres:

    Pour revenir sur le hack du site qui est arrivé en pleine vacance d’août, il a causé une interruption de service de plus de 2 semaines. L’impact en terme de référencement du site dans Google et donc de trafic n’est pas négligeable…

    Le point positif est que cette claque m’a permis de repartir sur une base saine (nouveau serveur, nouvelle procédure d’installation, backup…) et donc d’une nouvelle section du l’hébergement sur le site 🙂

    Cette année 2011 risque d’être un peu moins active sur ce blog de part mes activités professionnelles. Mais j’ai quelques petits billets dans la tête (suite des billets sur la sécurisation des blogs WordPress, découverte de Shinken, article sur la virtualisation des serveurs…).

    Bonne année à vous tous !

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

    Superviser son blog avec Nagios

    Pour moi, la vraie révolution Internet de ces dernières années est l’apparition de blogs ayant petit à petit pris le relais des sites institutionnels pour diffuser de l’information. Souvent tenu à bout de bras par des particuliers, ils ne disposent pas d’une infrastructure informatique professionnelle.

    Ainsi en cas de problème technique, l’administrateur est souvent prévenu par ses lecteurs…

    Nous allons donc voir dans ce billet comment utiliser le logiciel libre de supervision Nagios pour surveiller automatiquement son blog.

    Voilà ce que donnera le résultat dans l’interface Web de Nagios:

    Contexte

    Afin d’illustrer ce billet, nous allons partir sur l’hypothèse ou vous disposer d’un blog hébergé sur un serveur dédié ou virtuel sous Ubuntu Server 10.04 avec un accès SSH et un compte utilisateur avec les droits d’administration (sudo>r00t).

    Aller on se connecte en SSH sur son serveur et on suit le guide.

    Installation de Nagios

    Nous allons utiliser le script d’installation automatique de Nagios (développé par votre serviteur).

    On commence par le télécharger le script nagiosautoinstall-ubuntu.sh:

    mkdir ~/monitoring/

    cd ~/monitoring

    wget https://raw.github.com/nicolargo/nagiosautoinstall/master/nagiosautoinstall-ubuntu.sh

    chmod a+x nagiosautoinstall-ubuntu.sh

    Puis on lance l’installation (il y a quelques questions auxquelles il faudra répondre) :

    sudo ./nagiosautoinstall-ubuntu.sh

    On devrait ensuite pourvoir accéder à l’interface Web de Nagios à partir de l’URL suivant: http://@IP/nagios/

    Ou @IP est l’adresse IP de votre serveur.

    Configuration de Nagios

    Comme Nagios tourne sur la même machine que le serveur à superviser, toutes la configuration se fera dans le fichier de configuration localhost.cfg.

    J’utilise deux plugins non inclus dans les plugins de bases de Nagios (mais installé automatiquement par le script nagiosautoinstall-ubuntu.sh):

    On édite le fichier /usr/local/nagios/etc/objects/localhost.cfg (à adapter à votre configuration…):

    #######################################################################

    #

    # Supervision du blog blog.nicolargo.com

    #

    #######################################################################

     

    #######################################################################

    #######################################################################

    #

    # HOST DEFINITION

    #

    #######################################################################

    #######################################################################

     

    # Define a host for the local machine

     

    define host{

    use linux-server

    host_name blog

    alias blog.nicolargo.com

    address 127.0.0.1

    }

     

    #######################################################################

    #######################################################################

    #

    # SERVICE DEFINITIONS

    #

    #######################################################################

    #######################################################################

     

     

    # Define a service to « ping » the local machine

     

    define service{

    use local-service

    host_name blog

    service_description PING

    check_command check_ping!100.0,20%!500.0,60%

    }

     

     

    # Define a service to check the disk space of the root partition

    # on the local machine. Warning if < 20% free, critical if

    # < 10% free space on partition.

     

    define service{

    use local-service

    host_name blog

    service_description Root Partition

    check_command check_local_disk!10%!5%!/

    }

     

     

     

    # Define a service to check the number of currently logged in

    # users on the local machine. Warning if > 2 users, critical

    # if > 3 users.

     

    define service{

    use local-service

    host_name blog

    service_description Current Users

    check_command check_local_users!2!3

    }

     

     

    # Define a service to check the number of currently running procs

    # on the local machine. Warning if > 250 processes, critical if

    # > 400 processes.

     

    define service{

    use local-service

    host_name blog

    service_description Total Processes

    check_command check_local_procs!250!400!RSZDT

    }

     

    # Check memoire avec script check_memory

    # http://blog.nicolargo.com/2008/07/surveiller-la-memoire-de-vos-serveurs-avec-nagios.html

    # -w 800000000 -c 900000000

     

    define service{

    use local-service

    host_name blog

    service_description Memory

    check_command check_memory!800000000!900000000

    }

     

    # Define a service to check the load on the local machine.

     

    define service{

    use local-service

    host_name blog

    service_description Current Load

    check_command check_local_load!5.0,4.0,3.0!10.0,6.0,4.0

    }

     

    # Define a service to check the swap usage the local machine.

    # Critical if less than 10% of swap is free, warning if less than 20% is free

     

    define service{

    use local-service

    host_name blog

    service_description Swap Usage

    check_command check_local_swap!20!10

    }

     

    # Define a service to check SSH on the local machine.

    # Disable notifications for this service by default, as not all users may have SSH enabled.

     

    define service{

    use local-service

    host_name blog

    service_description SSH

    check_command check_ssh

    #notifications_enabled 0

    }

     

     

     

    # Define a service to check HTTP on the local machine.

    # Disable notifications for this service by default, as not all users may have HTTP enabled.

     

    define service{

    use local-service

    host_name blog

    service_description HTTP

    check_command check_http

    #notifications_enabled 0

    }

     

    # Define a service to check URL

    # http://blog.nicolargo.com/google89d0cf0b89815a2a.html

     

    define service{

    use local-service

    host_name blog

    service_description URL Google check file

    check_command check_url!http://blog.nicolargo.com/googl

    e89d0cf0b89815a2a.html

    }

     

    # Define a service to check URL

    # http://blog.nicolargo.com/sitemap.xml.gz

     

    define service{

    use local-service

    host_name blog

    service_description URL Sitemap

    check_command check_url!http://blog.nicolargo.com/sitem

    ap.xml.gz

    }

     

    # Define a DDOS detection service

    # http://blog.nicolargo.com/?p=4100

    # Warning: >50 SYN_RECV

    # Critical: >70 SYN_RECV

     

    define service{

    use local-service

    host_name blog

    service_description DDOS detect

    check_command check_ddos!50!70

    }

    Ce fichier de configuration va permettre de superviser les choses suivantes:

    • état du serveur (réponse au ping en moins de 500ms et 60% de paquets perdus)
    • espace disque disponible > 5% de la taille totale (10% pour un warning)
    • pas plus de 3 personnes connectés en même temps sur le serveur (2 pour un warning)
    • pas plus de 400 processus lancés en parallèle (250 pour un warning)
    • mémoire disponible (basée sur RAM 1 Go) > 10% de la mémoire totale (20% pour un warning)
    • charge (CPU) moyenne sur 5 minutes < 10% (5% pour un warning)
    • espace de swap disponible > 10% de la taille totale du swap (20% pur warning)
    • Port SSH en écoute
    • Port HTTP en écoute
    • Vérification de l’existence du fichier de check de Google
    • Vérification de l’existence du fichier sitemap.xml (référencement dans moteur de recherche)

    Il y a surement plein d’autres choses à vérifier…

    A vos claviers pour nous dire cela dans les commentaire.

    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: