debian-8-jessie

Serveur dédié : la mise à jour vers Debian 8 Jessie

Hier soir, j’ai mis à jour le serveur : nous sommes passés de Debian 7.8 Wheezy à Debian 8.0 Jessie.

Globalement, la migration s’est plutôt bien passée. Le serveur a connu environ dix minutes d’interruption, principalement le temps de comprendre les changements introduits par Apache 2.4 et de corriger quelques détails dans la configuration de Postfix.

Voici donc un retour d’expérience sur cette mise à jour, avec les commandes utilisées, les points de vigilance, les erreurs rencontrées et les corrections appliquées.

Petite précision utile : Debian 8 Jessie est aujourd’hui une ancienne version. Cet article garde donc surtout une valeur d’archive technique. Pour un serveur actuel, il faut évidemment viser une version Debian maintenue, avec des dépôts de sécurité actifs. Debian indique que la version stable actuelle est Debian 13 Trixie. Versions Debian

Avant de commencer : sauvegardes et plan de retour

Avant une mise à jour majeure de Debian, la première étape ne consiste pas à modifier sources.list. La première étape consiste à vérifier que les sauvegardes sont exploitables.

Dans l’idéal, il faut disposer de :

  • une sauvegarde complète des fichiers web ;
  • un dump récent des bases de données ;
  • une copie de /etc ;
  • une copie des configurations Apache, PHP, Postfix et cron ;
  • un accès console hors SSH, par exemple via l’interface de l’hébergeur ;
  • un plan de retour en arrière si le serveur ne redémarre pas correctement.

Une mise à jour majeure peut modifier le noyau, les services, les fichiers de configuration, les versions de PHP, les modules Apache ou les paquets système. Autant éviter de découvrir au milieu de la nuit que “sauvegarde” voulait dire “un vieux zip quelque part”.

Sur un serveur web, je conseille aussi de noter l’état des services avant l’opération :

service apache2 status
service mysql status
service postfix status

apache2 -v
php -v
mysql --version
postconf -n

Cela permet de comparer plus facilement l’avant et l’après.

Vérifier l’état du système avant la migration

Avant de changer de version Debian, j’ai commencé par vérifier qu’aucun paquet n’était cassé ou à moitié installé :

dpkg --audit

On vérifie aussi les paquets placés en attente :

dpkg --get-selections | grep 'hold'Code language: JavaScript (javascript)

Si des paquets sont retenus, il vaut mieux comprendre pourquoi avant de lancer une mise à niveau complète. Un paquet bloqué peut empêcher une dépendance importante de se mettre à jour.

On peut aussi vérifier les paquets installés depuis des dépôts tiers :

apt-cache policy
grep -R "^[^#]" /etc/apt/sources.list /etc/apt/sources.list.d/Code language: PHP (php)

Les notes de publication Debian recommandent de retirer ou désactiver les paquets tiers lorsque cela améliore la fiabilité de la mise à niveau. C’est particulièrement pertinent si le serveur utilise des dépôts externes pour PHP, Apache, MariaDB, Nginx, Node.js ou des outils de sécurité. Notes de publication Debian Jessie

Mettre à jour les dépôts APT

On édite ensuite le fichier des sources APT :

nano /etc/apt/sources.listCode language: PHP (php)

L’idée est de remplacer les occurrences de wheezy par jessie. À l’époque, ma configuration ressemblait à ceci :

# Debian Jessie.
deb http://mirror.ovh.net/debian/ jessie main contrib non-free
deb-src http://mirror.ovh.net/debian/ jessie main contrib non-free

# Sécurité.
deb http://security.debian.org/ jessie/updates main contrib non-free
deb-src http://security.debian.org/ jessie/updates main contrib non-free

# Backports.
deb http://ftp.debian.org/debian/ jessie-backports mainCode language: PHP (php)

J’éviterais d’utiliser stable dans sources.list sur un serveur. C’est pratique en apparence, mais dangereux : le jour où Debian change de stable, votre serveur peut se retrouver orienté vers une nouvelle version majeure sans que ce soit explicite. Un nom de code comme jessie, stretch, bookworm ou trixie rend l’intention beaucoup plus claire.

Dans le cas précis de Jessie, Debian précisait que les mises à niveau directes depuis des versions antérieures à Debian 7 Wheezy n’étaient pas prises en charge. Il fallait donc partir d’un système Wheezy à jour avant de migrer vers Jessie. Notes de publication Debian Jessie

Simuler la mise à niveau

Avant de lancer la vraie mise à jour, on peut simuler l’opération pour voir l’ampleur des changements :

apt-get update
apt-get -o APT::Get::Trivial-Only=true dist-upgradeCode language: PHP (php)

Dans mon cas, le résultat indiquait :

439 upgraded, 192 newly installed, 5 to remove and 1 not upgraded.
Need to get 275 MB of archives.
After this operation, 259 MB of additional disk space will be used.
E: Trivial Only specified but this is not a trivial operation.Code language: JavaScript (javascript)

Ce message n’est pas une erreur inquiétante. Il indique simplement que l’opération n’est pas “triviale”, donc qu’APT refuse de l’exécuter avec cette option de simulation restrictive.

Avant de continuer, on vérifie aussi l’espace disque :

df -h
du -sh /var/cache/apt/archives 2>/dev/nullCode language: JavaScript (javascript)

Une mise à niveau majeure télécharge beaucoup de paquets et peut nécessiter de l’espace supplémentaire. Ce n’est pas le moment de découvrir que /var est plein à 99 %.

Lancer la mise à niveau vers Debian Jessie

Une fois les sauvegardes faites et les dépôts mis à jour, on lance la première phase :

apt-get update
apt-get upgradeCode language: JavaScript (javascript)

APT affiche alors les paquets qui seront mis à jour, installés ou supprimés. Pendant l’opération, il peut poser des questions sur les fichiers de configuration modifiés localement.

Sur un serveur personnalisé, je fais très attention à ces questions. Garder automatiquement l’ancien fichier peut empêcher un service de profiter d’une nouvelle configuration attendue. Remplacer automatiquement le fichier peut écraser une configuration critique. Bref : lire, comparer, décider. Oui, c’est le moment sérieux.

Ensuite, on lance la mise à niveau complète :

apt-get dist-upgradeCode language: JavaScript (javascript)

dist-upgrade autorise APT à installer de nouveaux paquets et à en supprimer si nécessaire pour résoudre les dépendances. C’est indispensable lors d’un changement de version Debian.

Après la mise à niveau, un redémarrage est souvent nécessaire, notamment si le noyau a été mis à jour :

reboot

Vérifier la version après redémarrage

Après redémarrage, on vérifie que le serveur tourne bien sous Jessie :

cat /etc/debian_version
lsb_release -a 2>/dev/null || cat /etc/os-release
uname -aCode language: JavaScript (javascript)

Puis on contrôle les services essentiels :

service apache2 status
service mysql status
service postfix status

tail -n 100 /var/log/syslog
tail -n 100 /var/log/apache2/error.log
tail -n 100 /var/log/mail.logCode language: JavaScript (javascript)

Dans mon cas, le site web répondait avec une erreur 403. Direction Apache.

Apache 2.4 : les changements qui cassent tout joliment

Avec Debian Jessie, Apache passe en version 2.4. Ce changement introduit plusieurs modifications importantes, notamment dans les fichiers de configuration et les directives de contrôle d’accès.

C’est le principal point qui m’a causé une interruption de service.

Les fichiers de sites doivent porter l’extension .conf

Sous Apache 2.4 avec Debian, les fichiers de configuration des virtual hosts dans /etc/apache2/sites-available sont généralement attendus avec l’extension .conf.

On peut vérifier les sites disponibles :

ls -l /etc/apache2/sites-available/
ls -l /etc/apache2/sites-enabled/

Si un fichier s’appelle par exemple example.com, on peut le renommer :

mv /etc/apache2/sites-available/example.com /etc/apache2/sites-available/example.com.conf

Puis l’activer :

a2ensite example.com.confCode language: CSS (css)

La commande a2ensite active un site en créant un lien symbolique dans /etc/apache2/sites-enabled. Manpage Debian : a2ensite

On teste ensuite la configuration Apache :

apache2ctl configtest

Ou :

apache2ctl -t

Si le test retourne Syntax OK, on peut recharger Apache :

service apache2 reload

Changer les directives de contrôle d’accès

Apache 2.4 remplace les anciennes directives Order, Allow et Deny par la logique Require.

Pour tout bloquer, on utilisait auparavant :

# Apache 2.2.
Order deny,allow
Deny from allCode language: CSS (css)

Avec Apache 2.4, on écrit :

# Apache 2.4.
Require all deniedCode language: PHP (php)

Pour tout autoriser, on utilisait auparavant :

# Apache 2.2.
Order allow,deny
Allow from allCode language: CSS (css)

Avec Apache 2.4, on écrit :

# Apache 2.4.
Require all grantedCode language: PHP (php)

La documentation officielle Apache indique que le contrôle d’accès par hôte, IP ou variable utilise désormais les directives Require, par exemple Require all granted ou Require all denied. Documentation Apache 2.4 : contrôle d’accès

Dans un virtual host classique, on peut donc avoir :

<Directory /home/www/example.com/public_html>
    Options FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>Code language: HTML, XML (xml)

Sans cette directive, Apache peut refuser l’accès au répertoire et renvoyer une erreur 403. Ce fut précisément mon cas. Délicieux petit accueil après migration.

Désactiver mod_spdy

Autre problème rencontré : mod_spdy était incompatible avec ma nouvelle version d’Apache.

Apache refusait de démarrer avec une erreur de ce type :

apache2: Syntax error on line 140 of /etc/apache2/apache2.conf:
Syntax error on line 1 of /etc/apache2/mods-enabled/spdy.load:
Cannot load /usr/lib/apache2/modules/mod_spdy.so into server:
/usr/lib/apache2/modules/mod_spdy.so: undefined symbol: ap_log_cerrorCode language: JavaScript (javascript)

La solution immédiate consiste à désactiver le module :

a2dismod spdy

Puis à tester la configuration :

apache2ctl configtest

Et à redémarrer Apache :

service apache2 restart

À l’époque, SPDY était encore utilisé pour améliorer les performances HTTP. Aujourd’hui, il a été remplacé dans les usages modernes par HTTP/2 et HTTP/3. Pour un serveur actuel, on ne chercherait évidemment pas à conserver mod_spdy.

Corriger mod_security2

Au redémarrage d’Apache, mod_security2 a également posé problème :

apache2: Syntax error on line 141 of /etc/apache2/apache2.conf:
Syntax error on line 9 of /etc/apache2/mods-enabled/security2.conf:
No matches for the wildcard '*.conf' in '/etc/modsecurity',
failing (use IncludeOptional if required)Code language: PHP (php)

Dans mon cas, il suffisait de renommer le fichier recommandé en fichier actif :

mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

Ou avec l’expansion Bash :

mv /etc/modsecurity/modsecurity.conf{-recommended,}

Puis on active le module :

a2enmod security2

Et on redémarre Apache après vérification :

apache2ctl configtest
service apache2 restart

Sur une configuration plus moderne, on privilégierait souvent IncludeOptional lorsque des fichiers peuvent être absents. Mais dans ce cas précis, créer le fichier attendu suffisait.

Erreur 403 sur le sous-domaine statique

Après la migration, mon sous-domaine dédié aux images et ressources statiques renvoyait une erreur 403.

Le problème venait d’une directive Directory mal placée dans la configuration Apache. Je l’avais définie à l’intérieur du bloc VirtualHost. En la déplaçant en dehors, Apache a de nouveau appliqué correctement les règles d’accès au répertoire concerné.

Exemple de structure plus claire :

<VirtualHost *:80>
    ServerName static.example.com
    DocumentRoot /home/www/static.example.com/public_html

    ErrorLog ${APACHE_LOG_DIR}/static-error.log
    CustomLog ${APACHE_LOG_DIR}/static-access.log combined
</VirtualHost>

<Directory /home/www/static.example.com/public_html>
    Options FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>Code language: PHP (php)

Après modification :

apache2ctl configtest
service apache2 reload

Pour diagnostiquer une 403 Apache, les commandes les plus utiles restent :

tail -f /var/log/apache2/error.log
namei -l /home/www/static.example.com/public_html
apache2ctl -SCode language: JavaScript (javascript)

namei -l est particulièrement pratique pour vérifier les permissions de chaque répertoire du chemin. Une permission manquante sur un dossier parent suffit à produire une erreur 403.

Postfix : mails bloqués après la migration

Après Apache, j’ai remarqué que les mails n’arrivaient plus correctement avec Postfix.

Un tour dans les logs a montré des directives en double dans /etc/postfix/main.cf :

send-mail: warning: /etc/postfix/main.cf, line 150:
overriding earlier entry: smtpd_tls_key_file=$smtpd_tls_cert_file

send-mail: warning: /etc/postfix/main.cf, line 151:
overriding earlier entry: smtpd_tls_cert_file=/etc/ssl/postfix.pemCode language: JavaScript (javascript)

Ce type d’avertissement signifie qu’un paramètre est défini plusieurs fois. Postfix lit le fichier et la dernière valeur remplace la précédente. Ce n’est pas toujours fatal, mais cela rend la configuration ambiguë et peut provoquer un comportement inattendu.

Pour inspecter la configuration active, on utilise :

postconf -n

Pour tester la configuration :

postfix check

Ensuite, il suffit de supprimer les doublons dans :

nano /etc/postfix/main.cf

Puis de redémarrer Postfix :

service postfix restart

Enfin, on surveille les logs :

tail -f /var/log/mail.logCode language: JavaScript (javascript)

Après une migration système, je vérifie toujours l’envoi et la réception avec un vrai message de test. Un service peut être “running” et pourtant mal délivrer les mails. Postfix a le chic pour rester poli pendant qu’il boude.

Nettoyer les anciens paquets

Une fois le serveur stable, on peut nettoyer les paquets devenus inutiles :

apt-get autoremove
apt-get autocleanCode language: JavaScript (javascript)

Je préfère ne pas lancer ces commandes trop tôt. D’abord, on vérifie que le serveur web, les bases de données, les mails, les tâches cron et les sauvegardes fonctionnent. Ensuite seulement, on nettoie.

Checklist après migration

Après une mise à niveau Debian, je vérifie généralement les points suivants :

  • le serveur redémarre correctement ;
  • SSH fonctionne encore ;
  • Apache démarre sans erreur ;
  • les virtual hosts répondent correctement ;
  • les certificats SSL sont toujours valides ;
  • PHP exécute bien les sites ;
  • MySQL ou MariaDB démarre correctement ;
  • Postfix envoie et reçoit les mails ;
  • les tâches cron s’exécutent ;
  • les sauvegardes tournent encore ;
  • les logs ne montrent pas d’erreur bloquante ;
  • les permissions des répertoires web sont intactes.

Quelques commandes utiles :

apache2ctl -t
apache2ctl -S

service apache2 status
service mysql status
service postfix status

tail -n 100 /var/log/apache2/error.log
tail -n 100 /var/log/mail.log
tail -n 100 /var/log/syslog

df -h
free -mCode language: JavaScript (javascript)

Ce que je ferais différemment aujourd’hui

Avec le recul, cette migration s’est bien passée, mais je procéderais aujourd’hui avec une méthode un peu plus stricte.

Je commencerais par cloner le serveur ou créer un snapshot, puis je testerais la mise à niveau sur une instance temporaire. Ensuite, je noterais les modifications de configuration nécessaires, notamment pour Apache 2.4, PHP et Postfix. Enfin, je planifierais la migration réelle avec une fenêtre de maintenance claire.

Pour un serveur web en production, le luxe n’est pas d’aller vite. Le luxe, c’est de savoir exactement quoi faire quand quelque chose casse.

Mémo rapide

# Vérifier l’état des paquets.
dpkg --audit
dpkg --get-selections | grep 'hold'

# Modifier les dépôts.
nano /etc/apt/sources.list

# Mettre à jour les dépôts.
apt-get update

# Simuler une mise à niveau non triviale.
apt-get -o APT::Get::Trivial-Only=true dist-upgrade

# Lancer la mise à niveau.
apt-get upgrade
apt-get dist-upgrade

# Redémarrer si nécessaire.
reboot

# Vérifier Debian.
cat /etc/debian_version

# Tester Apache.
apache2ctl configtest
apache2ctl -S

# Corriger les modules.
a2dismod spdy
a2enmod security2

# Redémarrer Apache.
service apache2 restart

# Vérifier Postfix.
postconf -n
postfix check
service postfix restart

# Logs utiles.
tail -f /var/log/apache2/error.log
tail -f /var/log/mail.log
tail -f /var/log/syslogCode language: PHP (php)

Conclusion

La mise à jour de Debian 7 Wheezy vers Debian 8 Jessie s’est globalement bien passée, avec une courte interruption de service.

Les principaux problèmes venaient d’Apache 2.4 : extension .conf attendue pour les sites, nouvelles directives Require, module SPDY incompatible, configuration ModSecurity incomplète et erreur 403 sur un sous-domaine statique.

Postfix a également demandé un petit nettoyage à cause de directives dupliquées dans main.cf.

Au final, rien d’insurmontable, mais cette migration rappelle une règle simple : une mise à niveau de distribution ne se limite jamais à “changer les dépôts et appuyer sur Entrée”. Les paquets changent, les services changent, les fichiers de configuration changent, et le serveur vous le rappelle avec un sens de l’humour très personnel.

WordPress : récupérer la liste emails des membres et commentateurs photo

Résoudre les lightbox vides dans l’administration WordPress

Le problème : des iframes entièrement vides dans l’interface d’administration WordPress

Depuis mon passage à HTTPS, j’ai constaté que lorsqu’un plugin possédait une mise à jour et que l’on cliquait sur le lien “voir les détails de la version x.x”, j’avais droit à une jolie lightbox (ThickBox sous WordPress) toute vide.

C’était également le cas lors de la mise à jour des plugins, des thèmes ou de WordPress même : je n’obtenais jamais la ligne qui confirmait que le plugin avait bel et bien été réactivé.

Cette situation a duré des mois : j’ai d’abord soupçonné une mise à jour de WordPress qui aurait abimé un fichier donc j’ai ré-uploadé tous les fichiers, procédé à de multiples mises à jour mineures puis majeures.

J’ai ensuite jeté un œil aux plugins, en désactivant quelques uns pour essayer de trouver celui qui perturbait le système. Rien. Et visiblement, personne n’a jamais été confronté à ce problème sur la toile.

Et puis cette semaine, eurêka !

La solution : la configuration Apache du serveur

J’ai trouvé la solution un jour que je travaillais sur autre chose, en analysant les messages de l’inspecteur de code. Ce dernier me renvoyait de multiples avertissements lorsqu’un message a attiré mon attention :

Load denied by X-Frame-Options.... X-Frame-Options does not permit framing.

Et là, banco, j’ai immédiatement compris ce qui clochait. Lors de la bascule vers la version chiffrée du site, j’avais effectivement ajouté un nouvel entête X-Frame-Options comme ceci :

Header always set X-Frame-Options DENYCode language: JavaScript (javascript)

Cela est bien trop restrictif puisque la valeur DENY empêche l’affichage du site dans un cadre (frame).

Or le back-office de WordPress charge effectivement les messages relatifs aux mises à jour dans un cadre, sous la forme d’une lightbox: il faut donc utiliser la valeur SAMEORIGIN.

Lire la suite

Une semaine à Rome : le Mont Palatin, le Cirque Maxime et le Forum Trajan photo 6

Une semaine à Rome : le Mont Palatin, le Cirque Maxime et le Forum Trajan

Notre billet Colisée – Forum -Palatin n’est valable que 48 heures. Notre programme pour la journée est donc établi: nous commencerons par le Mont Palatin.

Petit coup de stress à l’entrée: le mont Palatin et le forum doivent être visités le même jour, dans la foulée. Or nous avons visité le forum la veille, ce qui bloque le portique de l’entrée. Heureusement, la dame a été gentille et nous a autorisés à rentrer grâce à son pass.

Devant le forum romain, depuis le Palatin
Devant le forum romain, depuis le Palatin

Le Mont Palatin

Le Mont Palatin est la célèbre colline sur laquelle le sort de Rome a été décidé : Romulus et Remus, deux frères jumeaux, recueillis puis allaités par la louve, se disputaient le pouvoir de la ville qu’ils s’apprêtaient à fonder. Pour se départager, rien de plus simple que d’observer le vol des oiseaux!

Les deux jumeaux allaités par la louve, Musée du Capitole, Rome
Les deux jumeaux allaités par la louve, Musée du Capitole, Rome

Romulus se plaça donc sur le Mont Palatin et Rémus grimpa sur la colline en face et les deux frères attendirent le passage de volatiles, signe divin par excellence. Romulus vit douze vautours alors que Rémus n’en vit que six. C’est donc Romulus qui l’emporta : il devint donc le premier Roi de Rome.

Mais Rémus eut la mauvaise idée de franchir les murailles, malgré l’interdiction de son frère. Alors, Romulus le transperça illico d’un coup d’épée. Entre les vautours et le fratricide, le Mont Palatin porte une riche histoire sur ses versants !

Bien sûr, il s’agit d’une légende et de tout cela, on ne voit plus rien. C’est aussi le lieu que l’empereur Auguste choisit pour faire construire un palais à son épouse Livie, détruit par le temps au fil des années.

Ruines du Palatin
Ruines du Palatin

Bon nombre d’empereurs tels que Tibère ou Dioclétien se firent à leur tour construire un palais sur le Mont Palatin (le nom même de “Palatin” est construit sur le terme “palais” et désigne ainsi les palais qui s’y succédèrent).

A la Renaissance, Alexandre Farnese réaménagea le site en de somptueux jardins, appelés “jardins du farnese”. La promenade y est très agréable car elle est propice à la rêverie et éveille l’imaginaire sur ces siècles d’histoire, et ce, dans un doux parfum d’orangers.

Au détour du chemin, les arbres et les fleurs laissent place à une vue magnifique et imprenable sur le forum romain.

Kholanta?
Kholanta?

Nous passons ensuite devant le Lupercal, une grotte ornée de mosaïques et de coquillages, qui serait la hutte de Romulus. On s’ imaginerait presque retrouver sa carte d’identité au pied d’un arbre!

Bien évidemment, il ne s’agit certainement pas de la maison de Romulus, mais d’un témoignage inestimable des premiers habitants du site au 8ème siècle avant Jésus Christ.

Le Cirque Maxime (Circus Maximus)

Du Mont Palatin, il est possible de voir le Cirque Maxime, qui a brûlé lors de l’incendie de Rome causé par Néron en 64. Il a été reconstruit à plusieurs reprises après mais il tomba en ruines et fut pillé pour la reconstruction des diverses églises et palais.

Le Cirque Maxime servait aux courses de chars, tirés par des chevaux comme dans le film “Ben Hur”. Les courses se déroulaient sur une piste ovale, autour d’une spina centrale.

Les auriges se tenaient sur des chars tirés par quatre chevaux, et concouraient les uns contre les autres. Tous les coups étaient permis pour terminer le premier ! Les naufragia (accidents de chars) étaient fréquents et provoquaient très souvent la mort de l’aurige.

Quatre équipes s’affrontaient sur la piste, distinguées par leurs couleurs : les verts, les rouges, les bleus et les blancs. Le public était extrêmement friand de ces courses, au point de parier des sommes d’argent pour son équipe favorite.

Imaginez l’ambiance survoltée parmi les 350 000 spectateurs qui se tenaient dans la cavea ! C’est en fait l’ancêtre un peu plus violent de nos courses de PMU.

Mais le lieu a aussi été le théâtre d’évènements bien différents : Néron y a organisé des courses de dromadaires et Genesis a donné un concert réunissant 500 000 spectateurs en 2007 !

Aujourd’hui, du Cirque Maxime, on ne peut que deviner la forme ovale et la spina sur laquelle se tenait le compte-tours, le reste ressemblant à un immense terrain vague.

Le Cirque Maxime
Le Cirque Maxime

Lire la suite