Category

Web/Tech

Category

Tous les tutoriels et articles de barbus orientés technique.

Je suis tombé sur une drôle d’erreur ce matin sur un VPS de mes clients : après mise à jour du système et redémarrage du serveur, webmin est injoignable et son service ne veut plus démarrer.

Les messages d’erreurs

On commence par lancer un curl distant depuis un autre serveur, histoire de voir si c’est bien injoignable de manière globale, et non propre à notre machine:

curl -I https://example.com:10000/

Résultat:
curl: (7) Failed to connect to example.com port 10000: Connection refused

Pas de doute, cela touche tout le monde. On vérifie donc l’état du service:

systemctl status webmin.service

Résultat:

webmin.service - LSB: web-based administration interface for Unix systems
   Loaded: loaded (/etc/init.d/webmin; generated)
   Active: failed (Result: exit-code) since Sat 2020-09-12 17:35:13 CST; 20s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 1803 ExecStart=/etc/init.d/webmin start (code=exited, status=25)

Sep 12 17:35:13 systemd[1]: Starting LSB: web-based administration interface for Unix systems...
Sep 12 17:35:13 systemd[1]: webmin.service: Control process exited, code=exited status=25
Sep 12 17:35:13 systemd[1]: webmin.service: Failed with result 'exit-code'.
Sep 12 17:35:13 systemd[1]: Failed to start LSB: web-based administration interface for Unix systems.

Ce n’est pas très loquace! journalctl est plus détaillé:

journalctl -xe

Résultat :

-- All system services necessary queued for starting at boot have been
-- started. Note that this does not mean that the machine is now idle as services
-- might still be busy with completing start-up.
--
-- Kernel start-up required 1709722 microseconds.
--
-- Initial RAM disk start-up required INITRD_USEC microseconds.
--
-- Userspace start-up required 152146335 microseconds.
Sep 12 17:35:13 systemd[1]: Starting LSB: web-based administration interface for Unix systems...
-- Subject: Unit webmin.service has begun start-up
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- Unit webmin.service has begun starting up.
Sep 12 17:35:13 systemd[1]: webmin.service: Control process exited, code=exited status=25
Sep 12 17:35:13 systemd[1]: webmin.service: Failed with result 'exit-code'.
Sep 12 17:35:13 systemd[1]: Failed to start LSB: web-based administration interface for Unix systems.
-- Subject: Unit webmin.service has failed
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
--
-- Unit webmin.service has failed.
--
-- The result is RESULT.

Mais nous n’obtenons toujours aucune information exploitable. Redémarrer le service avec service ne permet pas de le redémarrer.

La solution

Le seul moyen de redémarrer le service webmin sur ce VPS a été de la mnière suivante:

/etc/init.d/webmin stop
systemctl start webmin

Et là, plus de problème, webmin démarre comme il faut.

Le principe du chiffrement WPA-PSK

Il y a peu d’intérêt à utiliser les derniers systèmes d’authentification WiFi comme le WPA-PSK si vous utilisez un mot de passe trop facile à deviner et qui pourra être cracké en quelques minutes à peine sans trop d’effort.

Le chiffrement WPA-PSK, censé pallier les failles de son prédécesseur – WEP – est une version moins sécurisée que le WPA puisqu’il n’y a pas de serveur d’identification Radius.

Le protocole repose sur une clé partagée (Pre-Shared Key ou PSK) qui initialise le processus d’authentification.

Votre clé partagée est créée à l’aide d’un mot de passe de votre choix. Il est souhaitable et recommandé que le mot de passe ne contienne aucun mot figurant dans le dictionnaire, même sous une forme leet speak, les logiciels de crack type brute-force ou dictionnaire connaissent cette astuce depuis quelques années déjà.

La combinaison doit donc être illisible, le genre de clé qui est impossible à donner à un correspondant par téléphone.

Autrement dit, si votre mot de passe est un mot courant qui fait partie d’un dictionnaire, il pourra être cracké à l’aide d’une attaque type brute-force ou dictionnaire en moins d’une minute.

Ensuite, il faut augmenter le nombre de caractères de la clé partagée : il est plus facile de trouver un mot de passe de 4 caractères plutôt que de 63 caractères.

D’où l’intérêt d’utiliser un mot de passe de taille conséquente, composé de signes et caractères spéciaux. Cracker une clé de 63 caractères prend quelques années avec la puissance de calcul actuelle.

Générateur de clés WPA sécurisées

J’ai à cet effet créé un générateur de clés WPA sécurisées : il vous suffit de choisir le type de clé qui convient le mieux à votre usage.

Je vous recommande bien évidemment la clé de 63 caractères mais vous avez aussi la possibilité de choisir le nombre de caractères qui vous plait.

Aujourd’hui, nouvelle année scolaire donc nouvelle version Android pour le OnePlus One : on passe d’Android 9 à Android 10, toujours grâce à l’excellent LineageOS.

Si votre téléphone possède déjà LineageOS 16, vous pouvez vous rendre directement à l’étape 5.

Étape 1: activer le mode développeur

Sur le téléphone, on commence par activer le mode développeur:

  1. Ouvrez Paramètres > A propos du téléphone.
  2. Tapez 7 fois sur le numéro de build.
  3. Vous venez d’activer le mode développeur!

Grâce au mode développeur, vous avez maintenant accès à des options qui n’étaient pas visibles auparavant et qui vont nous être nécessaires.

Étape 2 : activer le mode déboggage USB

Pour activer le débogage USB:

  1. Ouvrez Paramètres > Système > Options pour les développeurs
  2. Activez l’option Débogage Android

Étape 3 : installation d’ADB

Android Debug Bridge (adb) est un outil de développement qui facilite la communication entre un appareil Android et un ordinateur. Cette communication s’effectue soit par câble USB, soit en WiFi.

Branchez votre OnePlus One en USB.

Téléchargez les derniers pilotes ADB issus du SDK Android puis décompressez l’archive.

Ouvrez le terminal, rendez-vous dans le répertoire platform-tools et listez ensuite votre téléphone avec cette commande:

./adb devices

Résultat:
List of devices attached
b4be4c53	device

Notre OnePlus One est bien détecté. On reboot en mode fastboot:

./adb reboot bootloader

On liste les appareils détectés par fastboot:

./fastboot devices

Résultat:
b4be4c53    fastboot

Attention, la commande suivante va effacer vos données donc pensez à sauvegarder les données importantes de votre téléphone avant!

On déverrouille le bootloader avec:

./fastboot oem unlock
                                                    OKAY [  0.168s]
 Finished. Total time: 0.168s

La partition est effacée, le téléphone va rebooter deux fois puis vous présenter le choix de la langue… comme au premier jour.

Comme c’est un reset de l’appareil, il faut de nouveau activer le débogage USB (étape 2).

La dernière version du serveur mail Dovecot nécessite quelques petits changements par rapport à la version antérieure.

Erreurs SASL

Voici ce que l’on peut lire dans les logs:

postfix/smtps/smtpd: warning: SASL: Connect to private/auth failed: Connection refused
postfix/smtps/smtpd: fatal: no SASL authentication mechanisms
postfix/master: warning: process /usr/lib/postfix/sbin/smtpd pid 635413 exit status 1
postfix/master: warning: /usr/lib/postfix/sbin/smtpd: bad command startup -- throttling

Solution: il faut éditer /etc/dovecot/conf.d/10-master.conf:

nano /etc/dovecot/conf.d/10-master.conf

et ajouter ce bloc de directives à la fin du bloc service auth:

service auth {
  # ... Previous config blocks
 
  # auth-master
  unix_listener auth-master {
    mode = 0660
    user = vmail
    group = vmail
  }

}

Stats writer

Dovecot inclut maintenant un module de statistiques et donne une erreur si jamais il n’est pas défini dans la configuration. Voici le message d’erreur:

Error: net_connect_unix(/var/run/dovecot/stats-writer) failed: Permission denied))

Il faut donc le rajouter:

nano /etc/dovecot/conf.d/10-master.conf

et ajouter ce bloc à la toute fin du fichier:

# fix Error: net_connect_unix(/var/run/dovecot/stats-writer) failed: Permission denied))
service stats {
   unix_listener stats-writer {
     group = dovecot
     mode = 0660
     user =
   }
  }

Ces derniers jours, en me rendant dans la Google Search Console, je me suis rendu compte que j’avais quelques milliers d’articles qui étaient indexés par Google mais sans être présents dans aucune sitemap.

Il s’agit en fait des articles de tablatures de guitare: au lieu de publier un article pour chaque tablatures, le site crée à la volée un article WordPress qui contient la tablature en question. C’est très efficace mais cela ne permet évidemment pas de les ajouter au fichier sitemap par défaut.

Si vous avez ce genre de configuration – ou si vous avez d’autres liens à soumettre à Google, voici ce que j’ai utilisé cette semaine.

État des lieux

On commence par se connecter à la Search Console pour se rendre dans Coverage > Valid > Indexed, not submitted in sitemap.

Voici un petit graphique qui montre les 1658 pages au 26 juillet et après soumission de la première sitemap – 1000 liens, car cela semble être la limite de l’export de la Search console, un premier résultat positif:

Export de la liste des articles

Tout en haut de la page, cliquez sur le bouton Export et sélectionnez Download CSV:

Cela lance le téléchargement d’un fichier zip. Décompressez l’archive et ouvrez le fichier Table.csv dans votre tableur préféré.

Nous mettons nos compétences au service de vos besoins

Stratégie

Nous étudions le parcours de votre site et vos besoins pour vous fournir une solution à long-terme, qui correspond à votre vision.

Développement

Vous souhaitez ajouter de nouvelles fonctionnalités à votre site ou boutique? Nous pouvons coder la solution!

Performance

Votre site doit être rapide et optimisé sur tous supports afin de convertir vos visiteurs. Nous pouvons auditer votre site et vous proposer la solution adaptée.

Hébergement

Vos projets ont besoin d’un hébergement de qualité, c’est la fondation de votre site web et elle doit être solide car c’est sur elle que tout repose.

Maintenance

Votre site a besoin d’une maintenance régulière afin de toujours utiliser la dernière mouture du code et rester sécurisé face aux menaces.

Assistance

Vous avez besoin d’aide ponctuelle? Pas de problème, nous sommes à votre écoute pour vous dépanner rapidement.

Il m’arrive très souvent d’utiliser une connexion Orange (depuis une Livebox 4) lorsque je suis chez mes parents.

Le problème est que la Livebox possède ses propres serveurs DNS intégrés et qu’ils sont menteurs, c’est-à-dire qu’ils obéissent à des règles de filtrage et de blocage décidés par l’opérateur (ou par des décisions de justice qui concernent tous les opérateurs).

Dans le cas d’Orange, les requêtes sont automatiquement redirigées vers votre machine locale, sur localhost. Comme j’utilise mon serveur Local tourne en quasi-permanence sur ma machine, cela me donne une belle erreur 502, comme vous pouvez le voir sur cette image:

MacOS : changer les serveurs DNS pour éviter les DNS menteurs de votre box photo
Lorsque votre les DNS intégrés à votre box vous mentent, il est temps de changer!

Nous avions déjà abordé le changement des serveurs DNS de notre Freebox mais il est un peu plus délicat de demander à vos hôtes de pouvoir changer les réglages de leur box… il y a une solution bien plus simple que de trifouiller au fond des entrailles du routeur fruitier : il suffit d’ajouter de nouveaux serveurs de noms sur votre machine, directement dans les options de votre connexion réseau.

Modification des serveurs de noms sous MacOS

Sous MacOS, il suffit de se rendre dans Préférences Systèmes > Réseau > Avancé :

Ce soir, on lance la mise à jour du serveur: nous passons notre version d’Ubuntu Server de Bionic Beaver (18.04 LTS) à Focal Fossa (20.04 LTS).

On commence par les précautions d’usage: faire ses sauvegardes et vérifier qu’elles sont bien intègres avant de commencer la mise à jour. C’est votre bouée en cas de soucis!

Étape 1: avoir l’installation d’Ubuntu actuelle à jour

Assurez-vous d’avoir une installation à jour avant de commencer:

apt update && apt dist-upgrade

On reboot ensuite pour appliquer les changements:

shutdown -r now

Étape 2: installation de screen et ouverture du port 1022 pour SSH

Comme nous allons lancer la mise à jour via un terminal SSH, il est possible que pour une raison ou un autre la connexion soit coupée. Cela arrive et cela peut être vraiment tendu à certaines étapes de la mise à jour (kernel anyone?).

Pour prévenir cela, on vérifie que screen est bien installé:

apt install screen

On peut lancer une session screen avec:

screen

et si la connexion SSH est interrompue lors de la mise à jour, on peut se raccrocher à la session de mise à jour avec la commande:

screen -Dr

Ensuite, au niveau du pare-feu, on ouvre le port 1022. C’est via ce port que l’on pourra reprendre la MAJ en cas de pépin. Suivant la configuration du serveur, on peut utiliser iptables:

iptables -I INPUT -p tcp --dport 1022 -j ACCEPT

ou alors ufw:

ufw allow 1022

Sur un serveur hébergé en Chine continentale, j’ai eu la surprise de ne pas être en mesure de mettre à jour wp-cli:

wp cli update

Error: Failed to get url 'https://api.github.com/repos/wp-cli/wp-cli/releases?per_page=100': cURL error 7: Failed to connect to api.github.com port 443: Connection refused.

Visiblement, certaines adresses sont injoignables, notamment lorsqu’elles utilisent le port 443 (https).

Evidemment, on peut télécharger wp-cli manuellement et le réinstaller mais si vous souhaitez une solution plus rapide, voilà comment j’ai procédé.

Première solution: édition de /etc/hosts

1. On récupère l’adresse IP de l’adresse api.github.com:

curl --ipv4 -v https://api.github.com

Résultat: 13.250.94.254 port 443

2. On édite le fichier /etc/hosts du serveur:

nano /etc/hosts

3. On y ajoute l’adresse IP correspondante à api.github.com:

13.250.94.254 api.github.com

Et voilà, le téléchargement depuis github est de nouveau accessible.

J’ai récemment joué avec l’API de YouTube pour pouvoir récupérer diverses informations sur les vidéos afin d’ajouter au site les données structurées idoines.

Il se trouve qu’en local, lorsque l’on utilise file_get_contents(), on peut obtenir une erreur de ce type lorsque le serveur n’est pas configuré avec le bundle de certificats OpenSSL:

Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in ...php on line 2

Warning: file_get_contents(): Failed to enable crypto in ...php on line 2

Warning: file_get_contents(https://........f=json): failed to open stream: operation failed in ...php on line 2

Si cela vous arrive, plusieurs solutions s’offrent à vous.

Méthode 1: configuration de PHP côté machine/serveur

1. Vérifiez qu’OpenSSL est bien installé sur votre machine (il devrait l’être sur le serveur!).

2. Ajoutez cette ligne à la configuration de PHP, dans votre php.ini:

openssl.cafile=/usr/local/etc/openssl/cert.pem

3. Redémarrez le service PHP.

Méthode 2 : une fonction qui utilise curl au lieu de file_get_contents()

Au lieu de m’embêter à configurer OpenSSL ou à toucher à PHP dans un conteneur docker (Local), il se trouve que l’on peut réécrire la fonction file_get_contents() avec une fonction maison qui utilise curl.

Voici la fonction en question:

/*
Custom CURL function that mimicks file_get_contents()
@returns false if no content is fetched
Matt Biscay (https://mattbiscay.com)
*/
function sky_curl_get_file_contents( $URL ){
	$c = curl_init();
	curl_setopt( $c, CURLOPT_RETURNTRANSFER, 1 );
	curl_setopt( $c, CURLOPT_URL, $URL );
	$contents = curl_exec( $c );
	curl_close( $c );
	if( $contents ) :
		return $contents;
	else:
		return false;
	endif;
}

La fonction retourne false si la requête échoue, ce qui est très utile pour éviter de faire des appels à des valeurs d’un tableau qui n’existe pas. On peut alors réfléchir à un autre moyen de peupler les champs de données structurées (mais c’est un sujet à aborder une autre fois).

J’ai eu besoin de tester l’existence d’un paramètre GET dans une URL en utilisant JavaScript. Il se trouve que cela ne prend que quelques lignes.

Pour ce tutoriel, nous allons considérer l’adresse de la page suivante, avec preview=yes passé comme paramètre:

https://example.com/?preview=yes

URLSearchParams() à la rescousse

Il est très simple de récupérer les variables $_GET avec PHP mais avec JavaScript, nous allons utiliser la classe URLSearchParams pour faire cela proprement.

1. On récupère les paramètres passés dans l’URL de la page:

let searchParams = new URLSearchParams(window.location.search);

2. On vérifie si l’un des paramètres recherchés est présent. Ici, on souhaite savoir si le paramètre preview existe:

searchParams.has('preview'); // returns true

3. On vérifie maintenant si preview est égal à yes:

let param = searchParams.get('sent');
param; // echoes 'yes'

Il ne nous reste plus qu’à utiliser la variable param pour l’utiliser ou la comparer.

Lors de la mise à jour d’un site vers PHP 7.4, je suis tombé sur cette erreur :

preg_match(): Compilation failed: invalid range in character class at offset 20 session.php on line 278

Depuis PHP 7.3, le moteur PCRE – qui est responsable de la gestion des expressions régulières – a été migré vers PCRE2.

Or, il s’avère que PCRE2 est plus strict dans la validation des pattern et c’est la raison pour laquelle, après la mise à jour de PHP, certaines expressions régulières ne peuvent plus être compilées correctement.

Voici un exemple d’expression régulière qui fonctionnait avant PHP7.3:

preg_match('/[\w-.]+/', ''); // this will not work in PHP7.3

Voici maintenant le même exemple mais qui sera désormais valide sous PHP 7.3 et les versions ultérieures :

preg_match('/[\w\-.]+/', ''); // the hyphen needs to be escaped

Comme vous pouvez le constater dans le deuxième exemple, il faut maintenant échapper le tiret (hyphen) avec un backslash.

Une fois la modification faite, plus d’erreur à ce niveau.