Installation

De Wiki de Jordan LE NUFF
Sauter à la navigation Sauter à la recherche
 
Ligne 181 : Ligne 181 :
 
source ../conf/EnvironmentFile
 
source ../conf/EnvironmentFile
 
set +o allexport
 
set +o allexport
MERCURE_PUBLISHER_JWT_KEY=$(cat ../conf/publisher.key.pub) \
+
MERCURE_PUBLISHER_JWT_KEY=\$(cat ../conf/publisher.key.pub) \\
MERCURE_SUBSCRIBER_JWT_KEY=$(cat ../conf/subscriber.key.pub) \
+
MERCURE_SUBSCRIBER_JWT_KEY=\$(cat ../conf/subscriber.key.pub) \\
 
./mercure run
 
./mercure run
 
EOF
 
EOF

Version actuelle datée du 10 janvier 2022 à 15:08

Présentation

Cette page a pour objet de décrire comment installer Mercure.

Contexte

  • Serveur
    • CentOS Linux release 7.9.2009 (Core) sans interface graphique
  • Service web
    • Apache 2.4.43
  • Mercure
    • Version 0.13.0
    • Port d'écoute désiré : 2020

Documentation

L'installation de Mercure se fait en s'appuyant sur la documentation officielle d'installation ainsi que sur la documentation officielle de paramétrage. Elle s'appuie également sur la documentation officielle de Caddy Server, Mercure étant une compilation personnalisée du server web Caddy.

Mercure sera lancé au travers d'un service systemd.

Mise en œuvre

Création de l'arborescence applicative

Sans recommandation particulière de la part de l'éditeur de Mercure, l'arborescence est organisée en fonction des bonnes pratiques et est donc la suivante :

  • Dossier /opt/mercure
    • Arborescence applicative de base
  • Dossier /opt/mercure/mercure-<version>
    • Sources de la version <version> de Mercure
  • Dossier /opt/mercure/conf
    • Fichiers de configuration propres à l'environnement
  • Lien symbolique /opt/mercure/current
    • Lien pointant vers la version en cours de Mercure

Cette arborescence permet de séparer les fichiers de configuration propres à l'environnement (qui ne sont pas censés évoluer) des binaires d'exécution (qui peuvent évoluer). Ainsi, lors d'une montée de version de Mercure, il suffira de déployer la version /opt/mercure/mercure-<version> et de faire pointer le lien symbolique /opt/mercure/current vers la version désirée.

Pour créer cette arborescence, lancer les commandes suivantes :

mkdir -p /opt/mercure/{mercure-0.13.0,conf}
ln -s mercure-0.13.0 /opt/mercure/current

Création de l'utilisateur Mercure

Mercure sera lancé en tant que service. Pour des questions de sécurité, il ne faut pas que l'utilisateur sous lequel sera exécuté le service puisse ouvrir de session. Pour créer un utilisateur système ne pouvant pas ouvrir de session, lancer la commande suivante :

useradd -r -s /sbin/nologin -d /opt/mercure/conf mercure

Options :

  • -r
    • Utilisateur système
  • -s /sbin/nologin
    • Shell de login empêchant l'ouverture de session
  • -d /opt/mercure
    • Répertoire home de l'utilisateur

Téléchargement de Mercure

Pour télécharger Mercure, lancer la commande suivante :

wget https://github.com/dunglas/mercure/releases/download/v0.13.0/mercure_0.13.0_Linux_x86_64.tar.gz

Déployer Mercure

Pour déployer Mercure dans le dossier applicatif, lancer la commande suivante :

tar -zxf mercure_0.13.0_Linux_x86_64.tar.gz -C /opt/mercure/mercure-0.13.0

Création des clés SSH

Mercure s'appuyant sur le standard ouvert JWT (JSON Web Token) pour sécuriser les échanges, il est donc possible de créer des clés RSA pour signer les JWT. Pour ce faire, créer les clés nécessaires avec les commandes suivantes :

ssh-keygen -t rsa -b 4096 -m PEM -f /opt/mercure/conf/publisher.key -q -N ""
openssl rsa -in /opt/mercure/conf/publisher.key -pubout -outform PEM -out /opt/mercure/conf/publisher.key.pub
ssh-keygen -t rsa -b 4096 -m PEM -f /opt/mercure/conf/subscriber.key -q -N ""
openssl rsa -in /opt/mercure/conf/subscriber.key -pubout -outform PEM -out /opt/mercure/conf/subscriber.key.pub

Cela aura pour effet de créer des clés privées de 4096 bits nommées "publisher.key" et "subscriber.key" avec une passphrase nulle dans le dossier /opt/mercure/conf et de générer les clés publiques correspondantes au format PEM nommées respectivement "publisher.key.pub" et "subscriber.key.pub" dans le dossier /opt/mercure/conf.

Création du fichier de configuration

Mercure s'appuie sur un fichier de configuration par défaut Caddyfile qui correspond à une utilisation de production. Le but de l'implémentation qui est réalisée dans cette page est de ne pas modifier ce fichier. En effet, s'appuyant sur l'idée de base du fichier de configuration de Mercure, il faudra utiliser les variables d'environnement mises à disposition.

Son contenu est le suivant :

# Learn how to configure the Mercure.rocks Hub on https://mercure.rocks/docs/hub/config
{
        {$GLOBAL_OPTIONS}
}

{$SERVER_NAME:localhost}

log

route {
        encode zstd gzip

        mercure {
                # Transport to use (default to Bolt)
                transport_url {$MERCURE_TRANSPORT_URL:bolt://mercure.db}
                # Publisher JWT key
                publisher_jwt {env.MERCURE_PUBLISHER_JWT_KEY} {env.MERCURE_PUBLISHER_JWT_ALG}
                # Subscriber JWT key
                subscriber_jwt {env.MERCURE_SUBSCRIBER_JWT_KEY} {env.MERCURE_SUBSCRIBER_JWT_ALG}
                # Extra directives
                {$MERCURE_EXTRA_DIRECTIVES}
        }

        respond /healthz 200

        respond "Not Found" 404
}

Il est possible de charger le fichier de configuration Caddyfile.dev réservé à une utilisation en développement. Il faudra donc prévoir de rajouter l'option -config Caddyfile.dev lors du lancement de Mercure avec la commande ./mercure run.

Comme indiqué plus haut, les fichiers de configuration de Mercure sont intéressants dans la mesure où il est possible d'injecter des variables d'environnement lors de son exécution, plutôt que de modifier manuellement les fichiers de configuration fournis. En effet, cela permet d'éviter de modifier les fichiers de configuration fournis en cas de montée de version de Mercure.

Ainsi, il va falloir créer un fichier /opt/mercure/conf/EnvironmentFile qui, comme son nom l'indique, contiendra les variables d'environnement nécessaires à l'exécution de Mercure, et qui, de par son emplacement, ne changera pas en cas de montée de version.

Pour ce faire, lancer la commande suivante :

cat <<EOF> /opt/mercure/conf/EnvironmentFile
GLOBAL_OPTIONS="debug
admin :2019"
SERVER_NAME=":2020"
MERCURE_PUBLISHER_JWT_ALG=RS256
MERCURE_SUBSCRIBER_JWT_ALG=RS256
MERCURE_EXTRA_DIRECTIVES="ui
cors_origins https://my.greaturl.com/"
EOF

Ce qui donne le fichier de configuration suivant :

GLOBAL_OPTIONS="debug
admin :2019"
SERVER_NAME=":2020"
MERCURE_PUBLISHER_JWT_ALG=RS256
MERCURE_SUBSCRIBER_JWT_ALG=RS256
MERCURE_EXTRA_DIRECTIVES="ui
cors_origins https://my.greaturl.com/"

Explication des options :

  • GLOBAL_OPTIONS
    Options générales de Caddy server, le server web de Mercure, telles que définies dans la section "Global options" de la documentation Caddy
    • debug
      • Permet d'activer le mode debug, utile en phase de développement
    • admin :2019
      • Permet de surcharger la valeur par défaut localhost:2019 par :2019, rendant ainsi l'interface d'administration de Caddy server accessible à distance
  • SERVER_NAME
    Nom du serveur ou adresse sur laquelle écouter les requêtes Mercure. La valeur par défaut est localhost.
    • :2020
      • Permet de spécifier le port et d'écouter sur toutes les adresses IP du serveur.
  • MERCURE_PUBLISHER_JWT_ALG
    • Algorithme du JWT utilisé par les éditeurs.
  • MERCURE_SUBSCRIBER_JWT_ALG
    • Algorithme du JWT utilisé par les abonnés.
  • MERCURE_EXTRA_DIRECTIVES
    Options locales de Mercure, telles que définies dans la section "Directives" de la documentation Mercure.


Remarques importantes en pratique :

  • D'ordre général
    • L'option admin :2019 est inutile pour Mercure. Elle peut être utile si Caddy server est utilisé pour d'autres besoins
    • Pour ajouter des valeurs multilignes à une variable d'environnement, ajouter simplement des sauts de lignes
  • D'ordre particulier
    • Les options code>debug et ui ne seront pas présentes en production, car inutiles
    • L'option :2020 avec le port seul permet à Mercure d'être accessible à distance, en HTTP
      • Cela peut être utile en développement pour des tests
      • En production, si Mercure est accessible uniquement en local (sur le même serveur, au travers une directive ProxyPass d'Apache ou une directive proxy_pass de NGINX par exemple), il faudra le spécifier avec localhost:2020 par exemple


Ainsi, un fichier de configuration de production ressemblera à ceci :

SERVER_NAME="localhost:2020"
MERCURE_PUBLISHER_JWT_ALG=RS256
MERCURE_SUBSCRIBER_JWT_ALG=RS256

Création du script d'exécution

Se basant sur un fichier EnvironmentFile, il aurait tout à fait été possible de lancer directement Mercure depuis un service systemd.

Toutefois, l'injection du contenu des clés publiques en tant que variable d'environnement ne pouvant être réalisé dynamiquement, il faudrait les ajouter au fichier EnvironmentFile.

Malheureusement, le contenu d'une clé publique au format PEM dépassant la valeur POSIX par défaut LINE_MAX de 2048 caractères, il est impossible de les charger dans le service systemd de façon standard.

Ainsi, il faut donc créer un script d'exécution qui se chargera d'injecter dynamiquement ces clés dans le service. Créer le fichier /opt/mercure/mercure.sh avec la commande suivante :

cat <<EOF> /opt/mercure/mercure.sh
#!/bin/bash
set -o allexport
source ../conf/EnvironmentFile
set +o allexport
MERCURE_PUBLISHER_JWT_KEY=\$(cat ../conf/publisher.key.pub) \\
MERCURE_SUBSCRIBER_JWT_KEY=\$(cat ../conf/subscriber.key.pub) \\
./mercure run
EOF


Explication du script :

  • set -o allexport
    source ../conf/EnvironmentFile
    set +o allexport
    
    Permet de charger en tant que variables d'environnement les variables définies dans le fichier ../conf/EnvironmentFile
  • MERCURE_PUBLISHER_JWT_KEY=$(cat ../conf/publisher.key.pub) et MERCURE_SUBSCRIBER_JWT_KEY=$(cat ../conf/subscriber.key.pub)
    Permet de charger dynamiquement les clés publiques
  • ./mercure run
    Lance Mercure

Rendre le script exécutable avec la commande suivante :

chmod ug+x /opt/mercure/mercure.sh

Affectation des droits d'accès

L'utilisateur mercure ayant précédemment été créé, le rendre propriétaire sur l'arborescence /opt/mercure avec la commande suivante :

chown -R mercure /opt/mercure

Création du service mercure

Créer le fichier de service avec la commande suivante :

cat <<EOF> /etc/systemd/system/mercure.service
[Unit]
Description=Mercure.Rocks service
After=network.target

[Service]
UMask=0007
User=mercure
WorkingDirectory=/opt/mercure/current
ExecStart=/opt/mercure/mercure.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

Corriger les droits d'accès au fichier de service avec la commande :

chmod o+r /etc/systemd/system/mercure.service

Prendre en compte le nouveau service :

systemctl daemon-reload

Démarrer le nouveau service :

systemctl start mercure

Activer le service au démarrage du serveur :

systemctl enable mercure

Autoriser des utilisateurs à gérer le service

Pour autoriser le groupe d'utilisateur mygroup à démarrer/arrêter/redémarrer/consulter le service mercure et consulter le journal de ce dernier, lancer la commande suivante :

cat <<EOF > /etc/sudoers.d/mercure_service
mygroup ALL=NOPASSWD:/usr/bin/systemctl start mercure
mygroup ALL=NOPASSWD:/usr/bin/systemctl stop mercure
mygroup  ALL=NOPASSWD:/usr/bin/systemctl restart mercure
mygroup  ALL=NOPASSWD:/usr/bin/systemctl status mercure
mygroup ALL=NOPASSWD:/usr/bin/journalctl -u mercure
mygroup ALL=NOPASSWD:/usr/bin/journalctl -f -u mercure
EOF