Serveur dédié : transférer et héberger un nouveau domaine sur votre serveur photo

Serveur dédié : transférer et héberger un nouveau domaine sur votre serveur

Aujourd’hui, nous allons voir comment héberger un nouveau domaine sur le serveur, en simplifiant au maximum les procédures.

Serveur dédié : transférer et héberger un nouveau domaine sur votre serveur photo

Le nom de domaine sera réservé chez OVH et le site hébergé sur notre serveur Debian. Nous allons servir le site avec NginX en HTTPS grâce à un certificat SSL fourni gratuitement par Let’s Encrypt.

Enfin, on utilisera le serveur email existant et on ajoutera la configuration OpenDKIM pour signer et authentifier tous les emails sortants du domaine.

Nom de domaine

J’achète mes noms de domaine chez OVH parce que le prix est relativement raisonnable (comparé à mon ancien registrar).

Au moment de la commande, faites pointer le nouveau domaine vers les DNS du serveur.

Si votre serveur n’est pas chez OVH, il suffit d’aller dans Domaines > Serveurs DNS et de renseigner le DNS primaire et secondaire de votre serveur.

Configuration DNS dans BIND

Une fois le domaine commandé, si vous vous rendez dans le Manager OVH, vous vous rendrez compte que le bouton DNS est en rouge : c’est normal puisqu’il nous faut paramétrer notre nouveau domaine dans BIND, notre serveur de noms.

On édite la configuration de BIND :

nano /etc/bind/named.conf.local

et on lui indique que nous créons une nouvelle zone :

zone "example.com" {
        type master;
        file "/etc/bind/example.com.hosts";
        allow-query { any; };
};Code language: JavaScript (javascript)

On crée maintenant notre fichier de zone:

nano /etc/bind/example.com.hosts
$ttl 84600
$ORIGIN example.com.

@       IN      SOA     XXXXXX.kimsufi.com. root.example.net. (
                        2018012801
                        14400
                        3600
                        604800
                        84600 )

; NAMESERVERS
 IN     NS      XXXXXX.kimsufi.com.
 IN     NS      ns.kimsufi.com.

example.com.   IN      A       XXX.XXX.XXX.XXX
example.com.   IN      AAAA    4001:41d0:1:4462::1
example.com.   IN      MX      10 mail.example.net.

www.example.com.       IN      A        XXX.XXX.XXX.XXX
www.example.com.       IN    AAAA    4001:41d0:1:4462::1
www       IN A          XXX.XXX.XXX.XXXCode language: PHP (php)

Ps: example.net est le domaine principal du serveur.

Pous vérifions la configuration BIND:

named-checkconf -z

et nous redémarrons BIND pour prendre en compte nos changements et activer notre nouveau fichier de zone:

service bind9 restart

Vous pouvez vérifier votre configuration DNS à l’aide de l’outil ZoneMaster.

Configuration du bloc serveur sous NginX

On commence par créer le répertoire qui va accueillir les fichiers du site et on lui attribue les bons droits:

mkdir -p /home/example/public_html
chown -R www-data:www-data /home/example/public_html
chmod 755 /home/example/public_html

On crée également un fichier index.php à la racine du site pour éviter une erreur 403 plus tard lors de la génération du certificat SSL :

echo "<!--?php echo 'hello world. Domain activated.'; ?-->" >> /home/example/public_html/index.phpCode language: HTML, XML (xml)

On crée maintenant le répertoire de cache du site, toujours avec les bons droits:

mkdir -p /home/nginx-cache/example
chown -R www-data:www-data /home/nginx-cache/example
chmod 755 /home/nginx-cache/example

Voici le server block de départ, en HTTP simple :

server {
       listen         80;
       listen    [::]:80;
       server_name    example.com www.example.com;
       #return         301 https://$server_name$request_uri;
        root /home/example/public_html;
        index index.php index.html;
}Code language: PHP (php)

On active le site :

ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

On teste la configuration de NginX et on redémarre le service:

nginx -t
service nginx restart

On crée maintenant le certificat SSL avec Let’s Encrypt :

certbot certonly --webroot -w /home/example/public_html -d example.com -d www.example.com

Lire la suite

Serveur dédié : script bash pour réparer les tables MySQL en cas de crash photo

Serveur dédié : mise à jour vers PHP 7.2

Aujourd’hui, le serveur passe à PHP 7.2 !

PHP 7.2 accroît fortement les performances des versions précédentes, notamment au travers de plusieurs améliorations en matière de sécurité. Ainsi, l’algorithme Argon2 qui sert au hachage sécurisé des mots de passe corrige les défauts des algorithmes actuels. Celui-ci permet notamment un taux de remplissage plus élevé de la mémoire.

PHP 7.2 intègre désormais dans son noyau la bibliothèque de cryptographie Sodium, utilisée pour le chiffrement authentifié, est désormais une extension de base et les performances de la bibliothèque pour la cryptographie sur les courbes elliptiques ont été améliorées.

Niveau programmation

Au-delà de Sodium, PHP 7.2 vient avec des améliorations et nouvelles fonctionnalités comme :

  • la possibilité de convertir des clés numériques dans les objets et tableaux lors de cast.
  • les clés numériques sont maintenant mieux appréhendées lors de cast d’un tableau en objet et d’objet en tableau (cast explicite ou par la fonction settype()) ;
  • le comptage d’objets non dénombrables. Un E_WARNING sera émis lors de la tentative d’utilisation de la fonction count() sur un type non dénombrable ;
  • HashContext en tant qu’objet ;
  • ajout d’Argon2 à l’API pour le hachage de mot de passe ;
  • amélioration des constantes TLS ;
  • la suppression de l’extension Mcrypt. L’extension MCrypt a maintenant été déplacée du noyau vers PECL. Étant donné que la bibliothèque mcrypt n’a pas eu de mises à jour depuis 2007, son utilisation est fortement découragée. Au lieu de cette extension, soit OpenSSL ou l’extension sodium doit être utilisé.

Les fonctions Deprecated (déconseillées) et supprimées pour PHP 8.0:

__autoload
$php_errormsg
create_function()
mbstring.func_overload
(unset) cast
parse_str() sans le second argument
gmp_random()
each()
assert() avec un argument string(texte)
$errcontext

La conversion des clés numériques dans les distributions objet/tableau résout un problème rencontré avec le moteur open source Zend Engine qui fait tourner PHP 7. Dans certaines situations, les tables de hachage de tableaux pouvaient contenir des chaînes numériques alors que les tables de hachage d’objets pouvaient contenir des clés entières, ce qui empêchait le code PHP de retrouver les clés. Le correctif apporté par PHP 7.2 convertit les clés des tables de hashage des tableaux et des tables de hachage des objets sont converties dans les bons formats, de sorte que les chaînes de format numériques personnalisées sont traduites en clefs entières, résolvant le problème d’inaccessibilité.

Les typages explicites d’objets ou « type hints » corrigent une situation dans laquelle un développeur ne peut pas déclarer une fonction supposée recevoir un objet en tant que paramètre ou déclarer qu’une fonction doit retourner un objet. Le correctif utilise l’objet comme type de paramètre et type de retour. HashContext en tant qu’objet, migre l’extension de hachage pour utiliser une extension objet pour les contextes de hachage au lieu d’utiliser des ressources. A noter aussi une nouvelle alerte ajoutée pour l’appel de la fonction count avec un paramètre scalaire ou nul, ou un objet qui n’implémente pas l’interface « Countable »

Mise à jour vers PHP7.2

Cela n’a pris que quelques minutes :

apt update && apt upgrade

Résultat :

Calculating upgrade... Done
The following packages were automatically installed and are no longer required:
  php7.1-cli php7.1-curl php7.1-fpm php7.1-gd php7.1-json php7.1-mbstring php7.1-opcache
  php7.1-readline php7.1-xml php7.1-xmlrpc
Use 'apt autoremove' to remove them.
The following NEW packages will be installed:
  libargon2-0 libsodium23 php7.2-cli php7.2-common php7.2-curl php7.2-fpm php7.2-gd php7.2-json
  php7.2-mbstring php7.2-opcache php7.2-readline php7.2-xml php7.2-xmlrpc
The following packages will be upgraded:
  php-common php-curl php-fpm php-gd php-mbstring php-xml php-xmlrpc php7.1-cli php7.1-common
  php7.1-curl php7.1-fpm php7.1-gd php7.1-json php7.1-mbstring php7.1-mcrypt php7.1-mysql
  php7.1-opcache php7.1-readline php7.1-soap php7.1-xml php7.1-xmlrpc php7.1-zip
22 upgraded, 13 newly installed, 0 to remove and 0 not upgraded.
Need to get 8,656 kB of archives.
After this operation, 19.7 MB of additional disk space will be used.Code language: JavaScript (javascript)

A ce stade, nous avons php7.1 et php7.2 installés séparément sur le serveur.

On installe les paquets manquants (toujours les deux mêmes):

apt install php7.2-mysqlCode language: CSS (css)

On édite chacun des VirtualHosts sous Nginx, en éditant cette ligne:

fastcgi_pass unix:/run/php/php7.2-fpm.sock;Code language: JavaScript (javascript)

On relance NginX et PHP:

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

Si tout va bien, il suffit de supprimer PHP7.1, ses dépendances et ses fichiers de configuration:

apt purge php7.1-*Code language: CSS (css)

Test de votre code sous PHP 7.2

Vous hésitez encore à sauter le pas ? Copiez-collez votre code sur le site d’3v4l, vous saurez immédiatement si cela produit des erreurs de type Notice.

Bonne mise à jour !

Serveur dédié : configurer Apache et NginX pour servir des polices de caractères photo

Serveur dédié : configurer Apache et NginX pour servir des polices de caractères

La plupart des sites modernes font appel à des polices de caractères qui ne sont pas installées sur les systèmes d’exploitation de leurs visiteurs.

L’utilisation de Google Fonts est très largement répandue mais cela ajoute un délai de traitement dans le chargement des pages car cela nécessite autant de requêtes externes.

Il est également possible de placer les fichiers dans le répertoire du thème graphique et de les servir directement depuis le serveur de fichier, comme Apache ou NginX.

Tout d’abord, il faut configurer les bons entêtes http. Cela permet aux navigateurs de bien interpréter les fichiers demandés comme polices de caractères.

Configuration des polices pour Apache

Pour définir le bon mime-type pour les polices, ajoutez ce bloc à votre configuration Apache:

AddType application/x-font-ttf ttc ttf
AddType application/x-font-otf otf
AddType application/font-woff woff
AddType application/font-woff2 woff2
AddType application/vnd.ms-fontobject eot

Si vous n’avez pas accès à la configuration du VirtualHost, placez ce bloc dans le fichier .htaccess du site.

Pour les entêtes CORS, ajoutez ce bloc:

<filesmatch ".(eot|ttf|otf|woff|woff2)"="">
  Header set Access-Control-Allow-Origin "*"Code language: JavaScript (javascript)

Configuration des polices pour NginX

LA configuration par default de NginX ne prend pas en compte les types mime des formats de fontes optimizés pour le web.

Il est à noter également que le type mime des fichiers .eot est erroné, il nous faut donc le modifier.

1. Editez le fichier /etc/nginx/mime.types et supprimez la ligne concernant l’extension eot.

2. Ensuite, ajoutez ce bloc :

application/x-font-ttf ttc ttf;
application/x-font-otf otf;
application/font-woff woff;
application/font-woff2 woff2;
application/vnd.ms-fontobject eot;

3. Pour les entêtes CORS, ajoutez ce bloc à la configuration du vhost:

location ~* \.(eot|otf|ttf|woff|woff2)$ {
add_header Access-Control-Allow-Origin *;
}

Et voilà, votre serveur de fichier est maintenant capable de servir vos fichiers de polices de caractères.

Il est recommandé de ne pas abuser des fontes de caractères : pas plus de 3 familles de fontes différentes sur un site web. Les navigateurs ayant chacun leurs petites subtilités et standards, ils ne se sont toujours pas mis d’accord sur un seul et même format de fichier.

En pratique, les formats WOFF2 et WOFF sont à privilégier (ils couvrent plus de 96% des utilisateurs) mais suivant le public ciblé, il faut penser à offrir les autres variantes de fichiers.

Serveur dédié : créer un certificat ECDSA avec Let's Encrypt photo

Serveur dédié : créer un certificat ECDSA avec Let’s Encrypt

Aujourd’hui, je vous montre comment j’ai mis en place un certificat ECDSA avec Let’s Encrypt, que j’utilise depuis l’année dernière.

Let’s Encrypt a annoncé il y a quelques mois qu’il sera possible au courant de l’année 2018 de créer des certificats ECDSA, pour plus de sécurité et de rapidité.

L’algorithme ECDSA

L’algorithme ECDSA (abbréviation d’Elliptic Curve Digital Signature Algorithm) a été proposé pour la première fois par Scott Vanstone en 1992.

Les signatures basées sur l’algorithme d’ECS, l’ancêtre de ECDSA, présente plusieurs avantages majeurs par rapport aux algorithmes RSA : leur taille est plus réduite et ils sont créés bien plus rapidement.

La vérification basée sur les algorithmes ECC est extrêmement rapide également.

Les avantages d’utiliser ECDSA par rapport à RSA

L’utilisation d’ECDSA pour les signatures numériques présente d’importants avantages, dont notamment:

  • un niveau de sécurité élevé,
  • pas de problèmes avec la performance d’applications,
  • un processus rapide de signature et de vérification (40% plus rapide que RSA),
  • adapté à la montée en puissance de la sécurité des applications,
  • support pour les pré-requis modernes de l’industrie

Une sécurité et une rapidité accrues donc, avec un usage de données réduit. Parfait.

Création d’un certificat ECDSA avec Let’s Encrypt

1. On crée les nouveaux répertoires pour notre certificat ECDSA:

mkdir -p /etc/letsencrypt/live-ecdsa/example.com/letmp
mkdir -p /etc/letsencrypt/live-ecdsa/example.com/backup
cd /etc/letsencrypt/live-ecdsa/example.com

2. On crée une clé privée avec l’algorithme secp384r1:

openssl ecparam -genkey -name secp384r1 > privkey-p384.pemCode language: CSS (css)

3. On crée un Certificate Signing Request (CSR):

openssl req -new -sha256 -key privkey-p384.pem -subj "/CN=example.com" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:example.com,DNS:www.example.com,DNS:mail.example.com,DNS:static.example.com")) -outform der -out csr-p384.derCode language: JavaScript (javascript)

4. On demande la création du certificat chez Let’s Encrypt:

cd letmp
certbot certonly -a webroot --webroot-path /home/public_html -d example.com -d www.example.com -d mail.example.com -d static.example.com --csr /etc/letsencrypt/live-ecdsa/example.com/csr-p384.der --renew-by-default --agree-tos --cert-path /etc/letsencrypt/live-ecdsa/example.com/cert_ecdsa.pem --fullchain-path /etc/letsencrypt/live-ecdsa/example.com/fullchain_ecdsa.pem --chain-path /etc/letsencrypt/live-ecdsa/example.com/chain_ecdsa.pemCode language: JavaScript (javascript)

5. Il reste à éditer la configuration de votre serveur de fichier. Sous NginX:

nano /etc/nginx/sites-available/example.com

ajoutez-y le nouveau certificat:

    # Let's Encrypt : ECDSA CERT
    ssl_certificate /etc/letsencrypt/live-ecdsa/example.com/fullchain_ecdsa.pem;
    ssl_certificate_key /etc/letsencrypt/live-ecdsa/example.com/privkey-p384.pem;Code language: PHP (php)

et on redémarre NginX:

service nginx restart

Voilà, vous venez de mettre en place votre certificat ECDSA. Voyons maintenant comment cela se passe pour la mise à jour.

Lire la suite

Serveur dédié : résoudre l'erreur "tail: inotify cannot be used, reverting to polling: Too many open files" photo

Serveur dédié : résoudre l’erreur “tail: inotify cannot be used, reverting to polling: Too many open files”

Ce matin, je me suis aperçu que le serveur était un peu moins réactif que d’habitude.

Ni une, ni deux, je lance le terminal et commence par vérifier les fichiers log. Un message attire alors mon attention :

tail: inotify cannot be used, reverting to polling: Too many open files Code language: HTTP (http)

C’est bien étrange puisque très peu de services sont censés lancer des tail. Nous allons donc lancer quelques commandes pour savoir qui est responsable de cet état.

Hotfix : à la recherche des anon_inode:inotify

1. Première méthode pour avoir un aperçu de tout ce qui tourne en ce moment sur le serveur :

ps -ef

La liste est très exhaustive (plusieurs pages chez moi) et ne permet pas vraiment de voir ce qui se passe, étant donné que rien n’est trié.

2. Changeons notre fusil d’épaule et trouvons la liste des processus qui font appel à inotify:

for foo in /proc/*/fd/*; do readlink -f $foo; done | grep inotify | sort | uniq -c | sort -nr

Résultat:

      8 /proc/25634/fd/anon_inode:inotify
      1 /proc/715/fd/anon_inode:inotify
      1 /proc/6146/fd/anon_inode:inotify
      1 /proc/330/fd/anon_inode:inotify
      1 /proc/32148/fd/anon_inode:inotify
      1 /proc/31695/fd/anon_inode:inotify
      1 /proc/31262/fd/anon_inode:inotify
      1 /proc/3067/fd/anon_inode:inotify
      1 /proc/3066/fd/anon_inode:inotify
      1 /proc/3065/fd/anon_inode:inotify
      1 /proc/3064/fd/anon_inode:inotify
      1 /proc/3063/fd/anon_inode:inotify
      1 /proc/3062/fd/anon_inode:inotify
      1 /proc/21853/fd/anon_inode:inotify
      1 /proc/2063/fd/anon_inode:inotify
      1 /proc/1924/fd/anon_inode:inotify
      1 /proc/1563/fd/anon_inode:inotify
      1 /proc/1196/fd/anon_inode:inotify

3. Maintenant, nous allons chercher dans cette liste de processus les commandes qui font appel à anon_inode:inotify :

ps -p $(find /proc/*/fd/* -type l -lname 'anon_inode:inotify' -print 2> /dev/null | sed -e 's/^\/proc\/\([0-9]*\)\/.*/\1/')Code language: JavaScript (javascript)

Résultat:

  PID TTY      STAT   TIME COMMAND
  330 ?        Ss     0:00 /lib/systemd/systemd-udevd --daemon
  715 ?        S      0:00 tail -f /tmp/bm-tarball.log.7lZV2O
 1196 ?        S      0:00 tail -f /tmp/bm-tarball.log.B1I64h
 1563 ?        S      0:00 tail -f /tmp/bm-tarball.log.hhDVas
 1924 ?        S      0:00 tail -f /tmp/bm-tarball.log.Ztuk8T
 2063 ?        Ss     0:06 /usr/bin/dbus-daemon --system
 3062 tty1     Ss+    0:00 /sbin/getty 38400 tty1
 3063 tty2     Ss+    0:00 /sbin/getty 38400 tty2
 3064 tty3     Ss+    0:00 /sbin/getty 38400 tty3
 3065 tty4     Ss+    0:00 /sbin/getty 38400 tty4
 3066 tty5     Ss+    0:00 /sbin/getty 38400 tty5
 3067 tty6     Ss+    0:00 /sbin/getty 38400 tty6
 6146 ?        Ss     0:00 gpg-agent --homedir /root/.gnupg --use-standard-socket --daemon
25634 ?        Sl     0:21 /usr/bin/python3 /usr/bin/fail2ban-server -s /var/run/fail2ban/fail2ban.sock -p /var/run/fail2ban/fail2ban.pid -
31262 ?        S      0:00 tail -f /tmp/bm-tarball.log.82bIqR
31695 ?        S      0:00 tail -f /tmp/bm-tarball.log.6Hqw69
32148 ?        S      0:00 tail -f /tmp/bm-tarball.log.UMpkfiCode language: JavaScript (javascript)

Ah on y arrive, c’est déjà beaucoup plus clair. Le service qui pose problème est donc backup-manager (voir le tutoriel Serveur dédié : sauvegarde automatique des fichiers avec Backup Manager sur le serveur de sauvegarde), qui semble laisser ouvert tous ses fichiers de logs !

Lire la suite

Télécharger vos fichiers torrents automatiquement avec Flexget photo

Télécharger vos fichiers torrent automatiquement avec FlexGet et Transmission

Aujourd’hui, nouvelle étape dans l’automatisation de nos téléchargements : au lieu d’uploader un fichier .torrent ou magnet sous Transmission, nous allons installer FlexgGet qui va nous permettre de surveiller un flux RSS pour télécharger automatiquement les fichiers bittorrent.

Une fois le fichier graine téléchargé, Transmission se chargera de télécharger les fichiers immédiatement. Tout sera donc automatisé !

En prérequis, je vous conseille d’avoir Transmission installé et configuré sur votre serveur ou machine, cela vous fera gagner pas mal de temps.

Étape 1 : configuration de Transmission

Vous avez déjà Transmission qui tourne ? Parfait, on commence par arrêter le service :

service transmission-daemon stop

On crée un nouveau répertoire qui sera surveillé par Transmission – dès qu’un fichier .torrent sera ajouté dans ce répertoire, Transmission lancera le téléchargement :

mkdir /home/transmission/torrentwatch

On lui donne les bons droits et le bon utilisateur :

chown debian-transmission:debian-transmission /home/transmission/torrentwatch
chmod 777 /home/transmission/torrentwatch

Et on édite le fichier de configuration :

nano /etc/transmission-daemon/settings.json

Je me suis aperçu qu’il me manquait deux directives importantes dans ce fichier pour surveiller un répertoire donc on les ajoute à la suite des autres directives :

   "watch-dir": "/home/transmission/torrentwatch",
    "watch-dir-enabled": true,Code language: JavaScript (javascript)

On sauvegarde le fichier et on redémarre Transmission :

service transmission-daemon start

Lire la suite

Serveur dédié : réinitialiser le mot de passe root d'un serveur MySQL ou MariaDB photo

Serveur dédié : réinitialiser le mot de passe root d’un serveur MySQL ou MariaDB

Pour les besoins d’un de mes clients préférés, j’ai eu la grande joie de paramétrer un VPS aux petits oignons avec réplication des données à la volée.

C’est un projet fascinant que j’ai déjà abordé dans la série réplication de données.

Serveur dédié : réinitialiser le mot de passe root d'un serveur MySQL ou MariaDB photo

Au moment de la réalisation des bases de données, je demande à mon client le mot de passe root du serveur de base de données pour y créer de nouveaux utilisateurs. La réponse ne se fait pas attendre : “je n’ai pas ce mot de passe mais j’ai confiance en toi Matt, tu pourras aisément contourner le problème!”.

Challenge accepted.

Voici donc un mini-tutoriel pour réinitialiser le mot de passe root quand vous ne l’avez jamais eu vous en souvenez plus.

Vous aurez besoin de deux fenêtres de terminal, que je nomme ici terminal1 et terminal2.

Etape 1 : lancer mysqld_safe

Voici le principe de la manipulation : nous allons “occuper” le serveur MySQL ou MariaDB en lançant le daemon mysqld_safe dans un terminal et nous allons lancer un second terminal qui nous permettre de réinitialiser le mot de passe root.

C’est parti : dans le terminal1, nous commençons par arrêter le serveur SQL:

service mysql stop

puis lançons mysqld_safe :

mysqld_safe --skip-grant-tables --skip-syslog --skip-networking

Le terminal semble arrêté ou attendre quelque chose : c’est bon signe, laissez-le comme ça pour le moment.

Lire la suite

Créer un serveur High Availability : la réplication des bases de données photo

MariaDB : résoudre l’erreur 1062 (duplicate entry for key PRIMARY) lors de la réplication des bases de données

Si vous utilisez les fonctions de réplication de MySQL ou MariaDB, il peut arriver que votre slave bloque sur une instruction qui devrait avoir un identifiant unique mais que le serveur tente d’insérer deux fois.

Et quand c’est le cas, la réplication des données prend fin donc c’est un problème à corriger rapidement si vous voulez que votre système haute disponibilité perdure et soit vraiment efficace en cas de coup dur.

Identification du problème

Je me suis rendu compte du problème lorsque j’ai ajouté de nouvelles bases à répliquer : j’ai relancé la procédure d’installation, relancé les serveurs, ajouté les nouvelles positions, démarré les slaves.

On regarde le status du slave :

MariaDB [(none)]> SHOW SLAVE STATUS\GCode language: CSS (css)

Résultat :

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.134.23.164
                  Master_User: replicator
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mariadb-bin.000210
          Read_Master_Log_Pos: 2753885
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 103794
        Relay_Master_Log_File: mariadb-bin.000210
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 1062
                   Last_Error: Error 'Duplicate entry '56-724' for key 'PRIMARY'' on query. Default database: 'frenchy'. Query: 'INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`) VALUES (56, 724)'
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1563407
              Relay_Log_Space: 1296874
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 1062
               Last_SQL_Error: Error 'Duplicate entry '56-724' for key 'PRIMARY'' on query. Default database: 'frenchy'. Query: 'INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`) VALUES (56, 724)'
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
               Master_SSL_Crl:
           Master_SSL_Crlpath:
                   Using_Gtid: No
                  Gtid_IO_Pos:
      Replicate_Do_Domain_Ids:
  Replicate_Ignore_Domain_Ids:
                Parallel_Mode: conservative
1 row in set (0.00 sec)Code language: JavaScript (javascript)

Comme on peut le constater, plusieurs choses ne tournent pas rond et empêchent la synchronisation des données entre nos deux serveurs :

Slave_SQL_Running: No
Last_SQL_Errno: 1062
Last_SQL_Error: Error 'Duplicate entry '56-724' for key 'PRIMARY'' on query. Default database: 'frenchy'. Query: 'INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`) VALUES (56, 724)'Code language: JavaScript (javascript)

Solution : un RESET sur le slave

En me documentant sur le problème, j’ai lu pas mal de choses sur le net. Certains préfèrent cacher l’erreur, au risque de perdre des données. D’autres préfèrent tout effacer pour recommencer la réplication.

Aucune de ces “solutions” ne me conviennent donc nous allons procéder autrement. Comme l’erreur n’apparaît que sur le serveur BACKUP et non sur le serveur principal, c’est sur lui que nous travaillerons.

Sur le serveur BACKUP, dans MariaDB, on arrête notre slave :

MariaDB [(none)]> STOP SLAVE;
Query OK, 0 rows affected (0.01 sec)Code language: CSS (css)

On flush les privilèges et donc les utilisateurs connectés :

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)Code language: CSS (css)

On efface les fichiers logs de notre slave. C’est comme effacer une ardoise pour repartir sur des bases saines. Cela ne supprime aucune donnée – cf le manuel sur RESET :

MariaDB [(none)]> RESET SLAVE;
Query OK, 0 rows affected (0.00 sec)Code language: CSS (css)

Et on redémarre notre slave :

MariaDB [(none)]> START SLAVE;
Query OK, 0 rows affected (0.00 sec)Code language: CSS (css)

On vérifie de nouveau le status de notre slave :

MariaDB [(none)]> SHOW SLAVE STATUS\GCode language: CSS (css)

Résultat :

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.134.23.164
                  Master_User: replicator
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mariadb-bin.000196
          Read_Master_Log_Pos: 77900062
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 6318821
        Relay_Master_Log_File: mariadb-bin.000192
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 6318531
              Relay_Log_Space: 344030331
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 833890
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 1
               Master_SSL_Crl:
           Master_SSL_Crlpath:
                   Using_Gtid: No
                  Gtid_IO_Pos:
      Replicate_Do_Domain_Ids:
  Replicate_Ignore_Domain_Ids:
                Parallel_Mode: conservative
1 row in set (0.00 sec)Code language: CSS (css)

Nous avons bien :

Slave_IO_Running: Yes
Slave_SQL_Running: YesCode language: HTTP (http)

Et voilà, plus d’erreur et une réplication active dans les deux sens.

Serveur dédié : mise à jour vers Debian 9 Stretch photo

Serveur dédié : mise à jour vers Debian 9 Stretch

Cette semaine, le système d’exploitation du serveur principal passe de Debian 8 Jessie à Debian 9 Stretch.

Mise à jour des paquets du système

La mise à jour s’est faite plutôt simplement pour la majeure partie des paquets :

apt update && apt upgrade

mais il a fallu s’y reprendre à plusieurs fois pour les paquets restants :

apt install 

Changements dans la configuration

Quelques changements notables sont à noter.

Configuration apt

On vérifie que tous nos dépôts pointent bien vers la version Stretch:

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

On sauvegarde et on lance les mises à jour:

apt update && apt upgrade

Configuration SSH

La configuration SSH a été modifiée et certaines directives ne sont plus valables. Avant de redémarrer le serveur SSH ou de rebooter et de perdre tout accès au serveur SSH, assurez-vous que la configuration est correcte :

sshd -t

Résultats :

/etc/ssh/sshd_config line 25: Deprecated option KeyRegenerationInterval
/etc/ssh/sshd_config line 26: Deprecated option ServerKeyBits
/etc/ssh/sshd_config line 44: Deprecated option RhostsRSAAuthentication

Il ne vous reste plus qu’à éditer le fichier de configuration SSH:

nano /etc/ssh/sshd_config

J’ai désactivé les lignes qui posaient problème et ai rajouté de nouveaux protocoles de clé :

HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

Sauvegardez le fichier puis lancez cette commande pour créer les couples de clés privées/publiques dans /etc/ssl:

ssh-keygen -A

Résultat:

ssh-keygen: generating new host keys: ECDSA ED25519Code language: JavaScript (javascript)

Vérifiez une dernière fois qu’il n’y a aucun problème avec le fichier de configuration SSH:

sshd -t

et redémarrez le service SSH:

service ssh restart

Configuration de Courier

C’est le bon moment de revoir la configuration IMAP et POP de Courier.

On commence par renouveler notre fichier Diffie-Hellman en 4096 bits:

cd /etc/courier
openssl dhparam -out dhparams4096.pem 4096

et on revoit la configuration de /etc/courier/imap-ssl :

SSLPORT=993

SSLADDRESS=0

SSLPIDFILE=/run/courier/imapd-ssl.pid

SSLLOGGEROPTS="-name=imapd-ssl"

IMAPDSSLSTART=YES

IMAPDSTARTTLS=YES

IMAP_TLS_REQUIRED=1

COURIERTLS=/usr/bin/couriertls

TLS_PROTOCOL=TLS1_2:TLS1_1:TLS1

TLS_STARTTLS_PROTOCOL=TLS1_2:TLS1_1:TLS1

TLS_CIPHER_LIST="ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS"

TLS_KX_LIST=ALL

TLS_COMPRESSION=ALL

TLS_CERTS=X509

TLS_DHCERTFILE=/etc/courier/dhparams4096.pem

TLS_CERTFILE=/etc/courier/skyminds-cert.pem

TLS_TRUSTCERTS=/etc/ssl/certs

TLS_VERIFYPEER=NONE

TLS_CACHEFILE=/var/lib/courier/couriersslcache
TLS_CACHESIZE=524288

MAILDIRPATH=MaildirCode language: JavaScript (javascript)

Le chemin de SSLPIDFILE a changé donc pensez à le vérifier.

Certificat TLS pour Courier

Depuis que j’utilise les certificats TLS de Let’s Encrypt, il y a une petite modification a exécuter pour que le certificat s’applique aussi à notre serveur de mail : créer automatiquement un certificat pour Courier dès que notre certificat principal est généré.

On crée un script bash pour compiler notre clé privée et notre certificat Let’s Encrypt :

nano /home/scripts/letsencrypt-skyminds-mailserver.sh

avec :

#!/bin/bash
cat /etc/letsencrypt/live/skyminds.net/privkey.pem /etc/letsencrypt/live/skyminds.net/fullchain.pem > /etc/courier/skyminds-cert.pemCode language: JavaScript (javascript)

et on édite notre fichier Let’s Encrypt pour le renouvellement :

nano /etc/letsencrypt/renewal/skyminds.net.conf

et on ajoute la directive renew_hook avec notre nouveau script:

[renewalparams]
account = ...
renew_hook = /home/scripts/letsencrypt-skyminds-mailserver.shCode language: JavaScript (javascript)

Il ne reste plus qu’à éditer la configuration IMAP:

nano /etc/courier/imapd-ssl

et y mettre :

TLS_CERTFILE=/etc/courier/skyminds-cert.pemCode language: JavaScript (javascript)

puis redémarrez le service:

service courier-imap-ssl restart

Voilà, ce sont les principales modifications a effectuer lors de la mise à jour vers Debian 9.

Linux : résoudre l'erreur "Cannot set LC_ALL to default locale" photo

Linux : résoudre l’erreur “Cannot set LC_ALL to default locale”

Récemment, j’ai installé un serveur en Chine, derrière le Great Firewall of China (GFW) pour un des mes clients.

Le code n’a pas de frontières mais la langue peut parfois poser problème – même pour un système d’exploitation, au niveau de la locale.

Les locales sont un ensemble de paramètres qui définissent la langue de l’utilisateur, sa région et les préférences régionales que l’utilisateur souhaire voir dans son interface.

Typiquement, une locale est identifiée par un code langue suivi d’un identifiant de région. Nous avons par exemple “en_US.UTF-8” pour l’anglais américain (en pour l’anglais, US pour les USA) ou “fr_FR.UTF-8” pour le français de France.

Dans le cas de mon serveur chinois, qui tourne sous Debian, les paramètres de la locale n’étaient pas uniformément remplis avec le même code langue et certains paramètres étaient manquants.

On obtenait donc ces messages lors d’un apt update :

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LANG = "fr_FR.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").Code language: PHP (php)

ou encore ces messages avec apt upgrade, après chaque installation ou mise à jour de paquets :

locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directoryCode language: JavaScript (javascript)

Pas de panique, j’ai quelques solutions pour régler le problème si vous aussi y êtes confronté.

Dans ce tutoriel, j’utilise “en_US.UTF-8” parce que j’aime tout avoir en anglais. Si vous préférez le français, remplacez tout par “fr_FR.UTF-8”.

Etape 1 : éditez le fichier locale

Editez votre fichier /etc/default/locale :

nano /etc/default/localeCode language: JavaScript (javascript)

et ajoutez ces lignes:

LC_ALL=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
LC_MESSAGES=en_US.UTF-8
LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8

Enregistrez le fichier, quittez votre session SSH puis reconnectez-vous pour avoir une nouvelle session avec le changement de locale.

Etape 2 : reconfigurer les locales

On commence par générer la locale de notre choix :

locale-gen "en_US.UTF-8"Code language: JavaScript (javascript)

Et on la reconfigure :

dpkg-reconfigure locales

Il ne reste plus qu’à tester les locales du système:

locale

Résultat:

LANG=en_US.UTF-8
LANGUAGE=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8Code language: JavaScript (javascript)

Et voilà, plus de messages d’avertissement ou d’erreur concernant les locales de votre système. Problème réglé.

Linux : donner les privilèges sudo à un utilisateur sur une instance Amazon Web Service EC2 photo

Linux : donner les privilèges sudo à un utilisateur sur une instance Amazon Web Service EC2

Amazon Elastic Compute Cloud ou EC2 est un service proposé par Amazon Web Services (AWS) permettant à des tiers de louer des serveurs sur lesquels exécuter leurs propres applications web.

Linux : donner les privilèges sudo à un utilisateur sur une instance Amazon Web Service EC2 photo

Si vous avez déjà travaillé sur une instance Amazon EC2 sous linux, vous avez très certainement essayé d’utiliser sudo pour lancer des commandes qui nécessitent une élévation des privilèges de votre utilisateur.

Or, la configuration Amazon ne le permet pas par défaut mais utilise une implémentation du fichier sudoers qui n’est pas standard pour une installation linux.

Une implémentation du fichier sudoers différente

Normalement, lorsque l’on lance visudo, on obtient une version éditable du fichier /etc/sudoers qui nous permet de modifier les comptes utilisateurs pour leur donner la permission d’exécuter la commande sudo et donc contrôler quelles commandes ces utilisateurs peuvent lancer.

Anatomie du fichier sudoers

Voici un exemple de fichier sudoers classique :

# User privilege specification
root ALL=(ALL:ALL) ALL# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL# See sudoers(5) for more information on “#include” directives:#includedir /etc/sudoers.dCode language: PHP (php)

Les membres des groupes admin et sudo bénéficient des privilèges sudo, tout comme le compte root. Toutefois, aucune de ces lignes ne s’appliquent à un compte EC2 qu’un utilisateur AWS peut utiliser.

C’est la dernière ligne, avec la directive #includedir, qui permet de charger le bon fichier avec les privilèges utilisateur. Il est vital de noter que le signe # dans #includedir n’est pas un commentaire mais indique qu’il faut charger les fichiers contenus dans le répertoire /etc/sudoers.d – cela peut prêter à confusion mais c’est comme cela que le fichier sudoers fonctionne.

EC2 : donner les droits sudo à un utilisateur

Sur une instance EC2, il suffit de lister le contenu du répertoire /etc/sudoers.d pour trouver le bon fichier:

ls /etc/sudoers.d

Dans la plupart des cas et des distributions, le nom du fichier débute par un nombre élevé tel que 90. Ces fichiers sont chargés par ordre décroissant, à la manière du lancement d’une fusée, donc un fichier qui commence par 90 sera exécuté avant un fichier qui commence par 10.

Lire la suite

MacOS : résoudre le problème d'encodage Unicode des accents photo

MacOS : résoudre le problème d’encodage Unicode des accents sous WordPress (ou autre CMS)

Des espaces après chaque caractère accentué

Pour le site du Kriya Yoga France, on me transmet régulièrement des fichiers PDF que je dois transformer en articles. Je fais donc la plupart du temps un copié-collé et ensuite je m’attèle à la mise en page dans l’éditeur WordPress.

MacOS : résoudre le problème d'encodage Unicode des accents photo

Le hic, c’est que depuis l’année dernière, je travaille sous MacOS pour tout ce qui est développement web.

J’ouvre donc chaque PDF avec Preview – la visionneuse PDF installée par défaut – mais lorsque l’on colle le contenu du PDF dans un autre document, tous les caractères accentués sont suivis d’une espace (oui, on dit bien une espace en typographie) et des sauts de ligne apparaissent de nulle part. Clairement improductif.

Un conflit Unicode

Le problème réside entre un conflit lors de l’encodage Unicode entre caractères précomposés et caractères décomposés.

Un caractère précomposé ou caractère composite ou caractère décomposable est une entité Unicode qui peut aussi être définie comme une combinaison de plus de deux caractères.

Un caractère précomposé peut typiquement représenter une lettre surplombée d’un accent, comme é (lettre e avec accent aigu).

Techniquement, é (U+00E9) est un caractère qui peut être décomposé en son équivalent unicode à base de la lettre e (U+0065) et du caractère combinant accent aigu (U+0301).

La solution : UnicodeChecker

Heureusement, il existe un petit utilitaire, UnicodeChecker, qui permet de régler le problème très simplement. Voici la marche à suivre.

1. Lancez UnicodeChecker > File > New Utilities Window.

2. Copiez le texte de votre fichier PDF en mémoire (sélectionnez le texte puis Cmd+C ou Ctrl+C au clavier).

3. Dans UnicodeChecker, choississez l’option Normalize (6ème icône) et collez votre texte dans le champ Input puis appuyez sur Entrée. Cela donne :

MacOS : résoudre le problème d'encodage Unicode des accents sous Preview photo

Quatre champs sont proposés avec le résultat de la normalisation. Les deux champs qui nous importent sont NFC et NFKC, qui utilisent tout deux de l’Unicode précomposé, dans lequel l’accent fait partie intégrante du caractère accentué et non une entité à part.

4. Sélectionnez et copiez le texte contenu dans le champ NFC:

MacOS : résoudre le problème d'encodage Unicode des accents sous Preview photo 1

5. Collez maintenant le texte précédemment copié dans votre document ou l’éditeur de texte de votre CMS. A l’œil nu, rien ne change mais dans le rendu, votre texte est désormais correctement accentué, sans espaces inopportunes.

Lire la suite