====== Wordpress sur SME Server / iPasserelle ====== Dans ce tutoriel, nous allons installer une instance de wordpress et voir comment le sécuriser un minimum. Bien que Wordpress soit de nature bien sécurisé (sous condition d'appliquer les MAJ fréquemment), ce CMS est bien trop utilisé pour sous-estimer l'aspect sécurité. ===== Installation sur une iPasserelle ===== Cette étape détails comment installer un Wordpress sur une iPasserelle. Si l'installation est déjà effectuée, vous pouvez directement passer au chapitre suivant. ==== Préparation ==== Procédez a la création d'un [[doc_ipasserelle:administrateurs:dossiers_partages|Dossiers partagés]] grâce aux [[https://wiki.contribs.org/SharedFolders/fr|Share Folders]]. Prenez bien soin d'activer : - L'accès web pour tout internet - L’exécution de contenue dynamique (PHP) - Et désactiver l'indexation A ce stade, vous pouvez gérer les accès utilisateurs en écriture aux comptes qui pourront éditer le site. Il est conseillé de créer un groupe pour une meilleur gestion (par exemple un groupe //webmaster//). Créez ensuite un domaine qui sera l'adresse de votre site via le menu Domaines. A titre d'exemple, nous utiliserons ici le domaine **wp.domain.tld** et le dossier de partage **wordpress**. Téléchargez la dernière version de wordpress : https://fr.wordpress.org et effectuez l'extraction dans le dossier ''/home/e-smith/files/shares/wordpress/files/''. === Installation de PHP-FPM === Pour disposer des dernières versions de PHP, il faut installer deux paquets supplémentaires : Activer, si ce n'est pas déjà fait, le dépôt **FWS** : db yum_repositories set fws repository \ BaseURL http://repo.firewall-services.com/centos/\$releasever \ EnableGroups no GPGCheck yes \ Name "Firewall Services" \ GPGKey http://repo.firewall-services.com/RPM-GPG-KEY \ Visible yes status disabled signal-event yum-modify Installer ensuite les paquets **smeserver-webapps-common** et **smeserver-php-fpm** yum --enablerepo=fws,smecontribs install smeserver-webapps-common smeserver-php-fpm On peut ensuite configurer notre dossier hébergeant Wordpress pour utiliser la dernière version de PHP: db accounts setprop wordpress PHPVersion 71 signal-event share-modify wordpress Ici dans cet exemple, on bascule sur la version **7.1**. Si besoin, les logs de php-fpm sont accessible dans ''/var/log/php//'' ==== Activation ==== Pour procéder a la configuration du domaine : db domains setprop wp.domain.tld TemplatePath WebAppVirtualHost DocumentRoot /home/e-smith/files/shares/wordpress/files/ Vous pouvez également préciser l'argument ''RequireSSL enabled'' à la fin de cette commande pour activer le SSL. Relancez le service webapps : signal-event webapps-update Votre Wordpress doit maintenant être joignable pour commencer l'installation. ==== Installation ==== Nous allons procéder à la création d'une base de donnée pour notre Wordpress, connectez vous sur MySQL et exécutez les requêtes suivantes : create database wordpress; grant all privileges on wordpress.* to 'wpuser'@'localhost' identified by'.................'; flush privileges; Ici nous créons donc la nouvelle base de donnée ''wordpress'' administré par l'utilisateur ''wpuser'' qui est identifié grâce au mot de passe ''.................''. Modifiez les requêtes avec vos propres identifiants. Vous pouvez à présent poursuivre l'installation de Wordpress en vous laissant guider par l’installateur. ==== Post-Configuration ==== === Accès en écriture === Wordpress demande les identifiants FTP quand l'appli détecte qu'elle n'a pas accès en écriture au répertoire du core (wp-content). Or, dans ce cas, le rep wp-content est bien accessible en écriture, mais pas via les permissions UNIX standard, uniquement via les ACL étendues. WP ne fait pas de tentative d'écriture (qui aurait réussi), mais regarde uniquement les permissions UNIX standard. Pour contourner cela, il faut définir les permissions pour l’ensemble du SF : chown -R apache:www /home/e-smith/files/shares/wordpress/files === Activation des règles de réécriture (.htaccess) === Les fichiers de règles **.htaccess** sont désactivés par défaut. De plus, pour que le moteur de Wordpress puisse modifier à la volé les permaliens, et ainsi éviter les erreurs 404 il faut activer les règles de réécritures. Pour que les règles de ré-écriture soient opérationnelles ils faut donc les réactivées manuellement : db accounts setprop wordpress AllowOverride All signal-event webapps-update === upload_max_filesize === Il est probable que la limite actuelle de PHP soit trop juste, empêchant alors d'envoyer de gros fichier depuis l'interface admin de Wordpress, comme par exemple, des thèmes. Ainsi une erreur de ce type peut apparaître : > La taille du fichier envoyé excède celle indiquée dans la directive upload_max_filesize, dans php.ini. La limite par défaut est de 10M Pour augmenter la taille maximum, par exemple à 100M : db accounts setprop wordpress PHPUploadMaxFilesize 100M PHPPostMaxSize 100M signal-event share-modify wordpress Pour vérifier : db accounts show wordpress === Installer une notification d'acceptation des Cookies === https://www.cnil.fr/fr/cookies-traceurs-que-dit-la-loi Voici un plugin Wordpress prêt à l'emploi : https://wordpress.org/plugins/cookie-notice/ ===== Sécuriser Wordpress ===== Maintenant que Wordpress est fonctionnel, voici comment le sécuriser un minimum. Tous les Plugins doivent être désactivées avant d'effectuer les manipulations suivantes. ==== Empêcher l'inscription ==== Si ce n'est pas l'objectif du site, il faut désactiver cette fonction.\\ Pour cela, rendez-vous dans le menu Réglages -> Général et décochez la case qui dit "Tout le monde peut s'enregistrer". ==== Désactiver l’éditeur de code ==== L’éditeur de code, bien que pratique reste plutôt dangereuse car elle permet à toute personne identifié de modifier directement le code source PHP de Wordpress, il devient alors très facile d'y injecter du code malicieux. Pour désactiver cette option, rendez-vous dans le fichier **wp-config.php** et ajoutez la ligne suivante : define('DISALLOW_FILE_EDIT',true); ==== Changer les clefs de sécurité (cookies) ==== WordPress chiffre les informations stockées dans les cookies grâce à des clefs de sécurité conservées dans le fichier **wp-config.php**. Par défaut, des clés aléatoires sont générées, mais vous pouvez les changer > https://api.wordpress.org/secret-key/1.1/salt/ ==== Template ==== Certains fichiers (comme le fichier **wp-config.php**) sont senssibles. Ces fichiers ne sont normalement pas lisibles, mais on peut renforcer la sécurité en interdisant l'accès de façon explicite order allow,deny deny from all order allow,deny deny from all order allow,deny deny from all order allow,deny deny from all php_admin_flag engine off SetHandler None Ce fichier **99WordPress** est à placer dans ''/etc/e-smith/templates-custom/etc/httpd/conf/httpd.conf/''.\\ Ensuite il faut le déployer : expand-template /etc/httpd/conf/httpd.conf Pour tester la syntaxe, un ''httpd -t'' doit renvoyer le code **OK**. Si c'est le cas, il ne reste plus qu'a relancer Apache : sv h /service/httpd-e-smith ==== Deviner l'identifiant ==== Wordpress dispose d'une fonction confortable lorsqu'on se trompe lors de notre authentification. En effet, il indique directement si nous nous somme trompé dans l'identifiant ou le mot de passe. Le problème de cette fonction, c'est que cela permet à l'attaquant de s'assurer que l'identifiant qu'il tente de brute-forcer existe bien. Pour éviter cela, il suffit de masquer le message d'erreur grâce à ce petit bout de code à rajouter dans le fichier **functions.php** présent dans le répertoire du thème : add_filter('login_errors', create_function('$no_login_error', "return 'Mauvais identifiants';")); Cela affichera sobrement le message "Mauvais identifiants" peux importe si l'erreur viens de l'identifiant ou du mot passe. ==== Reverse proxy ==== Ce sera rarement le cas sur une iPasserelle, mais si wordpress est installé derrière un reverse proxy, il faut faire quelques ajustements. Notamment, dans le ''wp-config.php'', ajouter une section: if ( (!empty( $_SERVER['HTTP_X_FORWARDED_HOST'])) || (!empty( $_SERVER['HTTP_X_FORWARDED_FOR'])) ) { // http://wordpress.org/support/topic/wordpress-behind-reverse-proxy-1 $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST']; } if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'){ $_SERVER['HTTPS'] = 'on'; } Et sur le reverse proxy, il faut également ajouter l'entête RequestHeader set X-Forwarded-Proto "https" ===== Changer de nom de domaine ===== S'il deveint nécessaire de changer l’URL du WordPress en raison d’un changement de nom de domaine ou de sous-répertoire, il y a quelques mesures à prendre pour effectuer la migration. WordPress utilise des liens absolus lorsqu’il stocke certains paramètres dans la base de données. Le plus efficace est donc d'executer des requêtes SQL en tant qu'admin directement pour rechercher et remplacer toutes les URL absolues. Il est préférable, si la version Wordpress le permet, d'effectuer ces changements depuis le panneau de configuration de Wordpress, dans les réglages généraux du site. Pour mettre à jour les options concernant l’emplacement du nouveau blog : UPDATE wp_options SET option_value = replace(option_value, 'http://www.ancien-domaine.com', 'http://www.nouveau-domaine.com') WHERE option_name = 'home' OR option_name = 'siteurl'; UPDATE wp_options SET option_value = replace(option_value, 'https://www.ancien-domaine.com', 'https://www.nouveau-domaine.com') WHERE option_name = 'home' OR option_name = 'siteurl'; Après cela, vous aurez besoin de réparer les URL des articles et de vos pages, ces valeurs URL sont stockées comme des URL absolues, elles ont donc besoin d’être modifiés : UPDATE wp_posts SET guid = replace(guid, 'http://www.ancien-domaine.com','http://www.nouveau-domaine.com'); UPDATE wp_posts SET guid = replace(guid, 'https://www.ancien-domaine.com','https://www.nouveau-domaine.com'); Si vous avez des URL en interne au sein d’articles ou de pages avec des URL absolues, ces liens pointent désormais vers de mauvaises URL puisque vous avez déménagé. Utilisez la commande SQL suivante pour corriger tous les liens internes des articles et des pages : UPDATE wp_posts SET post_content = replace(post_content, 'http://www.ancien-domaine.com', 'http://www.nouveau-domaine.com'); UPDATE wp_posts SET post_content = replace(post_content, 'https://www.ancien-domaine.com', 'https://www.nouveau-domaine.com');