Dotclear sous NetBSD avec Nginx et PostgreSQL

Un petit mémo sur l'installation à la main de Dotclear sur notre serveur web qui tourne sous NetBSD. Les URL seront gérées en mode PATH_INFO.

Bien évidemment, il suffit de lire la documentation officielle pour installer aisément ce moteur de blog bien sympa. Mais là, on va le faire à la main pour bien comprendre toutes les étapes. L'objectif sera de le packager par la suite pour pkgsrc, le gestionnaire de package de NetBSD.

Récupération et mise en place

Tout d'abord, nous récupérons l'archive contenant le code de Dotclear.

# curl -o dotclear-2.16.tar.gz https://download.dotclear.org/latest/dotclear-2.16.tar.gz

Il s'agit ici de la version 2.16, la dernière version stable au moment de l'écriture de cette note. Nous demandons à la commande curl d'écrire les octets téléchargés dans un fichier nommé dotclear-2.16.tar.gz dans le répertoire courant en lui spécifiant l'argument -o.

Il nous faut maintenant extraire l'archive là où notre daemon web Nginx sera en mesure de le trouver.

# mkdir -p /srv/http/blog
# tar -xzf dotclear-2.16.tar.gz -C /srv/http/blog

Nous créons un sous-répertoire blog dans l'arborescence /srv/http avec la commande mkdir. C'est dans cette arborescence que nous centralisons les applications web servies par Nginx. À l'aide de la commande tar, nous désarchivons (-x) et nous décompressons (-z) l'archive spécifiée avec l'argument -f vers le répertoire /srv/http/blog (-C).

Création de la base de donnée

Nous utilisons une base de données gérée par PostgreSQL parce que... voilà! Il nous faut tout d'abord créer un utilisateur qui manipulera la base.

# createuser -U pgsql dotclear

Pour une version de PostgreSQL installée en utilisant pkgsrc, l'utilisateur Unix qui gère le service est pgsql. Il faut donc le spécifier à la commande createuser via l'argument -U. Attention, l'utilisateur dotclear n'a ici d'existence que pour PostgreSQL et ne peut pas servir à s'authentifier sur la machine.

Nous créons maintenant la base à proprement parlé.

# createdb -U pgsql -O dotclear -E UTF-8 -T template0 dotclear

Nous spécifions à la commande createdb que le propriétaire de cette base est l'utilisateur dotclear via l'argument -O.

Configuration

C'est partie pour la phase de configuration! Nous copions le modèle de fichier de configuration fourni vers notre propre fichier.

# cp /srv/http/blog/dotclear/inc/config.php.in /srv/http/blog/dotclear/inc/config.php

À l'aide de notre éditeur de fichier préféré, nous renseignons certaines entrées pour les faire correspondre à la réalité de notre configuration.

define('DC_DBDRIVER', 'pgsql');
define('DC_DBHOST', 'localhost');
define('DC_DBUSER', 'dotclear');
define('DC_DBPASSWORD', '');
define('DC_DBNAME', 'dotclear');
define('DC_MASTER_KEY', 'f1d2d2f924e986ac86fdf7b36c94bcdf32beec15');
define('DC_ADMIN_URL', 'https://blog.triaxx.org/admin/');

Ici, nous pouvons noter qu'il n'y a pas de mot de passe pour accéder à la base de données car celle-ci n'est accessible que localement. Un autre point à remarquer est que l'URL du site d'administration se termine par un /. En effet, cette URL est utilisée pour en forger d'autre. Nous avons pu constaté dans les logs des URL invalides comme https://blog.triaxx.org/adminindex.php? en l'absence de /. Enfin, la clé maître peut être générée par exemple en utilisant la commande sha1.

# echo "########" | sha1

Nginx et FPM

Nous utilisons le serveur web Nginx pour propulser Dotclear. Dans le fichier de configuration principal /usr/pkg/etc/nginx/nginx.conf, nous incluons des fichiers de configuration dédiés à chaque hôte virtuel géré par ce serveur.

include                      vhosts/*.conf;

Ainsi, nous pouvons éditer séparemment notre fichier de configuration /usr/pkg/etc/nginx/vhosts/blog.conf.

server {
  listen                     80; 
  listen                     [::]:80;
  rewrite            ^       https://$host$request_uri permanent;
  server_name                blog.triaxx.org;
}

Tout d'abord, nous mettons en place un service qui écoute sur le port 80 (directives listen), aussi bien en IPv4 qu'en IPv6 ([::]:80), et qui traitre les requêtes reçues pour l'hôte dont le nom de domaine est blog.triaxx.org (directive server_name). L'URL de toutes ces requêtes est réécrite (directive rewrite) pour utiliser le protocole https et ainsi forcer une connexion chiffrée sur le port 443.

server { 
  access_log                 syslog:server=unix:/var/run/log,tag=blog,nohostname;
  error_log                  syslog:server=unix:/var/run/log,tag=blog,nohostname;
  index                      index.php;
  listen                     443             ssl http2;
  listen                     [::]:443        ssl http2;
  root                       /srv/http/blog/dotclear;
  server_name                blog.triaxx.org;
  ssl_certificate            /etc/openssl/certs/triaxx.org.pem;
  ssl_certificate_key        /etc/openssl/private/triaxx.org.pem;
  ssl_ciphers                'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
  ssl_prefer_server_ciphers  on;
  ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
  ssl_session_cache          shared:SSL:50m;
  ssl_session_tickets        off;
  ssl_session_timeout        1d;
  ssl_stapling               on;
  ssl_stapling_verify        on;

Ce service écoute sur le port 443 et la communication est sécurisée par TLS. Les logs d'accès et d'erreur sont envoyés au daemon syslogd en spécifiant le tag blog pour pouvoir les aiguiller correctement vers des fichiers dédiés. Le fichier de configuration /etc/syslog.conf contiendra alors les lignes suivantes.

!blog
local7.info    /var/log/nginx/blog.access.log
local7.err     /var/log/nginx/blog.error.log

Afin de ne pas voir ces fichiers grossir indéfiniment, nous pouvons rajouter une entrée dans /etc/newsyslog.conf pour activer les logs tournants.

/var/log/nginx/blog.access.log     root:wheel      644  7    250  *    X
/var/log/nginx/blog.error.log      root:wheel      644  7    250  *    X

Il faut définir comment seront interprétés les requêtes portants sur des fichiers PHP.

location ~ \.php$ {
    include                  fastcgi.conf;
    fastcgi_index            index.php;
    fastcgi_pass             php-fpm-blog;
  }

  location ~ \.php(/.*)$ {
    include                  fastcgi.conf;
    fastcgi_index            index.php;
    fastcgi_param            PATH_INFO       $fastcgi_path_info;
    fastcgi_param            PATH_TRANSLATED $document_root$fastcgi_path_info;
    fastcgi_pass             php-fpm-blog;
    fastcgi_split_path_info  ^(.+\.php)(.*)$;
  }

Avec la directive location, nous spécifions une expression régulière sensible à la casse (modifieur ~). Si une correspondance est trouvée pour cette expression, la requête est transmise à un serveur FastCGI via la directive fastcgi_pass. Le premier cas (expression \.php$ ) correspond à des URL traitées en mode Query String. Le second cas (expression \.php(/.*)$) correspond quant à lui à des URL traitées en mode Path Info.

location / {
    try_files $uri $uri/ @dotclear_path_info;
}

 location @dotclear_path_info {
    rewrite ^/(.*) /index.php/$1 last;
  }
}

Ces directives permettent la réécriture d'URL pour qu'une requête vers le lien https://blog.triaxx.org/post/2020/04/09/Installation-de-Dotclear soit redirigée vers https://blog.triaxx.org/index.php/post/2020/04/09/Installation-de-Dotclear. À ce stade, il faudra modifier dans les paramètres du blog l'URL du blog en https://blog.triaxx.org/ et la méthode de lecture de l'URL en PATH_INFO.

upstream php-fpm-blog {
  server                     unix:/var/run/php-fpm-blog.sock;
}

Nous définissons pour Nginx que ce serveur sera accessible via un socket Unix.

Pour instancier ce socket, nous ajoutons un fichier /usr/pkg/etc/php-fpm.d/blog.conf.

[blog]
user                           = fpm 
group                          = www 
listen                         = /var/run/php-fpm-blog.sock
listen.owner                   = nginx
listen.group                   = www 
pm                             = dynamic
pm.max_children                = 5 
pm.start_servers               = 2 
pm.min_spare_servers           = 1 
pm.max_spare_servers           = 3 
php_value[pcre.jit]            = 0

Nous pouvons remarquer que l'utilisateur qui exécutera ce serveur est fpm et que le groupe associé est www. Il faudra donc s'assurer que certains répertoires soient accessibles en écriture pour ce groupe.

# chown :www /srv/http/blog/dotclear/cache /srv/http/blog/dotclear/public
# chmod g+w /srv/http/blog/dotclear/cache /srv/http/blog/dotclear/public

Le propriétaire du socket est l'utilisateur nginx pour que le serveur du même nom puisse y avoir accès.

Il ne nous reste plus qu'à redémarrer les services Nginx et FPM en vérifiant préalablement que leur fichiers de configurations soient corrects.

# php-fpm -t
# service php_fpm restart
# nginx -t
# service nginx restart

Il est maintenant possible de finaliser l'installation en suivant le lien https://blog.triaxx.org/admin/install.

Page top