Héberger des sites web (httpd) §

Héberger votre propre site web, en voilà une bonne idée ! 😊 Rien de tel qu'un petit espace rien qu'à vous pour vous exprimer sans contraintes.

OpenBSD intègre par défaut un serveur HTTP qui s'appelle tout simplement httpd. Il ne propose pas de fonctionnalités exotiques, mais sa légèreté le rend d'autant plus simple à configurer et moins sensible à d'éventuelles failles de sécurité. Il s'avère amplement suffisant dans la plupart des cas. Si vous avez réellement besoin d'un serveur HTTP plus complet, sachez que nginx et apache sont disponibles dans les ports.

Avant d'aller plus loin, il est important de noter que pour des raisons de sécurité, le serveur web httpd sera lancé en chroot dans le dossier /var/www.

Et c'est censé vouloir dire quoi ?

En réalité, pour le serveur web (http), tous les documents qui sont "au-dessus" du dossier /var/www sont totalement inaccessibles. Pour lui, il s'agit de la racine /. Ce comportement peut être modifié, mais je vous le déconseille : autant garder un maximum de précautions.

Tout ça me semble très compliqué...

C'est vrai que le Web d'aujourd'hui est dramatiquement complexe.

Et encore, vous n'avez pas créé de sitemap, réfléchi au SEO, choisi des templates...

Vous préférerez peut-être vous intéresser à un protocole comme gemini qui se distingue par sa simplicité. (Voir vger plus loin)

Simple site statique §

Ce que l'on appelle un "simple site statique" est constitué de pages HTML. C'est ce qu'il y a de plus léger et sûr. Cet exemple nous servira de base à des choses plus complexes ensuite. Voici comment mettre en place votre premier site.

On commence par créer un dossier qui contiendra les pages du site :

# mkdir /var/www/htdocs/mon_super_site

Copiez maintenant les pages de votre site dans ce dossier (index.html...). Pour vous assurer que le serveur pourra lire et donc servir vos pages html, vous pouvez les rendre lisibles à tous ("chmod a+r") ou bien changer le propriétaire de ces fichiers pour qu'ils appartiennent au serveur http (www) :

# chown -R www:daemon /var/www/htdocs/mon_super_site

Vous devriez songer à ajuster les permissions plus finement un peu plus tard. 😉

Il ne nous reste plus qu'à modifier la configuration du serveur web httpd. Pour cela, on va éditer (ou créer selon l'exemple situé dans /etc/examples) le fichier /etc/httpd.conf. Vous pourrez constater que sa configuration est très simple.

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

server "chezmoi.tld" {
    listen on * port 80
    root "/htdocs/mon_super_site"
}

Quelques explications :

On termine en activant httpd et en le (re)démarrant :

# rcctl enable httpd
# rcctl start httpd

Vous pouvez désormais aller admirer votre site. Toutes les pages html que vous placerez dans /var/www/htdocs/mon_super_site seront servies.

Petite astuce : vous pouvez envoyer les pages de votre site via SFTP en ligne de commande ou avec un client graphique, seul un accès SSH au serveur est nécessaire.

Et voilà, c'est suffisant pour un simple site. Afin d'y accéder, n'oubliez pas d'ouvrir le port 80 (www) dans le pare-feu et de le rediriger 😉.

Obtenir un certificat SSL §

Prévoir un accès avec chiffrement pour votre site n'est pas obligatoire. C'est malgré tout intéressant si :

Un certificat sera de toute façon nécessaire dès que vous voudrez chiffrer les échanges, pas seulement pour un site web mais aussi pour un serveur mail entre autres.

Notez toutefois que le chiffrement n'est pas supporté par les (très) vieux ordinateurs. Les adeptes de permacomputing voudront donc conserver un accès sans chiffrement en parallèle.

Letsencrypt §

Nous allons proposer en exemple d'obtenir un certificat via letsencrypt, une autorité de certification gratuite.

Nous allons proposer en exemple d'obtenir un certificat via letsencrypt, une autorité de certification gratuite :

https://letsencrypt.org

Un client est disponible sous OpenBSD nativement : acme-client. Cette démarche est décrite dans la partie concernant httpd car nous en auront besoin pour "communiquer" avec letsencrypt. C'est un service absolument génial tout à fait adapté à l'auto-hébergement. Ces certificats pourront tout aussi bien être utilisés pour un site web qu'un serveur mail ou autre service en ayant besoin.

⚠ Attention : vérifiez que le port 80 est bien ouvert sur votre pare-feu (et si vous utilisez un adressage privé, vérifiez vos redirections de ports, beaucoup d'erreurs viennent de là) ! En effet, acme-client doit rendre disponible sur votre serveur des "fichiers secrets" générés spécifiquement lors de la certification pour obtenir le certificat.

Cet outil va vérifier que vous avez bien accès au domaine pour lequel vous souhaitez un certificat. Il procède ainsi :

Il demande tout d'abord à letsencrypt un fichier unique, une sorte d'empreinte, qui est enregistrée dans /var/www/acme. Ensuite, letsencrypt tente de récupérer ce fichier en allant sur votre site dans le dossier .well-known/acme-challenge pour certifier que c'est bien votre serveur qui a fait la demande. Autrement dit, il demande http://chezmoi.tld/.well-known/acme-challenge/unfichiersecret. S'il y accède, la demande de certificat est acceptée et le fichier est supprimé.

Cependant, votre site web est sans doute enregistré dans /var/www/htdocs/votresite. Il faut donc rendre disponible le dossier /var/www/acme lorsque letsencrypt cherche à récupérer le fichier en question.

Ajoutez une nouvelle instruction "location" dans votre fichier /etc/httpd.conf.

server "chezmoi.tld" {
    listen on * port 80

    location "/.well-known/acme-challenge/*" {
        root "/acme"
        request strip 2
    }
    root "/htdocs/super-site"
}

Quelques explications :

⚠ Attention, il faut mettre cette portion pour chaque sous-domaine indiqué dans la partie alternative names du fichier de configuration d'acme-client détaillé ci-dessous. Il sera donc plus pratique d'utiliser des instructions include dans la configuration d'httpd comme indiqué dans la partie des astuces pour httpd ou dans le paragraphe suivant 😉.

Avant d'utiliser acme-client, nous allons le configurer dans le fichier /etc/acme-client.conf qu'il faudra créer si besoin. Vous pouvez copier l'exemple situé dans /etc/examples/acme-client.conf.

Dans ce dernier fichier, nous allons donc mettre ces lignes suivantes :

authority letsencrypt {
  api url "https://acme-v02.api.letsencrypt.org/directory"
  account key "/etc/acme/letsencrypt-privkey.pem"
}

authority letsencrypt-staging {
  api url "https://acme-staging-v02.api.letsencrypt.org/directory"
  account key "/etc/acme/letsencrypt-staging-privkey.pem"
}

domain chezmoi.tld {
    alternative names { webmail.chezmoi.tld www.chezmoi.tld }
    domain key "/etc/ssl/private/chezmoi.tld.key"
    domain full chain certificate "/etc/ssl/chezmoi.tld.crt"
    sign with letsencrypt
}

Remplacez les éléments suivants :

Assurez-vous que les dossiers nécessaires sont bien créés (normalement ils le sont déjà):

# mkdir -p -m 700 /etc/ssl/private
# mkdir -p -m 755 /var/www/acme

Vérifiez que votre configuration est correcte, une faute de frappe est vite arrivée :

# acme-client -n

Si tout est bon, alors la commande précédente ne renvoie aucun message 😉.

Vous pourrez ensuite générer vos certificats avec cette commande :

# acme-client -v chezmoi.tld

Conseil : La première fois, il vaut mieux tester qu'il n'y a pas d'erreurs dans votre configuration en utilisant "sign with letsencrypt-staging" dans le fichier /etc/acme-client.conf. Lorsque tout fonctionne comme prévu, vous forcerez l'obtention d'un certificat avec l'option -F après avoir modifié la configuration d'acme-client.

Pour renouveler les certificats, il suffira d'entrer à nouveau la commande précédente.

Je vous invite à ajouter cette ligne dans le fichier /etc/weekly.local pour un renouvellement chaque semaine si nécessaire :

/usr/sbin/acme-client -v chezmoi.tld && /usr/sbin/rcctl reload httpd

L'utilisation de && permet de recharger httpd seulement si les certificats ont été renouvelés. Vous devriez recharger les autres services utilisant ce certificat (relayd et dovecot par exemple).

Maintenant, nous allons utiliser notre certificat en activant l'accès https dans la configuration de httpd :

# extrait de /etc/httpd.conf
server "chezmoi.tld" {
    listen on * port 80
    # partie http
    # [...]
}
server "chezmoi.tld" {
    listen on * tls port 443
    root "/htdocs/monsupersite"

    tls {
        certificate "/etc/ssl/chezmoi.tld.crt"
        key "/etc/ssl/private/chezmoi.tld.key"
    }
    hsts

    # n'oubliez pas d'ajouter la configuration
    # spécifique liée à votre site
}

Vous remarquerez que la connexion se fait désormais sur le port 443 (https), qu'il faut ouvrir dans le pare-feu et rediriger dans le routeur.

Vous voudrez peut-être rediriger les visiteurs de la version http vers la version https de votre site tout en gardant la possibilité d'utiliser acme-client.

On ajoute alors une redirection APRÈS le bloc concernant acme-client.

# extrait de /etc/httpd.conf
server "chezmoi.tld" {
    listen on * port 80

    location "/.well-known/acme-challenge/*" {
        root "/acme"
        request strip 2
    }

    # on redirige vers la version https
    location * { block return 301 "https://$SERVER_NAME$REQUEST_URI" }
}
server "chezmoi.tld" {
    listen on * tls port 443
    #[...]
}

Ce dernier morceau avec "block return 301" est important 😉.

Il permet de rediriger toutes les requêtes (location *) vers la version https. Si httpd en est arrivé là, c'est que la requête ne correspondait pas aux précédentes, c'est-à-dire celle pour acme-client.

Remarquez l'utilisation de "location *" qui correspond à toutes les requêtes APRÈS celle concernant acme. En effet, httpd lit chaque cas de figure dans l'ordre et traite le premier venu.

Cette configuration sera à mettre en place pour tous les sites servis. Dans l'exemple, nous avons aussi www.chezmoi.tld et webmail.chezmoi.tld. Puisque cela risque de vite devenir long, on va utiliser une petite astuce (voir paragraphe suivant).

Utilisons "include" pour configurer httpd §

Puisqu'on doit permettre l'obtention des certificats pour chaque site servi, autrement dit ceux définis dans l'instruction alternative names du fichier /etc/acme-client.conf, je vous propose de profiter de la capacité d'httpd à inclure des fichiers.

Commençons par créer un dossier qui contiendra les fichiers de configuration /etc/httpd.d :

# mkdir /etc/httpd.d

Ensuite, on crée le fichier /etc/httpd.d/acme.conf qui contient les lignes relatives à acme vues plus haut.

location "/.well-known/acme-challenge/*" {
    root "/acme"
    request strip 2
}

On peut pousser le bouchon un peu plus loin en créant /etc/httpd.d/tls.conf pour les lignes appelant le certificat :

tls {
    certificate "/etc/ssl/chezmoi.tld.crt"
    key "/etc/ssl/private/chezmoi.tld.key"
}
hsts

Désormais, le fichier /etc/httpd.conf pourra être réduit à ces quelques lignes, le tout pour servir 3 sites : www.chezmoi.tld, chezmoi.tld et webmail.chezmoi.tld (le "www" étant le principal) :

server "www.chezmoi.tld" {
    listen on * tls port 443
    include "/etc/httpd.d/tls.conf"
    root "/htdocs/www.chezmoi.tld"
}

server "www.chezmoi.tld" {
    listen on * port 80
    include "/etc/httpd.d/acme.conf"
    location * { block return 301 "https://$SERVER_NAME$REQUEST_URI" }
}

server "chezmoi.tld" {
    listen on * tls port 443
    include "/etc/httpd.d/tls.conf"
    block return 301 "https://www.$SERVER_NAME$REQUEST_URI"
}

server "chezmoi.tld" {
    listen on * port 80
    include "/etc/httpd.d/acme.conf"
    location * { block return 301 "https://$SERVER_NAME$REQUEST_URI" }
}

server "webmail.chezmoi.tld" {
    listen on * tls port 443
    include "/etc/httpd.d/tls.conf"
    root "/htdocs/webmail.chezmoi.tld"
}

server "webmail.chezmoi.tld" {
    listen on * port 80
    include "/etc/httpd.d/acme.conf"
    location * { block return 301 "https://$SERVER_NAME$REQUEST_URI" }
}

La configuration ci-dessus redirige les visiteurs de chezmoi.tld vers www.chezmoi.tld. Elle ajoute un site webmail.chezmoi.tld. À chaque fois, l'utilisation d'acme-client est possible pour récupérer le certificat qui va bien.

Vous aurez remarqué que chaque section est répétitive. Je vous laisse imaginer une façon encore plus réduite d'écrire ce fichier en utilisant encore plus d'instructions "include" si cela vous chante. Notez que cela n'a d'intérêt que si vous servez un grand nombre de sites.

Merci à Grégory Marchal pour les suggestions sur cette partie 😄

Générer un certificat SSL auto-signé §

Dans cette partie, nul besoin d'httpd. si vous avez besoin d'un certificat sans vouloir configurer httpd, vous êtes au bon endroit 😉.

Nous allons ici auto-signer le certificat comme indiqué dans le manuel ssl(8) :

https://man.openbsd.org/ssl.8#GENERATING_RSA_SERVER_CERTIFICATES_FOR_WEB_SERVERS

Les visiteurs de votre site risquent juste d'avoir un avertissement disant :

Cette connexion n'est pas certifiée, Que faire ?

Ils peuvent alors choisir d'accepter le certificat et la suite se déroule sans problème 😇.

Pour créer un certificat et le signer, il faut lancer la commande suivante. Bien sûr, remplacez le nom du fichier serveur à votre convenance :

# openssl genrsa -out /etc/ssl/private/serveur.key 4096
# openssl req -new -key /etc/ssl/private/serveur.key \
    -out /etc/ssl/private/serveur.csr
# openssl x509 -sha256 -req -days 365 \
    -in /etc/ssl/private/serveur.csr \
    -signkey /etc/ssl/private/serveur.key \
    -out /etc/ssl/serveur.crt

Quelques questions vous seront posées. Vous n'êtes pas obligé de remplir tous les champs, mais essayez d'être le plus précis possible, notamment pour "Common Name" où vous devriez préciser votre nom de domaine.

Deux fichiers sont créés :

Retenez bien le chemin vers ces fichiers. Il faudra le préciser dans la configuration de votre serveur web (http).

Finalement, il faut protéger la clé associée au certificat. Lancez ces deux dernières commandes afin d'en restreindre les permissions :

# chown root:wheel /etc/ssl/private/serveur.{key,csr}
# chmod 600 /etc/ssl/private/serveur.{key,csr}
# chmod -R go-rwx /etc/ssl/private

Facultatif : enregistrements CAA §

Vous pouvez ajouter à votre zone DNS des enregistrements de type CAA. Ce n'est pas obligatoire, mais ça permet de démontrer que vous, le propriétaire de ce domaine, avez autorisé letsencrypt à vous donner un certificat. Cette étape est une preuve de bonne foi supplémentaire. Dans votre zone, il y aura donc :

@ 300 IN   CAA   0 issue "letsencrypt.org"

Tester la sécurité apportée par le chiffrement §

Voici quelques services permettant de tester la qualité du chiffrement proposé par votre serveur :

https://www.ssllabs.com/

https://tls.imirhil.fr/

https://observatory.mozilla.org/

PHP §

Minimum requis pour PHP §

Il est fort possible que vous souhaitiez permettre l'utilisation de populaire langage PHP à un moment donné, surtout si vous voulez héberger un moteur de blog ou un CMS. Il s'agit d'un langage de programmation offrant davantage de possibilités que de simples pages HTML.

La commande suivante permet d'installer PHP (à remplacer par la version souhaitée):

# pkg_add php-7.4.7

Pour lister toutes les versions de PHP disponibles, entrez :

# pkg_info -Q php

Après installation du paquet, on active PHP et on le démarre :

# rcctl enable php74_fpm
# rcctl start php74_fpm

Ici, "74" correspond à la version 7.4.

Nous pouvons maintenant modifier la configuration de httpd pour lui dire de servir les pages au travers de PHP. Quelques lignes sont à ajouter au fichier /etc/httpd.conf :

server "chezmoi.tld" {
        listen on * port 80
        root "/htdocs/monsupersite"
        directory index index.php

        location "*.php" {
                fastcgi socket "/run/php-fpm.sock"
        }
}

Remarquez l'instruction directory index index.php. Elle permet de rendre l'adresse http://chezmoi.tld/ équivalente à l'adresse http://chezmoi.tld/index.php.

Et voilà, les fichiers php seront correctement interprétés. Cette configuration est suffisante dans la plupart des cas.

Ajouter des modules PHP §

Vous avez peut-être remarqué lors de l'installation de PHP une note concernant le dossier /usr/local/share/doc/pkg-readmes. Ce dernier contient des informations très intéressantes que nous allons appliquer ici.

Les extensions installées sont dans le dossier /etc/php-7.4.sample. Afin de les activer, il faut les relier dans le dossier /etc/php-7.4. On peut le faire en deux commandes :

# cd /etc/php-7.4.sample
# for i in *; do ln -sf ../php-7.4.sample/$i ../php-7.4/; done
# rcctl restart php74_fpm

Ainsi, toutes les extensions disponibles pour PHP sont activées. Pensez-y si vous en installez de nouvelles plus tard.

La plupart des extensions sont déjà présentes, mais vous voudrez peut-être y ajouter les paquets suivants (en adaptant le numéro de version):

Modifier la configuration de PHP §

On peut souhaiter modifier la configuration de PHP. Il faut pour cela éditer le fichier /etc/php-*.ini. Je vous conseille notamment de modifier ces quelques lignes :

; Augmente la taille des fichiers que vous pouvez envoyer sur le site
post_max_size = 10M
upload_max_filesize = 10M
; une application php peut chercher du contenu distant (images..)
allow_url_fopen = On
; Le fuseau horaire
date.timezone = Europe/Paris

Configuration PHP relative au chroot §

Il est possible que vos pages php doivent récupérer des informations ou données venant d'autres sites. Il a donc besoin de résoudre des noms de domaines, vérifier des certificats, connaître l'heure du système. Ces éléments sont situés dans le dossier /etc. Malheureusement, si vous vous souvenez bien, le serveur http est dans un chroot. Où se trouve ce chroot déjà?

Dans /var/www !!!

Très bien Jean-Michel ! Il y en a au moins un qui suit. 😁

On va donc être obligé de mettre quelques fichiers qui normalement se trouvent dans /etc à l'intérieur du chroot dans /var/www/etc.

Voici la procédure :

# cd /var/www     # On va dans le chroot
# mkdir etc/      # On fabrique un dossier etc
# cp /etc/resolv.conf etc/resolv.conf # Pour la résolution de domaine
# cp /etc/hosts etc/hosts
# cp /etc/localtime etc/localtime                
# mkdir etc/ssl   # On cree un autre dossier pour vérifier les certificats
# install -m 444 -o root -g bin /etc/ssl/cert.pem /etc/ssl/openssl.cnf /var/www/etc/ssl

Ces fichiers ne doivent qu'être lisibles et accessibles :

chmod -R 444 /var/www/etc/*
chmod -R a+X /var/www/etc/

Les fichiers copiés servent notamment à :

install -m 444 -o root -g bin /etc/ssl/cert.pem /etc/ssl/openssl.cnf /var/www/etc/ssl

Certaines applications ont besoin d'être capable d'envoyer des mails (forums, wikis...). Puisque PHP est dans un chroot, il ne pourra pas communiquer avec sendmail, le programme responsable de l'envoi des mails. Heureusement, lorsque vous avez installé PHP, l'outil femail-chroot a été lui aussi installé grâce au jeu des dépendances. Pour que PHP puisse l'utiliser, il faut copier sh dans le chroot (voir le fichier /usr/local/share/doc/pkg-readmes/femail-chroot*).

# cp /bin/sh /var/www/bin/

Une fois toutes vos modifications réalisées, n'oubliez pas de relancer PHP avec "# rcctl restart php74_fpm".

Quelles permissions donner aux fichiers de mon site ? §

Attribuer les permissions adéquates aux fichiers constituant vos sites web est très important d'un point de vue sécurité. Il n'y a cependant pas de règles générales, car cela dépend des besoins de l'application hébergée et des vôtres.

Voici quelques exemples :

Les fichiers du site devraient appartenir au serveur http (ou sinon être en lecture seule) :

# chown -R www:daemon /var/www/htdocs/mon_site

Dans le cas d'un site statique (sans PHP), il est inutile de laisser les droits d'exécution (-x). De même, s'il est statique, il n'y aura pas besoin d'écrire dedans (-w). On ajoute quand même le droit de se déplacer dans les répertoires (+X).

# chmod -R a-xw /var/www/htdocs/mon_site 
# chmod -R ug+X /var/www/htdocs/mon_site

On commence par retirer les permissions non-souhaitées à tout le monde avant d'en donner au propriétaire et au groupe.

Pour un site dynamique, le serveur aura peut-être besoin d'écrire dans les dossiers et d'en exécuter une partie.

# chmod -R a-xw /var/www/htdocs/mon_site
# chmod -R u+xwX /var/www/htdocs/mon_site
# chmod -R g+rX /var/www/htdocs/mon_site

Là aussi, on commence par retirer tous les droits avant d'en donner au cas par cas.

⚠ ATTENTION : il sera certainement judicieux de modifier les permissions plus finement. Dans tous les cas, la meilleure pratique est de se poser la question concernant les droits.

À titre informatif, la plupart des hébergeurs appliquent uniquement les permissions suivantes (sans prétendre que ce soit la meilleure solution) :

Tout ceci peut se faire en quelques lignes :

# chmod -R a-rwx /var/www/htdocs/site    # retrait des permissions
# chmod -R a+rX /var/www/htdocs          # tout le monde peut lire les dossiers
# chmod -R u+w /var/www/htdocs           # seul le proprietaire peut ecrire

On retire d'abord l'ensemble des permissions. Ensuite, on donne accès en lecture aux dossiers et fichiers. Attention, à cette étape, il s'agit d'un "X" majuscule. Enfin, on accorde au propriétaire les droits d'écriture dans les dossiers et fichiers.

Astuces pour httpd §

man httpd §

Je ne peux m'empêcher de vous inciter à lire le man httpd.conf.

https://man.openbsd.org/httpd.conf

On y trouve tout ce qui est écrit ici, et plus encore.

Journaux §

Vous pouvez choisir un fichier spécifique où seront enregistrés les logs dans la section de chaque site. Ils sont par défaut enregistrés dans le dossier /var/www/logs.

log access "nom_du_site.log"

Pour désactiver les logs, écrivez "no log".

Compression gzip §

Ajoutez l'instruction "gzip-static" dans la configuration d'un domaine ou dans une section "location". Ainsi, lorsqu'un visiteur demande à afficher un fichier, httpd tentera de lui délivrer un éventuel fichier du même nom avec l'extension ".gz" en plus s'il existe.

Cela peut diminuer drastiquement la bande passante nécessaire, de 2 à 10 fois. Privilégiez de compresser les fichiers texte (html, css, js, svg...).

Pour gzipper un fichier :

$ gzip -vk9 index.html
index.html:                49.5% -- replaced with index.html.gz
1395 bytes in, 733 bytes out

Page d'erreur personnalisée §

Vous pouvez préciser avec l'instruction "errdocs" le dossier du chroot dans lequel sont stockées des pages d'erreurs personnalisées.

Il peut s'agit d'une page nommée "err.html" ou bien de pages dont le nom correspond au code d'erreur, par exemple "404.html".

Cela donne :

errdocs "/htdocs/chezmoi.tld/err"

Vous déposerez dans le dossier /var/www/htdocs/chezmoi.tld/err un fichier err.html qui peut ressembler à :

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width">
<link rel="icon" href="/favicon.png" type="image/png" />
<style type="text/css">body, html {height:100%; margin:0}
#bg {
    position: relative;
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    background-image: url("/img/errimg.jpg");
    height: 100%;
    padding:0;
    margin:0;
}
#content {
    padding:1.5em;
}
</style>
<title>
$RESPONSE_CODE : $HTTP_ERROR
</title>
</head>
<body>
<div id="bg">
    <div id="content">
        <h1>Error page 😖</h1>
        <p>Sorry!</p>
    </div>
</div>
</body>
</html>

Améliorer la disponibilité §

Afin d'augmenter le nombre de processus par défaut, et donc pouvoir servir simultanément du contenu à plusieurs clients, augmentez la valeur par défaut qui est de 3 :

prefork 10

Publier en utf-8 §

Si vous essayez d'afficher un fichier texte brut, il est possible que le navigateur affiche mal les caractères accentués, à moins que vous sélectionniez l'encodage utf-8 dans les paramètres de ce dernier.

Pour éviter aux lecteur d'avoir à chercher ce paramètre, vous pouvez explicitement indiquer que le contenu est diffusé en utf-8 en modifiant le httpd.conf dans la section types. Ça suppose d'échapper le point-virgule, donc autant avoir un exemple pour les fichiers d'extension ".gmi" et ".txt" :

types {
    include "/usr/share/misc/mime.types"
        text/"plain;charset=UTF-8" gmi
        text/"plain;charset=UTF-8" txt
        text/"plain;charset=UTF-8" awk
        text/"plain;charset=UTF-8" sh
        text/"plain;charset=UTF-8" c
}

Remarquez qu'on ajoute ces déclarations après avoir inclus /usr/share/misc/mime.types pour remplacer celles qui concernent éventuellement déjà les extensions mentionnées.

Accès restreint par mot de passe §

Pour protéger l'accès à un site ou une partie du site par un mot de passe, utilisez la commande htpasswd pour créer un fichier d'accès :

# htpasswd /var/www/secret.htpw login

Remplacez "login" par le nom d'utilisateur que vous souhaiterez utiliser, puis définissez un mot de passe solide. Recommencez à chaque fois que vous voulez ajouter un nouvel utilisateur.

Modifiez les permissions sur ce fichier :

# chown www /var/www/secret.htpw
# chmod 400 /var/www/secret.htpw

Enfin, dans la configuration de httpd, pour protéger l'accès au sous-dossier /dossier_protege/* :

location "/dossier_protege/*" {
    authenticate "Acces restreint" with "/secret.htpw"
}

Remarquez que l'emplacement du fichier secret.htpw est relatif au chroot de httpd, on fait comme si /var/www était /.

Pour protéger un site complet, indiquez :

location "/*"

Ou alors, mettez l'instruction authenticate au tout début de la configuration sans jamais préciser de "location".

Index des fichiers §

Afin de lister automatiquement dans le navigateur les fichiers présents dans un dossier si aucun fichier index.html n'est présent, ajoutez dans le fichier /etc/httpd.conf :

location "/dossier/*" {
    directory auto index
}

Inclusion de fichiers de configuration §

Si vous avez plusieurs sites, ça peut vite être le bazar de tout configurer dans le fichier /etc/httpd.conf. Il vous est possible de découper la configuration dans plusieurs fichiers avec l'instruction include :

include "/etc/httpd/site1.conf"
include "/etc/httpd/site2.conf"

Accélérer les négociations TLS §

Pour accélérer les futures négociations TLS si vous servez votre site en https, vous pouvez ajouter un "ticket de session" :

hsts preload
tls {
  certificate "/etc/ssl/chezmoi.tld.crt"
  key "/etc/ssl/private/chezmoi.tld.key"
  ticket lifetime default
}

Relayd et les entêtes §

Une gestion fine des entêtes (headers) peut vous intéresser. Cela peut notamment servir pour indiquer aux navigateurs de garder en cache plus longtemps les fichiers téléchargés et alléger la charge du serveur, ou encore régler des questions de sécurité.

httpd n'est pas capable de gérer les entêtes. Heureusement, tout est prévu : nous allons utiliser relayd et le placer avant httpd.

Inutile d'installer quoi que ce soit, relayd est déjà présent dans OpenBSD. Elle est pas belle la vie ? 😁

Pour tester les entêtes de votre site, vous voudrez peut-être visiter securityheaders.com.

https://securityheaders.com/

Configuration de relayd §

La configuration de relayd est écrite dans le fichier /etc/relayd.conf que nous allons éditer.

À l'intérieur, et à titre d'exemple, nous allons mettre les lignes suivantes :

http protocol "http" {
	match request header remove "Proxy"
	match response header set "X-Xss-Protection" value "1; mode=block"

	return error
	pass
}

relay "www" {
	listen on 192.0.2.2 port 80
	protocol "http"
	forward to localhost port 8080
}

Voici ce que ces lignes signifient :

Justement, afin que httpd prenne la suite de relayd, il doit maintenant écouter sur local port 8080. On devra donc avoir cette ligne dans la configuration de httpd :

# configuration de httpd
listen on localhost port 8080

Si on résume, les choses se passent désormais ainsi :

Après avoir réalisé vos modifications, n'oubliez pas d'activer relayd et de redémarrer les services :

# rcctl enable relayd
# rcctl restart httpd
# rcctl start relayd

Notez que cela va modifier l'apparence des journaux pour httpd qui montreront une origine venant de 127.0.0.1, l'adresse locale de relayd.

Vous préférerez peut-être utiliser le format "forwarded" pour httpd (dans /etc/httpd.conf) qui ajoute l'IP d'origine à la fin.

log style forwarded

relayd et TLS ou https §

Si votre site propose un accès chiffré avec une adresse "https://...", (c'est bien ! 😉), la configuration de relayd peut-être déroutante.

Ci-dessous, voici un exemple de configuration de relayd correspondante. Notez les mentions de tls :

http protocol "https" {
	match request header remove "Proxy"
	match response header set "X-Xss-Protection" value "1; mode=block"

	return error
	pass

	tls keypair chezmoi.tld
	tls keypair ici.tld
}

relay "tlsforward" {
	listen on 192.0.2.2 port 443 tls
	protocol "https"
	forward to localhost port 8080
}

Prêtez attention aux lignes commençant par "tls keypair". Elles permettent de définir les certificats et clés à utiliser pour le chiffrement TLS. Dans l'exemple ci-dessus, on précise deux certificats possibles pour deux domaines différents. Vous pouvez ajouter une ligne pour chaque domaine géré par votre serveur.

Toutefois, il est indispensable que ces certificats soient placés comme on l'a présenté dans la partie sur acme-client. Autrement dit, vos certificats et clés seront les fichiers suivants :

/etc/ssl/private/chezmoi.tld.key
/etc/ssl/chezmoi.tld.crt

De plus, le fichier /etc/ssl/chezmoi.tld.crt doit être le certificat "full chain".

Le plus simple sera peut-être de modifier votre configuration pour acme en conséquence. Par exemple, dans acme.conf:

domain chezmoi.tld {
    domain key "/etc/ssl/private/chezmoi.tld.key"
    domain certificate "/etc/ssl/chezmoi.tld-cert.crt"
    domain chain certificate "/etc/ssl/chezmoi.tld-chain.crt"
    domain full chain certificate "/etc/ssl/chezmoi.tld.crt"
    sign with letsencrypt
}

Inutile de préciser quoi que ce soit en plus dans la configuration de relayd ou httpd, tout fonctionne normalement comme prévu avec l'utilisation de vos certificats 😉

Vous pouvez même retirer tout ce qui concerne le tls dans la configuration de httpd, c'est désormais relayd qui le gère.

Renouvellement des certificats §

Si vous renouvelez vos certificats avec acme-client, pensez à recharger relayd pour qu'il tienne compte des changements. Par exemple :

/usr/sbin/acme-client -v chezmoi.tld && \
    /usr/sbin/rcctl reload relayd

Relayd et IPv6 §

Si vous voulez proposer un accès IPv4 et IPv6 avec relayd, vous devrez configurer les 2 dans le fichier /etc/hosts :

127.0.0.1 localhost
::1 localhost

Vous avez ainsi l'ipv4 et l'ipv6 correspondant à "localhost", ce qui sera utile ensuite.

Maintenant, on indique "localhost" dans la configuration de relayd :

relay "http" {
        listen on $ext_ip4 port 80
        protocol "http"
        forward to localhost port 8080
}

La configuration de httpd pourra être plus simple elle aussi en profitant de "localhost" :

listen on localhost port 8080

Relayd pour gérer les entêtes de sécurité §

Vous pouvez ajouter d'autres règles pour améliorer la sécurité de votre site en modifiant les entêtes suivantes. C'est surtout utile si vous hébergez de grosses applications web (inutile dans le cas d'un site statique).

match request header remove "Proxy"
match response header set "Frame-Options" value "SAMEORIGIN"
match response header set "X-Xss-Protection" value "1; mode=block"
match response header set "X-Frame-Options" value "SAMEORIGIN"
match response header set "X-Robots-Tag" value "index,nofollow"
match response header set "X-Permitted-Cross-Domain-Policies" value "none"
match response header set "X-Download-Options" value "noopen"
match response header set "X-Content-Type-Options" value "nosniff"
match response header set "Permissions-Policy" value "interest-cohort=()"
# HSTS Equivalent:
match response header set "Strict-Transport-Security" value "max-age=31536000; includeSubDomains"
# only load resources from ourselves
match response header set "Content-Security-Policy" value "default-src 'self';"

Si vous n'hébergez qu'un seul nom de domaine, vous devriez ajouter ceci :

match response header set "Access-Control-Allow-Origin" value "chezmoi.tld"

En apprendre plus sur le site de mozilla

https://developer.mozilla.org/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

Optimisation du cache et de la bande passante §

Que vous ayez une bande passante performante ou non, je vous conseille vivement d'optimiser le nombre de requêtes qu'un visiteur réalisera lorsqu'il visitera votre site. Pour cela, vous pouvez indiquer à son navigateur de garder les ressources (images, feuilles de style...) en cache pendant un temps assez long (21 jours dans l'exemple : 21 jours = 1814400 secondes).

Voici les éléments à ajouter dans la section "protocol" juste avant le mot clé "pass" :

match request path "/*.css" tag "CACHE"
match request path "/*.js" tag "CACHE"
match request path "/*.atom" tag "CACHE"
match request path "/*.rss" tag "CACHE"
match request path "/*.xml" tag "CACHE"
match request path "/*.jpg" tag "CACHE"
match request path "/*.png" tag "CACHE"
match request path "/*.svg" tag "CACHE"
match request path "/*.gif" tag "CACHE"
match request path "/*.ico" tag "CACHE"

match response tagged "CACHE" header set "Cache-Control" value "max-age=1814400"

L'idée est très simple, à chaque fois qu'un visiteur demande un fichier se terminant par l'une des extensions ".css, .js, .atom, ... , .ico", on colle sur la requête une étiquette "CACHE". À la fin, lorsque relayd détecte une requête avec cette étiquette, il ajoute un entête "Cache-Control" avec une valeur assez grande pour que le navigateur ne tente pas de télécharger à nouveau ce fichier de sitôt.

Définir l'encodage par défaut §

Pour être sûr qu'un texte avec accents s'affiche bien, on peut préciser l'encodage. Pour tous les fichiers html et les URL se terminant avec "/", on applique l'étiquette "UTF8" puis on ajoute un entête:

match request path "/*.html" tag "UTF8"
match request path "*/" tag "UTF8"
match response tagged "UTF8" header set "Content-Type" value "text/html;charset=UTF-8"

Note à propos des étiquettes de relayd §

Vous ne pouvez pas appliquer plusieurs étiquettes à la fois. Si vous voulez ajouter plusieurs entêtes, alors vous devrez le faire au fur et à mesure. Par exemple, si je veux augmenter le cache pour une page html et préciser l'encodage, alors j'applique d'abord le tag "CACHE", définit l'entête "Cache-Control", puis plus loin applique le tag "UTF8" et définit le "Content-Type" :

match request path "/*.html" tag "CACHE"
match response tagged "CACHE" header set "Cache-Control" value "max-age=1814400"

match request path "/*.html" tag "UTF8"
match response tagged "UTF8" header set "Content-Type" value "text/html;charset=UTF-8"

Les bases de données §

Une base de données permet à une application de retrouver rapidement des informations reliées entre elles.

Prenons le cas d'un blog par exemple. Les commentaires peuvent être stockés dans une base de données. Chaque commentaire est écrit pour un article précis, par un visiteur donné, à une date précise. Le commentaire comme l'article ont un lien bien précis. L'utilisateur peut avoir donné son adresse e-mail pour être averti de nouveaux messages...

Vous l'aurez compris, toutes ces données s'entrecroisent, et il est plus efficace d'utiliser une base de données pour les retrouver rapidement.

Cependant, ce n'est pas forcément obligatoire. Surtout sur un serveur auto-hébergé, où vous n'aurez sans doute pas des milliers d'utilisateurs.

Comprenez donc bien que si vous pouvez choisir des applications qui n'ont pas besoin de base de données, c'est un avantage pour vous car c'est un élément en moins à administrer et sécuriser. Eh oui, car une base de données peut elle aussi subir des attaques.

Une alternative est d'utiliser dans ce cas SQLite, puisque ce moteur de base de données ne nécessite pas d'administration particulière, c'est l'application qui s'en charge. Tous les avantages d'une base de données avec ceux des fichiers simples en somme.

SQlite §

SQlite est un moteur de base de données tout simplement génial.

https://www.sqlite.org/

Vous n'avez rien de particulier à faire pour l'administrer, c'est l'application qui en a besoin qui se chargera de créer la base. En plus, c'est très facile à sauvegarder puisqu'il s'agit dans ce cas d'un simple fichier à copier. Enfin, ce moteur sait se montrer léger et fonctionne bien même sur du matériel peu puissant.

Alors certains diront que ce n'est pas le moteur le plus performant. C'est vrai. Il reste plus efficace que pas de base de données du tout. À moins d'avoir des milliers de visiteurs sur votre site, vous ne verrez pas la différence avec un autre moteur de base de données. N'hésitez pas, il y a plus d'avantages que d'inconvénients à utiliser SQLite en auto-hébergement.

Pour l'installer, c'est tout bête :

# pkg_add sqlite3.

Afin de l'utiliser avec PHP, installez les ports php-pdo_sqlite-* et php-sqlite3-*.

Pour sauvegarder une base SQLite, il vous suffit de copier le fichier sqlite présent dans le dossier de votre site web. Oui, c'est tout ! 😊

Pour la copie, c'est comme vous voulez. Utilisez cp ou rsync, ne vous compliquez pas la vie.

MariaDB (MySQL) §

MySQL est un autre moteur de base de données, sans doute le plus répandu. Puisqu'Oracle possède désormais MySQL et en distribue une version propriétaire, un fork a été créé qui s'appelle MariaDB. Ce dernier est entièrement libre et est empaqueté pour OpenBSD.

Veillez à vous renseigner sur la sécurisation de ce service pour compléter les informations suivantes. Vous lirez notamment le contenu du fichier /usr/local/share/doc/pkg_readmes/* en rapport.

Vous voudrez certainement utiliser MariaDB avec PHP. Installez dans ce cas les paquet php-mysqli-* et php-pdo_mysql-* et activez l'extension mysqli comme indiqué dans la partie sur PHP.

Afin d'installer MariaDB, il faut lancer les commandes suivantes :

# pkg_add mariadb-server
# /usr/local/bin/mysql_install_db

La deuxième commande prépare la base de données par défaut et les fichiers dont MariaDB aura besoin.

On démarre mysql :

# rcctl enable mysqld
# rcctl start mysqld

Très importante, la commande suivante permet de sécuriser un minimum l'installation de mysql :

# /usr/local/bin/mysql_secure_installation

Donner un mot de passe fort pour l'utilisateur root, et suivez les recommandations. Cela ressemblera à ça :

Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.

You already have a root password set, so you can safely answer 'n'.

Change the root password? [Y/n] n
 ... skipping.

By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MySQL comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
ERROR 1008 (HY000) at line 1: Can't drop database 'test'; database doesn't exist
 ... Failed!  Not critical, keep moving...
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MySQL
installation should now be secure.

Thanks for using MySQL!

MariaDB devra être accessible par le serveur web. Ce dernier étant dans un chroot, on lance la commande suivante qui nous permet de reproduire la structure de la racine tout en attribuant les droits nécessaires pour l'utilisateur _mysql :

# install -d -m 0711 -o _mysql -g _mysql /var/www/var/run/mysql

Il faut en plus mettre ces lignes dans le fichier /etc/my.cnf, afin de modifier les chemins pour le serveur httpd :

[client]
    socket = /var/www/var/run/mysql/mysql.sock

[mysqld]
    socket = /var/www/var/run/mysql/mysql.sock

Enfin, on relance mysql :

# rcctl restart mysqld

À partir de ce moment, vous pouvez créer et utiliser des bases de données avec MariaDB.

À titre d'exemple, on va créer une nouvelle base de données pour Wordpress. Adaptez-le à votre cas.

Entrez la commande "# mysql -u root -p" afin "d'entrer" dans MariaDB (MySQL). Les commandes à exécuter sont indiquées ci-dessous avec la réponse attendue :

# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 10.0.23-MariaDB-log openBSD port: mariadb-server-10.0.23p0v1

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> CREATE DATABASE wordpress_base;
Query OK, 1 row affected (0.01 sec)

MariaDB [(none)]> CREATE USER 'wp'@'localhost' IDENTIFIED BY 'motdepasse';
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> GRANT ALL PRIVILEGES ON wordpress_base.* TO 'wp'@'localhost';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> exit
Bye

Et voilà, vous pouvez utiliser cette base dans votre application.

Quelques explications tout de même :

Pour sauvegarder une base MariaDB ou MySQL, (ça s'appelle un "dump") on utilise la commande suivante:

# mysqldump -u root -p nom-de-la-base > /var/sauvegarde/base-sauvee

Bien entendu, vous aurez adapté cette commande en changeant root pour le nom d'utilisateur qui a accès à cette base ainsi que le nom de la base. Normalement, root a accès à toutes les bases.

Le mot de passe à entrer est celui de l'utilisateur.

Pour restaurer la base de données plus tard, cela se fait en trois étapes :

# mysql -u root -p -e "DROP DATABASE nom-de-la-base
# mysql -u utilisateur -e "CREATE DATABASE nom-de-la-nouvelle-base
# mysql -u utilisateur -p nom-de-la-nouvelle-base < /var/sauvegarde/base-sauvee

Vous aurez remarqué le sens du chevron "<" qui est en sens inverse lors de la restauration.

PostgreSQL §

PostgreSQL est un autre moteur de base de données, entièrement libre.

Pour l'installer, il faut le paquet postgresql-server.

Afin de l'utiliser avec PHP, installez php-pgsql-* et php-pdo_pgsql-*. Veillez à bien lire le contenu du fichier /usr/local/share/doc/pkg-readmes/postgresql*.

Ensuite, créez une base par défaut :

# su - _postgresql
$ mkdir /var/postgresql/data
$ initdb -D /var/postgresql/data -U postgres -A scram-sha-256 -E UTF8 -W
$ exit

L'utilisateur par défaut s'appelle donc postgres.

Des options supplémentaires seront à adapter à votre cas dans le fichier /var/postgresql/data/postgresql.conf.

Par exemple, pour que le serveur httpd qui est enfermé dans un chroot puisse accéder à la base :

unix_socket_directories = '/var/www/tmp/postgresql, /tmp'

Les permissions sur ce dossier doivent d'ailleurs être modifiées ainsi pour que postgresql puisse écrire dedans :

# mkdir -p /var/www/tmp/postgresql
# chown _postgresql:www /var/www/tmp/postgresql

Démarrez le serveur postgresql avec :

# rcctl enable postgresql
# rcctl start postgresql

Pour se connecter à postgresql, on utilise la commande :

# su _postgresql -c psql

Voici quelques commandes permettant de gérer PostgreSQL.

Modifier le mot de passe administrateur :

# psql -U postgres -c "ALTER USER postgres WITH PASSWORD 'mot_de_passe'";

Ajouter un utilisateur nommé "toto" à la base :

# psql -U postgres -c "CREATE USER toto WITH PASSWORD 'mot_de_passe';"

Créer une nouvelle base et donner à toto tous les droits dessus :

# psql -U postgres 
\connect template1
CREATE DATABASE "nouvelle_base" WITH ENCODING 'UTF-8';
GRANT ALL PRIVILEGES ON DATABASE "nouvelle_base" TO toto;
ALTER DATABASE "nouvelle_base" OWNER TO toto;
\q

La sauvegarde d'une base de données avec PostgreSQL est bien pensée. Vous allez enregistrer dans un fichier toutes les instructions permettant à PostgreSQL de créer une base identique si besoin.

La sauvegarde dans un fichier n'est pas très compliquée et se déroule ainsi :

# pg_dump nom-de-la-base > /var/sauvegarde

Et pour restaurer la base plus tard, il faut procéder ainsi :

# psql -U postgres nom-de-la-base < /var/sauvegarde

Services WEB à héberger §

Il existe de multiples applications à héberger : Wiki, Blog, CMS, Webmail...

Très souvent, cela nécessite PHP et parfois une base de données.

⚠ Puisque les applications reçoivent des mises à jour de sécurité, il faudra veiller à vous renseigner pour être toujours à la dernière version. Ça peut être une bonne idée de s'abonner au flux RSS ou mailing lists du projet officiel pour recevoir les annonces de mise à jour disponibles. Les instructions des développeurs de chaque application seront donc à suivre.

La méthode d'installation est à peu près toujours la même :

Sélection de quelques applications §

Puisqu'il existe des tas d'outils disponibles, je vous propose ici une sélection que je trouve intéressante. La priorité est donnée aux applications déjà empaquetées par les développeurs OpenBSD via les ports pour profiter ainsi des ajustements qu'ils ont réalisés. Ensuite, on privilégie légèreté : on s'auto-héberge, donc on n'a pas forcément du matériel très puissant. Enfin, je vous propose autant que possible des outils ne nécessitant pas de base de données ou SQLite pour profiter de la simplicité que cela représente.


CLOUD :

NextCloud. Installez le paquet "nextcloud" puis lisez /usr/local/share/doc/pkg-readme/nextcloud. 😁 Ça a tant évolué que c'est devenu une boîte à outils pour à peu près tout qui complète l'hébergement de documents : mail, chat, visio, ...

https://nextcloud.com/


WIKI:

Dokuwiki. Installez le paquet du même nom puis lisez /usr/local/share/doc/pkg-readme/dokuwiki. Ce n'est pas qu'un wiki, mais peut aussi servir de moteur de blog, de CMS... C'est absolument génial.

https://www.dokuwiki.org/dokuwiki

Recommandations de sécurité :

https://www.dokuwiki.org/security

Intégration de dokuwiki à OpenBSD :

https://www.dokuwiki.org/install:openbsd


WEBMAIL :

SnappyMail. Simple à installer, on en parle plus loin.

https://snappymail.eu/

Roundcube est présent dans les ports, mais plus difficile à maintenir.

https://roundcube.net/

Squirrelmail, plus vieux mais je le recommande chaudement car plus simple mais léger et éprouvé, ce qui me semble parfait en auto-hébergement.

https://www.squirrelmail.org/

Voici quelques notes à propos de son installation :

/log/0-archives/2022-09-14-squirrelmail-nice-webmail.txt


BLOG :

PluXML ne nécessite aucune base de données, est simple mais puissant.

https://pluxml.org/


LECTEUR DE FLUX :

Kriss Feeds est aussi simple qu'efficace : un seul fichier php à déposer sur votre serveur et Hop!

http://www.tontof.net/kriss/feed/

FreshRSS est chouette aussi et a l'avantage d'être dans les ports.

https://www.freshrss.org/

Où trouver d'autres outils à auto-héberger ? §

Le site WAAH, Wiki des Applications Auto-Hébergées recense de nombreuses applications que l'on peut héberger sur son serveur.

https://waah.quent1.fr/

Il existe aussi alternative.to qui recense quelques projets.

https://alternativeto.net/platform/self-hosted/

En anglais, on peut évoquer le dépôt github "awesome-selfhosted" qui recense de nombreuses applications à auto-héberger.

https://github.com/Kickball/awesome-selfhosted

Pièces jointes avec un Webmail et limites d'uploads de fichiers §

Les pièces jointes ne doivent pas dépasser 35M par défaut avec le serveur mail smtpd. Vous devriez changer les valeurs suivantes dans la configuration avancée de php du fichier /etc/php-*.ini.

post_max_size = 35M
upload_max_filesize = 35M

Il faudra aussi le préciser dans le configuration de httpd : on augmente la taille maximale des pièces jointes que l'on voudra téléverser.

connection max request body 36700160

Statistiques des visites sur vos sites §

Webalizer §

Bien que Webalizer ne semble plus mis à jour, mais il continue de bien fonctionner.

http://www.patrickfrei.ch/webalizer/

Webalizer est un outil qui peut générer graphiques et tableaux à partir des logs (journaux) de votre serveur. En un clin d'œil vous pourrez trouver à propos de votre site :

D'autres outils similaires existent, en particulier matomo. Ce dernier est toutefois moins facile à mettre en place (base de données MySQL) et nécessite l'insertion de code html dans toutes vos pages web. Il est aussi moins efficace si les visiteurs utilisent des addons Firefox comme noscript ou μblock. Cependant, les données récoltées sont plus pertinentes. Vous voudrez donc peut-être compléter l'installation de webalizer avec matomo.

https://matomo.org/

Quoi qu'il en soit, nous allons voir ici une méthode pour obtenir de belles statistiques avec webalizer.

Comme d'habitude, on commence par l'installer avec la commande magique :

# pkg_add webalizer

Pour le configurer, nous allons utiliser comme base le modèle fourni. On le copie par exemple dans /etc/ :

# cp /usr/local/share/examples/webalizer/sample.conf /etc/webalizer.chezmoi.tld.conf

Éditez ce nouveau fichier pour l'adapter à vos besoins. Voici quelques options pratiques que vous voudrez certainement changer :

HTMLHead body {
HTMLHead background: radial-gradient(circle,#2569A0,#000046);
HTMLHead }

Vous trouverez un exemple de configuration de webalizer à la fin du document.

Vous pouvez générer une première fois les statistiques avec la commande suivante :

# webalizer -c /etc/webalizer.chezmoi.tld.conf

Et hop, toutes les pages html et les graphiques sont dans le dossier défini par la variable OutputDir, il suffit de vous y rendre avec un navigateur web pour les étudier.

Cependant, vous devrez régler encore quelques petits détails. Par exemple, la partie des "Referers" qui recense les sites sur lesquels le votre est cité doit être bien maigre. Il faut régler la façon dont httpd produit les logs. Rien de bien compliqué, il faut juste ajouter dans le fichier /etc/httpd.conf la ligne suivante dans le site pour lequel on veut des statistiques : log style combined.

Euh, on peut avoir un exemple siouplé ? 😎

Le voici :

server "chezmoi.tld" {
    listen on * tls port 443
    root "/htdocs/chezmoi.tld"
    directory index index.html
    log style combined
}

N'oubliez pas de recharger httpd avec "# rcctl reload httpd".

Mais on doit lancer la commande webalizer manuellement ? C'est nul ce truc !

On n'en reste pas là bien entendu. Afin que les statistiques soient générées par exemple tous les jours, nous pourrions profiter du fichier /etc/daily.local.

De plus, il faut éviter que les logs n'aient été archivés avant d'avoir été traités par webalizer. Nous allons donc modifier la configuration de l'outil qui compresse les logs régulièrement. Il s'agit de newsyslog. On édite le fichier /etc/newsyslog.conf qui ressemble à ça :

# $OpenBSD: newsyslog.conf,v 1.34 2015/10/14 20:54:07 millert Exp $
#
# configuration file for newsyslog
#
# logfile_name      owner:group     mode count size when  flags
/var/cron/log       root:wheel      600  3     10   *     Z
/var/log/aculog     uucp:dialer     670  7     *    24    Z
/var/log/authlog    root:wheel      640  7     *    168   Z
/var/log/daemon                     640  5     30   *     Z
/var/log/lpd-errs                   640  7     10   *     Z
/var/log/maillog                    640  7     *    24    Z
/var/log/messages                   644  5     30   *     Z
/var/log/secure                     600  7     *    168   Z
/var/log/wtmp                       644  7     *    $W6D4 B
/var/log/xferlog                    640  7     250  *     Z
/var/log/pflog                      600  3     250  *     ZB "pkill -HUP -u root -U root -t - -x pflogd"
/var/www/logs/access.log            644  4     *    $W0   Z "pkill -USR1 -u root -U root -x httpd"
/var/www/logs/error.log             644  7     250  *     Z "pkill -USR1 -u root -U root -x httpd"

C'est l'avant-dernière ligne que nous allons changer afin de lancer webalizer avant de faire tourner les logs du serveur web (http). Elle ressemblera à :

/var/www/logs/access.log            644  4     *    $W0   Z "/usr/local/bin/webalizer -c /etc/webalizer.chezmoi.tld.conf && pkill -USR1 -u root -U root -x httpd"

Pour vérifier que tout fonctionne bien, lancez newsyslog en le forçant à archiver les logs et en le faisant parler. Vous devriez obtenir quelque chose de la sorte :

# newsyslog -vF
/var/cron/log <3Z>: size (KB): 0.07 [10] --> trimming log....
/var/log/authlog <7Z>: age (hr): 0 [168] --> trimming log....
/var/log/daemon <5Z>: size (KB): 0.07 [300] --> trimming log....
/var/log/lpd-errs <7Z>: size (KB): 0.07 [10] --> trimming log....
/var/log/maillog <7Z>: age (hr): 0 [24] --> trimming log....
/var/log/messages <5Z>: size (KB): 0.11 [300] --> trimming log....
/var/log/secure <7Z>: age (hr): 0 [168] --> trimming log....
/var/log/wtmp <7B>: --> trimming log....
/var/log/xferlog <7Z>: size (KB): 0.07 [250] --> trimming log....
/var/log/pflog <3ZB>: size (KB): 0.02 [250] --> trimming log....
/var/www/logs/access.log <4Z>: --> trimming log....
/var/www/logs/error.log <4Z>: size (KB): 0.07 [250] --> trimming log....
/var/www/logs/mateteestmalade.log <4Z>: size (KB): 0.07 [250] --> trimming log....
/var/www/logs/si3t.ch.log <4Z>: size (KB): 0.72 [250] --> trimming log....
/var/www/logs/puffy.cafe.log <4Z>: size (KB): 0.57 [250] --> trimming log....
/var/log/rspamd/rspamd.log <5Z>: size (KB): 0.07 [300] --> trimming log....
/var/prosody/prosody.log <5Z>: size (KB): 0.07 [300] --> trimming log....
/var/prosody/prosody.err <5Z>: size (KB): 0.07 [300] --> trimming log....
/var/log/vger.log <5Z>: size (KB): 0.07 [300] --> trimming log....
Webalizer Xtended RB30 (06-Apr-2014) / OpenBSD 7.3 amd64 / English
Copyright 2005-2014 by Patrick K. Frei
Based on Webalizer V2.23-08
Using logfile /var/www/logs/puffy.cafe.log (clf)
Creating output in /var/www/htdocs/solene/puffy.cafe/stats/
Hostname for reports is 'webzine.puffy.cafe'
Reading history file... webalizer.hist
Reading previous run data.. webalizer.current
Skipping bad record (1)
No valid records found!
Generating summary report
Webalizer Xtended RB30 (06-Apr-2014) / OpenBSD 7.3 amd64 / English
Copyright 2005-2014 by Patrick K. Frei
Based on Webalizer V2.23-08
Using logfile /var/www/logs/si3t.ch.log (clf)
Creating output in /var/www/htdocs/si3t.ch/stats/
Hostname for reports is 'si3t.ch'
Reading history file... webalizer.hist
Reading previous run data.. webalizer.current
Skipping bad record (1)
No valid records found!
Generating summary report

Il y a les messages de webalizer qui montrent qu'il a été exécuté.

Et voilà, les statistiques sont générées régulièrement et avant que les logs ne soient archivés.

goaccess §

Plus proche de webalizer que de Matomo dans son fonctionnement, goaccess propose une interface plus moderne. En effet, les images générées par webalizer sont peu lisibles et manquent d'interactivité. Il peut en outre générer des rapports au format html, mais aussi vous laisser consulter les statistiques en temps-réel.

https://goaccess.io/

Pour l'installer, rien de plus simple :

# pkg_add goaccess

Je vous propose ici d'utiliser goaccess pour générer des statistiques toutes les heures. Un historique sera conservé afin de voir l'évolution au fil du temps.

On part du principe que les logs de httpd sont au format "combined" et enregistrés dans /var/www/logs/chezmoi.tld.log.

# extrait de httpd
server "chezmoi.tld" {
    root "/htdocs/chezmoi.tld"
    log style combined
    log access "chezmoi.tld.log"
    ...

Afin de générer les statistiques avant l'archivage des logs par newsyslog, on écrira un script qui appelle goaccess avec les bonnes options, notamment celle permettant de l'exécuter en tant qu'utilisateur simple (pas root).

On va éditer le fichier de configuration pour goaccess situé dans /etc/goaccess/goaccess.conf. Vous devriez avoir les lignes suivantes au moins :

# format des [logs #logs]
date-format %d/%b/%Y
time-format %T %z
log-format %v %h %^ %^ [%d:%t] "%r" %s %b "%R" "%u"
# Dossier où seront enregistrees les statistiques
persist true
restore true

On crée le dossier qui contiendra l'historique de goaccess :

# mkdir -p /var/db/goaccess/chezmoi.tld.

Ce dossier doit appartenir à l'utilisateur qui dépose les fichiers sur le site. Pour l'exemple, on dira qu'il s'agit de "www".

# chown www /var/db/goacess/chezmoi.tld

Voici un script qu'on nommera "goaccess-chezmoi.tld" qui permettra de générer les statistiques. Pensez à modifier les premières lignes pour qu'il corresponde à vos besoins. Ici, il génère les statistiques dans une page nommée "goaccess.html" à la racine du site "chezmoi.tld". Les logs du site sont dans le fichier /var/www/logs/chezmoi.tld.log.

#!/bin/sh
# generate goaccess stats

out=/var/www/htdocs/chezmoi.tld/goaccess.html
db=/var/db/goaccess/chezmoi.tld
log=/var/www/logs/chezmoi.tld.log
u=www

/usr/local/bin/goaccess $log \
    -o $out \
    --db-path=$db \
    --user-name=$u \
    --persist \
    --restore

Vous pouvez appeler ce script via une tâche cron.

Par contre, il sera important de générer les statistiques avant l'archivage des logs. Aussi, dans le fichier /etc/newsyslog.conf, on trouvera :

/var/www/logs/chezmoi.tld.log    644  7    250  $W0   Z  "/usr/local/bin/goaccess-chezmoi.tld && pkill -USR1 -u root -U root -x httpd"

Table des matières

Donate