Cet article se concentre sur httpd, le serveur Web. Si vous cherchez un article plus complet qui inclut également relayd, le reverse proxy, vous le trouverez sur mon autre blog, OpenBSD Desktop .

OpenBSD httpd

Afin que les choses soient claires, on parle ici d’OpenBSD httpd, à ne pas confondre avec Apache httpd qu’on appele généralement Apache. Ce dernier peut être installé via pkg, le gestionnaire de packages.

OpenBSD httpd est un serveur Web développé par l’équipe qui est derrière OpenBSD. Pour un système d’exploitation utilisé majoritairement sur serveur, embarquer un serveur Web est cohérent et pratique. Si besoin il peut être couplé avec relayd, le reverse proxy / load balancer livré avec OpenBSD, que je présenterai dans un autre article.

Note: doas est l’équivalent OpenBSD de sudo, donc quand une commande est précédée de doas, elle est exécutée en tant qu’administrateur.

Installation de PHP

Puisqu’on veut faire tourner un site Web écrit en PHP, commençons par l’installer. Il suffit d’exécuter :

doas pkg_add php

et de choisir la version de PHP si plusieurs sont proposées.
Il est aussi possible d’installer des extensions, par exemple :

doas pkg_add php-pdo_mysql

et de les activer :

doas ln -s /etc/php-8.5.sample/pdo_mysql.ini /etc/php-8.5/pdo_mysql.ini

Pour vérifier que PHP est bien installé, tapez php -v.

Le serveur Web utilise PHP FPM, installé avec PHP, il ne reste qu’à activer et démarrer le service :

doas rcctl enable php85_fpm && doas rcctl start php85_fpm

Voilà pour PHP, passons à httpd.

Démarrage du serveur httpd

Avant de commencer, il faut savoir que httpd et PHP FPM sont chrootés dans /var/www/, c’est-à-dire qu’ils ne voient pas le reste du système. Quand ils tentent d’accéder à la racine, /, ils voient en fait le contenu de /var/www/.
Il s’agit d’une mesure de sécurité : si un attaquant exploite une vulnérabilité dans votre application (ou dans httpd) et parvient à exécuter des commandes, il n’aura pas accès à l’ensemble des fichiers du serveur, il sera limité à /var/www/. Vous n’avez rien à faire pour l’activer, c’est déjà en place par défaut.

Puisqu’on va s’en servir, activons le service httpd :

doas rcctl enable httpd

Passons à la configuration, qui se trouve à /etc/httpd.conf.

D’abord on le configure en HTTP, pour générer un certificat TLS ensuite.

types { include "/usr/share/misc/mime.types" }

# Ici on configure pour HTTP uniquement
# On configure phpmyadmin.abosec.fr, la configuration DNS doit avoir été faite
# au préalable
server "phpmyadmin.abosec.fr" {
    # Écoute sur Internet, sur le port 80
    listen on egress port 80
    # La base du site est /var/www/htdocs/phpmyadmin/
    # On n'oublie pas que httpd est chrooté dans /var/www/
    root "/htdocs/phpmyadmin"
    # Pour générer des certificats Let's Encrypt (LE), acme-client génère des
    # fichiers, stockés dans /var/www/acme/, qui vont ensuite être accédés par
    # l'infrastructure de LE. Le bloc ci-dessous dit simplement que toute URL
    # ressemble à http://phpmyadmin.abosec.fr/.well-known/acme-challenge/<fichier>
    # cherche <fichier> dans le répertoire /var/www/acme, noté /acme car httpd est
    # chrooté dans /var/www/.
    location "/.well-known/acme-challenge/*" {
        root "/acme"
        request strip 2
    }
}

On (re)démarre httpd avec

doas rcctl -d restart httpd

On est prêt à générer le certificat TLS.

Génération du certificat TLS

Note : il est important de vérifier que le dossier /var/www/acme/ est accessible en lecture par httpd. Il suffit de créer un fichier /var/www/acme/test.txt contenant “test” et d’accéder à l’URL “ http://phpmyadmin.abosec.fr/.well-known/acme-challenge/test.txt" . Si vous ne voyez pas “test”, ajustez les droits du dossier.

Ensuite on configure acme-client, dans le fichier /etc/acme-client.conf.
acme-client permet de générer et regénérer des certificats en utilisant le protocole ACME. Sur Linux, on utilise souvent certbot pour cela.

# On définit une autorité de certification, ici Let's Encrypt
authority letsencrypt {
    api url "https://acme-v02.api.letsencrypt.org/directory"
    account key "/etc/acme/letsencrypt-privkey.pem"
}

# Ici on définit le serveur de test de Let's Encrypt
# Peut être utile pour vérifier que notre installation fonctionne avant de
# passer sur la production
authority letsencrypt-staging {
    api url "https://acme-staging-v02.api.letsencrypt.org/directory"
    account key "/etc/acme/letsencrypt-staging-privkey.pem"
}

domain phpmyadmin.abosec.fr {
    # Quand on veut inclure plusieurs domaines dans un certificat,
    # par exemple le sous-domaine www, on utilise "alternative names"
    #alternative names { www.phpmyadmin.abosec.fr }
    domain key "/etc/ssl/private/phpmyadmin.abosec.fr.key"
    domain full chain certificate "/etc/ssl/phpmyadmin.abosec.fr.fullchain.pem"
    # On choisit l'autorité de certification à utiliser
    sign with letsencrypt
}

Une fois configuré, il suffit d’exécuter

doas acme-client phpmyadmin.abosec.fr

on pourra ensuite l’exécuter dans une tâche cron afin de renouveler le certificat automatiquement.

Si tout s’est bien passé, on peut modifier la configuration de httpd pour fonctionner en HTTPS.

Configuration de httpd

De retour dans /etc/httpd.conf, on adapte la configuration pour que le site redirige de HTTP vers HTTPS.

# Ici on configure pour HTTPS uniquement
# C'est le site principal
server "phpmyadmin.abosec.fr" {
    listen on egress port 443

    # Les clefs sont chargés au démarrage du serveur, avant que le chroot
    # ne soit appliqué
    tls {
        certificate "/etc/ssl/phpmyadmin.abosec.fr.fullchain.pem"
        key         "/etc/ssl/private/phpmyadmin.abosec.fr.key"
    }

    root "/htdocs/phpmyadmin"
    location "*.php" {
        # Optionnel : une authentification basique
        # pour éviter que phpMyAdmin ne soit scanné par des bots
        #authenticate with "/auth-files/phpmyadmin"
        # Tout ce qui termine par .php est traité par PHP
        fastcgi socket "/run/php-fpm.sock"
    }

    # ACME est désormais géré via HTTPS
    location "/.well-known/acme-challenge/*" {
        root "/acme"
        request strip 2
    }
}

# Ici on configure pour HTTP uniquement
server "phpmyadmin.abosec.fr" {
    listen on egress port 80
    root "/htdocs/phpmyadmin"
    # On redirige vers la page demandée, en HTTPS
    block return 301 "https://phpmyadmin.abosec.fr$REQUEST_URI"	
}

On redémarre à nouveau httpd avec

doas rcctl -d restart httpd

et c’est parti, l’application Web est accessible.


Prêt à passer votre serveur en production ? Découvrez comment je peux migrer et héberger votre infrastructure OpenBSD , ou parlons-en directement .