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

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 GMT

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
    

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

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

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

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] y

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;

par cette ligne:

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

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

service nginx restart
service php8.2-fpm restart

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.0
  • 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.

Installation de la WordPress Rocket Stack

# MySQL
# Latest link is always on the apt page: https://dev.mysql.com/downloads/repo/apt/
wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.23-1_all.deb
dpkg -i mysql-apt-config_0.8.23-1_all.deb

# Packages
apt install software-properties-common tmux curl wget zip unzip git
add-apt-repository ppa:ondrej/php
add-apt-repository ppa:ondrej/nginx-mainline
apt update -y
apt upgrade -y
apt install mysql-server -y # accept all defaults

# PHP 8.0
# Note: the json module is now part of PHP core
apt install php8.0 php8.0-bcmath php8.0-curl php8.0-gmp php8.0-imap php8.0-mbstring php8.0-readline php8.0-xml php8.0-apcu php8.0-cli php8.0-fpm php8.0-igbinary php8.0-intl php8.0-mysql php8.0-redis php8.0-zip php8.0-common php8.0-gd php8.0-imagick php8.0-opcache php8.0-soap -y

# Run installs
apt install nginx -y
apt install fail2ban -y
apt install redis -y

# Get NginX config files
git clone https://github.com/skyminds/wordpress-rocketstack
cp wordpress-rocketstack/nginx/* /etc/nginx/ -R
rm wordpress-rocketstack

DNS : ajout du site sur le serveur

Mon serveur est hébergé chez OVH donc il faut ajouter le domaine aux DNS secondaires du serveur.

Sur l’interface Kimsufi, cela se fait très simplement:

Ajouter le domaine au serveur (dns secondaire)
Ajouter le domaine au serveur (dns secondaire)

Configurer Cloudflare

Si vous utilisez Cloudflare – ce que je vous recommande fortement – et que vous obtenez une erreur 403 ou alors une page “Welcome to NginX” en lieu et place de votre nouveau site, veillez bien à sélectionner la bonne option SSL dans Cloudflare > Example.com > SSL/TLS > Overview : il faut sélectionner Full ou Full (Strict) mais surtout pas “Flexible“:

Choisissez toujours l'option SSL/TLS Full (Strict) chez Cloudflare
Choisissez toujours l’option SSL/TLS Full (Strict) chez Cloudflare

Ensuite, il ne nous reste qu’à faire pointer le CNAME vers l’adresse IP du serveur et d’ajouter le champs TXT qui a été indiqué par OVH dans l’étape précédente:

Ajout de l'enregistrement DNS au format TXT pour valider le DNS secondaire chez OVH
Ajout de l’enregistrement DNS au format TXT pour valider le DNS secondaire chez OVH

Ajout du server block NginX

DOMAIN="example.com"
DOMAINDIR="example"

mkdir -p /home/www/$DOMAINDIR
chown www-data:www-data /home/www/$DOMAINDIR

mkdir -p /home/nginx-cache/$DOMAINDIR
chown -R www-data:www-data /home/nginx-cache/

cp /etc/nginx/sites-available/wprocketstack.conf /etc/nginx/sites-available/$DOMAINDIR.conf

rm /etc/nginx/sites-enabled/default
rm /etc/nginx/sites-available/default

On édite ensuite la configuration:

nano /etc/nginx/sites-available/$DOMAINDIR.conf

Mettez l’adresse du site dans la directive server_name:

server_name example.com

Lire la suite