Sidekick: a productivity browser for becoming focused and unstoppable.

Sidekick, le navigateur avancé et sécurisé qui booste votre productivité

Et voilà, je viens encore d’installer un nouveau navigateur sur mon Mac! Il s’appelle Sidekick, est basé sur Chromium et résolumment orienté productivité.

Alors, vous allez me dire “quoi, encore un navigateur basé sur Chromium? mais pour quoi faire?”. Et bien accrochez-vous bien à vos baskets, c’est parti pour un petit aperçu de ses nombreux avantages.

1. Une organisation optimisée

Sidekick propose un système unique de gestion des onglets qui permet de garder votre espace de travail organisé. Les onglets peuvent être regroupés par projet – un peu comme les IDE comme Visual Studio Code – ou par catégorie, ce qui facilite grandement la navigation entre différentes tâches:

A computer screen with a variety of icons on it, alongside a secure browser that boosts productivity as a sidekick.
Les Workspaces sous Sidekick

On peut aussi créer des sessions d’onglets:

A screen shot of a desktop with a variety of icons on it, including an advanced browser for secure browsing.
Les sessions sous Sidekick

C’est très bien fait, vraiment efficace et cela permet d’y voir un peu plus clair lorsque l’on jongle avec des dizaines d’onglets sur des projets différents.

La dernière version, sortie il y a quelques jours, proposent également de passer d’onglets horizontaux (comme dans tous les navigateurs classiques) à des onglets verticaux, qui apparaissent au survol quand on place le pointeur de la souris à gauche. C’est bien à l’usage car cela donne plus de place à l’écran et permet de se focaliser sur l’onglet courant, sans être distrait.

2. Intégration des applications

Un des points forts de Sidekick est sa capacité à intégrer de nombreuses applications Web directement dans le navigateur. Des outils comme Slack, Asana, et Gmail peuvent être ancrés dans votre environnement de travail, permettant un accès rapide sans avoir à jongler entre différents onglets ou fenêtres.

A screen showing a variety of icons on a purple background, designed to enhance productivity and provide advanced security for users.
Sidekick : des applications directement accessibles dans le navigateur

J’ai ajouté 5 applications dans ma barre d’application: Gmail, Google Drive, ChatGPT, Whatsapp et Slack. Un clic sur l’icone bascule directement dans l’application dans le navigateur, et ce sans avoir à ouvrir un nouvel onglet. C’est tout simplement génial – plus besoin d’ouvrir l’application dédiée ou de remetttre la main sur son smartphone (pour Whatsapp). Tout est accessible en un clic.

3. Performance et efficacité

Sidekick est conçu pour être rapide et léger. Il optimise l’utilisation de la RAM et du CPU, ce qui est particulièrement avantageux pour les utilisateurs qui ouvrent de nombreux onglets ou utilisent des applications web gourmandes en ressources.

Fini le navigateur qui rame – mon Firefox a plus de 7000 onglets ouverts en permanence, je me soigne mais c’est dur – là, c’est de l’instantané. Notamment aussi parce que Sidekick est sécurisé par défaut et n’a pas besoin de X extensions tierces pour fonctionner.

Lire la suite

A robotic hand is typing on a laptop keyboard to extract content.

Comment empêcher les chatbots IA d’extraire le contenu de votre site

Vous êtes inquiet à l’idée que des chatbots basés sur l’intelligence artificielle puissent aspirer le contenu de votre site Web ? Heureusement, il existe des moyens de les en empêcher. Voici comment procéder.

Comment les chatbots IA accèdent-ils au contenu de votre site ?

Les chatbots alimentés par intelligence artificielle sont formés à l’aide de multiples jeux de données, dont certains sont en libre accès et disponibles au grand public. Selon un article de recherche publié par OpenAI, GPT-3 a été formé à partir de cinq jeux de données distincts :

  • Common Crawl (contribution de 60% à l’entraînement)
  • WebText2 (contribution de 22% à l’entraînement)
  • Books1 (contribution de 8% à l’entraînement)
  • Books2 (contribution de 8% à l’entraînement)
  • Wikipédia (contribution de 3% à l’entraînement)

Common Crawl englobe des pétaoctets de données issues de sites Web collectées depuis 2008, un peu à la manière dont l’algorithme de recherche de Google scrute les contenus en ligne. WebText2 est un jeu de données créé par OpenAI, qui contient environ 45 millions de pages Web liées depuis des publications Reddit ayant reçu au moins trois votes positifs.

Il est donc important de noter que, dans le cas de ChatGPT, le chatbot n’accède ni n’explore directement les pages de votre site Web — du moins, pas pour l’instant. Néanmoins, l’annonce récente d’un navigateur Web hébergé par ChatGPT a suscité des inquiétudes sur une éventuelle évolution de cette situation.

À l’heure actuelle, les propriétaires de sites Web devraient surveiller d’autres chatbots IA qui entrent sur le marché. Bard est un autre acteur majeur dans ce domaine, mais on en sait peu sur les jeux de données utilisés pour son entraînement. Bien sûr, nous savons que les robots d’exploration de Google parcourent constamment les pages Web, mais cela ne signifie pas nécessairement que Bard a accès aux mêmes données.

Pourquoi certains propriétaires de sites Web sont-ils inquiets ?

La principale inquiétude des propriétaires de sites Web est la dévalorisation de leur contenu par des bots IA tels que ChatGPT, Bard et Bing Chat. Ces bots IA utilisent le contenu existant pour générer des réponses, réduisant ainsi le besoin pour les utilisateurs d’accéder à la source originale. Au lieu de visiter des sites Web pour obtenir des informations, les utilisateurs peuvent simplement demander à Google ou à Bing de générer un résumé des informations dont ils ont besoin.

Dans le contexte des chatbots IA intégrés aux moteurs de recherche, la perte de trafic est la préoccupation majeure des propriétaires de sites Web. Par exemple, Bard, le chatbot IA, inclut rarement des citations dans ses réponses génératives, ce qui indique aux utilisateurs de quelles pages il tire ses informations.

Ainsi, en plus de remplacer les visites sur les sites Web par des réponses générées par IA, Bard supprime presque toute possibilité pour le site source de recevoir du trafic — même si l’utilisateur souhaite obtenir des informations supplémentaires. À l’opposé, Bing Chat lie plus fréquemment aux sources d’information.

En résumé, la génération actuelle d’outils IA génératifs utilise le travail des créateurs de contenu pour systématiquement supplanter le besoin de ces créateurs. Cela soulève la question de l’incitatif pour les propriétaires de sites Web à continuer à publier du contenu. Et, par extension, que se passera-t-il pour les chatbots IA si les sites Web cessent de publier le contenu dont ils dépendent pour fonctionner ?

Lire la suite

An English Romanticism painting of a landscape with trees and hills. William Turner, Dawn in the Valleys of Devon.

English Romanticism (1798-1832)

  1. The 18th Century: the Age of Enlightenment
  2. The Gothic and the Fantastic
  3. The 19th Century : Romanticism in Art and Literature
  4. English Romanticism (1798-1832)
  5. 19th Century Literary Movements : Realism and Naturalism
  6. British Civilisation and Literature: 19th and 20th centuries

English Romanticism began in 1798 with the publication of Wordsworth and Coleridge’s The Lyrical Ballads and ended in 1832 with Walter Scott’s death. William Blake and Robert Burns also belong to this literary genre, though they lived before the Romantic period.

Romanticism took place during a period of wars and revolutions, of considerable shifts and changes. It was a time of profound political and social reorganisation.

Romantic texts were varied and dealt with the Industrial Revolution and its consequences: a new class system, and a new type of economy. It’s important to emphasize the fact that this is the time when numerous kinds of problems appeared. Famous writers include William Blake, William Wordsworth and Samuel Coleridge.

Besides the Industrial Revolution, it is impossible to ignore the two major political upheavals that took place at that time, namely the American War of Independence (1776-1783) and the French Revolution (1789), which challenged old systems of social and political organizations.

Eugene Delacroix Le 28 Juillet. La Liberte guidant le peuple
Eugene Delacroix – Le 28 Juillet. La Liberté guidant le peuple.

The French Revolution struck British consciousness at first very favourably. Samuel Coleridge celebrated and praised it in a poem entitled “Destruction of the Bastille”.

Enthusiasm melted away as the war between France and Britain broke out four years later (1793), about the same time as the Reign of Terror started (1793-1794).

Romanticism was a period of constant tensions, observable in some of the poems we will study.

Lire la suite

A woman using a cell phone while sitting at a table with a cup of coffee and reading an eBook on her tablette.

ePub, comment lire un eBook (tablette et PC) ?

Découvrez la simplicité de la lecture numérique avec ePub

ePub est devenu le format de prédilection pour les adeptes du livre numérique, et pour cause : sa facilité d’utilisation est inégalée. Cet article vous guide à travers le processus en deux étapes faciles : télécharger un lecteur d’eBook et plonger dans votre lecture.

Qu’est-ce que le format ePub ?

ePub, l’acronyme de ‘electronic publication’, est largement reconnu comme le standard universel pour les livres numériques. Sa conception ouverte et adaptable garantit que le texte s’affiche parfaitement sur tous vos appareils, qu’il s’agisse d’ordinateurs, de tablettes ou de smartphones.

Vos premiers pas avec les lecteurs d’eBooks

La première étape consiste à choisir et installer un lecteur d’eBooks. Cette étape franchie, vous pourrez accéder à votre bibliothèque numérique à tout moment, sans aucune manipulation supplémentaire.

Comment lire un ePub sur Smartphone ou Tablette ?

Pour les utilisateurs d’iOS (iPad ou iPhone) :

Transférez vos fichiers ePub sur votre appareil via iTunes, et retrouvez-les facilement sur l’application iBooks, préinstallée et prête à l’emploi.

Pour les utilisateurs d’Android :

Aldiko est une excellente option, mais libre à vous d’explorer et de choisir l’application qui vous convient le mieux.

Lire un ePub sur un ordinateur

Sur Mac et Windows :

Adobe Digital Editions (ADE) est le choix privilégié pour les nouveaux venus dans le monde de la lecture numérique sur ordinateur. C’est une solution fiable qui promet une expérience de lecture fluide et intuitive. Voici comment démarrer avec ADE :

  1. Téléchargez et installez le logiciel sur votre ordinateur, qu’il soit sous Windows ou macOS.
  2. Une fois l’installation terminée, ouvrez ADE et ajoutez vos livres au format ePub à la bibliothèque.
  3. Double-cliquez sur un livre pour commencer à lire.

Sur Mac, Windows et Linux :

Calibre est bien plus qu’un simple lecteur d’eBooks : c’est une véritable bibliothèque numérique pour votre ordinateur, compatible avec Windows, macOS et Linux. C’est un outil complet qui permet non seulement de lire, mais aussi de gérer et d’organiser votre collection d’eBooks. Suivez ces instructions pour utiliser Calibre :

  1. Téléchargez et Installez Calibre et lancez-le.
  2. Importez vos eBooks au format ePub dans Calibre en cliquant sur “Ajouter des livres”.
  3. Sélectionnez un livre et cliquez sur “Lire” pour ouvrir le livre et profiter de votre lecture.

Lire la suite

Here we go round the mulberry bush, singing and dancing in a joyful circle.

Here We Go Round the Mulberry Bush

Introduction

“Here We Go Round the Mulberry Bush” is not just a traditional nursery rhyme; it’s a formative part of childhood for many people around the world. This enchanting singing game has been passed down from generation to generation, captivating young minds and fostering a sense of community and fun.

With its simple yet memorable lyrics and universally relatable themes, the nursery rhyme holds a special place in global folklore. This article seeks to delve deep into the intricate world of this nursery rhyme, exploring its rich history, diverse variations, and the underlying meanings and messages that have made it a timeless classic.

The Nursery Rhyme

Before embarking on this fascinating journey, it’s essential to familiarize ourselves with the most popularly recited version of the nursery rhyme. This rendition has served as the standard form for many English-speaking households.

Here we go round the mulberry bush,
The mulberry bush, the mulberry bush,
Here we go round the mulberry bush,
On a cold and frosty morning.

This is the way we wash our hands,
Wash our hands, wash our hands,
This is the way we wash our hands,
On a cold and frosty morning.

This is the way we brush our hair,
brush our hair, brush our hair,
This is the way we brush our hair,
On a cold and frosty morning.

This is the way we go to school,
Go to school, go to school,
This is the way we go to school,
On a cold and frosty morning.

This is the way we wave bye-bye,
Wave bye-bye, wave bye-bye,
This is the way we wave bye-bye,
On a cold and frosty morning.
Here We Go Round The Mulberry Bush

Here we go round the mulberry bush

Origins and history

England: the birthplace

Many believe that “Here We Go Round the Mulberry Bush” originated in England. Historical records hint at the rhyme being popular as far back as the 19th century. Intriguingly, the “mulberry bush” in question is often thought to represent a prison exercise yard. In this interpretation, the song’s roots lie in the harsh realities of historical English penitentiaries, where prisoners would be led around a mulberry tree as a form of exercise.

Theories and speculations

The song’s origins are not just limited to the prison yard theory. Over the years, scholars and enthusiasts have developed various hypotheses about its genesis. One compelling theory suggests that the song initially served as a way for children to mimic adult activities. The original game accompanying the song involved children forming a circle and imitating daily chores, reflecting the societal norms and routines of the time.

Lire la suite

An image of a computer screen with a green and purple background displaying the Message Of The Day (MOTD) on Ubuntu Server.

Changer le Message Of The Day (MOTD) sous Ubuntu Server

Le Message Of The Day (communément appelé MOTD) est un message d’accueil ou des notifications importantes que les administrateurs de serveurs peuvent configurer pour s’afficher lorsqu’un utilisateur se connecte au serveur via SSH.

Ce tutoriel vous montre comment mettre à jour et personnaliser le MOTD sur un serveur Ubuntu 22.04.

Prérequis

  • Serveur Ubuntu 22.04 avec accès root ou un utilisateur avec des privilèges sudo.
  • Accès SSH au serveur.

Étape 1 : connexion au Serveur

Connectez-vous à votre serveur Ubuntu via SSH:

ssh USER@SERVER_IP -pPORTCode language: CSS (css)

Étape 2 : vérifier le MOTD existant

Pour voir le MOTD actuel, utilisez la commande suivante :

cat /run/motd.dynamic

Étape 3 : modifier le MOTD dynamique

Ubuntu 22.04 utilise des scripts dans le répertoire /etc/update-motd.d/ pour générer une partie du MOTD dynamiquement. Vous pouvez ajouter, supprimer ou modifier les scripts dans ce répertoire pour personnaliser davantage le MOTD.

Entête MOTD

Nous allons créer un entête qui contient le nom de notre serveur en ASCII art, ce qui nous permettra de bien l’identifier lors de nos sessions SSH:

sudo nano /etc/update-motd.d/00-custom

Et on y ajoute notre script bash:

#!/bin/sh

# Reset
Color_Off='\033[0m'       # Text Reset

# Bold
BBlack='\033[1;30m'       # Black
BRed='\033[1;31m'         # Red
BGreen='\033[1;32m'       # Green
BYellow='\033[1;33m'      # Yellow
BBlue='\033[1;34m'        # Blue
BPurple='\033[1;35m'      # Purple / Magenta
BCyan='\033[1;36m'        # Cyan
BWhite='\033[1;37m'       # White

# Set the text color to green
printf "$BGreen"

# https://patorjk.com/software/taag/#p=display&f=Doom&t=APOLLO%20.%20SKYMINDS%20.%20NET
cat << "EOF"
  ___  ______ _____ _      _     _____       _____ _   ____   ____  ________ _   _______  _____       _   _  _____ _____
 / _ \ | ___ \  _  | |    | |   |  _  |     /  ___| | / /\ \ / /  \/  |_   _| \ | |  _  \/  ___|     | \ | ||  ___|_   _|
/ /_\ \| |_/ / | | | |    | |   | | | |     \ `--.| |/ /  \ V /| .  . | | | |  \| | | | |\ `--.      |  \| || |__   | |
|  _  ||  __/| | | | |    | |   | | | |      `--. \    \   \ / | |\/| | | | | . ` | | | | `--. \     | . ` ||  __|  | |
| | | || |   \ \_/ / |____| |___\ \_/ /  _  /\__/ / |\  \  | | | |  | |_| |_| |\  | |/ / /\__/ /  _  | |\  || |___  | |
\_| |_/\_|    \___/\_____/\_____/\___/  (_) \____/\_| \_/  \_/ \_|  |_/\___/\_| \_/___/  \____/  (_) \_| \_/\____/  \_/
EOF

# Set the text color to magenta
printf "$BPurple"

# Left image lines
left1="                                   88 88  "
left2="                                   88 88  "
left3="                                   88 88  "
left4=",adPPYYba, 8b,dPPYba,   ,adPPYba,  88 88  ,adPPYba,"
left5="\"\"     \`Y8 88P'    \"8a a8\"     \"8a 88 88 a8\"     \"8a"
left6=",adPPPPP88 88       d8 8b       d8 88 88 8b       d8"
left7="88,    ,88 88b,   ,a8\" \"8a,   ,a8\" 88 88 \"8a,   ,a8\""
left8="\"8bbdP\"Y8 88\`YbbdP\"'   \"\"YbbdP\"'  88 88  \"\"YbbdP\"'"
left9="           88                                          "
left10="           88                                         "

# Right image lines
right1=" .              +   .                .   . .     .  ."
right2="                   .                    .       .     *"
right3="  .       *                        . . . .  .   .  + ."
right4="            \"You Are Here\"            .   .  +  . . ."
right5=".                 |             .  .   .    .    . ."
right6="                  |           .     .     . +.    +  ."
right7="                 \\|/            .       .   . ."
right8="         . .        V          .    * . . .  .  +   ."
right9="               +      .           .   .      +"
right10="                               .       . +  .+. ."

# Combine and print
echo "$left1 $right1"
echo "$left2 $right2"
echo "$left3 $right3"
echo "$left4 $right4"
echo "$left5 $right5"
echo "$left6 $right6"
echo "$left7 $right7"
echo "$left8 $right8"
echo "$left9 $right9"
echo "$left10 $right10"

# STATS
upSeconds="$(/usr/bin/cut -d. -f1 /proc/uptime)"
secs=$((${upSeconds}%60))
mins=$((${upSeconds}/60%60))
hours=$((${upSeconds}/3600%24))
days=$((${upSeconds}/86400))
UPTIME=$(printf "%d days, %02dh%02dm%02ds" "$days" "$hours" "$mins" "$secs")

# get the load averages
read one five fifteen rest < /proc/loadavg

# text in yellow
printf "$BYellow"

echo "
   .~~.   .~~.    `date +"%A, %e %B %Y, %r"`
  '. \ ' ' / .'   `uname -srmo`
   .~ .~~~..~.
  : .~.'~'.~. :   Uptime.............: ${UPTIME}
 ~ (   ) (   ) ~  Memory.............: `cat /proc/meminfo | grep MemFree | awk {'print $2'}`kB (Free) / `cat /proc/meminfo | grep MemTotal | awk {'print $2'}`kB (Total)
( : '~'.~.'~' : ) Load Averages......: ${one}, ${five}, ${fifteen} (1, 5, 15 min)
 ~ .~ (   ) ~. ~  Running Processes..: `ps ax | wc -l | tr -d " "`
  (  : '~' :  )   IP Addresses.......: `ip a | grep glo | awk '{print $2}' | head -1 | cut -f1 -d/` and `wget -q -O - https://icanhazip.com/ | tail`
   '~ .~~~. ~'    Weather............: `curl -s "https://rss.accuweather.com/rss/liveweather_rss.asp?metric=1&locCode=EUR|FR|FR|NANTES|" | sed -n '/Currently:/ s/.*: \(.*\): \([0-9]*\)\([CF]\).*/\2°\3, \1/p'`
       '~'
"

# text default colour
printf "$Color_Off"Code language: PHP (php)

Cela affiche le nom du serveur (apollo.skyminds.net) puis une petite frise, et enfin les statistiques ainsi que la météo pour Nantes. Vous pouvez modifier la ville dans l’avant-dernière ligne.

Notez que j’ai compilé deux images pour qu’elles s’affichent sur les mêmes lignes: le mot “apollo” en ASCII art et une version de l’univers avec le texte “You are here!”. Il faut jouer avec l’indentation mais au bout de quelques essais, cela rend plutôt pas mal je trouve.

Rendez le script exécutable :

sudo chmod +x  /etc/update-motd.d/00-custom

Lancez la compilation de tous les modules dynamiques pour obtenir le MOTD final qui sera affiché à chaque connexion SSH:

run-parts /etc/update-motd.d/ > /run/motd.dynamicCode language: JavaScript (javascript)

Lire la suite

viewport overflow

Vanilla JS : identifier l’élément plus large que le viewport

Aujourd’hui, je régle un petit souci d’affichage sur un une boutique WooCommerce propulsée par Astra.

Le problème est le suivant: lorsqu’on visite le site depuis un mobile, il est possible de faire bouger le contenu de la page vers la gauche, ce qui dévoile une hideuse colonne grise/verte sur le côté droit. Pourtant, aucun élément ne semble dépasser la largeur du contenu.

L’identification de l’élément causant ce défaut d’affichage n’est pas vraiment une chose aisée, car visuellement, on ne distingue rien qui dépasse.

Vanilla JS à la rescousse

Voici un petit script en Vanilla JS qui permet de trouver l’élément qui dépasse la largeur du viewport de votre page:

/**
 * Identify elements that exceed the viewport width
 * by Matt Biscay
 * https://www.skyminds.net/?p=614036
 */
document.addEventListener("DOMContentLoaded", function() {
  const elements = document.querySelectorAll('body *');
  elements.forEach(element => {
    if (element.offsetWidth > document.documentElement.clientWidth) {
      console.log('Element causing overflow: ', element);
    }
  });
});Code language: JavaScript (javascript)

CSS: couvrez cet overflow que je ne saurais voir

Une fois votre ou vos éléments identifiés, il ne vous reste plus qu’à cacher son overflow-x :

#element {
  overflow-x: hidden;
}Code language: CSS (css)

Rafraîchissez la page. Hop, problème résolu.

A black and white photo of the statue of Apollo.

Nouveau serveur dédié OVH : Apollo

J’ai craqué pour un nouveau serveur chez OVH. C’est mon premier serveur OVH, si l’on considère que je n’ai jamais utilisé que des Kimsufi auparavant, depuis mars 2010.

Voyons voir ce qu’il a dans le ventre.

Processeur

On obtient les spécifications du processeur:

lscpu

Ce qui nous donne:

lscpu

Architecture:            x86_64
  CPU op-mode(s):        32-bit, 64-bit
  Address sizes:         39 bits physical, 48 bits virtual
  Byte Order:            Little Endian
CPU(s):                  16
  On-line CPU(s) list:   0-15
Vendor ID:               GenuineIntel
  Model name:            Intel(R) Xeon(R) E-2288G CPU @ 3.70GHz
    CPU family:          6
    Model:               158
    Thread(s) per core:  2
    Core(s) per socket:  8
    Socket(s):           1
    Stepping:            13
    CPU max MHz:         5000.0000
    CPU min MHz:         800.0000
    BogoMIPS:            7399.70
    Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts a
                         cpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch
                         _perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq
                         dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_
                         2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowp
                         refetch cpuid_fault epb invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow
                         vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpci
                         d mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida a
                         rat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d arch_capabilitie
                         s
Virtualization features:
  Virtualization:        VT-x
Caches (sum of all):
  L1d:                   256 KiB (8 instances)
  L1i:                   256 KiB (8 instances)
  L2:                    2 MiB (8 instances)
  L3:                    16 MiB (1 instance)
NUMA:
  NUMA node(s):          1
  NUMA node0 CPU(s):     0-15
Vulnerabilities:
  Gather data sampling:  Mitigation; Microcode
  Itlb multihit:         KVM: Mitigation: VMX disabled
  L1tf:                  Not affected
  Mds:                   Not affected
  Meltdown:              Not affected
  Mmio stale data:       Mitigation; Clear CPU buffers; SMT vulnerable
  Retbleed:              Mitigation; Enhanced IBRS
  Spec store bypass:     Mitigation; Speculative Store Bypass disabled via prctl and seccomp
  Spectre v1:            Mitigation; usercopy/swapgs barriers and __user pointer sanitization
  Spectre v2:            Mitigation; Enhanced IBRS, IBPB conditional, RSB filling, PBRSB-eIBRS SW sequence
  Srbds:                 Mitigation; Microcode
  Tsx async abort:       Mitigation; TSX disabledCode language: JavaScript (javascript)

Nous avons donc un Intel(R) Xeon(R) E-2288G CPU @ 3.70GHz (8c/16t), avec toutes les corrections appliquées pour corriger les vulnérabilités.

C’est une belle mise à jour par rapport à l’ancien serveur, qui était un Intel(R) Xeon(R) CPU W3530 @ 2.80GHz (4c/8t), qui n’était pas aussi sécurisé.

Bande passante

On passe sur une bande passante à 500Mbit/s et non plus en 100Mbit/s, toujours en illimité (unmetered).

Mémoire et disques

On reste sur 32GB de RAM mais on double sa vitesse: on passe de la DDR3 @ 1333 MHz à de la DDR4 ECC @ 2666 MHz:

sudo dmidecode -t memory | grep -i speed

Résultat:

Speed: 2666 MT/s
Configured Memory Speed: 2666 MT/s

Au niveau des disques, changement également: nous avions 2 × 2TB Soft RAID avec des disques durs classiques et maintenant on passe sur 2 × 960GB SSD NVMe Soft RAID.

Système d’exploitation

On reste sous Ubuntu Server, qui est vraiment agréable à utiliser et configurer. J’ai été surpris de voir que lorsqu’on installe Ubuntu Server 22.04 de rien, il crée un utilisateur par défaut, qui n’est pas root. C’est plutôt bien, mais ce n’était pas le cas avec Ubuntu Server 18.04 (root était alors le seul utilisateur créé lors de l’installation).

C’est bien au quotidien, pour la migration, il a fallu pas mal changer les commandes rsync toutefois.

Migration d’Orion à Apollo

La migration s’est bien déroulée. D’ailleurs, si vous pouvez lire cet article, c’est que le site est bien servi par Apollo.

Outre les fichiers et les bases de données, c’est aussi tout le serveur email qui a été entièrement recréé.

La bonne nouvelle, c’est que c’est plus simple que ce j’avais fait la première fois avec Postfix et Courier. La moins bonne nouvelle, c’est que cela prend un temps fou parce qu’il y a environ une quinzaine de fichiers à éditer constamment pour que tout soit parfait.

Bonus du serveur email: il est mieux configuré que le précédent, avec une configuration plus simple mais mieux sécurisée, et toujours avec DNSSEC et DANE.

J’ai écrit pas mal de scripts bash pour automatiser certaines installations dans le cadre d’une future migration. On en reparle bientôt!

Update MySQL client and server versions using apt config.

Mettre à jour MySQL client, server et apt-config

Un an après mon article sur l’erreur APT : the following packages have been kept back, voici que cela recommence : impossible d’installer les mises à jour de mysql-client et mysql-server parce que mysql-apt-config n’est plus à jour.

J’ai tendance à oublier la solution parce que je n’y suis confronté que depuis peu donc j’ai écris un petit script bash que je pourrai lancer la prochaine fois, histoire de gagner du temps.

Pré-requis: installation de pup

pup est un outil en ligne de commande pour traiter le HTML. Il lit à partir de stdin, imprime vers stdout, et permet à l’utilisateur de filtrer des parties de la page en utilisant des sélecteurs CSS.

Nous téléchargeons pup depuis son repo sur Github, on extraie le binaire et on le déplace dans /usr/local/bin/ :

wget https://github.com/ericchiang/pup/releases/download/v0.4.0/pup_v0.4.0_linux_amd64.zip

unzip pup_v0.4.0_linux_amd64.zip

sudo mv pup /usr/local/bin/Code language: JavaScript (javascript)

Script bash pour mettre à jour MySQL avec mysql-apt-config

Nous créons notre nouveau script, et nous le rendons exécutable:

cd /home/scripts

nano install-latest-mysql-apt.sh

chmod +x install-latest-mysql-apt.sh

Et voici le contenu du script:

#!/bin/bash
# ----------------------------------------- #
# Script Name: install-latest-mysql-apt.sh  #
# Author: Matt Biscay                       #
# URL: https://www.skyminds.net/?p=613967   #
# ----------------------------------------- #

# Color codes
RED=$(tput bold; tput setaf 1)
GREEN=$(tput bold; tput setaf 2)
YELLOW=$(tput bold; tput setaf 3)
MAGENTA=$(tput bold; tput setaf 5)
NC=$(tput sgr0) # No Color

# Function to print the header
function print_header() {
  echo -e "${YELLOW}# ----------------------------------------- #${NC}"
  echo -e "${YELLOW}# Script Name: install-latest-mysql-apt.sh  #${NC}"
  echo -e "${YELLOW}# Author: Matt Biscay                       #${NC}"
  echo -e "${YELLOW}# URL: https://www.skyminds.net/?p=613967   #${NC}"
  echo -e "${YELLOW}# ----------------------------------------- #${NC}"
}

# Print the header
print_header

# Function to check if the command exists
function check_command() {
  command -v "$1" &> /dev/null || {
    echo -e "${RED}$1 is not installed. Please install it and try again.${NC}"
    exit 1
  }
}

# Check if wget, unzip are installed
check_command wget
check_command unzip

# Check if pup is installed
if ! command -v pup &> /dev/null; then
  read -p $"${MAGENTA}The \"pup\" tool is not installed, would you like to install it now? (Y/N) ${NC}" INSTALL_PUP
  case ${INSTALL_PUP:0:1} in
    [Yy]* )
      TMP_DIR=$(mktemp -d)
      wget https://github.com/ericchiang/pup/releases/download/v0.4.0/pup_v0.4.0_linux_amd64.zip -O "$TMP_DIR/pup.zip"
      unzip "$TMP_DIR/pup.zip" -d "$TMP_DIR"
      mv "$TMP_DIR/pup" /usr/local/bin/
      rm -r "$TMP_DIR"
      echo -e "${GREEN}Package pup has been installed.${NC}"
      ;;
    [Nn]* )
      echo "Exiting since pup is not installed."
      exit 1
      ;;
    * )
      echo -e "${RED}Invalid input. Please enter Y or N.${NC}"
      exit 1
      ;;
  esac
fi

BASE_URL="https://dev.mysql.com"
INITIAL_URL="${BASE_URL}/downloads/repo/apt/"

# Create temporary files
TMP_INITIAL=$(mktemp)
TMP_SECONDARY=$(mktemp)

echo "Fetching initial page... $INITIAL_URL"
wget -qO- "$INITIAL_URL" > "$TMP_INITIAL"

# Extract the secondary download page URL from the main page
echo "Extracting secondary page URL..."
SECONDARY_URL=$(cat "$TMP_INITIAL" | pup 'div.button03 a attr{href}')
echo "Secondary URL: ${BASE_URL}${SECONDARY_URL}"

# Fetch the secondary page and store its content for debugging
echo "Fetching secondary page..."
wget -qO- "${BASE_URL}${SECONDARY_URL}" > "$TMP_SECONDARY"

# Extract the download link from the secondary page
echo "Extracting download link..."
DOWNLOAD_URL=$(cat "$TMP_SECONDARY" | pup 'a:contains("No thanks, just start my download.") attr{href}')
echo "Download URL: ${BASE_URL}${DOWNLOAD_URL}"

# Ask user if they want to install mysql-apt-config
read -p $"${MAGENTA}Do you want to download and install the package? (Y/N) ${NC}" DOWNLOAD_MYSQL_APT_CONFIG
case ${DOWNLOAD_MYSQL_APT_CONFIG:0:1} in
    [Yy]* )
        wget "${BASE_URL}${DOWNLOAD_URL}" -O mysql-apt-config.deb
        dpkg -i mysql-apt-config.deb

        echo -e "${GREEN}Package mysql-apt-config has been updated.${NC}"

        read -p $"${MAGENTA}Are you ready to install updates with \"apt update && apt upgrade\"? (Y/N) ${NC}" UPDATE_UPGRADE
        case ${UPDATE_UPGRADE:0:1} in
            [Yy]* )
                apt update && apt upgrade
                ;;
            [Nn]* )
                echo "Exiting without installing updates."
                ;;
            * )
                echo -e "${RED}Invalid input. Please enter Y or N.${NC}"
                ;;
        esac
        ;;
    [Nn]* )
        echo "Exiting without installing."
        ;;
    * )
        echo -e "${RED}Invalid input. Please enter Y or N.${NC}"
        ;;
esac

# Trap to clean up temporary files
trap 'rm -f "$TMP_INITIAL" "$TMP_SECONDARY" mysql-apt-config.deb' EXITCode language: PHP (php)

Fonctionnement du script

Le script commence par vérifier que pup est installé. S’il ne l’est pas, on prompte l’utilisateur pour l’installer:

The "pup" tool is not installed, would you like to install it now? (Y/N) y

Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.109.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1718186 (1.6M) [application/octet-stream]
Saving to: ‘/tmp/tmp.4buPXeejfo/pup.zip’

Archive:  /tmp/tmp.4buPXeejfo/pup.zip
  inflating: /tmp/tmp.4buPXeejfo/pup
Package pup has been installed.Code language: JavaScript (javascript)

Le script effectue deux requêtes sur le site de MySQL: lors de la première requête, il identifie le lien du bouton “Download”.

Lire la suite

Resolve error 526 with Cloudflare and NginX.

Résoudre l’erreur 526 entre Cloudflare et NginX

Dernièrement, je me suis apercu qu’une requête curl sur le domaine skyminds.net (sans www donc), donnait une erreur 526 sous Cloudflare (avec le proxy activé, mais aussi sans):

curl -Ik https://skyminds.net


HTTP/2 526
date: Fri, 18 Aug 2023 23:50:35 GMT
content-type: text/html; charset=UTF-8
content-length: 7111
cf-ray: 7f8e0f5538300636-CDG
cf-cache-status: BYPASS
cache-control: private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
expires: Thu, 01 Jan 1970 00:00:01 GMT
set-cookie: cf_ob_info=526:7f8e0f55430d0636:CDG; path=/; expires=Fri, 18-Aug-23 23:51:05 GMT
vary: Accept-Encoding
cf-apo-via: origin,resnok
referrer-policy: same-origin
set-cookie: cf_use_ob=443; path=/; expires=Fri, 18-Aug-23 23:51:05 GMT
x-frame-options: SAMEORIGIN
report-to: {"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v3?s=KQ7z1CYzwZD3r%2FzoJ2QLzFRmcgQzql1Oz3KwXyVnHVWHH5mUgxKqwU8p2%2F0C9rn%2FJUOSQG%2BWZl9%2B%2FDdQSPXznmFKKeiqFdqXzpuGFK5xgZbHAohOVxY4Vk6%2F1bM73jNRhrjfYZ42r6FMJ6c%3D"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
server: cloudflare
alt-svc: h3=":443"; ma=86400
Code language: JavaScript (javascript)

Sous tous les navigateurs par contre, une brève page d’erreur s’affiche (quelques millisecondes) avant que finalement la redirection vers le sous-domaine www ne s’effectue. Je me suis dis que c’était bizarre et que je réglerais le problème plus tard.

Quelques semaines mois passent et j’effectue une petite visite de routine sur mes sous-domaines, notamment celui de postfixadmin. Et là, patatras : erreur 526 avec le proxy Cloudflare actif, mais aussi une ribambelle d’erreurs selon les navigateurs utilisés:

Échec de la connexion sécurisée Une erreur est survenue pendant une connexion à demo.skyminds.net.

Le pair SSL a rejeté un message d’établissement de liaison à cause d’un contenu inacceptable. Code d’erreur : SSL_ERROR_ILLEGAL_PARAMETER_ALERT

La page que vous essayez de consulter ne peut pas être affichée car l’authenticité des données reçues ne peut être vérifiée. Veuillez contacter les propriétaires du site web pour les informer de ce problème.

Firefox

Ce site est inaccessibleIl se peut que la page Web à l’adresse https://demo.skyminds.net soit temporairement inaccessible ou qu’elle ait été déplacée de façon permanente à une autre adresse Web. ERR_QUIC_PROTOCOL_ERROR

Brave

Bon, il va falloir s’atteler à comprendre ce qui se passe vraiment ici!

Vérification du certificat TLS

On vérifie que le certificat est valide:

echo | openssl s_client -connect skyminds.net:443 -servername skyminds.net 2>/dev/null | openssl x509 -noout -dates

notBefore=Aug  6 12:15:26 2023 GMT
notAfter=Nov  4 12:15:25 2023 GMTCode language: JavaScript (javascript)

Tout est bon, le certificat est toujours valide.

On vérifie ensuite que les sous-domaines sont bien inclus (au cas où, mais je crée toujours des certificats wildcard par défaut):

echo | openssl s_client -connect skyminds.net:4echo | openssl s_client -connect skyminds.net:443 -servername skyminds.net 2>/dev/null | openssl x509 -noout -text


Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            03:cc:a2:48:39:97:ea:6c:d0:5d:86:5a:e3:f8:e3:d3:b2:1a
        Signature Algorithm: ecdsa-with-SHA384
        Issuer: C = US, O = Let's Encrypt, CN = E1
        Validity
            Not Before: Aug  6 12:15:26 2023 GMT
            Not After : Nov  4 12:15:25 2023 GMT
        Subject: CN = skyminds.net
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:69:84:99:0b:ea:1b:6f:38:ac:ee:fa:76:7d:4f:
                    59:01:02:bd:6e:d8:25:83:a7:8a:c5:d5:a4:b9:c5:
                    64:65:2d:49:20:3d:bc:4c:06:38:7d:73:d0:c0:55:
                    0b:90:cf:44:f7:5a:8c:37:8f:f9:da:51:eb:c3:f0:
                    5b:87:ce:00:ba
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                E7:3A:09:C3:D5:75:02:65:A6:D7:7D:12:D4:F3:5D:42:72:11:75:B4
            X509v3 Authority Key Identifier:
                5A:F3:ED:2B:FC:36:C2:37:79:B9:52:30:EA:54:6F:CF:55:CB:2E:AC
            Authority Information Access:
                OCSP - URI:http://e1.o.lencr.org
                CA Issuers - URI:http://e1.i.lencr.org/
            X509v3 Subject Alternative Name:
                DNS:*.skyminds.net, DNS:skyminds.net
            X509v3 Certificate Policies:
                Policy: 2.23.140.1.2.1
            CT Precertificate SCTs:
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : 7A:32:8C:54:D8:B7:2D:B6:20:EA:38:E0:52:1E:E9:84:
                                16:70:32:13:85:4D:3B:D2:2B:C1:3A:57:A3:52:EB:52
                    Timestamp : Aug  6 13:15:26.501 2023 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
                Signed Certificate Timestamp:
                    Version   : v1 (0x0)
                    Log ID    : B7:3E:FB:24:DF:9C:4D:BA:75:F2:39:C5:BA:58:F4:6C:
                                5D:FC:42:CF:7A:9F:35:C4:9E:1D:09:81:25:ED:B4:99
                    Timestamp : Aug  6 13:15:26.502 2023 GMT
                    Extensions: none
                    Signature : ecdsa-with-SHA256
    Signature Algorithm: ecdsa-with-SHA384
    Code language: PHP (php)

Le certificat couvre bien skyminds.net et *.skyminds.net, donc tous les sous-domaines.

Lire la suite

php 8.2

Installation de PHP 8.2 sur le serveur

Aujourd’hui, on installe PHP 8.2 sur le serveur vu que SkyMinds est compatible avec selon notre testeur de compatibilité PHP.

La dernière version stable installée sur le serveur est PHP8 donc on récupère la liste des extensions PHP installées avec PHP 8:

dpkg -l | grep php8.0 | grep ii | awk '{print $2}'

php8.0
php8.0-apcu
php8.0-bcmath
php8.0-cli
php8.0-common
php8.0-curl
php8.0-fpm
php8.0-gd
php8.0-gmp
php8.0-igbinary
php8.0-imagick
php8.0-imap
php8.0-intl
php8.0-mbstring
php8.0-mysql
php8.0-opcache
php8.0-readline
php8.0-redis
php8.0-soap
php8.0-xml
php8.0-zipCode language: JavaScript (javascript)

C’est bien mais nous pouvons améliorer la commande pour replacer php8.0 par php8.2:

dpkg -l | grep php8.0 | grep ii | awk '{print $2}' | sed 's/php8.0/php8.2/g'

php8.2
php8.2-apcu
php8.2-bcmath
php8.2-cli
php8.2-common
php8.2-curl
php8.2-fpm
php8.2-gd
php8.2-gmp
php8.2-igbinary
php8.2-imagick
php8.2-imap
php8.2-intl
php8.2-mbstring
php8.2-mysql
php8.2-opcache
php8.2-readline
php8.2-redis
php8.2-soap
php8.2-xml
php8.2-zipCode language: JavaScript (javascript)

Transformons maintenant le résultat pour avoir une liste séparée par des espaces et non des sauts de lignes:

dpkg -l | grep php8.0 | grep ii | awk '{print $2}' | sed 's/php8.0/php8.2/g' | tr '\n' ' '

php8.2 php8.2-apcu php8.2-bcmath php8.2-cli php8.2-common php8.2-curl php8.2-fpm php8.2-gd php8.2-gmp php8.2-igbinary php8.2-imagick php8.2-imap php8.2-intl php8.2-mbstring php8.2-mysql php8.2-opcache php8.2-readline php8.2-redis php8.2-soap php8.2-xml php8.2-zipCode language: JavaScript (javascript)

Installation de PHP 8.2

Parfait, nous pouvons maintenant lancer apt install combinée avec notre dernière commande:

apt install $(dpkg -l | grep php8.0 | grep ii | awk '{print $2}' | sed 's/php8.0/php8.2/g' | tr '\n' ' ')

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
php8.2-cli is already the newest version (8.2.7-1+ubuntu22.04.1+deb.sury.org+1).
php8.2-cli set to manually installed.
php8.2-common is already the newest version (8.2.7-1+ubuntu22.04.1+deb.sury.org+1).
php8.2-common set to manually installed.
php8.2-imagick is already the newest version (3.7.0-3+ubuntu22.04.1+deb.sury.org+1).
php8.2-imagick set to manually installed.
php8.2-opcache is already the newest version (8.2.7-1+ubuntu22.04.1+deb.sury.org+1).
php8.2-opcache set to manually installed.
php8.2-readline is already the newest version (8.2.7-1+ubuntu22.04.1+deb.sury.org+1).
php8.2-readline set to manually installed.
Suggested packages:
  php-pear
The following NEW packages will be installed:
  php8.2 php8.2-apcu php8.2-bcmath php8.2-curl php8.2-fpm
  php8.2-gd php8.2-gmp php8.2-igbinary php8.2-imap php8.2-intl
  php8.2-mbstring php8.2-mysql php8.2-redis php8.2-soap
  php8.2-xml php8.2-zip
0 upgraded, 16 newly installed, 0 to remove and 0 not upgraded.
Need to get 3440 kB of archives.
After this operation, 10.7 MB of additional disk space will be used.
Do you want to continue? [Y/n] yCode language: JavaScript (javascript)

Configuration de PHP 8.2

Pour la configuration du php.ini ainsi que du pool PHP, je vous conseille d’utiliser la configuration de notre WordPress RocketStack, qui donne d’excellents résultats en terme de performance et réactivité.

Mise à jour du server block NginX

C’est plutôt simple, il vous suffit d’éditer le server block NginX de votre domaine et de changer cette ligne:

# PHP 8
fastcgi_pass unix:/run/php/php8.0-fpm.sock;Code language: PHP (php)

par cette ligne:

# PHP 8.2
fastcgi_pass unix:/run/php/php8.2-fpm.sock;Code language: PHP (php)

Ensuite, il ne nous reste plus qu’à relancer les services:

service nginx restart
service php8.2-fpm restartCode language: CSS (css)

Et voilà PHP 8.2 est installé et fait tourner le site, en moins de 10 minutes.

wordpress rocketstack

WordPress Rocket Stack : envoyez WordPress sur orbite !

Sur Orion, j’ai installé ma WordPress Rocket Stack qui est configurée avec la stack suivante:

  • Ubuntu Server 22.04 LTS
  • MySQL 8+
  • NginX 1.25+
  • PHP 8.3
  • Redis
  • Nginx FastCGI Cache
  • Fail2ban
  • LetsEncrypt avec acme.sh

Hébergement

L’hébergement est la base de votre site, c’est tout simplement la fondation sur laquelle va reposer votre code.

Vous avez tout intérêt à avoir un très bon hébergeur : il doit être rapide dès le départ et offrir de bonnes garanties en termes de performance et de sécurité.

Si vous avez un site WordPress ou WooCommerce, je ne peux que vous recommander Kinsta, WPEngine ou Nexcess. Tous trois sont de très bons hébergeurs, particulièrement orientés vers la performance avec des ressources garanties et un support technique réactif et efficace en cas de besoin.

Personnellement, j’utilise un serveur dédié chez OVH parce que j’héberge pas mal de sites et j’ai besoin d’avoir un contrôle fin sur la configuration de chacun des services.

Ubuntu Server

J’étais auparavant sous Debian mais j’ai finalement opté pour Ubuntu Server 22.04 LTS pour ce nouveau serveur.

L’avantage d’Ubuntu est de pouvoir disposer des mises à jour plus rapidement que sous Debian.

Lire la suite