Comment héberger son serveur avec OpenBSD ?

Vous êtes sur le point de plonger dans l'univers de l'auto-hébergement. Ce document va vous aider à héberger chez vous ou sur un serveur dédié certains services malheureusement trop souvent confiés à des tiers. L'objectif est de vous guider dans la découverte de ces notions le plus simplement possible tout en apprenant de nouvelles choses 😎. Bien sûr, vulgariser l'auto-hébergement entraîne des compromis. Si lire les notions évoquées ici vous a donné envie d'en apprendre davantage, alors l'objectif est atteint 😊.

Pourquoi OpenBSD?

Afin que ce voyage soit le plus confortable possible, nous décrirons l'utilisation du système OpenBSD dans sa dernière version stable. Ce dernier est réputé pour être sûr. Il est aussi, à mon avis, nettement plus simple à configurer que d'autres systèmes. En effet, de nombreux services sont déjà intégrés et se configurent avec une syntaxe semblable.

Site officiel OpenBSD

Why OpenBSD rocks : pourquoi OpenBSD est génial?

Il paraît que la documentation d'OpenBSD est de grande qualité. À quoi va servir ce manuel alors?

C'est vrai, les pages man sont excellentes : je vous encourage à vous y référer dès que possible. Cette documentation est un point d'entrée qui a l'avantage d'être francophone. J'espère aussi qu'elle permettra de faciliter certains concepts plus fondamentaux en y ajoutant quelques astuces.

Vous verrez que s'auto-héberger n'est finalement pas si difficile et consiste en grande partie à modifier du texte dans des fichiers. Cette démarche devrait donc être accessible à tous.

Alors, prêt à plonger ?

L'auto-hébergement : c'est quoi? Avantages et inconvénients

La plupart des sites web que vous avez l'habitude de consulter (vos courriels, les réseaux sociaux...) sont hébergés sur des ordinateurs quelque part dans le monde. Ces derniers ne servent qu'à proposer des services et du contenu à d'autres ordinateurs. On les appelle donc des "serveurs". La seule différence notable pour la plupart des gens est qu'ils ne sont en général pas reliés à un écran.

Lorsque vous voulez consulter vos e-mails, votre client mail (le webmail, Thunderbird...) va chercher sur un serveur tous vos messages. Une COPIE de ces derniers est alors téléchargée vers votre ordinateur. C’est comme si pour lire votre courrier postal, vous deviez aller dans une agence pour demander au facteur :

Y a-t-il du courrier pour moi?

Oui, une carte postale de ta maman. Je te la donne dès que la photocopieuse a terminé de l'imprimer.

Bien sûr, on peut demander au bureau de poste de détruire la copie originale qu'il possède de vos messages et espérer qu'il n'avait pas fait une autre copie ailleurs.

Autant dire que cette situation nous semble inacceptable. C'est pourtant ainsi que ça se passe avec votre fournisseur de messagerie ou lorsque vous consultez un site web.

Autant devenir son propre bureau de poste 😁.

À l'origine, chacun pouvait constituer un nouveau noeud au web. Aujourd'hui, la majeure partie de notre utilisation d'internet dépend de sociétés tierces peu soucieuses de votre vie privée.

Avantages

Héberger chez soi les services que l'on utilise présente plusieurs avantages :

Prétendre que votre droit à une sphère privée n'est pas important parce que vous n'avez rien à cacher n'est rien d'autre que dire que la liberté d'expression n'est pas essentielle car vous n'avez rien à dire. -- E. Snowden

Lire à propos de l'argument "Je n'ai rien à cacher".

Inconvénients

Cependant, cette démarche n'est pas sans inconvénients :

À propos du contenu et de la syntaxe de cette documentation

Notations utilisées

Afin de bien se comprendre et réussir à vous auto-héberger sans tracas, on suppose dans ce document que :

À propos et licence

Cet ouvrage est publié sous licence CC-BY à l'aide de fichiers au format "gemtext" (texte brut), convertit avec "gmi2xhtml.awk" et un Makefile. Il a été écrit par un libriste curieux (et des contributeurs) qui s'est dit "si moi j'y arrive, pourquoi pas les autres ?". Merci de prévenir si vous partager ce texte ailleurs, juste pour information 😉.

Si vous trouvez une erreur, souhaitez contribuer ou avez besoin d'aide, n'hésitez pas à me contacter.

Licence CC BY

gmi2xhtml.awk

Site de l'auteur

Contacter l'auteur

Il n'y a aucune publicités ou scripts de profilage (tracker) sur ce site.

Ce n'est que grâce à votre aide que je peux financer l'hébergement et le temps consacré à cet ouvrage.

Si vous voulez et pouvez m'encourager, vous pouvez faire un don ♥. Merci! 😃

N'hésitez pas à imprimer cet ouvrage si vous le souhaitez, sur papier ou en PDF 🌳. Le code CSS a été spécialement concu pour un rendu de qualité à l'impression 😉.

Et la documentation officielle?

Ce document ajoute des éléments par rapport à la FAQ officielle, en simplifie d'autres et parfois en traduit tout simplement.

Gardez en tête qu'en cas de doute, seule la documentation et les manpages officielles font foi.

Alors n'hésitez pas à la consulter en ligne.

Il en va de même pour les manpages présentes sur le système 😉.

Sinon, je tiens à jour une archive à télécharger de la FAQ officielle pour ceux qui souhaitent la garder sous le coude.

FAQ officielle d'OpenBSD

openbsd-faq.tgz : à télécharger et extraire pour lire hors-ligne

Quel matériel utiliser ?

Vous n'avez pas besoin d'une puissance phénoménale pour vous auto-héberger. Commencez plutôt à vous faire la main avec une machine récupérée car trop peu puissante pour une utilisation bureautique.

Si vous souhaitez investir dans du nouveau matériel, je vous conseille de vérifier la compatibilité avec OpenBSD. Ça évite une mauvaise surprise et un coup de pas-de-chance 😉. Pour cela, le plus simple reste de demander aux utilisateurs d'OpenBSD.

La liste du matériel supporté, classé par architecture, est disponible sur la FAQ officielle (lien)

Mon petit coup de cœur ? Les architectures arm car très peu gourmandes en énergie. Je recommande aussi la carte APU2 dont je parle plus loin, (apu2d0), économe, peu chère et fiable. C'est sur ce matériel que cette documentation est hébergée. 😊

Page officielle d'OpenBSD concernant l'architecture arm64

Enfin, jetez un oeil au projet bsd-hardware et n'hésitez pas à y participer.

Quid d'OpenBSD sur Raspberry Pi ?

À partir de la version 3 du raspberry pi en choisissant l'architecture arm64, OpenBSD peut supporter ce matériel. Tout est expliqué sur la page précédente puisqu'il faut avoir quelques fichiers permettant le bon démarrage du RPi et il est possible de les placer sur une clé USB.

Vous trouverez encore davantage de conseils sur le fichier INSTALL.amd64.

Exemple d'installation d'OpenBSD

Cette section est là pour vous rassurer.

Pour des informations plus complètes, n'hésitez pas à consulter la documentation officielle concernant l'installation d'OpenBSD.

Par la suite, vous changerez "XX" par le numéro de version d'OpenBSD souhaité/utilisé. Par exemple "69" pour OpenBSD 6.9.

Préparation

On télécharge tout d'abord l'image d'installation de la dernière version d'OpenBSD.

Utilisez un des miroirs de téléchargement.

Choisissez une image ".iso" pour une installation à partir d'un CD.

Je décrirai ci-dessous l'installation à partir d'une clé USB : je télécharge donc "installXX.img".

N'oubliez pas de vérifier la somme de contrôle. Téléchargez le fichier SHA256 listé dans le lien ci-dessus, puis à partir d'un système OpenBSD, utlisez cette commande :

signify -Cp /etc/signify/openbsd-XX-base.pub -x SHA256.sig install*.img

Sinon, sur un autre système, calculez la somme de contrôle "sha256sum" puis comparez avec le contenu du fichier SHA256.

Pour préparer une clé USB, utilisez l'outil "dd" (remplacez /dev/sdb par le chemin vers votre clé USB). Par exemple sur un système GNU/Linux (remarquez le "M" majuscule):

# dd if=/location/install*.img of=/dev/sdb bs=1M 

À partir d'OpenBSD :

# dd if=/location/install*.img of=/dev/rsd1c bs=1m 

La commande dd va reproduire le contenu de l'image sur la clé USB. Pour éviter d'avoir à écrire le nom exact de l'image d'installation, on utilise le symbole "*" qui veut dire "n'importe quelle suite de caractères". Les autres options servent au bon fonctionnement du transfert.

Bien sûr, vous remplacerez "sdb" ou "sd1" par ce qui correspond à votre clé USB. Vérifiez avec la commande "dmesg" juste après avoir inséré votre clé USB.

Vous pouvez récupérer un outil graphique nommé "etcher" pour préparer la clé USB plus sereinement si la commande dd ne vous plaît pas.

Les utilisateurs de Windows pourront faire la même chose avec le logiciel "rufus".

Et hop, on insère tout ça dans le lecteur ou port USB du PC, puis on redémarre sur le bon disque ("boot" en anglais). Repérez les messages qui s'affichent du type "F12 : Boot Menu" ou "F7 : Setup" indiquant les touches qui permettent de faire apparaître les fenêtres (bleues) des tableaux de réglage du BIOS. On y indique souvent le lecteur de CDROM ou la clef USB comme média de démarrage numéro 1.

Si au cours de la configuration de l'installation vous vous trompez, pas de panique. Appuyez sur ctrl-C puis entrez la commande "install" afin de recommencer la configuration au début en retrouvant vos choix précédents.

Le premier écran nous propose d'ajouter des options pour démarrer OpenBSD. Normalement, on n'en a pas besoin, on appuie donc juste sur "Entrée" :

>> OpenBSD/amd64 BOOT 3.47
boot> 

Si votre machine a un port série, vous avez besoin d'un retour console. Vous devrez alors préciser ces options :

>> OpenBSD/i386 PXEBOOT 1.00
boot> stty com0 19200
boot> set tty com0
boot> <Appuyez sur entree>

Plein de texte sur fond bleu apparaît, indiquant la détection du matériel et autres choses qui ne doivent pas vous inquiéter.

Ensuite, l'écran suivant apparaît :

erase ^?, werase ^W, kill ^U, intr ^C, status ^T
Welcome to the OpenBSD/amd64 6.7 installation program.
(I)nstall, (U)pgrade, (A)utoinstall or (S)hell?

Installation 100% chiffrée

Si un jour votre serveur est volé par un méchant cambrioleur, vos données peuvent rester illisibles si vous chiffrez l'ensemble de votre système. Tout est bien pensé par OpenBSD qui a décrit la procédure dans sa FAQ. Notez que vous devrez être en mesure d'entrer la phrase de déchiffrement du disque à chaque démarrage et redémarrage du serveur, ce qui peut être une contrainte pour certains. Dans ce cas, passez à l'étape suivante.

⚠ À ce propos, le mappage du clavier à l'invite de commande demandant le mot de passe est en QWERTY. (sauf si vous gérer votre serveur via un port série).

Documentation officielle pour chiffrer un disque

Notez que la procédure serait la même si vous souhaitez chiffrer un autre disque de stockage.

À l'invite suivante, choisissez "S".

Welcome to the OpenBSD/amd64 X.X installation program.
(I)nstall, (U)pgrade, (A)utoinstall or (S)hell? s

Si vous souhaitez passer l'agencement du clavier pour azerty, entrez

kbd fr

On fait en sorte que l'accès aux disques soit possible :

# cd /dev && sh MAKEDEV sd0

On remplit le disque de zéros pour écraser toutes les données pré-existantes (sd0 correspond à votre disque dur ici):

# dd if=/dev/urandom of=/dev/rsd0c bs=1m

Ça peut être long selon le matériel (taille et vitesse d'écriture).

Ensuite, on crée une partition softraid qui sera chiffrée :

Créez la table de partition sur sd0. On utilise une partition entière "a" de type RAID:

# disklabel -E sd0
Label editor (enter '?' for help at any prompt)
> a a         
offset: [64]
size: [39825135] *
FS type: [4.2BSD] RAID
> w
> q
No label changes.

Ensuite, on peut créer le périphérique chiffré avec une bonne phrase de passe :

# bioctl -c C -l sd0a softraid0
New passphrase:
Re-type passphrase:
sd1 at scsibus2 targ 1 lun 0: <OPENBSD, SR CRYPTO, 005> SCSI2 0/direct fixed
sd1: 19445MB, 512 bytes/sector, 39824607 sectors
softraid0: CRYPTO volume attached as sd1

Cela crée un pseudo-périphérique sd1. Pour être sûr que l'installateur le prenne en compte, lancez :

# cd /dev && sh MAKEDEV sd1

On écrase les premières données du pseudo-périphérique :

# dd if=/dev/zero of=/dev/rsd1c bs=1m count=1

Enfin, entrez "exit" pour retrouver l'installateur et procéder à l'installation sur ce pseudo-périphérique sd1.

Début du script d'installation

On lance l'installation en entrant "I" :

Les valeurs proposées pour l'installation sont largement suffisantes dans la plupart des cas. Les choix par défaut sont indiqués entre crochets : [choix]. À chaque fois, des exemples sont disponibles avec "?".

On choisit une disposition de clavier : fr

At any prompt except password prompts you can escape to a shell by typing '!'.
Default answers are shown in []'s and are selected by pressing RETURN.  
You can exit this program by pressing Control-C, 
but this can leave your system in an inconsistent state.
Choose your keyboard layout ('?' or 'L' for list) [default] fr

On choisit ensuite un nom de machine, par exemple "maitre.chezmoi.tld" ou "maitre".

System hostname? (short form, e.g. 'foo')

Ensuite, on configure la connexion à Internet. Notez qu'il n'est pas obligatoire d'avoir un accès en ligne si vous avez choisi une image install*.* qui contient tous les éléments pour faire l'installation.

Vous avez la possibilité de définir une IP statique pour votre serveur ou bien utiliser la configuration DHCP par facilité.

Available network interfaces are: re0 vlan0.
Which network interface do you wish to configure? (or 'done') [re0]
IPv4 address for re0? (or 'dhcp' or 'none') [dhcp]
DHCPDISCOVER on re0 - interval 1
DHCPOFFER from 10.0.2.2 (52:55:01:00:02:02)
DHCPREQUEST on re0 to 255.255.255.255
DHCPACK from 10.0.2.2 (52:55:01:00:02:02)
bound to 10.0.2.15 -- renewal in 43200 seconds.

Pour avoir une IPv6, choisissez autoconf le moment venu pour en avoir une automatiquement. Vous souhaiterez certainement configurer cette partie par la suite.

IPv6 address for re0? (or 'autoconf' or 'none') [none] autoconf
Available network interfaces are: re0 vlan0.
Which network interface do you wish to configure? (or 'done') [done]

La configuration réseau se termine par la route IPv4 et le DNS. Laissez les choix par défaut à moins d'avoir un besoin très particulier :

Default IPv4 route? (IPv4 address or none) [10.0.2.2]
add net default: gateway 10.0.2.2
DNS domain name? (e.g. 'bar.com') [my.domain]
Using DNS nameservers at 10.0.2.3

Gardez en tête votre passerelle (gateway) si vous configurez plus tard une connexion statique.

Ensuite, l'installateur vous demande le mot de passe de l'administrateur système dont le petit nom est "root". Choisissez un mot de passe robuste.

Password for root account? (will not echo)
Password for root account? (again)

Vous pouvez ensuite faire en sorte que SSH soit lancé par défaut au démarrage. C'est conseillé pour un serveur afin de pouvoir l'administrer sans écran à partir d'un autre ordinateur.

On nous demande si un serveur X sera utilisé (session graphique) : ce n'est absolument pas nécessaire pour un serveur.

Vous ne voudrez sans doute pas changer la console par défaut, laissez "no".

Password for root account? (will not echo)
Password for root account? (again)
Start sshd(8) by default? [yes]
Do you expect to run the X Window System? [yes] no
Change the default console to com0? [no]

Vous pouvez ajouter un utilisateur si vous le souhaitez en entrant son login. Vous n'êtes pas obligés, mais je vous le conseille pour vous connecter à votre serveur via SSH. Ainsi, vous éviterez d'utiliser le compte root.

Setup a user? (enter a lower-case loginname, or 'no') [no] luffy
Full name for user luffy? [luffy] Mugiwara No Luffy
Password for user luffy? (will not echo)
Password for user luffy? (again)

On vous demande ensuite si vous voulez autoriser l'utilisateur "root" à se connecter via SSH. C'est une très mauvaise idée, puisque cet utilisateur a tous les droits et est la cible privilégiée des pirates. Choisissez "no".

WARNING: root is targeted by password guessing attacks, pubkeys are safer.
Allow root ssh login? (yes, no, prohibit-password) [no]

Le fuseau horaire peut être modifié :

What timezone are you in? ('?' for list) [Canada/Mountain] Europe/Paris

C'est parti pour le choix du disque sur lequel installer OpenBSD :

Which disk is the root disk? ('?' for details) [wd0]
Use (W)hole disk MBR, whole disk (G)PT, (O)penBSD area or (E)dit? [whole]

Après avoir appuyé sur Entrée, vous voyez :

Disk: wd0      geometry: 2610/255/63 [41943040 Sectors]
Offset: 0      Signature: 0xAA55
    		Starting         Ending     LBA Info:
    #: id     C   H   S -      C   H  S [    start:     size ]
-----------------------------------------------------------------
    0: 00     0   0   0 -      0   0  0 [        0:        0 ] unused
    1: 00     0   0   0 -      0   0  0 [        0:        0 ] unused
    2: 00     0   0   0 -      0   0  0 [        0:        0 ] unused
*3: A6     0   1   2 -   2609 254 63 [       64: 41929586 ] OpenBSD
Use (W)hole disk MBR, whole disk (G)PT, (O)penBSD area or (E)dit? [W]

Nous voilà à la partie sans doute la plus complexe : le partitionnement. Notez que celui par défaut proposé par l'installateur conviendra dans la majorité des cas. À moins de savoir ce que vous faîtes, faîtes confiance à l'installateur, il est assez intelligent.

Je tape donc "W" (ou "G") dans la suite pour utiliser le disque entier, puis "A" pour le partitionnement automatique.

Vous pouvez modifier le partitionnement par défaut en entrant "E".

Setting [OpenBSD https://www.openbsd.org/] MBR partition to whole wd0...done.
The auto-allocated layout for wd0 is :
#            size     offset  fstype [fsize bsize   cpg]
    a:   738.1M         64  4.2BSD   2048 16384     1 # /
    b:   223.8M    1511648  swap
    c: 20480.0M          0  unused
    d: 172.9.1M    1969888  4.2BSD   2048 16384     1 # /tmp
    e:  1791.0M    4372032  4.2BSD   2048 16384     1 # /var
    f:  1558.1M    8040032  4.2BSD   2048 16384     1 # /usr
    g:   906.8M   11230976  4.2BSD   2048 16384     1 # /usr/X11R6
    h:  3364.2M   13088192  4.2BSD   2048 16384     1 # /usr/local
    i:  1287.2M   19977984  4.2BSD   2048 16384     1 # /usr/src
    j:  1826.5M   22614208  4.2BSD   2048 16384     1 # /usr/obj
    k:  7604.8M   26354784  4.2BSD   2048 16384     1 # /home
Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout? [a] e

Ensuite, vous pouvez lire le manuel de disklabel si vous êtes perdus.

Il faut en général indiquer une action (avec une lettre) à réaliser sur la partition où il faudra l'effectuer.

Par exemple : la suite "d f (entrée)" permet de supprimer la partition f (delete f), qui était /usr, et "d k" pour supprimer le /home.

Ensuite, saisir "a f" permet de re-créer cette partition, et d'en définir la taille. Notez que vous pouvez définir une taille en pourcentage du disque (par exemple 50%) ou en pourcentage de l'espace libre restant (50&). Ici, je vais réduire le /home au profit de /usr qui prendra 75% de l'espace restant. De la même façon avec "a k", on re-crée /home à la taille souhaitée.

Use (A)uto layout, (E)dit auto layout, or create (C)ustom layout? [a] e
Label editor (enter '?' for help at any prompt)
> d f
> d k
> a f
offset: [26354784]
size: [15574867] 75&
FS type: [4.2BSD]
mount point: [none] /usr
> a k
offset: [38035904]
size: [3893746]
FS type: [4.2BSD]
mount point: [none] /home

Quand vous voulez, vous pouvez entrer p pour afficher les partitions actuelles, histoire de voir où vous en êtes.

> p 
OpenBSD area: 64-41929650; size: 41929586; free: 3190962
The auto-allocated layout for wd0 is :
#           size       offset  fstype [fsize bsize   cpg]
    a:     1511584           64  4.2BSD   2048 16384     1 # /
    b:      458240      1511648  swap
    c:    41943040            0  unused
    d:     2402144      1969888  4.2BSD   2048 16384     1 # /tmp
    e:     3678000      4372032  4.2BSD   2048 16384     1 # /var
    f:    11681120     26354784  4.2BSD   2048 16384     1 # /usr
    g:     1857216     11230976  4.2BSD   2048 16384     1 # /usr/X11R6
    h:     6889792     13088192  4.2BSD   2048 16384     1 # /usr/local
    i:     2636224     19977984  4.2BSD   2048 16384     1 # /usr/src
    j:     3740576     22614208  4.2BSD   2048 16384     1 # /usr/obj
    k:     3893728     38035904  4.2BSD   2048 16384     1 # /home

Quelques points à garder en tête :

Entrer "q" permet de valider les changements.

> q
Write new label?: [y]
newfs: reduced number of fragments per cylinder group from 94472 to 94096 to
enlarge last cylinder group
/dev/rwd0a: 738.1MB in 1511584 sectors of 512 bytes
5 cylinder groups of 114.559MB, 7334 blocks, 14720 inodes each
...
...
/dev/wd0a (8c0364801ae0817e.a) on /mnt type ffs  \
    (rw, asynchronous,local, nodev, nosuid)
/dev/wd0k (8c0364801ae0817e.k) on /mnt/home type ffs  \
    (rw, asynchronous,local, nodev, nosuid)
...
...

Enfin l'installation des composants du système peut commencer. L'installateur doit savoir où aller les chercher : sur le cdrom d'installation (cd0), la clé USB d'installation (disk) ou directement sur un miroir de téléchargement (http). Choisissez cd0 ou disk si vous installez avec une image install*.* ou bien http en cas de doute.

Petite astuce pour choisir un miroir si ça vous intéresse. Entrez "?" pour avoir la liste numérotée des serveurs disponibles. Quittez cette liste avec "q", puis entrez seulement le numéro du miroir que vous souhaitez utiliser.

Pour ajouter un set, saisissez simplement son nom, par exemple game67.tgz. Pour retirer un set, saisissez son nom précédé du signe moins : -game67.tgz. Ils ne prennent vraiment pas beaucoup de place, je vous conseille de tout laisser coché.

Let's install the sets!
Location of sets (cd0 disk http or 'done') [http]
HTTP proxy URL? (e.g. ’http://proxy:8080’, or ’none’) [none]
HTTP Server? (hostname, list#, ’done’ or ’?’) [ftp.fr.openbsd.org]
Server directory? [pub/OpenBSD/6.7/amd64]
Select sets by entering a set name, a file name pattern or ’all’. De-select
sets by prepending a ’-’ to the set name, file name pattern or ’all’. Selected
sets are labelled ’[X]’.
    [X] bsd     [X] base67.tgz  [X] game67.tgz    [X] xfont67.tgz
    [X] bsd.rd  [X] comp67.tgz  [X] xbase67.tgz   [X] xserv67.tgz
    [X] bsd.mp  [X] man67.tgz   [X] xshare67.tgz
Set name(s)? (or ’abort’ or ’done’) [done]

bsd.mp est le noyau optimisé pour les systèmes multi-processeurs, et bsd le noyau classique. C'est l'un ou l'autre qui est automatiquement utilisé, et non pas l'un en plus de l'autre. OpenBSD est suffisamment intelligent pour choisir le noyau optimisé si le matériel le permet, vous n'avez rien à faire.

Si vous installez les sets à partir du CD, un avertissement sur la signature apparaît. Rien d'inquiétant, vous pouvez dans ce cas continuer.

Directory does not contain SHA256.sig. Continue without verification? [no] yes

L'installation avance

Get/Verify SHA256.sig    100% |**************************| 2152        00:00
Signature Verified
Get/Verify bsd           100% |**************************| 10423 KB    00:14
Get/Verify bsd.rd        100% |**************************| 9215  KB    00:11
...
...
Installing base67.tgz    100% |**************************| 52181 KB
...
...
Installing xserv67.tgz    100% |**************************| 22686 KB
Location of sets? (cd0 disk http or 'done' [done]

Pour terminer, l'installateur s'occupe de la configuration et de générer un noyau unique :

Saving configuration files...done.
Making all device nodes...done.
Relinking to create a unique kernel...
CONGRATULATIONS! Your OpenBSD install has been successfully completed!
When you login to your new system the first time, please read your mail using the 'mail' command.
Exit to (S)hell, (H)alt or (R)eboot? [reboot]

Et voilà, l'installation est terminée, on valide le reboot pour redémarrer.

Lors du premier démarrage, éditez (créez) le fichier "/etc/installurl" puis assurez-vous d'avoir une ligne contenant le miroir choisi. Pour faire simple, autant utiliser le CDN d'OpenBSD qui vous redirigera automatiquement vers un serveur rapide :

https://cdn.openbsd.org/pub/OpenBSD

Normalement, le fichier est déjà présent et rempli. Vous pouvez passer à la suite 😄

Quelqu'un peut-il héberger OpenBSD pour moi?

Si vous n'avez pas un bon accès à internet à la maison, ou si vous voulez vous entraîner, vous pouvez louer un serveur ou une machine virtuelle. On notera notamment les fournisseurs suivants :

Openbsd.amsterdam

Vous disposez d'une machine virtuelle. Les administrateurs sont très sympatiques. Ils participent notamment au développement d'OpenBSD et reversent une partie des gains obtenus à OpenBSD.

vultr

Ce fournisseur propose d'installer OpenBSD. Ça fonctionne vraiment bien, c'est robuste et disponible en quelques clics. Un bon service pro. La facturation est différente de ce à quoi on peut être habitué : cela dépend de la quantité de données transférées.

ARP Networks propose aussi des machines virtuelles OpenBSD à prix abordables.

Il en existe d'autres bien évidemment si ces 3 ne vous conviennent pas.

Guide de survie : quelles commandes dois-je absolument connaître?

Lorsque vous allumerez votre serveur, qu'il soit relié à un écran ou au travers d'SSH, vous verrez une invite de commande :

acdc$ █

C'est en entrant des commandes avec votre clavier que vous administrerez votre serveur.

Bien sûr, il en existe beaucoup. Vous les découvrirez petit à petit selon vos besoin.

Pour l'instant, en voici quelques unes. Ne cherchez pas à retenir tout d'un coup : revenez piocher le moment venu.

Astuces

Astuce n°1 : Tab

En utilisant la touche "tabulation" ↹, vous pouvez compléter une commande ou un chemin vers un fichier. Commencer à en écrire le début puis appuyez sur ↹.

Tab, c'est in-dis-pen-sable ! 😉

Astuce n°2 : ctrl-c

Pour annuler ce que vous êtes en train d'écrire, appuyez simultanément sur "ctrl" et "c". ("cancel").

Astuce n°3 : "\"

Bien que ce soit très rare, il arrive que certains noms de fichier contiennent des espaces " ", voire des symboles un peu étranges. Or, un espace est considéré par l'invite de commande comme un séparateur entre les fichiers. Il risque donc de penser que vous faîtes référence à plusieurs fichiers au lieu d'un seul.

Utilisez alors "\" pour "échapper" le symbole bizarre. De cette façon, l'invite de commande va en quelque sorte l'ignorer. Par exemple :

/chemin/vers/un/fichier\ avec\ des\ espaces.txt

Dans tous les cas, évitez de créer des fichiers aux noms étranges.

Si vous devez en traiter un grand nombre, renseignez-vous sur l'outil "detox" (port du même nom).

Astuce n°4 : historique des commandes

Pour retrouver l'historique et relancer rapidement une ancienne commande, utilisez le raccourci ctrl-R.

Vous devez avant tout l'avoir activé en ajoutant export "HISTFILE=~/.history" dans le fichier "~/.profile" :

$ echo "export HISTFILE=~/.history" >> ~/.profile

Au prochain login, l'historique sera actif.

su et doas : comment devenir superutilisateur (root) ?

Entrez la commande "su -l" puis le mot de passe de l'utilisateur root.

ATTENTION : dans ce cas, votre utilisateur doit appartenir au groupe "wheel" pour que cela soit possible. C'est le cas du premier utilisateur créé sur un système.

Vous pouvez aussi configurer doas pour lancer une commande avec les droits superutilisateurs ainsi :

doas commande

Modifiez/créez le fichier /etc/doas.conf (doas.conf) pour y ajouter :

permit utilisateur

Adaptez "utilisateur" selon votre cas.

Voir aussi :

"man doas"

ls : lister le contenu d'un répertoire

Lancez "ls" suivi du chemin vers le dossier à lister (ou rien pour lister le dossier courant).

L'option "-l" permet aussi d'indiquer les permissions, propriétaires, tailles et dates de modification.

Exemple :

$ ls -l /etc
drwxr-xr-x  7 root  wheel        512 Apr 19 19:12 X11
drwx------  2 root  wheel        512 Apr 19 18:16 acme
-rw-r--r--  1 root  wheel       1542 Apr 13 15:39 acme-client.conf
-rw-r--r--  1 root  wheel       1764 Nov 28 13:56 adduser.conf
drwxr-xr-x  2 root  wheel        512 Apr 19 18:16 amd
drwxr-xr-x  2 root  wheel        512 Apr 19 18:16 authpf
-rw-r--r--  1 root  wheel         30 Aug  2  2020 boot.conf
[...]

On obtient une ligne par fichier/dossier. Chaque ligne est découpée de cette façon :

<permissions> <inode> <proprietaire> <groupe> <taille> <date dernier acces> <nom du ficher>

Une méthode simple et pourtant redoutable pour sécuriser son site web -- et plus généralement son serveur -- consiste à modifier les droits et le propriétaire des fichiers dudit site.

Lisez les parties sur "chmod" et "chown" pour en savoir plus.

chmod : changer les permissions

Regardons en détail ce que nous indique le retour de la commande "ls -l" vue précédemment.

Les lettres en début de ligne décrivent les permissions accordées au fichier. Nous pouvons retenir deux choses :

1. Si le premier caractère est un d, alors il s'agit d'un répertoire. Sinon, c'est un fichier (sauf exceptions).

2. Les caractères restants se lisent 3 par 3. Chaque "trio" décrit respectivement les permissions pour le propriétaire, pour le groupe puis pour tous les autres.

Par exemple, pour cette ligne :

drwxr-xr-x   2 www  daemon    512 May  5 17:10 bin

On voit qu'il s'agit d'un répertoire. Ensuite, on lit par groupe de 3 par 3 :

rwx : Le propriétaire www peut :

"r-x" : Ceux appartenant au groupe "daemon" peuvent

"r-x" : Tous les autres peuvent :

En règle générale, il faut éviter autant que possible de donner les droits d'écriture et d'exécution à d'autres personnes que le propriétaire. Parfois, on retire aussi les droits de lecture sur certains fichiers (mots de passe...).

Pour changer les droits, il existe plusieurs méthodes.

chmod "symbolique"

Certains utilisent une série de chiffres, comme chmod 700. Je trouve cette façon peu explicite lorsqu'on n'a pas encore l'habitude. Quitte à devoir taper quelques commandes en plus, préférez utiliser chmod <identite>±<permission> où :

Vous prendrez bien quelques exemples?

Ces modifications peuvent être appliquées récursivement (à tous les sous-documents d'un dossier) avec l'option -R.

Astuce : pour autoriser à se déplacer dans les dossiers, sans rendre exécutables les fichiers, utilisez X (majuscule) au lieu de x.

chmod "absolu"

Si vous souhaitez comprendre la notation numérique d'un chmod :

Il n'y a pas de distinction entre les dossiers ou les fichiers, il faut dont procéder avec prudence.

Le premier chiffre correspond au droit attribué au propriétaire, le second au groupe, le dernier aux autres.

On additionne les chiffres entre eux. Cela signifie que "chmod 700" attribue les permissions "rwx" au propriétaire, et aucune pour le groupe et les autres (7 = 4+2+1).

Pour finir, afin de définir les permissions en faisant la distinction entre le dossiers et les fichiers, et ne pas rendre exécutable un fichier avec un "chmod -R" (récursif), la commande "find" est votre amie:

Comme toujours, la commande "man chmod" vous en apprendra davantage.

chown : Propriétaire et groupe

Chaque fichier appartient à un propriétaire et fait partie d'un groupe. Cela nous permettra de donner certaines permissions aux propriétaires, qui ne seront pas forcément les mêmes que celles données au membre du groupe.

Pour modifier le propriétaire et le groupe, on utilise la commande chown (change owner).

# chown <proprietaire>:<groupe> nom_du_fichier

Gestions des fichiers

Avant de voir comment gérer les fichiers, prenez note des notations suivantes :

pwd : afficher le dossier courant

Avec pwd, vous demandez "où suis-je" 😄

mkdir : créer un répertoire

$ mkdir nom_du_nouveau_dossier

Utilisez l'option "-p" pour créer toute une structure d'un coup :

$ mkdir -p ~/dossier/avec/des/sous-dossiers

cd : changer de répertoire

Pour vous déplacer dans le dossier "/var/www" :

$ cd /var/www

La commande "cd" sans argument vous déplace dans votre "$HOME".

cp : copier

Pour copier un fichier :

$ cp fichier_source fichier_copie

Pour copier un dossier et son contenu :

$ cp -R dossier_source dossier_copie

rm : supprimer

$ rm chemin_vers_le_dossier
$ rm -R chemin_vers_le_dossier

mv : déplacer

$ mv source destination

C'est comme faire un couper-coller.

less : comment lire et chercher dans du texte ?

Pour seulement consulter un fichier, utilisez la commande "less".

Ensuite, vous pouvez chercher n'importe quelle chaîne de caractères en appuyant sur "/" puis en écrivant votre recherche. Appuyez sur "n" pour aller à l'occurrence suivante, ou bien "N" pour revenir en arrière.

Pour quitter less, appuyez sur "q".

Si vous voulez chercher dans le contenu des logs, ça peut être pratique 😉.

man

Voici la véritable raison pour laquelle il n'y a pas 36 forums d'entraide autour d'OpenBSD mais seulement une liste de discussion : les pages de manuel sont très complètes, agrémentées d'exemples, et suffisent la plupart du temps à répondre aux problèmes rencontrés.

La commande "man" vous permet d'afficher une page de manuel.

Notez qu'il existe différentes sections pour classer les pages de manuel :

Aussi, il arrive parfois qu'une page man existe dans plusieurs section différentes : son contenu n'est alors pas le même. Afin de les différencier, on fait référence à une manpage ainsi : "nom_de_la_page(section)".

Par exemple : "apm(8)", ou "apm(4)". Ou encore "man(1)" et "man(7)". Oui, "man" a une page "man".

On utilise cette commande ainsi, sans les parenthèses :

$ man (section) page

La section est facultative.

Pour vous entrâiner, lancez "man hier". Utilisez les flèches pour faire défiler. Comme avec "less", vous pouvez faire une recherche avec "/". Remarquez la partie "SEE ALSO" qui vous invite à lire d'autres manpages pouvant avoir un intérêt. Quittez avec "q".

Si vous ne savez pas quel est le nom de la page man, vous pouvez la rechercher avec la commande "apropos" :

$ apropos votre_recherche 

vi : pour éditer un fichier

Savoir éditer un fichier est crucial.

Il existe une ribambelle d’éditeurs de texte (vim, nano…). L'éditeur par défaut sur OpenBSD est vi (il y a ed aussi).

vi

Il est peut être étonnant à utiliser au premier abord, si bien que certains voudront peut-être installer un autre éditeur à la place. Cependant, vi est très pratique une fois qu'on l'a pris un peu en main. Si au contraire vous êtes déjà habitué à l'éditeur emacs, vous trouverez votre bonheur avec l'éditeur mg présent lui aussi par défaut.

Voici quelques conseils pour utiliser vi au travers d'un exemple. Pour éditer le fichier /etc/iloverocknroll, vous saisirez ceci :

$ vi /etc/iloverocknroll

Apparaîtra alors le contenu de ce fichier dans le terminal :

We will rock you
# Commentaire

En général, vous procéderez seulement ainsi :

Vous êtes toujours là ? 😁

Allons donc un peu plus loin (mais pas trop, promis 😁). Comprenez tout de suite qu'il existe trois modes :

Pour enregistrer les modifications, appuyez sur ":" puis sur "w". Validez avec entrée. On peut maintenant quitter en écrivant ":q". Notez que vous pouvez aller plus vite en saisissant directement ":wq".

Pour annuler une modification appuyez sur "u". Pour retirer plusieurs modifications, appuyez sur "u" puis sur "." autant de fois que nécessaire. "." permet de répéter la dernière action.

Afin de chercher un texte, ce qui est bien utile dans les gros fichiers, appuyez sur la touche "/" puis écrivez votre recherche.

Si vous souhaitez quitter sans enregistrer vos modifications, saisissez alors ":q!".

D'autres astuces bien pratiques :

rcctl : Comment gérer les services ?

Afin d'activer/désactiver des services (qu'on appelle "démons" car ils tournent en arrière-plan), la commande "rcctl" est prévue à cet effet. Tous les services disponibles sont dans le dossier "/etc/rc.d". Voici quelques rappels :

Si vous préférez la méthode manuelle, alors il vous est possible d'éditer directement le fichier "/etc/rc.conf.local" qui gère les services lancés au démarrage.

TP : un peu de pratique

Entraînons nous avec un petit exercice. Réalisez les consignes suivantes puis vérifiez que vous obtenez la même chose que dans la "correction". Essayez de répondre de mémoire dans un premier temps. Si vous êtes bloqués, relisez la page à la recherche de ce qui vous manque.

La correction :

$ cd /tmp
$ mkdir ah
$ cd ah
$ vi vital.txt
$ cp vital.txt Karadoc.txt
$ chmod 600 Karadoc.txt
$ rm vital.txt
$ cd ~
$ pwd
/home/prx
$ ls -l /tmp/ah
total 2
-rw-------  1 prx  wheel  22 May  5 21:10 Karadoc.txt
$ cat /tmp/Karadoc.txt
Le gras, c'est la vie

Notez que on peut remplacer "cd ~" par "cd $HOME", voire même par "cd".

Que faire après l'installation?

Vous devriez lire les man "afterboot(8)" et "intro(8)". Si si, les développeurs d'OpenBSD ont vraiment prévu de vous parler jusque après l'installation ✌.

$ man afterboot
$ man intro

On vous y explique en premier lieu comment accéder aux pages de manuel justement.

man afterboot(8) en ligne

man intro(8) en ligne

Regarder les exemples de configuration

Plusieurs exemples pour configurer les services venant de base sont disponibles dans "/etc/examples".

Lorsque vous ajouterez des ports (ou paquets), vous irez lire les instructions complémentaires dans "/usr/local/share/doc/pkg-readmes".

Indiquer l'adresse mail de l'administrateur

Éditez le fichier "/etc/mail/aliases" pour indiquer l'adresse mail de root. Cela vous permettra de recevoir des rapports importants sur l'état de votre serveur.

root: batman@chezmoi.tld

Services à éteindre

Il y a peut-être quelques services que vous voudrez désactiver. Je pense notamment au serveur de son (sndiod), qui a peu de chance d'être utile, à moins que vous ne vouliez diffuser de la musique chez vous avec le serveur.

C'est l'occasion de vour parler de la commande "rcctl".

Cette dernière permet de gérer les "démons", services qui tournent en arrière plan.

Pour lister les services actifs :

# rcctl ls on

Pour en éteindre, par exemple le serveur de son :

# rcctl stop sndiod

Et pour désactiver leur lancement pour le prochain démarrage :

# rcctl disable sndiod

Il est probable que vous souhaitiez activer la gestion d'énergie pour les systèmes qui le supporte avec le démon apmd. Les trois commandes suivantes ont les effets suivants :

# rcctl enable apmd
# rcctl set apmd flags -A
# rcctl start apmd

Si vous ne savez pas ce qu'est un des services listé par la première commande, ayez le réflexe de chercher la page man. Par exemple :

man syslogd

Ou alors, lisez l'excellente description du système OpenBSD dans intro(8) qui détaille chaque service :

man 8 intro

Adresses réseau

Pour les pressés : c'est quoi une adresse réseau ?

Avant de définir une adresse IP (Internet Protocol), soyons sérieux deux minutes et parlons du Père Noël 😁. Chaque enfant sait très bien qu'il doit envoyer sa liste de cadeaux à "Route du Ciel, Pôle Nord". S'il veut une réponse, il notera sa propre adresse derrière l'enveloppe.

C'est le même principe pour l'ordinateur de votre collègue relou qui vous montre une vidéo de chat : l'ordinateur sait où trouver le site hébergeant la vidéo, et ce site sait à quelle adresse envoyer la vidéo.

Chaque appareil connecté à Internet dispose de son adresse : l'adresse IP. Cependant, les ordinateurs n'ont pas le même sens de la poésie que les enfants. Les adresses utilisées dans un réseau sont des séries de chiffres, par exemple 192.0.2.2. Nettement moins classe que l'adresse du Père Noël 🎅.

D'accord, mais comment font les appareils pour connaître l'adresse d'un domaine comme wikipedia.org? Il y a un annuaire ?

Quelle idée intéressante. C'est effectivement prévu, lisez la partie sur les noms de domaine (DNS) pour en savoir davantage.

Il faut distinguer l'IP publique de l'IP locale (ou privée). La plupart du temps, pour vous connecter à Internet, votre fournisseur d'accès vous a donné une box. Celle-ci fait le relais entre internet et votre ordinateur. Cela donne :

+-----------------------+
|                       |
| Réseau local (maison) |
|     IP PRIVÉES        |
|                       |
|                       |
|     PC portable   <---+------+
|     192.168.1.20      |      |
|                       |      |
|                       |      |
|     Smartphone    <---+--+  ++---------------+
|     192.169.1.21      |  |  |                |
|                       |  +--+  Routeur (box) |    +----------+
|                       |     |                |<---+ INTERNET |
|     PC Fixe       <---+-----+  IP PUBLIQUE:  |    +----------+
|     192.168.1.22      |     |   192.0.2.2    |
|                       |  +--+                |
|   * * * * * * * * *   |  |  ++---------------+
|   * Votre serveur <---+--+   |
|   * 192.168.1.23  *   |      |
|   * * * * * * * * *   |      |
|                       |      |
|     Console de jeu <--+------+
|     192.168.1.24      |
|                       |
+-----------------------+

S'il faut retenir quelque chose, c'est :

Pour les besoins de l'auto-hébergement, il est nettement plus pratique que cette dernière adresse soit fixe. Certains fournisseurs d'accès refusent de vous en donner.

Il existe des moyens de contourner ce problème avec une IPv6, un VPN (décrit plus loin) ou un DNS dynamique, mais vous vous faciliterez vraiment la vie en prenant votre abonnement internet chez un fournisseur qui accepte de vous fournir une IP fixe.

Rappel des concepts

Pour construire un serveur, il vous faut impérativement configurer correctement sa configuration réseau. Vous avez en particulier besoin d'adresses (publiques et privées) stables, ainsi que de connaître l'adresse de votre passerelle ou routeur.

Vous pouvez passer ce chapitre si vous n'êtes pas à l'aise et commencer vos premiers essais avec une configuration automatique avec "dhcp" puis revenir ici une fois que vous vous êtes habitués. Dans tous les cas, les différentes parties se complètent, vous voudrez donc peut-être passer de l'une à l'autre quitte à les relire 2 fois. Courage, ce n'est pas aussi compliqué que ça en a l'air 😄.

Voici quelques précisions ou rappels qui vous permettront de mieux appréhender la suite.

Adresse publique, adresse privée/locale

Tout d'abord sachez que votre fournisseur d'accès ne vous connecte sûrement pas directement sur le réseau internet, mais plutôt par ce qu'on appelle du NAT. Si vous utilisez un routeur (box), ce qui est probablement le cas, alors cet appareil (on va beaucoup parler de lui plus loin) va, lui, recevoir une adresse Internet publique.

Avoir une adresse publique signifie que les gens qui naviguent sur le net peuvent contacter cette adresse. Elle est routable et unique.

Le routeur va alors distribuer des adresses privées sur votre réseau local. Cela signifie que vous avez chez vous plusieurs adresses privées - une pour chaque appareil connecté sur votre réseau : TV connectée, smartphone, console de jeu, imprimante... - qui se partagent une seule adresse publique.

OK ? Bien, on continue 😊.

Les adresses privées peuvent être dans trois rangées:

Votre adresse privée, ou locale, c'est celle que votre ordinateur utilise, celle qu'il connait.

Pour trouver l'IP locale d'un appareil, de votre serveur en l'occurence, appelez la commande "ifconfig" que l'on renvoie à "grep" pour filtrer ce qui nous intéresse seulement ( "|" s'obtient avec Altgr-6) :

# ifconfig |grep inet

Vous verrez apparaître des lignes comme celles-ci :

inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3
inet 127.0.0.1 netmask 0xff000000
inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255
inet6 fe80::feaa:14ff:fe65:5f86%re0 prefixlen 64 scopeid 0x1

C'est quoi tous ces trucs incompréhensibles? 😲

On va y aller petit à petit ensemble 😉

Les lignes commençant par "inet6" décrivent des IPv6 et "inet" des IPv4.

Votre adresse publique, c'est celle que vous affichez pour la navigation internet. C'est cette adresse que connaissent les différents sites web que vous fréquentez. Et justement, si vous ne la connaissez pas, il vous suffit d'aller voir par exemple :

lehollandaivolant.net

ipaddress

ipecho

ifconfig.me

wizcase

Si quelqu'un veut visiter votre site web, il ne connaît que votre IP publique. Or, cette IP publique renvoie vers votre box (routeur), les données ne sont pas dessus mais sur votre serveur. Il doit donc rediriger le visiteur vers l'IP locale de votre serveur. La box est un routeur qu'il faut configurer. Ça tombe bien, c'est expliqué juste après. 😉

Le routeur

Le routeur, c'est la box internet. On parle aussi de passerelle (gateway en anglais).

D'un côté du routeur, on a donc une adresse internet publique (que dans l'ensemble de cette documentation, on a supposée fixe, comme dit juste au-dessus), de l'autre on a une adresse privée. Cette dernière adresse est très importante : c'est celle que votre serveur (ainsi que votre ordinateur personnel, votre smartphone, votre grille-pain connecté…) doit connaître pour atteindre internet.

Dans les faits, quand quelqu'un dans votre réseau doit contacter un site internet, il passera par cette adresse, qui s'avère donc critique, et qui plus est un goulet d'étranglement.

C'est également le routeur qui fait les redirections de ports.

Pour trouver l'adresse de votre "gateway", vous pouvez vous connecter en dhcp dans un premier temps puis entrer la commande suivante :

# route -n show
Routing tables
Internet:
Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface
default            192.168.1.1      UGS       35     4827     -     8 re0  
224/4              127.0.0.1          URS        0       13 32768     8 lo0  
127/8              127.0.0.1          UGRS       0        0 32768     8 lo0  
127.0.0.1          127.0.0.1          UHhl       9      969 32768     1 lo0  
...

La première ligne vous donne la réponse : 192.168.1.1 dans l'exemple.

Pour obtenir votre "gateway" en IPv6, vous pouvez prendre le préfixe qui vous a été attribué (le "subnet") et le terminer par "::1". Par exemple, pour ce serveur, l'IP est " 2a01:e0a:2b8:ca70::1bad" et la gateway " 2a01:e0a:2b8:ca70::1"

Nom de machine

Chaque appareil sur le réseau a un nom (qu'on appelle nom d'hôte, ou nom de machine. Certaines documentations parlent de nom de réseau de la machine).

Sur les éléments les plus sophistiqués (les vrais ordinateurs), on peut changer ce nom. De nombreux appareils actuels sont toutefois verrouillés (essayez de changer le nom de machine d'un smartphone Android...). Ça n'a l'air de rien mais avoir un nom de machine permet de reconnaître les appareils effectivement présents et fonctionnels dans le réseau.

Le nom de machine d'un ordinateur tournant sous OpenBSD se définit dans "/etc/myname", où sera juste inscrit son nom complet. Par exemple:

serveur.chezmoi.tld

dhcp

Pour configurer l'adresse locale, vous pouvez utiliser le client dhcp qui vient par défaut avec chaque installation OpenBSD.

Pour ce faire, il suffit d'indiquer "dhcp" dans le fichier de configuration de l'interface réseau de votre serveur. Ce fichier est /etc/hostname.if avec "if" le nom de ladite interface. Si vous avez sélectionné dhcp lors de l'installation, alors il existe déjà.

toto@maitre:/home/toto cat /etc/hostname.re0
dhcp

Suivant la configuration du routeur que vous utilisez (configuration que vous ne pouvez pas forcement changer facilement), il peut être nécessaire d'utiliser DHCP pour obtenir de la connectivité sur votre serveur (le routeur pourrait refuser de relayer les connexions à une machine qui n'est pas dans sa table DHCP).

Si vous obtenez votre configuration réseau par DHCP, alors il n'est pas nécessaire de connaître ou de renseigner l'adresse de votre routeur.

Configuration statique

La configuration statique d'une machine s'avère plus complexe, mais on a davantage de maîtrise dessus (on peut par exemple assigner plusieurs adresses si on l'estime nécessaire).

On configure d'abord l'interface voulue :

toto@maitre:/home/toto $ cat /etc/hostname.re0 
inet            192.168.1.2    255.255.255.0     192.168.1.255
inet   alias    192.168.1.9    255.255.255.0     192.168.1.255
## et autant d'autres que vous le voulez…
# Dans l'ordre : inet (alias) ip_locale     masque     passerelle
up

Il faut ensuite indiquer l'adresse de la passerelle par laquelle on passe pour accéder à internet. Il s'agit en fait de votre routeur. Le plus pratique est d'ajouter une ligne appelant la commande "!route". Vous pouvez aussi indiquer la passerelle dans le fichier "/etc/mygate", mais cela disperse l'information. À vous de voir 😄

inet            192.168.1.2    255.255.255.0     192.168.1.255
inet   alias    192.168.1.9    255.255.255.0     192.168.1.255
!route add -inet default 192.168.1.1
up

Vous devez connaître l'adresse de votre passerelle. Cette adresse n'est pas standard, en revanche les constructeurs ou les FAI ont souvent des réglages par défaut qui sont connus et qu'on peut retrouver sur le web. Il est également possible d'utiliser DHCP au début du processus de construction du serveur, puis mettre la configuration en statique quand on a pris la main et qu'on commence à vouloir faire des trucs sophistiqués.

Une fois ces deux fichiers configurés, l'interface sera prête et mise en service automatiquement à chaque démarrage de la machine. Notez également que vous pouvez combiner des éléments de configuration dynamique (dhcp) avec de la configuration statique.

Vous pouvez tester votre bonne connexion au net grâce à la (célèbre) commande ping.

Tout d'abord "pingez" votre passerelle :

ping 192.168.1.1

Puis "pinger" le serveur de l'APNIC (www.apnic.net) par exemple :

ping 1.1.1.1

Si tout va bien, alors votre serveur est connecté au net.

IPv6

IPv6 c'est le nouveau protocole IP. Aujourd'hui, ça devient essentiel de le maîtriser un petit peu. Sachez que si vous n'avez pas encore d'ipv6 chez vous, il est probable que vous en ayez d'ici un ou deux ans. Mieux vaut être préparé pour en tirer le meilleur profit non ?

Le principal avantage est que votre machine est directement accessible de l'extérieur, plus besoin de NAT par le routeur pour rediriger un visiteur.

La configuration reprend les grands principes d'ipv4, mais avec des différences sur les méthodes et la syntaxe:

toto@maitre:/home/toto $ cat /etc/hostname.re0 
inet...
inet6   2001:db8:1:1::2    64 # adresse
inet6   autoconf              # utilisation des adresses 
                              # SLAAC automatiques
# on n'oublie pas la passerelle
!route add -inet6 default 2001:db8::1
up

Les adresses SLAAC ont l'avantage d'être stables (si on utilise pas l'attribut autoconfprivacy), ce qui est exactement ce dont vous avez besoin sur un serveur. En revanche, elles sont encombrantes et peu mémorisables par un être humain.

Vous pouvez aussi utiliser les adresses ULA, qui sont des adresses locales pour votre réseau. Elles permettent de configurer un réseau de manière permanente sans avoir besoin de tout renuméroter en cas de changement de FAI. Elles sont également non-routables, ce qui veut dire que personne ne peut les attaquer. Enfin, elles constituent un excellent moyen de commencer à mettre en place votre réseau en attendant d'avoir vos adresses publiques définitives (si vous n'en avez pas encore).

Vous pouvez lire davantage à propos de ces adresses en suivant ce lien.

Ces divers paramètres se combinent de manière adéquate les uns avec les autres. Ainsi, vous pouvez tout à fait utiliser des adresses SLAAC et des adresses statiques.

En ipv6, il n'est plus question de redirection de ports (et ça c'est cool 😊) : votre serveur est directement connecté à internet. Soyez donc prudent et vérifiez bien le pare-feu de votre serveur.

Rediriger les ports sur son routeur

Votre serveur, comme votre ordinateur probablement, sera connecté à Internet par l’intermédiaire d’un modem-routeur (une *box). Il faut s’assurer que lorsqu'un visiteur voudra accéder à votre serveur, ce routeur le redirige bien vers votre serveur, et non vers une autre machine du réseau local.

Autrement dit, imaginez votre routeur comme un grand mur avec dedans plusieurs portes. Chacune est numérotée. Quand quelqu'un veut accéder à votre serveur, il va venir frapper à l’une des portes, par exemple la numéro 80 pour un serveur web (http). Si le routeur est correctement configuré, il va diriger le visiteur vers l'adresse IP interne (privée) de votre serveur. Sinon, le port reste fermé, et c'est une bonne chose pour tous les autres appareils de votre réseau domestique. Bien sûr, pour encore plus de sécurité, une fois la porte 80 passée, votre serveur sera équipé d’un parefeu pour vérifier que vous avez bien le droit d’entrer. Ce sera un peu le concierge 😁.

                       +---------------+
                       |               |
                       | Routeur (box) |
                       |  ***********  |
                       |               |
              +--------+-- Porte 443   |
+---------+   |        |               |
|         |<--+        |               |
| Serveur |         ?<-+---Porte 143 <-+--- [Petit malin 👿]
|         |<--+        |               |
+---------+   |        |               |
         ^    +--------+-- Porte 80 <--+--- [Visiteur 👼]
         |             |               |
         |             |               |
         +-------------+-- Porte 22    |
                       |               |
                       +---------------+

Dans le schéma ci-dessus, seuls les ports 443, 80 et 22 sont associés au serveur. Si le petit malin demande un port qui n’est pas redirigé vers le serveur (la porte est fermée), alors la requête ne peut pas aller jusqu'au bout. C’est comme s’il demandait à rejoindre une destination qui n’existe pas. En revanche, lorsque le visiteur demande de passer par la porte 80, il est bien renvoyé vers le serveur.

Notez que si votre serveur est connecté en IPV6, il n'y a pas besoin de configurer la redirection de ports dans le routeur : l'accès au serveur est direct. C'est donc d'autant plus important de bien configurer le parefeu.

L’interface de configuration n’est pas la même selon si vous avez une livebox, freebox, modem OVH... Pas d’inquiétude, voici quelques indices.

Déjà, pour accéder à la configuration, c'est à partir d'un navigateur web (Firefox par exemple). On peut trouver l’adresse à entrer dans un navigateur web pour accéder à cette interface. Essayez dans l’ordre suivant (Bien sûr, cette “adresse” est à utiliser sur un ordinateur lui-même connecté à la *box.) :

Sachez que cette adresse (on parle d'adresse du routeur, ou adresse passerelle) s'avère un élément important de la configuration de votre réseau. Retenez-la bien.

Il est possible qu’un nom d’utilisateur et un mot de passe soient demandés. Essayez dans ce cas admin/admin, sinon, demandez directement à votre fournisseur d’accès à Internet. Une fois connecté, allez dans la section "Configurer mon routeur".

DMZ

Si vous n'avez pas envie d'être embêté avec des redirections de port, vous pouvez configurer une "DMZ" dans votre routeur. Cela permet de rediriger tout le traffic entrant vers une IP locale : vous indiquerez alors l'IP privée de votre serveur.

Notez toutefois que votre serveur sera exposé à TOUS les flux entrant. Vous comprenez donc que la configuration du parefeu sera à soigner (mais vous ne comptiez pas faire autrement n'est-ce pas 😉).

Obtenir un nom de domaine

Au lieu d'écrire votre IP, ça serait plus pratique d'accéder à votre serveur de façon plus "humaine" avec un nom de domaine. Ce n'est pas une obligation ceci dit. Cela vous donne aussi la possibilité de mieux vous organiser avec des sous-domaines, par exemple mail.chezmoi.tld, blog.chezmoi.tld...

Mais c'est quoi un nom de domaine?

Imaginons que M. Ali Gator vit au 5 rue du moulin à Picsouville. Pour aller lui rendre visite, c’est à cette adresse que vous irez. Sur le web, l’adresse de votre serveur, c’est une série de nombres : l'IP.

Par exemple : 192.0.2.2. C’est pratique pour les machines, pas pour les humains.

Un nom de domaine nous permet d’utiliser l’adresse wikipedia.org, qui est traduite par les ordinateurs en 91.198.174.192.

Avouez que c’est plus facile à retenir. 😉

L’association d’une IP avec un nom de domaine est possible grâce aux enregistrements DNS (Domain Name System). Ce système est à la base de toutes les interactions qui se servent des noms de domaines : Email, Web, ... C'est une sorte d'annuaire numérique.

Voici une petite BD qui explique comment se passe une résolution DNS (EN) :

../../../img/life-of-a-dns-query.png

Vous pouvez acheter un nom de domaine auprès de ce que l’on appelle un registre ou registrar comme OVH ou GANDI que je conseille. Ce n'est pas très onéreux, mais sachez qu'il en existe aussi des gratuits, comme nic.eu.org.

Registre GANDI (lien de parrainage, 20% de réduction)

Registre OVH

nic.eu.org (voir l'exemple détaillé plus loin)

Si vous le souhaitez, vous pourrez gérer les enregistrements DNS vous-mêmes en installant un serveur de noms (voir la partie sur nsd).

Une fois votre domaine acquis, configurez les champs DNS pour le faire pointer vers votre adresse IP. Pour ça, référez-vous à la partie suivante sur les enregistrements DNS et registres.

Les enregistrements DNS

Lorsque un ordinateur doit aller sur un site dont le nom est "chezmoi.tld", il va demander à un serveur DNS (qu'on appelle résolveur dans ce cas) à quelle adresse IP ce nom de domaine correspond. Le DNS, c'est un peu comme des panneaux sur le bord de la route qui indiquent le chemin à suivre pour arriver à destination.

Pour créer ce panneau une fois que vous avez un nom de domaine, il faut le relier à l’adresse IP de votre serveur. Mais si, souvenez-vous, cette série de nombres ressemblant à 192.0.2.2. Pour cela, enregistrez un champ de type A dans votre zone à l'aide de l’interface d’administration du registre (sauf si vous hébergez vous même un serveur de noms, vois nsd plus loin 😉). Par exemple :

chezmoi.tld   A   192.0.2.2

Notez qu'il existe plusieurs types d’enregistrements :

blog.chezmoi.tld    CNAME chezmoi.tld
wiki.chezmoi.tld    CNAME chezmoi.tld
webmail.chezmoi.tld CNAME chezmoi.tld

Pour en savoir plus, vous pouvez lire les pages suivantes :

Page Wikipédia sur le DNS;

Site interactif pour comprendre le fonctionnement des DNS.

Rapports quotidiens

Une fois votre serveur en route, il faudra veiller à ce que tout fonctionne correctement. Ça paraît bête, mais c'est très important. Inutile d'aller plus loin si vous comptiez laisser votre serveur dépérir 😉. Heureusement, tout est déjà prévu dans OpenBSD pour nous faciliter la vie.

En effet, chaque jour (enfin plutôt chaque nuit 😄) un rapport est généré à l'aide d'un outil nommé "security". Il est envoyé à l'administrateur du serveur, cet utilisateur répondant au charmant nom de "Charlie Root". Vous pourrez y lire un tas d'informations utiles comme :

Lisez la page man security(8) pour en apprendre davantage.

Au bout du compte, un rapport peut ressembler à ceci :

Running security(8):
Checking mailbox ownership.
user spamd.black mailbox is owned by root
user spamd.black mailbox is -rw-r--r--, group wheel
======
/etc/rc.local diffs (-OLD  +NEW)
======
--- /var/backups/etc_rc.local.current   Sat Jun  4 03:46:48 2016
+++ /etc/rc.local       Thu Oct 20 09:46:54 2016
@@ -1 +1 @@
-su pi -c "tmux new -s rtorrent -d rtorrent"
+/usr/bin/su pi -c "/usr/bin/tmux new -s rtorrent -d /usr/local/bin/rtorrent"
======
/etc/spwd.db SHA-256 checksums
======
OLD: 075455a721ef[...]b942f590fb8e3edfd88c5dd4
NEW: 37eba7537dd7[...]42468cc4cbe768fcf496b230

On y voit des alertes sur les propriétaires de certains fichiers.

Ensuite, les modifications sur un fichier. Les lignes commençant par un + correspondent à ce qui a été rajouté et celles qui commencent par un - à ce qu'il y avait avant.

Enfin, on voit qu'une somme de contrôle a changé : un nouvel utilisateur a-t-il été créé par vos soins ? Espérons que oui puisque le fichier /etc/spwd.db a changé. Normalement, ce rapport est très peu rempli, c'était un exemple 😉.

Tout ceci, c'est bien beau, mais comment recevoir ces messages?

Comme vous allez le voir, c'est d'une simplicité enfantine :

Bien sûr, vous remplacerez l'adresse mail par celle que vous consultez régulièrement.

Lancez maintenant la commande "# newaliases".

Et voilà ! 😎

Si vous voulez tester que tout fonctionne comme prévu, saisissez la commande suivante pour envoyer un mail test à root, c'est à dire à vous-même :

echo "Coucou toi!" | mail -s "test" root

Vous devriez le recevoir à l'adresse définie dans "/etc/mail/aliases".

Ne vous reste plus qu'à lire soigneusement ces messages que le serveur va vous envoyer.

Si besoin, vous pouvez configurer le nom de domaine des adresses d'expéditeur de mail, dans le fichier "/etc/mail/mailname".

Éditez ce fichier, et écrivez, en première ligne, votre nom de domaine. Par exemple :

chezmoi.tld

Ainsi, les mails qui seront envoyés par l'utilisateur root partiront avec l'expéditeur "root@chezmoi.tld", et ceux qui seront envoyés par votre utilisateur partiront avec l'expéditeur "mon-user@chezmoi.tld".

Vérification des disques

Je vous suggère d'ajouter la ligne suivante dans le fichier "/etc/daily.local" :

CHECKFILESYSTEMS=1

De cette façon, les systèmes de fichier seront vérifiés tous les jours à la recherche d'erreurs.

Lisez aussi le man 8 daily pour en apprendre plus 😉

Le pare–feu (pf)

Quoi? Déjà le firewall?

Eh oui, on va commencer par cet élément essentiel à la sécurité du serveur. Avouez que ce serait dommage de travailler sur une machine vulnérable dès le départ 😕. Donc avant d'aller plus loin : le pare-feu ! Comme toujours on va simplifier au maximum puis proposer des exemples plus complexes (pas "compliqués" 😉) pour ceux qui veulent aller plus loin.

Sur OpenBSD, le pare-feu s'appelle pf, comme "packet filter". Sa configuration se déroule dans le fichier "/etc/pf.conf", et comme vous le verrez, est nettement plus facile à appréhender que celle d'iptables (l'outil servant à configurer le pare-feu sous Linux...).

Avant toutes choses, il faut se demander ce dont on va avoir besoin sur notre serveur. Un serveur web (http) ? Les mails ? Un serveur ftp ? Selon les réponses à ces questions, nous n'ouvrirons pas les mêmes ports. En effet, pour assurer un maximum de sécurité, on ne va rien laisser passer sauf ce que qui est réellement utile. Redoutable 😁.

Pour trouver les ports sur lesquels écoutent les services dont vous pourriez avoir besoin, regardez le contenu du fichier "/etc/services". Ainsi, écrire "www" ou "80" revient au même pour pf, mais est plus lisible pour les humains.

Les règles que vous allez définir seront appliquées dans l'ordre de lecture du fichier de configuration.

Un premier exemple

Prêts ? C'est parti pour un exemple détaillé mais simple. Nous allons configurer le parefeu pour un simple site web avec accès sur les ports 80 (www) et 443 (https).

On commence par tout bloquer, et enregistrer dans le journal les connexions interdites avec le mot "log".

block log

Afin de nous simplifier la vie, nous allons mettre les ports à ouvrir dans une variable. Ça sera particulièrement pratique lorsqu'on aura davantage de ports à gérer.

tcp_pass = "{ 80 443 }"

Remarquez que c'est identique à tcp_pass = "{ www https }"

Ensuite, on autorise les visiteurs éventuels à accéder à votre serveur. Ce seront des connexions dites "entrantes", on utilisera donc le mot clé "in". Au lieu de chercher le nom de votre interface réseau (qui dépend de votre matériel), nous allons préciser le nom du groupe que portent ces interfaces afin que ça fonctionne sans inquiétudes : egress.

pass in quick on egress proto tcp to port $tcp_pass 

T'es mignon hein, mais c'est du charabia tout ça!

D'accord, nous allons expliquer ce que veut dire cette syntaxe. On peut la traduire la ligne de configuration précédente ainsi : "laisse passer vers l'intérieur (pass in) sans tenir compte des règles qui pourraient suivre (quick) à travers l'interface egress (on egress) pour le protocole tcp (proto tcp) vers les ports dans $tcp_pass (to port $tcp_pass).

Pfouh! 😋

Enfin, on autorise tout le trafic en sortie (mot clé "out") :

pass out on egress 

Cela nous donne au final :

tcp_pass = "{ 80 443 }"
block log
pass in quick on egress proto tcp port $tcp_pass 
pass out on egress all

Facile, non ? 😁

Je vous propose de remplacer la dernière ligne par quelque chose d'un peu plus restrictif :

pass out on egress proto { tcp udp icmp ipv6-icmp } modulate state

On précise simplement les protocoles autorisés en sortie avec une précaution pour chaque connexion sortante (modulate state).

Vous l'aurez compris, pf nous permet un contrôle de premier ordre sur notre serveur. Dans un premier temps, vous souhaiterez simplement choisir quels ports doivent être ouverts.

Cela fait de nombreuses nouvelles notions, prenez le temps de relire ce qui a été écrit jusqu'ici si besoin.

Lorsque vous serez plus à l'aise, sachez qu'on pourra filtrer le trafic entrant et sortant, et même rediriger une partie de celui-ci vers des services internes (par exemple un anti-spam). Je vous invite à lire la partie un peu plus bas "aller-plus-loin-avec-pf". Vous y verrez comment ignorer certaines listes d'IP connues comme nuisibles que l'on enregistrera dans des tables, des règles contre les attaques bruteforce ou encore une proposition d'outil qui ajoute sur liste noire d'éventuels pirates en temps réel.

Je vous laisse construire votre fichier "/etc/pf.conf" selon vos besoins. Partez de l'exemple vu au-dessus puis ajoutez les ports à ouvrir pour commencer. N'hésitez pas à consulter l'exemple fourni à la fin du document.

Pour être sûr, on peut avoir un exemple pour ouvrir le port SSH ?

Si le port SSH configuré est le 22, alors vous aurez dans la configuration de pf :

pass in quick on egress proto tcp to port 22

Bien sûr, vous pouvez aussi vous contenter de modifier uniquement la variable tcp_pass :

tcp_pass = "{80 443 22}"
pass in...

Commandes pratiques pour pf

Je vous propose une liste de commandes utiles pour gérer pf :

Aller plus loin avec pf

pf-badhost : liste noire d'IP

Certaines IP sont connues pour être nuisibles. Entre celles qui scannent pour trouver un port ouvert ou celles qui tentent des attaques par bruteforce, la liste est longue. Heureusement, on peut configurer le parefeu pour qu'il ignore totalement ces IP et ainsi protéger et alléger la charge de notre serveur.

pf-badhost C'est ce que permet le projet pf-badhost dont je vous invite à lire la page officielle.

Ci-dessous, je vous propose une traduction pour mettre ce dispositif en place.

Il consiste en un script qui récupère une liste d'IP qui seront ensuite ignorées par pf.

On commence par créer un utilisateur dédié à ce script. On l'appelle "_pfbadhost". Cela permet de séparer les privilèges, ce qui est bienvenu, même si les étapes intermédiaires pourraient être évitées si on faisait tout en tant que superutilisateur (mais non 😋) :

# useradd -s /sbin/nologin -d /var/empty _pfbadhost 

On télécharge et installe le script pfbadhost avec les bonnes permissions :

# ftp https://www.geoghegan.ca/scripts/pf-badhost.sh
# install -m 755 -o root -g bin pf-badhost.sh /usr/local/bin/pf-badhost

On doit ensuite créer les fichiers nécessaires au bon fonctionnement du script (liste des IP et logs):

# install -m 640 -o _pfbadhost -g wheel /dev/null /etc/pf-badhost.txt
# install -d -m 755 -o root -g wheel /var/log/pf-badhost
# install -m 640 -o _pfbadhost -g wheel /dev/null /var/log/pf-badhost/pf-badhost.log
# install -m 640 -o _pfbadhost -g wheel /dev/null /var/log/pf-badhost/pf-badhost.log.0.gz

L'auteur conseille d'installer les programmes ripgrep et mawk pour de meilleurs performances. C'est facultatif:

# pkg_add ripgrep mawk

Ajoutez ces lignes dans le fichier "/etc/doas.conf" afin que l'utilisateur _pfbadhost puisse recharger la liste des IP à blacklister dans le parefeu :

permit root
permit nopass _pfbadhost cmd /sbin/pfctl args -nf /etc/pf.conf
permit nopass _pfbadhost cmd /sbin/pfctl args -t pfbadhost -T replace -f /etc/pf-badhost.txt
# Optional rule for authlog scanning
permit nopass _pfbadhost cmd /usr/bin/zcat args -f /var/log/authlog /var/log/authlog.0.gz

Faîtes en sorte que l'utilisateur _pfbadhost lance le script toutes les nuits à minuit en modifiant son crontab

# crontab -u _pfbadhost -e
~ 0~1 * * *	-s pf-badhost -O openbsd

(La ligne est à écrire avec l'éditeur vi décrit dans la partie "Guide de survie : quelles commandes dois-je absolument connaître?")

Ainsi, pf-badhost sera lancé chaque nuit entre minuit et 1h du matin. Cela permet d'éviter que tous les utilisateurs de pf-badhost n'utilisent ce script en même temps et surcharger les serveurs.

Ajoutez ces lignes au fichier "/etc/pf.conf" pour que pf tienne compte de la liste noire :

table <pfbadhost> persist file "/etc/pf-badhost.txt"
block quick on egress from <pfbadhost>

Lancez le script pour la première fois comme si vous étiez l'utilisateur _pfbadhost :

# doas -u _pfbadhost pf-badhost -O openbsd

Notez que vous devez pouvoir utiliser doas. Enfin, rechargez le parefeu puis relancez le script :

# pfctl -f /etc/pf.conf
doas -u _pfbadhost pf-badhost -O openbsd

Et voilà !

Configuration de pf-badhost

Pour configurer pf-badhost, vous devez éditer directement le script et chercher ce qui est en-dessous de la ligne

### User Configuration Area -- START

Vous pourrez notamment décommenter (retirer le "#") pour une liste spécifique ou activer l'IPv6.

Lisez le manuel de pf-badhost bien sûr 😉.

Listes noires fournies par l'auteur

Notez que je mets à disposition des listes d'IP à blacklister sur votre serveur.

N'hésitez pas à vous servir régulièrement 😉.

Anti-Bruteforce intégré à pf

Une méthode qu'utilisent les pirates pour s'en prendre à un serveur s'appelle "bruteforce". Ce type d'attaque consiste à essayer toutes les combinaisons d'identifiants/mot-de-passe possibles jusqu'à tomber sur la bonne.

Si vous avez choisi des phrases de passe robustes, vous êtes normalement à l'abri. Toutefois, ces attaques utilisent inutilement des ressources sur votre serveur et peuvent potentiellement réussir un jour (avouez que ça serait pas de bol).

Afin de déjouer ces attaques, il faudrait prendre le temps de décortiquer les journaux des services que vous hébergez (dans "/var/log" et "/var/www/logs") à la recherche d'échecs d'identification et repérer d'où viennent ces attaques pour en bannir les auteurs. Mais soyons honnête, c'est à la fois pénible et chronophage.

L'idéal serait un outil qui surveille les journaux à votre place et s'occupe de mettre sur la liste noire de votre parefeu les IP des "attaquants". Ça tombe bien, vous pouvez utiliser vilain ou sshguard qui sont faits pour ça.

En attendant, pf intègre déjà une protection qui limite le nombre de connexions sur un port pendant un temps donné. C'est très efficace et reste léger. Lisez le paragraphe suivant 😉.

pf dispose d'une fonctionnalité très intéressante : les "tables" (tableaux). Ça va nous permettre de garder en mémoire certaines adresses IP de pirates qui tenteraient de compromettre le serveur. Par exemple, pour protéger le service SSH, on va procéder ainsi :

Ça nous donne donc ceci :

ssh_port = "22"
table <ssh_abuse> persist
block in log quick proto tcp from <ssh_abuse> to any port $ssh_port
pass in on egress proto tcp to any port $ssh_port flags S/SA keep state (max-src-conn-rate 3/60, overload <ssh_abuse> flush global)

Notez que nous avons enregistré le numéro du port utilisé pour le serveur SSH. C'est inutile, car on peut mettre à la place de "$ssh_port" simplement ssh, c'est-à-dire le nom du service. Cependant, on peut vouloir changer le port par défaut du serveur SSH, comme décrit dans le chapitre sur ce service.

Voici un autre exemple pour un site web (ports http et https) :

http_ports = "{ www https }"         # ports http(s)
# Si + de 40 connexions toutes les 5 secondes sur les ports http(s)
# ou si elle essaie de se connecter + de 100 fois
# on ajoute l'ip pour la bloquer.
pass in on egress proto tcp to any port $http_ports flags S/SA keep state (max-src-conn 100, max-src-conn-rate 40/5, overload <http_abuse> flush global)

Anti-bruteforce en temps réel avec vilain

Je me permets de vous proposer un outil que j'ai écrit avec l'aide de Vincent Delft dans le but de mettre sur liste noire d'éventuels pirates lorsque l'attaque a lieu. Vos retours d'utilisation permettront de l'améliorer.

Le script en question s'appelle vilain.

Vous pouvez suivre ce lien suivant pour consulter le code.

Anti-bruteforce en temps réel avec sshguard

Contrairement à ce que son nom indique, sshguard est en mesure de vérifier les tentatives de connexions sur plusieurs services, pas seulement SSH.

Site officiel de sshguard

Son installation sous OpenBSD n'est pas très compliquée à mettre en place. Vous devrez créer une table dans pf qui contiendra toutes les IP mises sur liste noire. Ainsi, on ajoute dans le fichier /etc/pf.conf une nouvelle table contenant les IP des pirates qui sont aussitôt bloquées :

table <sshguard> persist
block in from <sshguard>

Rechargez le parefeu avec "# pfctl -f /etc/pf.conf".

Maintenant, on installe sshguard comme on a l'habitude de le faire :

# pkg_add sshguard

Copiez le fichier de configuration donné en exemple :

# cp /usr/local/share/examples/sshguard/sshguard.conf.sample /etc/sshguard.conf

Éditez ce fichier si vous le souhaitez pour le rendre plus ou moins sévère. Les options par défaut sont plutôt raisonnables.

Nous pouvons maintenant activer et lancer sshguard :

# rcctl enable sshguard
# rcctl start sshguard

Et voilà, votre serveur est désormais sous bonne garde.

Vous voudrez peut-être mettre sur liste blanche quelques adresses IP avec l'option "-w". Procédez ainsi (cette option peut être employée plusieurs fois).

rcctl set sshguard flags -w 192.168.1.0/24 -w 123.123.123.123

Piège avec iblock

iblock vous permet de bannir des IP qui tenteraient de joindre votre serveur sur des ports inutilisés. Puisque vous n'avez aucun service derrière ces ports, il y a fort à parier que ce sont des scans aux intentions discutables.

Lisez la page du projet iblock, que je recommande vivement.

SSH : administrer à distance

Configuration de SSH

SSH, est un outil génial 🙋. Il vous permettra de vous connecter au serveur à partir d'un autre ordinateur. Vous pourrez alors l'administrer à distance sans devoir y brancher un clavier et un écran. À vrai dire, sauf exception, tous les serveurs sont administrés ainsi, mais vous êtes chez vous après tout, donc vous pouvez faire comme vous voulez.

De plus, SSH est un protocole permettant bien plus : créer des tunnels chiffrés vers votre serveur, avoir un espace de stockage de fichiers en SFTP...

Quoi qu'il en soit, si vous n'avez pas activé SSH lors de l'installation d'OpenBSD, vous pouvez l'activer avec la commande suivante :

# rcctl enable sshd

Bien que ce protocole soit fiable, il faut le garder ainsi et éventuellement éditer la configuration de SSH dans le fichier "/etc/ssh/sshd_config".

PermitRootLogin no

Pour vous connecter à la machine, il faudra créer un utilisateur simple avec la commande "adduser".

Une fois les modifications réalisées, relancez le démon SSH :

# rcctl reload sshd

Par la suite, pour vous connecter au serveur, vous utiliserez la commande suivante à partir de votre ordinateur (dans un terminal, ou avec un client comme putty sous windows) :

$ ssh toto@chezmoi.tld

Et si vous avez changé le port par défaut :

$ ssh -p 222 toto@chezmoi.tld

Ça demandera le mot de passe de l'utilisateur toto, puis vous pourrez administrer le serveur à distance.

Connexion par clés (sans mot de passe)

Il est tout à fait possible de se connecter en SSH sans utiliser de mot de passe. À la place, on se sert de paire de clés. C'est une bonne idée au moins pour les raisons suivantes :

Toutefois, cela vous impose d'avoir la clé privée sur la machine servant à se connecter, ce qui n'est pas toujours le cas.

Voici la marche à suivre :

Sur le serveur, modifiez le fichier "/etc/ssh/sshd_config" pour qu'il contienne cette ligne :

PubkeyAuthentication yes

Maintenant, sur l'ordinateur qui veut accéder au serveur, nous allons générer la paire de clés avec la commande suivante :

ssh-keygen -t ed25519 -f ~/.ssh/clessh -a 100

Vous trouverez deux nouveaux fichiers :

L'algorithme ed25519 est utilisé, car très fiable à l'heure actuelle.

Ne mettez pas de mot de passe puis patientez le temps que les clés soient générées.

Sur un système OpenBSD ou Linux, vous prendrez soin d'éditer le fichier "~/.ssh/config" de votre utilisateur pour le remplir ainsi :

Host votreserveur
HostName nomtreslong.vraimenttroplong.long
User jeanbaptiste.professeurdanseur
Port 222
PasswordAuthentication no
IdentityFile ~/.ssh/clessh

Bien sûr, vous modifierez le nom de domaine de votre serveur ainsi que le nom de l'utilisateur qui doit se connecter. Ensuite, lancez la commande suivante pour copier la clé publique sur le serveur.

ssh-copy-id -p xxx -i ~/.ssh/clessh.pub "jeanbaptiste.professeurdanseur@nomtreslong.vraimenttroplong.long"

Ici, remplacez "xxx" par le port utilisé par SSH.

Dans le cas où l'outil ssh-copy-id ne serait pas disponible, il faut copier la clé publique manuellement. Pour l'afficher, entrez :

$ cat ~/.ssh/clessh.pub

Connectez-vous sur le serveur en SSH, puis ajoutez dans le fichier "~/.ssh/authorized_keys" le contenu du fichier affiché précédemment.

Une fois ceci fait, vous pouvez vous connecter sans devoir entrer de mot de passe avec simplement la commande :

$ ssh votreserveur

Pratique non?

Si ça fonctionne comme prévu, vous pouvez si vous le souhaitez désactiver l'identification par mot de passe pour de bon afin de ne garder que le jeu de clés comme possibilités. Modifiez le fichier "/etc/ssh/sshd_config" pour qu'il contienne cette ligne :

PasswordAuthentication no

⚠ ATTENTION à ne pas perdre votre jeu de clés !

Transférer un fichier

Vous aurez certainement besoin d'envoyer des fichiers sur votre serveur de temps en temps. Une fois que SSH est configuré, vous pourrez utiliser la commande scp depuis n'importe quel ordinateur afin de copier un fichier vers votre serveur. Par exemple :

$ scp -P <port ssh> utilisateur@chezmoi.tld:/emplacement/de/destination fichier-a-copier

C'est très pratique.

Si vous souhaitez toutefois transférer de nombreux fichiers, sauvegarder ou stocker des documents, tournez-vous plutôt vers le protocole SFTP, disposant de davantage de fonctionnalités comme la reprise d'un transfert partiel.

Si les fichiers sont trop gros, vous pouvez les découper pour réaliser les transferts en plusieurs fois.

Pour en apprendre plus sur la sécurisation et l'utilisation de SSH, vous pouvez lire la page man, ou encore le site officiel.

Enregistrements DNS SSHFP

Lors de la premières connexion à votre serveur via SSH, un client va récupérer l'empreinte de votre serveur. Cependant, comment être sûr qu'il s'agit bien de la bonne? Au lieu d'accepter la première fois puis vérifier ensuite si l'empreinte a changé (il y a certainement dans ce cas un problème), vous pouvez publier dans votre zone DNS les informations permettant de vérifier que tout va bien.

Pour cela, depuis votre serveur, entrez la commande "ssh-keygen -r chezmoi.tld" puis copiez le résultat dans votre zone (sans oublier d'adapter au besoin en ajoutant un "." final après votre domaine ou en le modifiant pour un "@").

Par exemple :

@ IN SSHFP 1 1 97f5a9479fd16fbee1381c425297f7b2773a67a4
@ IN SSHFP 1 2 bd50a3c271e83dc769ea7c249a5c07aea1a817c62910129de56eba2763f93607
@ IN SSHFP 2 1 05fb8516842fc270ea5abda38d1c32b41e75da8a
@ IN SSHFP 2 2 491489437e137d7d27959a4de3ba7660185ef98cbd3abc2287c82f82e8f032ab
@ IN SSHFP 3 1 b7305417b0e981c4513642020a1f57ee03915af5
@ IN SSHFP 3 2 f15d33852df5f4043c77b6bf1c6134a5e11de0a513c1ec127fcbb8fae733b178
@ IN SSHFP 4 1 a1120fe90e69c0f534fece3dc837db6a262c3371
@ IN SSHFP 4 2 a36e418b517d95a74f1e0be1228d46e7aeaa8ed310359e91162d8c40b373eb55

Rassurez-vous, on parle des zones DNS un peu plus loin 😉.

Afin que ces enregistrements soient comparés à l'empreinte du serveur, les utilisateurs devront avoir activé l'option "VerifyHostKeyDNS" lorsqu'ils utiliseront ssh. Cela peut s'activer en ajoutant dans leur fichier "~/.ssh/config" :

Host *
	VerifyHostKeyDNS yes

Maintenir le système à jour

Pour conserver un système sécurisé, il est essentiel de le maintenir à jour. Afin d'appliquer les correctifs de sécurité, vous devrez maintenir :

Pour les pressés 😉 :

# syspatch
# pkg_add -u

Mettre les ports (paquets) à jour

Mettre les paquets à jour est l'histoire d'une seule commande :

# pkg_add -u

Oui, c'est tout. 😁

Merci à solene qui a rendu cela possible.

Puisque ce paragraphe est un peu court, j'en profite pour vous donner deux astuces 😊. Je vous conseille d'ajouter au fichier /"etc/daily.local "la commande

pkg_add -nu

De cette façon, dans le mail journalier envoyé par Charlie Root, vous verrez ce qu'il pourrait se passer si des paquets pouvant être mis à jours sont disponibles. En réalité, rien n'est fait, car si un programme mis à jour doit être redémarré, il risque de ne pas fonctionner le temps que vous le relanciez. Ainsi, vous êtes avertis d'éventuelles mises à jour à appliquer, et avec l'option -n, les paquets sont gardés dans le cache afin de gagner du temps sans risquer de mettre un service en panne s'il doit être redémarré suite à la mise à jour. Vous entrerez à la main "pkg_add -u" lorsque vous en aurez l'occasion.

Si vous souhaitez tout de même appliquer les mises à jour automatiquement, je vous conseille d'installer avant tout le port "checkrestart" qui vous indiquera si un service doit être relancé suite à la mise à jour. Cela donnera donc dans "/etc/daily.local" :

pkg_add -u
echo "Service à relancer avec rcctl restart:"
checkrestart

Il faudra tout de même recharger les services à la main avec rcctl.

Mettre le système à jour

Tout d'abord, un petit rappel : OpenBSD est disponible en 3 "saveurs" (flavour) :

Il peut en effet arriver que des bugs soient découverts. À chaque fois, des correctifs sont rapidement proposés. Il est alors recommandé d'appliquer les patchs de sécurité.

Depuis la version 6.1, cette opération se réalise très simplement avec la commande suivante :

# syspatch

Les patchs binaires sont alors téléchargés et installés. Wouhou ! 😁 Ça ressemblait à ça sous OpenBSD 6.1 (c'était il y a déjà longtemps) :

Get/Verify syspatch61-002_vmmfpu.tgz 100% |*******************************|  9377 KB    00:49    
Installing patch 002_vmmfpu
Get/Verify syspatch61-003_libress... 100% |*******************************| 11391 KB    00:22    
Installing patch 003_libressl
...

Cet outil n'est disponible que pour les architectures i386, amd64, et plus récemment arm64. Vous souhaiterez alors peut-être utiliser l'ancienne méthode de récupération des sources et installation manuelle.

Tout ceci est décrit dans la FAQ officielle.

Être averti des mises à jour

Pour savoir si des mises à jour doivent être appliquées, vous pouvez consulter la page errata qui contient la liste des patchs de sécurité disponibles. Il s'agit de "https://www.openbsd.org/errataXX.html", en remplaçant "XX" par le numéro de version OpenBSD : 70 pour la version "7.0" par exemple.

Vous pouvez aussi être averti par mail (et ça c'est top 😊). Pour recevoir les messages importants de mises à jour disponibles sur le système, inscrivez-vous aux listes announce et security-announce. Pour ça, on envoie un premier mail à majordomo@OpenBSD.org contenant simplement :

subscribe announce

Puis envoyez un second message avec :

subscribe security-announce

Je vous conseille aussi de vous inscrire à la liste indiquant qu'il existe une nouvelle version des ports en vous inscrivant à la liste ports-security en envoyant toujours à la même adresse un message contenant :

subscribe ports-security

Passer à une nouvelle version

Lorsqu'une nouvelle version majeure d'OpenBSD est disponible, la procédure de mise à jour est toujours détaillée sur le site officiel. Les notes de version sont toujours consultables sur "https://www.openbsd.org/faq/upgradeXX.html". Remplacez "XX" par la version vers laquelle vous voulez mettre à jour.

Depuis la version 6.5, il suffit d'une simple commande pour réaliser la mise à jour vers la dernière publication release ou vers -current :

# sysupgrade

À CHAQUE FOIS : lisez les instructions officielles de changement de version.

Nettoyer après plusieurs mises à jour

Si votre installation date un peu, vous pouvez vérifier quels fichiers vous avez peut-être oublié de supprimer avec l'aide du port "sysclean" (commande du même nom).

Seront alors listés les fichiers qui ne sont pas censés être présents par rapport à un système de base. Lisez attentivement la sortie, car il y a fort à parier que la plupart sont des fichiers de configuration créés par vos soins 😉.

Sauvegarder

On peut utiliser un serveur à la maison pour sauvegarder ses documents. C'est une précaution qui ne fait jamais de mal.

Il faut penser aussi à sauvegarder le serveur en cas de défaillance du disque dur qui vieillit un peu, d'un orage virulent ou encore d'un dérapage incontrôlé du chat qui joue derrière les meubles 😼... Ça, c'est INDISPENSABLE.

Sauvegarde automatique de la racine du serveur

OpenBSD a déjà pensé à tout. En effet, il sauvegardera chaque jour le système si une partition /altroot est présente.

Nous allons donc ajouter la ligne suivante dans le fichier "/etc/fstab" :

782f1ddb783cdd13.a /altroot ffs xx 0 0

Vous remarquerez qu'on identifie la partition avec <numéro duid du disque>.a. C'est bien "xx" qui doit être précisé comme option de montage, c' est spécifique à la fonctionnalité altroot.

Afin que le serveur soit sauvegardé chaque nuit, ajoutez maintenant la ligne suivante dans le fichier "/etc/daily.local" :

ROOTBACKUP=1

Et c'est tout ! 😁

Si un jour le disque du serveur a une défaillance, vous pourrez quand même démarrer pour le dépanner. Il faudra alors booter sur la partition de sauvegarde. Tout cela se passera au tout début du démarrage de la machine, lorsque vous verrez le prompt boot >. Vous écrirez à ce moment là :

boot > set device hd1a
boot > boot -s

Ou tout en une seule fois :

boot > boot -s hd1a:/bsd

Si le moment venu vous ne savez plus sur quelle partition se trouve votre sauvegarde, entrez ceci :

boot > machine diskinfo

⚠ ATTENTION : seul le contenu de la partition racine / est sauvegardé. Si /usr/local, /var ou autres sont montées sur des partitions respectives, elles ne seront pas sauvegardées. Ce n'est pas grave pour dépanner un système puisqu'avec le partitionnement par défaut, vous disposerez quand même du système de base, mais en aucun cas des paquets tiers installés ou vos données de sites web, ... Le paragraphe suivant est donc essentiel, ne passez pas à côté 😉

N'hésitez pas à consulter la FAQ officielle sur le sujet.

Autres sauvegardes

rsync

Vous pouvez utiliser une partition dédiée à vos sauvegardes. Dans l'exemple ci-dessous, on utilisera le moint de montage "/mnt/sauvegarde" créé pour nos besoins.

Je vous conseille d'installer l'excellent outil "rsync" pour vos sauvegardes, qui ne copiera que les fichiers qui ont été modifiés. Notez que sous OpenBSD, vous disposez de base d'un équivalent "openrsync".

Il s'agit en effet d'une réécriture de rsync pour OpenBSD, qui propose moins d'options et est actuellement moins performante, mais qui a le mérite d'exister par défaut.

Si la machine cible est une OpenBSD "pure" (sans le port rsync d'installé en plus), précisez l'option "--rsync-path=openrsync". Par défaut, c'est l'exécutable "rsync" qui est utilisé sinon.

Voici un exemple d'utilisation sur votre serveur.

Ajoutez au fichier "/etc/weekly.local" les lignes suivantes afin de sauvegarder quotidiennement les dossiers "/var" et "/usr/local" :

/usr/local/bin/rsync -a --delete /var/ /mnt/sauvegardes/var.bak/
/usr/local/bin/rsync -a --delete /usr/local/ /mnt/sauvegardes/usrlocal.bak/

Notez que vous pouvez aussi envoyer des données à sauvegarder de votre ordinateur personnel si vous voulez utiliser votre serveur comme espace de stockage. À partir de cet ordinateur, lancez la commande :

$ rsync -e "ssh" -avz --delete /dossier/a/sauvegarder \
  toto@chezmoi.tld:/mnt/sauvegarde/toto

On utilise une connexion SSH avec le compte toto pour envoyer tout un dossier sur le serveur.

tar

Vous pouvez créer une archive des différents points de montage de votre système avec "tar".

Voici une proposition générant une archive avec un nom contenant la date du jour.

BACKDIR="/mnt/bckp"
BACKLIST="/var
/home
/etc"
for i in $BACKLIST; do
    backupfile="${BACKDIR}/$(basename ${i})-$(date +%F).tar.gz"
    tar -czf "${backupfile}" "${i}"
done
chmod 700 "${BACKDIR}"
# remove olds
#find "${BACKDIR}" -type f -mtime +90 -delete

À la fin du script, vous pouvez décommenter la ligne commençant par "#find" si vous souhaitez supprimer les archives vieilles de plus de 90 jours.

SFTP : Transférer des fichiers sur le serveur

Le protocole SFTP ressemble beaucoup au célèbre FTP qui sert surtout à transférer des fichiers, mais se base sur un tunnel SSH. À vrai dire, chaque utilisateur disposant d'un accès SSH peut envoyer et télécharger des données en SFTP avec ses identifiants habituels. Un des avantages intéressant est de pouvoir reprendre un chargement partiel là où il en était, très utile pour envoyer/recevoir des fichiers volumineux.

Si vous voulez déployer un serveur SFTP pour un plus grand nombre d'utilisateurs, la mise en place d'un "chroot" est conseillée. Cette procédure est décrite plus loin dans le document car un poil plus complexe.

Transferts en ligne de commande

Pour copier des fichiers, vous pouvez utiliser la commande sftp qui s'utilise ainsi :

$ sftp -P <port> utilisateur@chezmoi.tld

Si vous avez désactivé l'identification par mot de passe au profit des clés, indiquez quelle est votre clé privée ainsi :

$ sftp -P <port> -i ~/.ssh/clessh utilisateur@chezmoi.tld

ou :

$ sftp -P <port> -o IdentityFile=~/.ssh/clessh utilisateur@chezmoi.tld

Vous voilà alors devant une invite de commande.

Voici quelques commandes utiles :

Rien de bien compliqué finalement, mais vous préférerez peut-être un client graphique comme expliqué ci-dessous.

Transferts avec un client graphique

Avec Filezilla

Le logiciel Filezilla peut se télécharger ou s'installer directement via le gestionnaire de paquets de votre distribution. Vérifiez qu'il s'agit bien d'une version à jour.

Ouvrez Filezilla, puis cliquez sur la petite icône en haut à gauche "Gestionnaire de sites". Une nouvelle fenêtre s'ouvre.

Cliquez sur "Nouveau Site", puis remplissez les champs ainsi :

Il ne vous reste plus qu'à cliquer sur Connexion. Sélectionnez les fichiers que vous souhaitez envoyer ou récupérer, puis faites un clic-droit pour les télécharger. La même chose est possible avec des glisser/déposer.

D'autres clients graphiques existent, on pourra notamment citer WinSCP disponible sous Windows.

Avec votre gestionnaire de fichiers

Selon votre système d'exploitation, il y a fort à parier que votre gestionnaire de fichiers (Dolphin sous KDE ou Nautilus sous Gnome par exemple) soit lui même capable d'ouvrir une session SFTP. Comme chemin vers le dossier, indiquez simplement :

sftp://utilisateur@chezmoi.tld:222

Remplacez 222 par le port ssh du serveur (22 si vous ne mettez rien). Bien sûr, "utilisateur" est aussi à remplacer (par exemple jean_eudes ou toto).

Cela peut fonctionner par exemple avec Nautilus (gestionnaire de fichiers de GNOME) ou encore Thunar (XFCE).

Avec sshfs

sshfs est un outil qui permet de monter un dossier disponible via SFTP comme s'il s'agissait d'un point de montage de votre système. Peu importe votre gestionnaire de fichiers, vous pourrez copier vos documents comme s'il s'agissait d'un dossier classique.

sshfs s'utilise tout simplement ainsi :

sshfs -d utilisateur@chezmoi.tld:/dossier/distant /mnt/sftp 

Ensuite, le dossier /mnt/sftp contiendra le contenu du dossier distant.

Dans le cas où vous utilisez une identification par clé uniquement, indiquez quelle clé privée utiliser ainsi :

sshfs -d utilisateur@chezmoi.tld:/dossier/distant /mnt/sftp \
    -o IdentityFile=/home/toto/.ssh/sshkey

SFTP avec chroot

L'idée ici est d'enfermer dans un dossier les utilisateurs appartenant au groupe sftpusers que l'on crée pour cette occasion afin de gérer finement les permissions. Cela leur évitera de copier n'importe où leurs documents, mais aussi de supprimer des éléments importants du serveur.

À titre d'exemple, nous allons mettre le chroot dans le dossier /var/sftp. Chaque utilisateur aura dans ce dernier un dossier qui lui sera propre. Il ne pourra pas en sortir. Les utilisateurs auront l'impression qu'il s'agit d'une nouvelle racine /. Automatiquement, ils seront placés dans un dossier "/home" situé dans cette nouvelle racine. Il faudra donc créer des répertoires "/var/sftp/home/utilisateur1", "/var/sftp/home/utilisateur2", ...

Créons de suite le groupe en question :

# groupadd sftpusers

Éditez le fichier de configuration ssh "/etc/ssh/sshd_config" puis ajoutez les lignes suivantes pour enfermer les utilisateurs de ce groupe dans un chroot :

Match Group sftpusers
      ChrootDirectory /var/sftp/
      ForceCommand internal-sftp
      AllowTcpForwarding no

Notez que vous pouvez faire de même pour un utilisateur en particulier. Dans ce cas vous ajouterez une section "Match User utilisateur".

Si vous souhaitez ne permettre que l'identification par clé, précisez dans cette section :

PasswordAuthentication no

Ensuite, relancez SSH : "rcctl reload sshd"

Créez maintenant un dossier /sftp dans le dossier /var/ pour que les utilisateurs y soient automatiquement placés à leur connexion.

# mkdir -p /var/sftp

Modifiez les permissions pour assurer une sécurité supplémentaire :

# chown root:wheel /var/sftp
# chmod 700 /var/sftp

Chaque utilisateur du groupe sftpusers verra ce dossier comme la nouvelle racine "/". Notez que ces utilisateurs ne pourront qu'utiliser le protocole sftp, et donc la commande sftp (ou un client graphique), mais pas scp ou openrsync au travers d'un tunnel ssh.

Ajouter un compte SFTP

Ajouter un compte SFTP revient à créer un nouvel utilisateur et mettre ce dernier dans le groupe sftpusers.

Il faut quand même faire attention à plusieurs points :

Voici la marche à suivre :

# install -d -o ${user} -g ${user} -m 700 "/var/sftp/home/${user}"

L'utilisateur peut maintenant utiliser le protocole SFTP. Il sera enfermé dans son dossier précédemment créé.

Je vous invite à créer un script pour vous faciliter cette procédure :

#!/bin/sh
# addsftpuser.sh : 
  if [ $# -ne 1 ]; then
      echo "usage: $0 user"
      exit
  fi
# CHANGE MOI
  CHROOT=/var/sftp/
  user="$1"
  mkdir -p "${CHROOT}"
  useradd -G sftpusers -s /sbin/nologin -m "${user}" || exit 1
  install -d -o ${user} -g ${user} -m 700 "${CHROOT}/home/${user}"
exit

Si vous avez activé l'identification par clé, vous remplirez le fichier ".ssh/authorized_keys" dans le dossier personnel de l'utilisateur : celui placé dans "/home", ⚠ pas le "/home" du chroot mais celui du système hôte".

Un serveur à l'heure (ntpd)

Il est essentiel que votre serveur dispose d'une date et heure justes. Normalement un système d'exploitation, et OpenBSD fait de même, récupère cette information du matériel (carte mère). Néanmoins, dans certains cas cette donnée n'est pas fiable : matériel embarqué, machine virtuelle... Votre machine doit disposer d'une date et d'une heure précises avec peu de variation, sinon certaines données n'auront plus de valeur et vous devrez faire face à de nombreux problèmes : fichiers de logs inutiles, agenda fou, bases de données corrompues...

Afin de maintenir à l'heure votre beau serveur, nous allons utiliser OpenNTPD qui permet de synchroniser notre horloge à intervalles réguliers sur des serveurs de temps de confiance. Pas d'inquiétude, là encore c'est très simple.

Installation

OpenNTPD développé par l'équipe OpenBSD est déjà présent sur votre machine 😁. Nous devons juste préciser à notre serveur de lancer OpenNTPD au démarrage (c'est normalement déjà le cas par défaut).

# rcctl enable ntpd

Configuration

Nous allons maintenant passer à l'étape de configuration. Tout se passe dans un seul fichier situé ici : "/etc/ntpd.conf"

# See ntpd.conf(5) and /etc/examples/ntpd.conf
## http://support.ntp.org/bin/view/Servers/WebHome#Finding_A_Time_Server
# Serveurs de backup
servers fr.pool.ntp.org
servers pool.ntp.org
server time.cloudflare.com
# use all detected timedelta sensors
sensor *
# constraint without requiring DNS resolution
constraint from "9.9.9.9" 
constraint from "2620:fe::fe"
# get the time constraint from a well-known HTTPS site
constraints from "www.openbsd.org"

On liste plusieurs serveurs de temps utilisés et on termine par se référer à des sites disponible via https de confiance pour éviter les attaques "Man in the middle".

Vous ne voulez pas de "#listen on *" puisque vous n'êtes que clients : ce n'est pas vous qui indiquez aux autres serveur quelle est la bonne heure.

Terminez par relancer ntpd pour prendre les changements en compte :

# rcctl restart ntpd

Et voilà 😊

httpd par défaut

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 s'oppose par sa simplicité.

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 ajuster les permissions ensuite.

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 parefeu 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.

Letsencrypt

Nous allons proposer en exemple d'obtenir un certificat via letsencrypt (https://letsencrypt.org), une autorité de certification gratuite dont 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 parefeu (et si vous utilisez un adressage privé, vérifiez vos renvois de ports, beaucoup d'erreurs viennent de là) ! En effet, acme-client doit rendre disponible sur votre serveur des "fichiers secrets" 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. Enfin, 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 :

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
    # specifique liee à votre site
}

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

Vous voudrez sans doute 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 le bloc suivant :

# 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 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 pasaux 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"

Puisqu'on doit permettre l'obtention des certificats pour chaque site servi, autrement dit ceux définis dans la ligne "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 nommé "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 pouser 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 est possible.

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 😄

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. Ça démontre que le certificat n'est pas là de façon fortuite. Cette étape est une preuve de bonne foi supplémentaire. Dans votre zone, il y aura donc :

@ 300 IN   CAA   0 issue "letsencrypt.org"

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 "man 8 ssl"

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

Cette connexion n'est pas certifiés, 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 req -x509 -sha512 -nodes -days 365 -newkey rsa:4096 \
  -keyout /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.

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
# chmod 600 /etc/ssl/private/serveur.key
# chmod -R go-rwx /etc/ssl/private

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

Il est fort possible que vous souhaitiez ajouter le support de PHP à votre site, 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.

PHP avec des modules et du chroot

Je vous propose dans cette partie d'aller un peu plus loin pour préparer l'installation d'applications plus complètes (blog, CMS...) en activant des extensions et des options qui ne le sont pas par défaut, toujours dans un souci de sécurité.

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-7.4.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 du cache pour le pas régénérer à chaque fois les pages
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.enable_file_override=1

Configuration 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 le programme responsable de l'envoi des mails : sendmail. 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.

Astuces pour httpd

man

Je ne peux m'empêcher de vous inciter à lire le man 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"

Le dossier /var/www/htdocs/chezmoi.tld/err" contient alors le fichier "err.html" suivant :

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<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.

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 {
        text/"plain;charset=UTF-8" gmi
        text/"plain;charset=UTF-8" txt
}

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
}

Inclusions 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"

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
}

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 droits non-souhaités à 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.

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.

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 127.0.0.1 port 80
}

Voici ce que ces lignes signifient :

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

# configuration de httpd
listen on localhost port 80

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

1. Un visiteur demande à voir votre site web, il se présente sur le port 80.

2. relayd modifie quelques entêtes et redirige le tout à httpd qui retourne la page web demandée comme il le faisait d'habitude.

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":

log style forwarded

Vous pouvez consulter un exemple de configuration à la fin du document.

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 with tls to 127.0.0.1 port 443
}

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 😉

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

IPv6

Si vous voulez proposer un accès IPv4 et IPv6 avec relayd, vous devrez configurer les 2.

Tout d'abord, assurez-vous d'avoir 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, créez dans la configuration de relayd 2 entrées :

relay "http" {
        listen on $ext_ip4 port 80
        protocol "http"
        forward to 127.0.0.1 port 80
}
relay "http6" {
        listen on $ext_ip6 port 80
        protocol "http"
        forward to ::1 port 80
}

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

listen on localhost port 80

Gestion des entêtes

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éberger de grosses applications web (inutile dans le cas d'un site statique).

match request header remove "Proxy"
match response header set "X-Xss-Protection" value "1; mode=block"
match response header set "Frame-Options" value "SAMEORIGIN"
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=()"

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

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 étiquette

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.

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 "php-pdo_sqlite-*" et "php-sqlite3-*".

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 contennu 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.

Créer une base de données

À 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 :

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

Sauvegarder / Restaurer une base de données

Avec 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 openrsync, ne vous compliquez pas la vie.

Avec MariaDB

Pour MariaDB ou MySQL, la sauvegarde s'appelle un "dump" et se réalise via 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 :

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

Avec PostgreSQL

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, 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. Les instructions des développeurs de chaque application seront donc à suite.

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.

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.

Il existe aussi alternative.to qui recense quelques projets.

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

Configuration d'un Webmail

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 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

Malheureusement, webalizer ne semble plus mis à jour, mais il continue de bien fonctionner.

Webalizer

Webalizer est un outil qui peut générer graphiques et tableaux à partir des logs (journaux) de votre serveur. En un clin d'oeil 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.

matomo

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 HTMLHead body { HTMLHead background: radial-gradient(circle,#2569A0,#000046); HTMLHead } 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é? 😎

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 ♥Z>: size (KB): 7.24 [10] --> trimming log....
/var/log/authlog <7Z>: age (hr): 88 [168] --> trimming log....
/var/log/daemon <5Z>: size (KB): 0.41 [30] --> trimming log....
/var/log/lpd-errs <7Z>: size (KB): 2.02 [10] --> trimming log....
/var/log/maillog <7Z>: age (hr): 16 [24] --> trimming log....
/var/log/messages <5Z>: size (KB): 0.45 [30] --> trimming log....
/var/log/secure <7Z>: age (hr): -1 [168] --> trimming log....
/var/log/wtmp <7B>: --> trimming log....
/var/log/xferlog <7Z>: size (KB): 0.00 [250] --> trimming log....
/var/log/pflog ♥ZB>: size (KB): 64.26 [250] --> trimming log....
/var/www/logs/access.log <4Z>: --> trimming log....
/var/www/logs/error.log <7Z>: size (KB): 212.87 [250] --> trimming log....
/var/www/logs/mateteestmalade.log <7Z>: size (KB): 3.93 [250] --> trimming log....
Webalizer Xtended RB30 (06-Apr-2014) / [OpenBSD https://www.openbsd.org/] 5.9 amd64 / English
Copyright 2005-2014 by Patrick K. Frei
Based on Webalizer V2.23-08
Using logfile /var/www/logs/access.log (clf)
Using GeoIP Country Edition (/var/db/GeoIP/GeoIP.dat)
GEO-106FREE 20151201 Build 1 Copyright (c) 2015 MaxMind Inc All Rights Reserved
Creating output in /var/www/htdocs/chezmoi.tld/stats
Hostname for reports is 'chezmoi.tld'
Reading history file... webalizer.hist
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.

goaccess

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"

Introduction à l'hébergement d'emails

Devenir responsable de ses communications est un pas de géant vers l'autonomie et la liberté. Cette partie explique l'installation d'un serveur de courriel à la maison. Aucune base de données ne sera requise, puisque cela ne représente aucun intérêt en auto-hébergement. Restons simples !

La mise en place d'un serveur mail est souvent considérée comme délicate. C'est vrai qu'il faut prendre le temps pour le configurer. Ce n'est pas compliqué, mais complexe. On va donc détailler l'installation pas à pas en petites étapes simples :

Nous verrons en passant comment ajouter de nouveaux comptes mail sur votre serveur et comment configurer votre client de messagerie pour l'utiliser.

Vous devrez tout d'abord ouvrir le port 25 (smtp) dans la configuration de votre parefeu.

Notez que certains fournisseurs d'accès à internet bloquent les mails sortant (port 25). Renseignez-vous avant d'avoir une mauvaise surprise. À défaut, regardez une proposition au paragraphe parlant de service smtp externe.

En complément, vous voudrez (devriez 😉) peut-être lire le tutoriel du développeur d'opensmtpd.

Configuration de votre zone DNS pour un serveur mail

Le système de mail passe par des enregistrements qui lui sont propres. Nous devons donc procéder à quelques modifications dans notre zone DNS. Ajoutez deux nouveaux champs.

Un champ de type A qui pointe vers votre IP (sans doute déjà présent):

chezmoi.tld.  IN  A  192.0.2.2

Bien sûr, remplacez 192.0.2.2 par votre IP.

Un champ de type MX qui pointe vers le A précédent :

chezmoi.tld.  IN  MX  1  chezmoi.tld.

Notez l'importance du "." final.

Le "1" indique le "poids" de ce champ. Vous pourrez plus tard définir d'autre champs MX avec un poids plus important afin qu'ils aient une priorité plus faible et servent de "backup" en cas d'indisponibilité. On en parlera plus tard lorsque vous organiserez plusieurs serveurs avec des amis.

Certains utilisent un nom de domaine spécifique, soit un champ A différent du domaine principal afin de gérer des backups (serveurs de mail secondaires) ou bien tout simplement héberger un serveur mail derrière une autre IP que celle du serveur web. Ce n'est pas nécessaire du tout, mais si vous y tenez, voici à quoi ça ressemblera :

mail1.chezmoi.tld.  IN  MX  1  mail1.chezmoi.tld.
mail1.chezmoi.tld.  IN  A      192.0.2.2

Voici un autre exemple :

$ORIGIN chezmoi.tld
[...]
@                             IN MX 10  mail1.chezmoi.tld.
@                             IN A      192.0.2.2
mail1                         IN A      192.0.2.3

On voit ici que si on demande quel serveur s'occupe des mails pour le domaine "chezmoi.tld", la zone indique : "c'est la machine située à mail1.chezmoi.tld". Plus loin, on voit que mail1.chezmoi.tld est derrière l'ip 192.0.2.3 qui n'est pas la même que celle pour chezmoi.tld seul.

Ça sera tout pour cette partie.

Obtention des certificats

Ces certificats permettront de chiffrer la communication entre votre serveur et le logiciel qui récupère vos mails. De plus, cela rend chaque communication authentique.

Pour obtenir ou créer des certificats, je vous renvoie à la partie consacrée dans le chapitre sur httpd.

Que vous utilisiez letsencrypt ou bien des certificats auto-signés (voir man ssl(8)) n'a pas grande importance, les deux fonctionnent très bien. Veillez juste à bien prendre note de l'emplacement des certificats sur votre serveur.

Par la suite, nous feront comme si nous utilisions les certificats obtenus avec letsencrypt seulement dans un souci de cohérence.

Veillez à bien indiquer dans la liste des domaines certifiés une entrée correspondant à votre champ MX.

Un serveur mail en 10 minutes

Voici une configuration pour les trop pressés. Vous pouvez aussi voir cette partie comme une ébauche sur laquelle dont on se servira de base pour la suite. Avec cette dernière :

La configuration sera plus détaillée et expliquée dans la partie avec utilisateurs virtuels. Ici, c'est pour les pressés.

C'est parti ? 😊

Fichier smtpd.conf

Voici le contenu du fichier /etc/mail/smtpd.conf :

# Configuration generale
## Tables 
table aliases "/etc/mail/aliases"
## Certificats
pki chezmoi.tld key "/etc/ssl/private/chezmoi.tld.key"
pki chezmoi.tld cert "/etc/ssl/chezmoi.tld.crt"
### Reception
listen on all tls pki chezmoi.tld 
### Envoi avec client de messagerie
listen on all port submission tls-require pki chezmoi.tld auth 
# ACTIONS
action "envoilemail" relay 
## On applique les alias systeme
action local_maildir maildir alias <aliases>
## On delivre l'enveloppe dans un dossier maildir
action in_maildir maildir 
# Correspondances
## Reception
### Message du systeme pour les utilisateurs locaux
match for local action local_maildir
### Message veant d'ailleurs correspondant au domaine géré
match from any for domain "chezmoi.tld" action in_maildir
## Envoi
match for any action "envoilemail"
match auth from any for any action "envoilemail"

C'est tout 😊

Il y a autant de commentaires que de réelles instructions.

Configuration de dovecot (IMAP)

Installez dovecot avec "# pkg_add dovecot".

Dans le fichier "/etc/dovecot/local.conf" indiquez :

# On écoute en IPV4 et IPV6.
listen = *, [::]
# On stocke en Maildir
mail_location = maildir:~/Maildir
# imap > pop
protocols = imap
# Securisation. Editez ces lignes
ssl = yes
ssl_cert = </etc/ssl/chezmoi.tld.crt
ssl_key = </etc/ssl/private/chezmoi.tld.key
disable_plaintext_auth = yes
# methodes d'authentification
passdb {
        driver = bsdauth
}
userdb {
        driver = passwd
}

Rechargez dovecot : "# rcctl restart dovecot".

Et voilà ! Vous pouvez maintenant configurer votre client de messagerie.

Serveur mail complet avec utilisateurs virtuels

Cette désignation fait référence à des utilisateurs qui sont bien réels, mais qui ne sont pas des comptes UNIX à proprement parler pouvant accéder à un shell (la ligne de commande).

Ainsi, un nouveau compte mail ne sera pas créé avec adduser, mais en éditant un simple fichier texte contenant le nom d'utilisateur et un hash de son mot de passe.

On verra ici comment installer un serveur SMTP (opensmtpd) et IMAP (Dovecot).

Un utilisateur responsable des mails : _vmail

On va créer utilisateur en charge de tous les mails. Il portera le doux nom de "_vmail" 😁. Ce dernier ne servira qu'à ça et n'aura donc pas accès au shell, c'est plus sûr 😊 :

# useradd -m -g =uid -c "Virtual Mail" -d /var/vmail -s /sbin/nologin _vmail

Un nouveau dossier est créé : /var/vmail. Les messages des utilisateurs seront dedans, mais bien organisés : dans ce dossier, il y aura des sous-répertoires portant le nom des utilisateurs virtuels. Ainsi, les messages seront enregistrés dans, par exemple :

/var/vmail/chezmoi.tld/batman/Maildir
/var/vmail/chezmoi.tld/utilisateur/Maildir
/var/vmail/chezmoi.tld/ninja/Maildir
...

/etc/mail/virtuals

Ce fichier contient la liste des utilisateurs, un par ligne. Il fonctionne comme le fichier /etc/mail/aliases (lisez le man aliases(5) 😉):

heros@chezmoi.tld batman@chezmoi.tld,superman@chezmoi.tld
batman@chezmoi.tld _vmail
superman@chezmoi.tld _vmail
kiki@chezmoi.tld _vmail

Eh oui, toutes ces adresses correspondent (lire "appartiennent") à l'utilisateur _vmail.

Notez que sur la première ligne, on a fait un alias à titre d'exemple pour transférer un mail d'une adresse (heros@chezmoi.tld) vers plusieurs autres (batman@chezmoi.tld et superman@chezmoi.tld).

/etc/mail/passwd

Même logique ici, une ligne pour un mot de passe :

batman@chezmoi.tld:$2b$09$lerdFpdQtnu.Bs5EpAsVbeF851GjdD0aza8IDhho38i1DOHk.ujzi
superman@chezmoi.tld:$2b$09$VRU/CYJUS3QZHVUFP70xIOURPbiNQeyOEZHoZo6NOY3uO.XSpd2MW

Chaque ligne est constituée de l'adresse mail puis du hash du mot de passe, séparés par un ":" : <email>:<hash>

Afin de chiffrer le mot de passe, utilisez la commande encrypt ainsi :

encrypt -p

Ou bien l'équivalent : "smtpctl encrypt mot_de_passe".

Ça vous demande d'entrer le mot de passe. Lorsque vous validez avec "Entrée", un hash du mot de passe s'affiche, il reste à le copier dans "/etc/mail/passwd".

(Facultatif) Permissions sur les fichiers d'identification

Les fichiers précédents ne doivent pas être lisibles par un simple utilisateur de passage. Faisons en sorte que seul l'administrateur (root) puisse écrire dedans et rendons-les lisibles par les démons qui en auront besoin : dovecot et smtpd. Ce n'est pas une obligation, mais c'est une précaution qui ne peut blesser personne 😉.

Dovecot et smtpd fonctionnent à partir d'utilisateurs aux accès restreints, respectivement _dovecot et _smtpd. Tout ceci permet de protéger votre serveur si un jour, l'un de ces services était compromis.

Nous allons créer un groupe _maildaemons dans lequel nous mettrons les deux utilisateurs cités ci-dessus afin de faciliter la gestion des permissions :

# groupadd _maildaemons
# usermod -G _maildaemons _smtpd
# usermod -G _maildaemons _dovecot

dovecot n'est peut-être pas installé à ce stade de votre lecture puisqu'on en parle plus loin. Installez-le avant la dernière commande : "# pkg_add dovecot".

On définit maintenant le propriétaire et le groupe des fichiers contenant les mots de passe et identifiants :

# chown root:_maildaemons /etc/mail/passwd /etc/mail/virtuals

Enfin, on ne permet qu'à root d'écrire dans ces fichiers et au groupe _maildaemons d'en lire le contenu :

# chmod 640 /etc/mail/passwd /etc/mail/virtuals

Si vous vérifiez, vous voyez que les permissions et propriétaires sont corrects :

# ls -l /etc/mail/passwd
-rw-r-----  1 root  _maildaemons  17226 Nov 12 08:40 /etc/mail/passwd

Configuration d'Opensmtpd (smtpd)

Opensmtpd (smtpd) est le serveur mail par défaut sur OpenBSD. Il est déjà installé, reste à le configurer.

Cependant, avant toutes choses, ouvrez et redirigez les ports suivants : 25 (smtp), 587 (submission) et 993 (imaps). Ce dernier servira à dovecot. Nous ne préoccupons pas du port 465 (smtps) car il est déprécié.

Pour configurer opensmtpd, on édite "/etc/mail/smtpd.conf". Ce dernier sera mis en oeuvre dans l'ordre de lecture.

Ce dernier se décompose en 3 parties :

Le voici, à adapter à vos besoins :

# Configuration generale
## Tables 
table aliases "/etc/mail/aliases"
table passwd "/etc/mail/passwd"
table virtuals "/etc/mail/virtuals"
## Certificats
pki chezmoi.tld key "/etc/ssl/private/chezmoi.tld.key"
pki chezmoi.tld cert "/etc/ssl/chezmoi.tld.crt"
## Ecoute pour recevoir/envoyer
### Reception
listen on all tls pki chezmoi.tld 
### Envoi avec client de messagerie
listen on all port submission tls-require pki chezmoi.tld auth <passwd> 
# ACTIONS 
action "envoi" relay 
action local_mail maildir alias <aliases>
action virtual_maildir maildir "/var/vmail/%{dest.domain:lowercase}/%{dest.user:lowercase}/Maildir" virtual <virtuals>
# Correspondances
## Reception
### Message pour les utilisateurs virtuels
match from any for domain chezmoi.tld action virtual_maildir
### Message pour les utilisateurs locaux
match from any for local action local_mail
## Envoi
match auth from any for any action "envoi"
match for any action "envoi"

Vous n'avez quasiment rien à modifier dans ce fichier, mis à part "chezmoi.tld" à remplacer par votre nom de domaine.

STOOOP! On veut des détails!

Regardons les lignes de ce fichier les unes après les autres.

Tous d'abord, les premières lignes correspondent à des options générales.

Ensuite, sont définies quelques actions qui seront appliquées aux mails. Il peut s'agir d'envoyer un courriel à l'extérieur ou bien de distribuer une enveloppe à un utilisateur du serveur.

Enfin, on regarde si on doit envoyer un message ou le délivrer pour appliquer les actions définies.

Notez que si rien n'est précisé, on considère que la règle s'applique pour un message venant du serveur : le "from local" est sous-entendu. Sinon, "from any" permet d'envoyer un message à partir de votre ordinateur, en passant par le serveur.

Nous passons maintenant à une étape simple mais importante afin que les mails soient correctement émis. Il faut indiquer dans le fichier "/etc/mail/mailname" votre nom de domaine sur une seule ligne. Il s'agit du domaine de l'enregistrement MX de votre zone DNS :

chezmoi.tld

Nous pouvons maintenant activer et relancer le serveur smtpd :

# rcctl enable smtpd
# rcctl restart smtpd

Voilà pour opensmtpd 😊.

Dovecot

Dovecot va être utilisé comme serveur IMAP, afin de pouvoir récupérer son courrier à partir d'un client comme Thunderbird.

On installe dovecot comme d'habitude :

# pkg_add dovecot

On édite maintenant le fichier "/etc/dovecot/local.conf" pour y mettre le contenu suivant :

# On écoute en IPV4 et IPV6.
listen = *, [::]
# imap > pop
protocols = imap
# Chiffrement. Editez ces lignes
ssl = yes
ssl_cert = </etc/ssl/chezmoi.tld.crt
ssl_key = </etc/ssl/private/chezmoi.tld.key
disable_plaintext_auth = yes
# emplacement des mails. %d : domaine, %n : nom d'utilisateur
mail_location = maildir:/var/vmail/%d/%n/Maildir
# tres important comme on a modifie les permissions
# sur /etc/mail/passwd
service auth {
    user = $default_internal_user
    group = _maildaemons
}
# methodes d'authentification
passdb {
    args = scheme=blf-crypt /etc/mail/passwd
    driver = passwd-file
}
# Les messages sont dans /var/vmail et appartiennent à _vmail
userdb {
    driver = static
    args = uid=_vmail gid=_vmail home=/var/vmail/%d/%n/ 
}

L'exemple ci-dessus est commenté pour vous aider à comprendre ce qui y est fait.

Pensez à adapter l'emplacement des certificats aux variables ssl_cert et ssl_key.

Par ailleurs, une configuration ssl est déjà pré-configurée dans le fichier "/etc/dovecot/conf.d/10-ssl.conf". C'est censé nous faciliter la vie avec un script qui génère un certificat auto-signé, mais comme on a déjà nos certificats et configuré cette partie, il risque de ne pas trop aimer. Dans ce fichier, commentez donc toutes les lignes restantes :

## Fichier /etc/dovecot/conf.d/10-ssl.conf
#ssl_cert = </etc/ssl/dovecotcert.pem
#ssl_key = </etc/ssl/private/dovecot.pem

Pour terminer cette partie, on active dovecot et on relance les différents éléments constituant le serveur mail.

# rcctl enable dovecot
# rcctl start dovecot
# rcctl restart smtpd

Il vous est désormais possible d'utiliser un client de messagerie afin de consulter votre courrier.

Ajouter un nouveau compte mail

Vous devez remplir les fichiers "/etc/mail/virtuals" et "/etc/mail/passwd" avec une ligne en plus comme on l'a vu au tout début. Ensuite, lancez les commandes suivantes pour que smtpd prenne vos changements en compte :

smtpctl update table virtuals
smtpctl update table passwd

Ou alors, relancez smtpd avec rcctl.

Gérer plusieurs domaines

Vous pouvez héberger un serveur mail recevant/envoyant des messages pour plusieurs domaines différents. Un peu d'organisation pour y arriver ne fait pas de mal. Vous devrez aussi être attentif à la façon dont vous gérer les certificats SSL.

Voici quelques notes à ce sujet:

smtpd

Je vous recommande de créer un fichier contenant la liste de tous les domaines que vous gérez. Ce dernier pourrait être "/etc/mail/domains" et contenir:

chezmoi.tld
domain.tld
other.bar

Ainsi, au lieux d'avoir dans "/etc/mail/smtpd.conf" une ligne pour chaque domaine, il suffira :

table domains "/etc/mail/domains"
...
match from any for domain <domains> action virtual_maildir

Vous devrez être attentif aux certificats utilisés. En supposant qu'il existe un certificat par domaine, vous pourrez indiquer les lignes suivantes. Vous remarquerez qu'on termine par un certificat par défaut avec "*" :

pki chezmoi.tld key "/etc/ssl/private/chezmoi.tld.key"
pki chezmoi.tld cert "/etc/ssl/chezmoi.tld.crt"
pki domain.tld key "/etc/ssl/private/domain.tld.key"
pki domain.tld cert "/etc/ssl/domain.tld.crt"
pki other.bar key "/etc/ssl/private/other.bar.key"
pki other.bar cert "/etc/ssl/other.bar.crt"
pki "*" key "/etc/ssl/private/chezmoi.tld.key"
pki "*" cert "/etc/ssl/chezmoi.tld.crt"
...
listen on all tls
...
listen on all port submission tls-require auth <passwd>

TOUTEFOIS, il vous est tout à fait possible de n'utiliser qu'un seul certificat contenant une certification pour plusieurs domaines, en utilisant "alternative names" dans la configuration d'acme-client. C'est nettement plus facile à gérer. La configuration de smtpd est alors la même qu'avec 1 seul certificat.

dovecot

Pour dovecot, la principale différence à prendre en compte est la gestion des certificats. Il faudra ajouter des sections "local_name" pour les domaines supplémentaires. Cela pourra ressembler à cette configuration:

ssl = yes
ssl_cert = </etc/ssl/chezmoi.tld.crt
ssl_key = </etc/ssl/private/chezmoi.tld.key
# pas de plaintext
disable_plaintext_auth = yes
local_name domain.tld {
        ssl_cert = </etc/ssl/domain.tld.crt
        ssl_key = </etc/ssl/private/domain.tld.key
}
local_name other.bar {
        ssl_cert = </etc/ssl/other.bar.crt
        ssl_key = </etc/ssl/private/other.bar.key
}

Ici aussi, n'utiliser qu'un seul certificat pour plusieurs domaines sera nettement plus pratique.

Redirection de mail

Il est simplissime de transférer les mails reçus sur une adresse vers un autre compte de messagerie comme c'est indiqué dans la page man aliases(5).

Par exemple, vous disposez d'une adresse bibi@chezmoi.tld et souhaitez que tous les messages reçus par bibi soient transférés automatiquement à jean-eudes@ouaf.xyz.

Pour ça, il suffit d'éditer le fichier /etc/mail/virtuals, puis d'y ajouter une ligne comme celle-ci :

bibichezmoi.tld: jean-eudes@ouaf.xyz

Dans le fichier /etc/mail/aliases, vous pouvez aussi faire des redirections avec les utilisateurs du serveur, très utile pour l'adminstration système. On peut dans ce cas ne spécifier que le nom d'utilisateur.

root: jean
hostmaster: root
postmaster: root
webmaster:  arthur
jean: toto@serveurmail.net

De façon générale, ça donne :

utilisateur: adresse1.mail.com, adresse2.mail.com

Afin que ce changement soit pris en compte, le plus simple reste la commande suivante :

# rcctl restart smtpd

C'est tout! Je vous l'avais dit que c'était simple. 😎

Configurer son client de messagerie

Pour consulter vos mails sur le serveur, vous pouvez utiliser un client de messagerie comme l'excellent Thunderbird, logiciel-libre respectueux de votre vie privée.

Voici les paramètres qu'il faudra indiquer au logiciel pour envoyer et recevoir des courriels. Notez que tous ne vous seront peut-être pas demandés :

Enregistrements DNS facultatifs pour clients

Pour simplifier la configuration des clients de messagerie lorsqu'on veut ajouter un nouveau compte mail, vous pouvez ajouter dans votre zone DNS les enregistrements suivants, compris par la plupart des logiciels existants :

_submission._tcp.chezmoi.tld  86400   IN  SRV 0 1 587 chezmoi.tld
_imap._tcp.chezmoi.tld        86400   IN  SRV 0 0 0   .
_imaps._tcp.chezmoi.tld       86400   IN  SRV 0 1 993 chezmoi.tld

Ainsi, les clients pourront détecter plus facilement la configuration nécessaire et auto-configurer votre accès.

Lire la rfc6186 correspondante.

Ne pas perdre de messages : champs MX et backup

Il est possible que des mails n'arrive pas à votre serveur si ce dernier est hors-ligne pendant plus d'une semaine. Normalement, tous les serveurs de messagerie tenteront à intervalles régulier de renvoyer un mail qui n'a pas pu être délivré.

Cependant, c'est plus rassurant de prévoir le coup en configurant une solution de secours. Il vous faut pour cela :

Ce serveur gardera vos messages en file d'attente le temps que le vôtre redevienne disponible.

De votre côté, il vous suffit d'ajouter à votre zone un nouveau champ MX avec un "poids" plus élevé que le vôtre. Ce champ pointe vers le serveur secondaire :

@                     IN MX 10  chezmoi.tld.
@                     IN MX 70  mail.copain.eu.

Dans l'exemple ci-dessus, votre serveur a un poids inférieur (10) que celui de du serveur secondaire (70). Ce dernier sera utilisé si le premier n'est pas disponible.

De son côté, votre ami, pour peu qu'il utilise lui aussi opensmtpd n'aura qu'à ajouter les lignes suivantes à son "/etc/mail/smtpd.conf" afin de se constituer serveur mail de secours :

action relaybackup relay backup mx "chezmoi.tld" 
...
match from any for domain chezmoi.tld action relaybackup

L'idéal, c'est de lui rendre la pareille 😉.

Ne pas être mis dans les spams (SPF, DKIM...)

En l'état, vous pouvez recevoir et envoyer des messages. Cependant, il se peut que certains serveurs de messagerie considèrent vos mails comme des spams. Heureusement, il existe quelques petites manipulations pour rendre vos messages légitimes. Nous allons les détailler dans les paragraphes suivants. Gardez à l'esprit qu'elles se complètent sans se suffire à elles-mêmes.

Reverse DNS

Chez votre Fournisseur d'accès à internet, cherchez les options correspondant à votre adresse IP. Vous pourrez configurer un reverse DNS ou en français DNS inverse.

Alors que votre nom de domaine est relié à l'IP du serveur, il faut aussi configurer la réciproque, c'est-à-dire relier à votre IP le nom de domaine.

Un petit mail à votre fournisseur permettra de savoir comment s'y prendre si vous ne trouvez pas 😉.

Si vous ne pouvez pas faire cette manipulation, ce n'est pas une catastrophe, du moment que vous pouvez mettre en place SPF et DKIM (voir paragraphes suivants). Vous disposez très certainement d'un DNS inverse valide, bien qu'il ne corresponde pas forcément à votre domaine.

Une autre possibilité consiste à louer un VPN pour obtenir une nouvelle IP dédiée à votre serveur. Les fournisseurs de VPN proposent souvent un reverse DNS configurable.

SPF

Normalement, seul votre serveur est autorisé à envoyer des messages avec votre nom de domaine. Un enregistrement SPF dans votre zone permet de le préciser. Puisque normalement, c'est l'administrateur du serveur de mail qui gère aussi la zone, c'est une preuve de bonne foi. L'absence de champ SPF est très mauvais pour la réputation d'un mail.

Ajoutez un champ DNS de type SPF dans votre zone DNS qui correspond au champ A utilisé pour vos mails (chez votre registrar ou sur votre serveur de noms si vous l'hébergez aussi) tel que celui-ci :

chezmoi.tld.   SPF "v=spf1 a mx ~all"

ou bien sous forme de champ TXT si le SPF n'est pas disponible :

chezmoi.tld. TXT "v=spf1 a mx ~all"

Cet exemple est très simple mais devrait convenir à la plupart des cas. Vous pouvez vous renseigner sur la syntaxe de ces champs si ça vous chante :)

Signature DKIM

Cette technique complète SPF et consiste à signer avec le serveur les messages émis par le serveur à l'aide d'une clé privée. On ajoute ensuite dans un champ DNS la clé publique correspondante qui permettra au destinataire de vérifier que le mail reçu provient bien de votre serveur.

Hum... Pas sûr d'avoir compris.

Je reprends. Nous allons créer une clé privée et une clé publique.

La clé privée servira à signer les messages. On l'appelle "privée" car vous devez être la seule personne capable de signer (comme pour vos chèques ou vos impôts). La clé publique disponible dans un champ DNS, donc accessible à tous, est là pour vérifier que la signature est bien authentique. On peut voir ça comme une pièce de puzzle unique, qui est la seule à pouvoir entrer dans l'empreinte créée par la signature.

On présentera ici deux méthodes pour signer les messages : l'une avec une extension à smtpd, l'autre avec un paquet faisant office de proxy. Le premier est le plus simple 😊. Notez que c'est aussi possible avec rspamd (voir la page correspondante), la méthode de génération des clés restant identique. Si vous choisissez d'utiliser cet antispam, vous voudrez certainement aussi utiliser sa capacité à signer les messages plutôt que mutliplier les outils installés.

Génération des clefs pour dkim

Les commandes suivantes permettent de fabriquer la paire de clés qui servira à signer les mails émis :

On génère les clefs :

# openssl genrsa -out private.key 2048               
# openssl rsa -in private.key -pubout -out public.key

On ajuste les permissions sur les clefs :

# chmod 400 private.key

Enregistrements DNS

Il faut absolument rendre publique une façon de vérifier que la signature DKIM sur les messages envoyés est bien correcte.

Nous allons pour cela ajouter un nouveau champ dans vos DNS auprès de votre registrar ou dans votre zone. Eh oui, encore ! On va en réalité indiquer le nécessaire pour pouvoir vérifier la signature des messages qui auront un drapeau "dkimpubkey".

Il s'agira d'un champ DKIM ou TXT selon ce qui est disponible. Remplissez-le ainsi :

Recopiez à la place des points de suspension le contenu du fichier public.key, que vous pouvez afficher avec la commande cat :

# cat /etc/dkim/public.key

Ce qui nous donnera dans la zone DNS de votre domaine :

dkimpubkey._domainkey    IN TXT    ( "v=DKIM1; k=rsa; t=s;p=v+Fb...vhP/oB")

Signer avec opensmtpd-filter-dkimsign

Depuis qu'smtpd est équippé de "filtres", il vous est possible de signer vos messages de cette façon. Cela rendra la configuration un peu plus simple.

Tout d'abord, installer le port opensmtpd-filter-dkimsign.

# pkg_add opensmtpd-filter-dkimsign

On modifie les permissions pour que l'outil de signature puisse accéder aux clés:

# chown -R _dkimsign:_dkimsign /etc/dkim/

Si vos clés de signature ont bien été générées auparavant, vous pouvez ajouter en haut de votre fichier de configuration "/etc/mail/smtpd.conf" la définition du filter "dkimsign":

filter "dkimsign" proc-exec "filter-dkimsign \
    -d <domain> \
    -s <selector> \
    -k /etc/dkim/private.key" \
    user _dkimsign group _dkimsign

Remplacez "<domain>" par votre nom de domaine et "<selector>" par "dkimpubkey" : c'est ce qu'on a mis un peu plus haut dans le champ DNS.

Enfin, il vous suffit de faire passer les mails sortants par ce filtre. On modifie la ligne correspondant à l'envoi des messages dans "/etc/mail/smtpd.conf":

listen on all port submission tls-require auth <passwd> filter "dkimsign"

Avec dkimproxy

On peut aussi utiliser dkimproxy pour signer les messages.

On l'installe comme d'habitude :

# pkg_add dkimproxy

Vous rendrez dkimproxy propriétaire du dossier contenant les clés:

# chown -R _dkimproxy:_dkimproxy /etc/dkim/

Afin de configurer la signature des messages envoyés, il faut éditer le ficher "/etc/dkimproxy_out.conf" ainsi :

listen    127.0.0.1:10027
relay     127.0.0.1:10028
domain    chezmoi.tld
signature dkim(c=relaxed)
signature domainkeys(c=nofws)
keyfile   /etc/dkim/private.key
selector  dkimpubkey

Euh, c'est quoi tout ça?

Quelques menues explications :

Bien, reste à indiquer à opensmtpd de signer les mails. On va donc ajouter dans le fichier "/etc/mail/smtpd.conf" une ligne pour écouter sur le port 10028 en local, afin d'envoyer les mails que dkimproxy aura signé. On leur colle l'étiquette "DKIM" pour les repérer ensuite.

listen on lo0 port 10028 tag DKIM   

Les messages qui auront l'étiquette "DKIM" peuvent être envoyés. On n'envoie plus les mails s'ils ne sont pas passés par dkimproxy.

match tag DKIM for any action "sendthismail"
match auth tag DKIM from any for any action "sendthismail"

Enfin, les messages pas encore signés doivent être envoyés à dkimproxy. On définit l'action correspondante :

action dkimproxy relay host smtp://127.0.0.1:10027 

S'ensuit les règles de correspondance qui vont bien, à placer à la fin du fichier smtpd.conf:

match auth from any for any action dkimproxy
match for any action dkimproxy

Ça va? Vous suivez toujours?

Courage, c'est presque fini. 😉

Finalement, activez dkimproxy puis rechargez opensmtpd avant de tester si vous avez réussi à configurer correctement l'envoi de vos mails.

# rcctl enable dkimproxy_out
# rcctl start dkimproxy_out
# rcctl restart smtpd

Vérifications

Pour vérifier que vos messages envoyés ne sont pas considérés comme spam, suivez les indications du site mail-tester.

Vous allez envoyer un message à l'adresse donnée, vous devriez obtenir une bonne note. La preuve avec mon propre serveur :

../../../img/mail-tester-fr.png

Il se peut qu'on vous parle d'un enregistrement dmarc. Libre à vous de l'ajouter à vos DNS, mais ce n'est pas obligatoire. En réalité, "ça fait juste bien" d'en avoir un... À vrai dire, le score obtenu est déjà meilleur qu'avec nombre de "grands" services de messagerie (testez avec gmail pour rigoler : 6.1/10 lors de mon dernier test...).

Utiliser un relai SMTP externe (FAI bloquants)

Si votre fournisseur d'accès à internet bloque le port smtp (25), vous serez bien embêtés pour envoyer des messages. Au moins deux solutions s'offrent à vous :

Nous supposerons que vous disposez d'un accès par smtp sur un autre serveur (votre fournisseur de mail habituel). Vous envoyez déjà des courriels avec ce dernier à l'aide d'un identifiant et d'un mot de passe. Mettez ces derniers dans un fichier "/etc/mail/secrets" sous cette forme :

# echo "id_secret utilisateur:motdepasse" > /etc/mail/secrets

Bien sûr, vous aurez remplacé les éléments suivants :

Avant d'aller plus loin, modifiez les permissions sur ce fichier afin que seul smtpd puisse le lire et root le modifier :

# chmod 640 /etc/mail/secrets
# chown root:_smtpd /etc/mail/secrets

Ensuite, modifiez le ficher "/etc/mail/smtpd.conf" comme ceci afin d'indiquer d'envoyer les messages à l'aide de ce service externe :

...
table secrets "/etc/mail/secrets"
...
listen on all...
...
action "relay" relay host smtp+tls://id_secret@smtp.exemple.com \
      auth <secrets> mail-from "@chezmoi.tld"
...
match from any for any action "relay"

Un peu d'explications ne feront pas de mal, surtout pour que vous sachiez quoi modifier :

Pour finir, rechargez smtpd pour profiter de cette nouvelle configuration :

rcctl restart smtpd

Pour un autre exemple, vous pouvez consulter la fin du manuel de configuration pour smtpd.

Lutter contre les spams à la réception : filtre senderscore

Senderscore maintient une base de données concernant la réputation de certains serveurs.

Autant avoir une réputation moyenne ne veut pas dire grand chose concernant la légitimité des mails envoyés par un serveur, une mauvaise réputation signifie que ce dernier a envoyé à plusieurs reprise des spams.

smtpd permet désormais d'utiliser des filtres variés ce qui rend la vérification avec senderscore plus facile.

Installez le paquet opensmtpd-filter-senderscore.

Ensuite, à la ligne gérant la réception dans /etc/mail/smtpd.conf :

filter senderscore \
         proc-exec "filter-senderscore -junkBelow 70 -slowFactor 2000"
...
listen on all tls pki chezmoi.tld filter { senderscore }

Lutter contre les spams à la réception : spamassassin

On ne présente plus spamassassin, un filtre antispam à la réception. Avec spamd, il est utilisé par OpenBSD sur leurs listes de diffusion. Voyons comment le faire communiquer avec smtpd. On va détailler ici une méthode utilisant des étiquettes pour bien comprendre comment les choses fonctionnent, mais sachez qu'il existe un filtre opensmtpd-filter-spamassassin que vous trouverez sans doute plus pratique à utiliser (installez le paquet du même nom puis lisez le contenu de "/usr/local/share/doc/pkg-readmes/opensmtpd-filter-spamassassin").

C'est parti, on commence par installer les paquets utiles :

# pkg_add p5-Mail-SpamAssassin spampd

Pour que spampd puisse faire le lien entre le serveur smtpd et spamassassin qui vérifie les messages, il doit tourner en arrière-plan. On active donc ce service :

# rcctl enable spampd

Vous pouvez préciser certaines options pour spampd afin d'être sûr qu'il fonctionne comme prévu :

# rcctl set spampd flags "--relayhost=127.0.0.1:10026"

Ensuite, on démarre le service :

# rcctl start spampd

Il en va de même pour spamassassin qui doit être actif :

# rcctl enable spamassassin
# rcctl start spamassassin

Nous allons maintenant faire passer tous les messages entrants par spamassassin qui va les vérifier. Pour cela, il faut les envoyer sur le port 10025. S'il ne s'agit pas de spam, alors spampd se charge de les renvoyer sur le port 10026. Tous les messages arrivant ainsi recevront l'étiquette "SPAMASSASSIN", pour que l'on sache qu'il faut les distribuer car ils ont déjà été traités.

Voici donc les lignes à ajouter au fichier "/etc/mail/smtpd.conf" :

...
# Messages verifies par spamassassin
listen on lo0 port 10026 tag SPAMASSASSIN
...
action spamassassin relay host smtp://127.0.0.1:10025 
...
# Message venant du système
accept from local for local alias <aliases> deliver to maildir "~/Maildir"
# Message SPAMASSASSIN
match tag SPAMASSASSIN from any for domain "chezmoi.tld" action virtual_maildir
### Messages a faire verifier par spamassassin
match from any for domain "chezmoi.tld" action spamassassin
...

Actuellement, spamassassin modifie le sujet des mails spams en indiquant clairement leur nature.

Vous pouvez modifier la configuration de spamassassin pour que les spams soient directement supprimés mais c'est déconseillé en cas de faux positifs.

Spamassassin ajoute un entête "X-spam" aux messages indésirables. On va modifier l'action de distribution pour ajouter le mot-clé "junk" afin que ces messages soient automatiquement classés dans le dossier des spams lorsqu'ils seront livrés :

# Dans /etc/mail/smtpd.conf
action virtual_maildir maildir "/var/vmail/%{dest.domain:lowercase}/%{dest.user:lowercase}/Maildir" junk virtual <virtuals>

Lutter contre les spams à la réception : rspamd

Rspamd n'est pas qu'un antispam. Il est extrêmement complet et peut aussi gérer le greylisting, les signatures DKIM...

Il faudra donc absolument consulter la documentation officielle pour maîtriser pleinement ce dernier. Dans cette partie, je vous propose une configuration succinte de rspamd qui gèrera et remplacera certaines éléments décrits dans ce document concernant le greylisting et les listes noires avec spamd, spamassassin pour l'antispam et dkimproxy pour la signature DKIM.

Mais, n'est-ce pas mieux de confier à chaque tâche un outil spécifique ?

C'est à vous de voir ce que vous préférez 😊. À l'heure où j'écris ces lignes, spamd ne gère pas encore l'IPv6, alors que rspamd si en théorie. Cependant, il n'est pas en mesure de piéger les spammeurs avec les spamtraps : les pièges ne servent qu'à apprendre qui est un spammeur, mais pas de les ralentir et lutter activement contre ces derniers. Par ailleurs, il est écrit en C, plus performant que le perl avec lequel spamassassin est développé.

À vous de peser le pour et le contre. 😋

Et toi, t'utilises quoi?

rspamd et spamd. Mais n'y voyez aucune publicité 😉.

Installation

# pkg_add rspamd redis opensmtpd-filter-rspamd
# rcctl enable redis rspamd
# rcctl start redis rspamd

/etc/mail/smtpd.conf

Ce fichier devra contenir les lignes suivantes :

filter rspamd proc-exec "filter-rspamd"
### filtre en reception
listen on all tls pki chezmoi.tld \
    filter { rspamd }

Gestion DKIM

rspamd peut gérer les signatures dkim. Nul besoin de dkimproxy par conséquent.

Créez les clés puis faîtes en sorte qu'elles appartiennent au groupe _rspamd.

# chown -R _rspamd:_rspamd /etc/dkim/

N'oubliez pas de publier le champ DNS approprié 😉.

Créez le fichier "/etc/rspamd/local.d/dkim_signing.conf" :

# If true, username does not need to contain matching domain
allow_username_mismatch = true;
path = "/etc/dkim/private.key";
selector = "dkimpubkey";

Afin de signer les mails sortants, vous devez avoir ceci dans "/etc/mail/smtpd.conf"

filter rspamd proc-exec "filter-rspamd"
### Envoi avec signature DKIM geree par rspamd
listen on all port submission tls-require pki chezmoi.tld auth \
    filter { rspamd }

Greylisting

Rspamd fait du greylisting par défaut. Si vous souhaitez continuer à utiliser spamd à la place, vous pouvez désactiver le greylisting en éditant le fichier "/etc/rspamd/local.d/actions.conf" :

greylist = none;

Ainsi que le fichier /"etc/rspamd/local.d/greylist.conf"

enabled = false;

Spamtraps

Contrairement à spamd, rspamd ne garde pas captif les spammeurs qui écrivent sur une spamtrap. Cela sert tout de même à reconnaître des spammeurs pour plus tard.

Si une spamtrap vous tente quand même, alors écrivez dans le fichier "/etc/rspamd/local.d/spamtrap.conf" :

action = "no action";
learn_spam = true;
map = file://$LOCAL_CONFDIR/maps.d/spamtrap.map;
enabled = true;

Puis remplissez le fichier "/etc/rspamd/maps.d/spamtrap.map" avec des expressions régulières des fausses adresses piège. Par exemple :

/^trap@chezmoi.tld$/
/^fake@chezmoi.tld$/

Listes noires

Vous pouvez paramétrer des listes noires comme avec spamd avec le module multimap.

Accès au WebUI

Configurez l'accès administrateur en suivant ces instructions.

Depuis votre ordinateur de bureau, créez un tunnel SSH :

ssh -N -L 9999:127.0.0.1:11334 utilisateurssh@chezmoi.tld

Ouvrez ensuite votre navigateur à l'adresse http://localhost:9999.

Vous pourrez alors admirer de magnifiques graphiques.

Gestion des spams avec dovecot

On peut laisser l'antispam faire son travail tranquille dans son coin. Toutefois, c'est intéressant de lui indiquer les quelques mails indésirables qu'il n'a pas détecté ou au contraire les faux-positifs afin qu'il apprenne et devienne de plus en plus efficace.

Si vous utilisez dovecot afin de consulter vos messages avec un client IMAP, il est possible de marquer comme spam les messages que vous déplacez dans le dossier "Junk" (par exemple). De la même façon vous pouvez marquer un message comme légitime si vous le retirez du dossier "Junk".

Notez que cette fonctionnalité pourra être mise en place quel que soit l'antispam que vous utilisez.

L'installation va se dérouler en trois étapes :

1. Installation du plugin.

2. Activation et configuration du plugin.

3. Création des scripts d'apprentissage relatifs à chaque antispam.

Tout ceci est décrit dans la documentation de dovecot.

Pour configurer dovecot de cette façon, nous commençons par installer le plugin pigeonhole qui donnera accès à sieve.

# pkg_add dovecot-pigeonhole

On active ce plugin en ajoutant les lignes suivantes à la fin du fichier "/etc/dovecot/local.conf" :

protocol imap {
	mail_plugins = $mail_plugins imap_sieve
}

Enfin, toujours dans le même fichier, on configure ce plugin. On indique des actions à réaliser selon les emplacements où sont déplacés les messages. :

plugin {
	sieve_plugins = sieve_imapsieve sieve_extprograms
	# Un message déplacé dans le dossier Junk est un spam
	imapsieve_mailbox1_name = Junk
	imapsieve_mailbox1_causes = COPY
	imapsieve_mailbox1_before = file:/usr/local/lib/dovecot/sieve/report-spam.sieve
	# Du dossier des spams vers n'importe ou : le mail est légitime
	imapsieve_mailbox2_name = *
	imapsieve_mailbox2_from = Junk
	imapsieve_mailbox2_causes = COPY
	imapsieve_mailbox2_before = file:/usr/local/lib/dovecot/sieve/report-ham.sieve
	sieve_pipe_bin_dir = /usr/local/lib/dovecot/sieve
	sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.execute
}

On crée maintenant deux fichiers dans le dossier "/usr/local/lib/dovecot/sieve/".

Le premier s'appelle report-spam.sieve:

require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.user" "*" {
  set "username" "${1}";
}
pipe :copy "learn-spam.sh" [ "${username}" ];

Le second s'appelle report-ham.sieve

require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.mailbox" "*" {
  set "mailbox" "${1}";
}
if string "${mailbox}" "Trash" {
  stop;
}
if environment :matches "imap.user" "*" {
  set "username" "${1}";
}
pipe :copy "learn-ham.sh" [ "${username}" ];

On fait maintenant en sorte que sieve tienne compte de ces fichiers. Avant tout, il faut recharger dovecot :

# rcctl restart dovecot

Ensuite, compilez les scripts sieve :

# sievec /usr/local/lib/dovecot/sieve/report-spam.sieve
# sievec /usr/local/lib/dovecot/sieve/report-ham.sieve

Ces deux fichiers font appel à deux scripts : learn-spam.sh et learn-ham.sh. Le contenu de ces derniers va dépendre de l'antispam que vous utilisez. Ils serviront à apprendre à votre antispam si un message est légitime ou non. Lisez la suite pour terminer.

Scripts d'apprentissage

Voici comment remplir les scripts d'apprentissages pour spamassassin et rspamd. Nous mettrons ces scripts dans le dossier "/usr/local/lib/dovecot/sieve".

Pour spamassassin

#!/bin/sh
#learn-spam.sh
/usr/local/bin/spamc -u ${1} -L spam -C report
#!/bin/sh
# learn-ham.sh
/usr/loca/bin/spamc -u ${1} -L ham -C report

Pour rspamd

#!/bin/sh
#learn-spam.sh
exec /usr/local/bin/rspamc -d "${1}" learn_spam
#!/bin/sh
# learn-ham.sh
exec /usr/local/bin/rspamc -d "${1}" learn_ham

Dans tous les cas

Afin que ces scripts puissent être lancés, rendez-les exécutables avec cette commande :

# chmod +x /usr/local/lib/dovecot/sieve/learn-*.sh

Pour terminer, n'oubliez pas de recharger dovecot :

# rcctl reload dovecot

Et voilà, désormais, les scripts d'apprentissages seront appelés selon le dossier dans lequel les utilisateurs déplaceront les mails.

Si vous souhaitez en savoir plus, vous pouvez lire la documentation de dovecot.

Lutte contre les spams avant réception avec un outil OpenBSD : spamd

Trier les spams une fois qu'ils sont reçus, c'est pas mal. Mais embêter les spammeurs, c'est bon pour tout le monde 😋. Spamd fait semblant d'être un serveur mail afin de filtrer les spams et ralentir les spammeurs. Il a été écrit dans l'optique d'être très efficace et ne pas ralentir la machine. Bien sûr, il transmet les mails légitimes au serveur smtpd ensuite.

Ce qui est rigolo, c'est qu'il va communiquer tout doucement avec les spammeurs et leur faire dépenser inutilement temps et ressources 😊.

Enfin, avantage non négligeable, il est présent par défaut dans OpenBSD.

Comment ça marche?

Deux méthodes sont possibles et compatibles. La première consiste à laisser traîner sur le web une fausse adresse mail. Tous les messages envoyés à cette adresse sont émis par des robots spammeurs : l'origine de ces derniers est alors mise sur liste noire puis ralentie.

L'autre méthode est le "greylisting". Afin de reconnaître les pourriels, spamd va mettre en attente ceux qui contactent le serveur. Ils sont mis sur liste grise.

Il existe aussi un mode "blacklist only" pour ne piéger que des IP déjà sur des listes noires.

Normalement, un serveur expéditeur légitime réessaie automatiquement de délivrer le message après un certain temps. Lors du 2e essai, ce serveur est mis sur liste blanche et le message est correctement distribué. Tous ceux à qui vous avez écrit sont aussi mis sur liste blanche.

Les spammeurs ne vont pas réessayer de délivrer le message. Dans ce cas, ils seront oubliés après un délai assez long, et vous n'aurez pas reçu le spam.

Attention : Cette méthode, bien que très efficace, suppose que l'expéditeur fait les choses comme il faut. Ce n'est malheureusement pas toujours le cas, notamment pour certains sites marchands. Pensez-y. C'est heureusement facile d'ajouter un serveur sur liste blanche.

Vous devriez de toute manière utiliser une adresse poubelle comme guerrilamail dans ces cas de figure.

Afin d'enregistrer les vilains (et bons) expéditeurs, il faudra exécuter la commande spamd-setup régulièrement.

Mise en place

On commence par activer spamd au démarrage, en indiquant les options dont il aura besoin, puis on le lance :

# rcctl enable spamd
# rcctl set spamd flags "-v -G 25:4:864"
# rcctl start spamd

Le premier nombre correspond au nombre de minutes qu'un expéditeur doit attendre avant de réessayer de nous renvoyer son mail (puisque les spammeurs envoient des salves de mails très rapidement). Le second correspond au temps qu'une entrée reste dans la liste grise, et le dernier le temps pendant lequel une entrée restera sur la liste blanche (en heures).

En complément, je vous invite à activer spamlogd qui gardera en mémoire les expéditeurs légitimes de mail dans le temps sans repasser par la case "liste grise", tant que ces derniers envoient des mails régulièrement. Il enregistre aussi sur liste blanche les serveurs auxquels vous envoyez des messages. Attention, il faut bien avoir précisé le mot clé "log" dans la configuration du parefeu, comme précisé un peu plus loin.

# rcctl enable spamlogd
# rcctl start spamlogd

spamd se place juste avant smtpd. On va éditer la configuration du parefeu en conséquence. Il va envoyer à spamd tout le flux destiné au serveur smtp, qui relaiera ensuite le mail normalement s'il est légitime.

Voici ce qu'il faut donc ajouter dans /etc/pf.conf :

table <spamd-white> persist
table <nospamd> persist file "/etc/mail/nospamd"
pass in on egress proto tcp to any port smtp divert-to 127.0.0.1 port spamd
pass in on egress proto tcp from <nospamd> to any port smtp
pass in log on egress proto tcp from <spamd-white> to any port smtp

Dans l'ordre des lignes :

Voilà pour le parefeu. N'oubliez pas de le recharger :

# pfctl -ef /etc/pf.conf

Il est nécessaire de régulièrement charger la liste noire des spammeurs dans pf afin que spamd fonctionne bien. Nous allons nous servir d'une tâche cron pour ça. Saisissez # crontab -e, puis décommentez la ligne suivante :

~  *  *  *  *  /usr/libexec/spamd-setup

Le "~" permet de lancer à intervalles aléatoires la commande précédente 😉. Notez que c'est un nombre de minutes aléatoire, cette intevalle sera donc toujours inférieure à 1h.

Spamtrap

Vous pouvez piéger les spammeurs en laissant traîner sur le web une fausse adresse mail. Si spamd voit un message arriver pour cette adresse, alors il sait déjà que c'est un spam : il peut donc le mettre sur liste noire. Vous voilà protégés pour l'avenir.

Afin de glisser cette "adresse-piège" sur le web sans que ça soit visible par les humains, vous pouvez l'insérer ainsi dans le code html de votre site :

<a href="mailto:piege@chezmoi.tld"></a>

Sinon, copiez-la sur des pastebins publics.

Pour indiquer à spamd cette adresse piège, il faut ajouter les options suivantes à spamdb (attention au "b" final, ce n'est pas spamd). :

# spamdb -T -a 'piege@chezmoi.tld'

Bien entendu, cette adresse piège ne doit pas être créée et ne risque pas de servir à quiconque.

Utiliser des listes noires ou blanches pré-existantes

Les gens sympas, ça existe ! Ces derniers ont rassemblé une liste de spammeurs qu'ils rendent publique. Afin de les utiliser avec spamd, il faut éditer le fichier /etc/mail/spamd.conf.

Voyons l'exemple par défaut livré de base:

la liste nixspam

Dans le fichier /etc/mail/spamd.conf, nous mettrons les lignes suivantes :

all:\
        :nixspam
# Nixspam recent sources list.
# Mirrored from http://www.heise.de/ix/nixspam
nixspam:\
        :black:\
        :msg="Your address %A is in the nixspam list\n\
        See http://www.heise.de/ix/nixspam/dnsbl_en/ for details":\
        :method=http:\
        :file=www.openbsd.org/spamd/nixspam.gz

Au début du fichier, vous lisez all. Précisez ensuite le nom des listes qui seront utilisées et qui sont configurées en-dessous en les séparant par des ":". Nous allons en ajouter dans les paragraphes suivants.

Les listes peuvent être récupérées par spamd-setup en précisant leur URL, ou bien être des fichiers présents sur votre serveur.

Utiliser la liste noire de bsdly

Peter N.M.Hansteen publie une liste d'IP piégées avec ses propres SPAMTRAPS.

Il met sur liste noire les IP cherchant à télécharger trop souvent sa liste pour éviter les surcharges sur son serveur. On va donc les récupérer régulièrement en ajoutant à votre crontab, toutes les heures à 20 minutes passées :

20 * * * *   /usr/local/sbin/bsdly-spamd

Le script bsdly-spamd ne fait que récupérer la liste de Peter :

#!/bin/sh
# update bsdly.net traplist into DST
URL="https://www.bsdly.net/~peter/bsdly.net.traplist"
# alternative URL
#URL="https://home.nuug.no/~peter/bsdly.net.traplist"
DST=/var/db/bsdly.traplist
ftp -o "${DST}" "${URL}"

Ensuite, indiquez dans /etc/mail/spamd.conf d'ajouter le contenu du fichier /var/db/bsdly.traplist à la liste noire :

all:\
      :nixspam:bsdlyblack:
nixspam:\
      :black:\
      :msg="Your address %A is in the nixspam list\n\
      See http://www.heise.de/ix/nixspam/dnsbl_en/ for details":\
      :method=https:\
      :file=www.openbsd.org/spamd/nixspam.gz
bsdlyblack:\
      :black:\
      :msg="SPAM.  Your address %A has sent spam within the last 24 hours.  See http://www.bsdly.net/~peter/traplist.shtml for details.":\
      :method=file:\
      :file=/var/db/bsdly.traplist

Utiliser les listes noire et blanches de uceprotect

Le site uceprotect devrait vous plaire si vous n'aimez par les spams.

Ils proposent des listes d'IP mises à jour toutes les heures. Il est possible de récupérer les listes en entier comme on l'a fait avec bsdly.net.traplist, mais cela consommera moins de bande passante de ne récupérer que les changements avec (open)rsync. C'est mieux pour vous et pour uceprotect.

Dans le crontab, on appelle le script qui mettra à jour toutes les heures (Ne mettez pas à jour les listes plus souvent, sinon vous serez bloqués par leur serveur) :

10 * * * *     /usr/local/sbin/uceprotect-spamd 

Le contenu du script uceprotect-spamd est le suivant :

#!/bin/sh
RSYNC="/usr/bin/openrsync -a"
URLS="rsync-mirrors.uceprotect.net::RBLDNSD-ALL/dnsbl-1.uceprotect.net
rsync-mirrors.uceprotect.net::RBLDNSD-ALL/dnsbl-2.uceprotect.net
rsync-mirrors.uceprotect.net::RBLDNSD-ALL/ips.whitelisted.org"
OUT="/var/db/RBLDNSD-ALL/"
mkdir -p "${OUT}"
for URL in ${URLS}; do
      ${RSYNC} "${URL}" "${OUT}"
done

On charge ces listes dans /etc/mail/spamd.conf. Il y a des listes noires et des listes blanches :

all:\
      :nixspam:bsdlyblack:\
      rbldnsd-1:rbldnsd-2:rbldnsd-white:
...
rbldnsd-1:\
      :black:\
      :msg="Your address %A is listed on UCEPROTECT-Level 1\n \
      see http://www.uceprotect.net/en":\
      :method=file:\
      :file=/var/db/RBLDNSD-ALL/dnsbl-1.uceprotect.net
rbldnsd-2:\
      :black:\
      :msg="Your address %A is listed on UCEPROTECT-Level 2\n \
      see http://www.uceprotect.net/en":\
      :method=file:\
      :file=/var/db/RBLDNSD-ALL/dnsbl-2.uceprotect.net
rbldnsd-white:\
      :white:\
      :method=file:\
      :file=/var/db/RBLDNSD-ALL/ips.whitelisted.org

N'hésitez pas à faire un don à uceprotect.net, leur travail est impressionnant. 😃

Problèmes éventuels avec le greylisting

Trop de personnes utilisent encore un fournisseur de mail, comme Gmail. Ces derniers disposent de plusieurs serveurs et donc de plusieurs adresses IP. Malheureusement, le temps que l'adresse IP du premier serveur à tenter l'envoi d'un message soit mise sur liste blanche, c'est un autre de leurs serveurs avec une IP différente qui prend le relais. Au final, ils ne sont jamais mis sur liste blanche.

Ici, nous allons créer une liste des domaines pour lesquels on ne veut pas faire de greylisting.

Je vous propose de mettre sur liste blanche les adresses IPs des fournisseurs de mail relativement connus. Depuis qu'OpenBSD est disponible en version 6.3, nous pouvons utiliser la commande smtpctl spf walk très pratique pour récupérer ces informations.

Tout d'abord, on crée un fichier qui contient la liste des domaines à qui on épargne le greylisting. Ce fichier sera /etc/mail/nospamd_domains_list.txt :

gmail.com
hotmail.com
facebookmail.com
apple.com
microsoft.com
lists.openbsd.org
linkedin.com
freebsd.org
twitter.com
amazon.com
yahoo.com
yahoo.fr
live.fr
mail-out.ovh.net
mxb.ovh.net
gandi.net
laposte.net
protonmail.com

Complétez ce fichier à votre guise si vous remarquez que des serveurs restent indéfiniment sur liste grise.

Maintenant, on crée le script /usr/local/sbin/generate-nospamd qui va enregistrer dans le fichier /etc/mail/nospamd les IP des serveurs définis ci-dessus.

#!/bin/sh
# /usr/local/sbin/generate-nospamd
# Auteur :      prx <prx@si3t.ch>
# licence :     MIT
DOMAINS=/etc/mail/nospamd_domains_list.txt
WHITELIST=/etc/mail/nospamd
echo "#$(date)" > "$WHITELIST"
smtpctl spf walk < "${DOMAINS}" >> "$WHITELIST"
exit 0

Je vous invite à appeler ce script via /etc/daily.local afin de régulièrement mettre à jour la liste des IP. Ensuite, il faut penser à recharger la table dans le parefeu :

# /etc/daily.local
/usr/local/sbin/generate-nospamd
pfctl -t nospamd -T replace -f /etc/mail/nospamd

spamd en mode blacklist seul

Pour éviter le problème cité ci-dessus, et être sûr de n'embêter QUE les spammeurs sans gêner les expéditeurs légitimes, vous pouvez seulement faire tourner spamd en mode blacklist. On retire alors le greylisting, et on piège seulement les communications venant d'IP connues comme malsaines.

Pour cela, ajoutez le flag "-b" au lancement de spamd :

# rcctl set spamd flags -b

La configuration du parefeu est aussi à revoir : seules les IP dans la table "spamd" seront à piéger. Dans "/etc/pf.conf" :

table <spamd> persist
[...]
pass in on egress inet proto tcp from <spamd> to any port smtp \
     divert-to 127.0.0.1 port spamd

Vous ouvrirez ensuite le port "smtp" si vous en avez besoin. En effet, vous pouvez très bien héberger spamd sans avoir de serveur mail, rien que pour lutter contre le spam 😄

Enfin, reste à ajouter le flag "-b" à spamd-setup. Lancez "crontab -e" puis veillez à avoir cette ligne qui permet de lancer spamd-setup toutes les heure s:

~       *       *       *       *       /usr/libexec/spamd-setup -b

Consulter l'activité de spamd

Pour voir l'activité de spamd, lancez la commande spamdb pour voir apparaître des choses comme ça :

WHITE|62.4.1.33|||1462699174|1462699174|1465809574|1|0
GREY|182.70.43.24|abts-mum-dynamic-024.43.70.182.airtelbroadband.in|<Estella32@thunderguy.co.uk>|<toto@chezmoi.tld>|1473409924|1473424324|1473424324|1|0
GREY|14.183.132.63|static.vnpt.vn|<Abby5@toddelliott.com>|<kiki@chezmoi.tld>|1473410586|1473424986|1473424986|1|0

On peut lire dans l'ordre :

Il n'y a pas à dire, les "temps" sont illisibles pour les humains. Utiliser la commande date pour avoir un format lisible :

$ date -r 1462699174
    Sun May  8 11:19:34 CEST 2016

Pour manuellement mettre sur liste blanche une IP que vous savez valide, utilisez :

# spamdb -a "62.4.1.37"

Partager les informations entre deux instances de spamd

Puisque vous avez demandé à un(e) ami(e) d'être un backup au cas où votre serveur mail serait indisponible (n'est-ce pas ? 😊), il est important que son serveur ait connaissance des spammeurs détectés par votre spamd. Sinon, les spammeurs pourraient passer par leur backup pour vous délivrer des messages gênants.

Heureusement, spamd peut partager ses listes. Vous devez le lancer avec les options -Y et -y :

Éditez le fichier "/etc/rc.conf.local" en fonction pour obtenir par exemple :

spamd_flags=-y em0 -Y 211.217.177.100 -Y domaine.tld

Avant de relancer spamd, créez un fichier "/etc/mail/spamd.key" qui servira de clé partagée :

# dd if=/dev/random of=/etc/mail/spamd.key bs=2048 count=1

Tous les serveurs qui communiqueront entre eux devront avoir le même fichier. Envoyez-le donc à vos amis 😊.

Ouvrez dans votre parefeu et routeur le port 8025/udp (spamd-sync) au cas où il serait fermé.

#/etc/pf.conf
pass in quick on egress proto udp to any port spamd-sync

Enfin, relancez spamd :

# rcctl restart spamd

Vérifier que tout fonctionne bien

Vous voudrez peut-être tester votre serveur mail après tous ces efforts. Vous l'avez bien mérité. Vous pouvez bien entendu écrire à des amis, mais cela peut poser des soucis :

Il existe heureusement des robots auxquels on peut écrire un mail, qui vous répondront très vite en vous donnant de précieuses informations. Il existe les adresses suivantes :

Vous en trouverez d'autres sur cette page.

Vous pouvez aussi avoir des tests détaillés sur votre serveur mail est ses backup éventuels sur mxtoolbox et mail-tester.

mxtoolbox

mail-tester

Le serveur smtp ne fonctionne pas comme prévu

Si votre serveur mail rencontre des problèmes pour envoyer ou recevoir des messages, vous pouvez utiliser la commande smtpctl pour voir en détail ce qu'il se passe.

Par exemple, pour obtenir des informations générales :

# smtpctl show stats
control.session=1
mda.envelope=0
mda.pending=0
mda.running=0
mda.user=0
mta.connector=1
mta.domain=1
mta.envelope=1
mta.host=2
mta.relay=1
mta.route=1
mta.session=1
mta.source=1
mta.task=1
mta.task.running=0
queue.evpcache.load.hit=1675
queue.evpcache.size=2
queue.evpcache.update.hit=6
scheduler.delivery.ok=826
scheduler.delivery.tempfail=6
scheduler.envelope=2
scheduler.envelope.incoming=0
scheduler.envelope.inflight=1
scheduler.ramqueue.envelope=2
scheduler.ramqueue.message=2
scheduler.ramqueue.update=0
smtp.session=0
smtp.session.inet4=787
smtp.session.local=31
smtp.tls=0
uptime=777861
uptime.human=9d4m21s

Pour voir les messages en attente :

# smtpctl show queue
1101f6e60c169eac|inet4|mta||0100015b3a046476-f7d7955a-5842-49af-927c-4fa677f311c6-000000@bounces.duolingo.com|deux@domaine.eu|deux@domaine.eu|1491327053|1491672653|0|5|pending|3154|Network error on destination MXs
1a2123e1c2b3e462|inet4|mta||gitlab@framasoft.org|deux+framagit@domaine.eu|deux+framagit@domaine.eu|1491333449|1491679049|1491333849|1|inflight|50|Network error on destination MXs

Pour suivre en temps réel ce qu'il se passe :

# smtpctl monitor

Bien sûr, davantage d'explications sont disponibles dans la page "man smtpctl". 😉

Serveur de noms : Principes généraux

Le DNS (Domain Name System), c'est ce qui vous permet de reconnaître les noms de machines sur Internet. Ce sont les panneaux indicateurs et les annuaires téléphoniques du net.

C'est aussi ce qui indique où doit être envoyé le courrier, ainsi que plein d'autres détails techniques barbants dont la plupart des gens n'ont pas idée mais qui contribuent à la robustesse du réseau.

Ce système repose d'abord sur l'idée de zone. On commence par la zone racine, représentée par un point à l'extrémité d'une adresse. Cette zone racine contient les adresses des serveurs de noms autoritaires des tld (fr., de., dk., ph., com., net., org. etc). Chaque TLD constitue lui-même une zone contenant les adresses des serveurs de noms autoritaires pour les niveaux suivants.

                     .
                     |
                     |
 +-------+-------+---+--+-------+-------+
 |       |       |      |       |       |
 v       v       v      v       v       v
.fr    .com    .tld   .xyz    .org    .net
                 |
   +-------------+--------------+
   |             |              |
   v             v              v
site.tld     chezmoi.tld     autre.tld
                 |
                 +------------------+
                 |                  |
                 v                  v
         webmail.chezmoi.tld   wiki.chezmoi.tld

Ainsi, pour peu que l'on connaisse les adresses des serveurs de la zone racine (aussi appelés serveurs racines, ou serveurs root), on peut normalement connaître n'importe quelle adresse dans le système de noms Internet : il suffit de commencer à la racine et parcourir la chaîne, zone après zone.

Cette action de parcourir la zone s'appelle la résolution (de noms). Les serveurs qui effectuent cette recherche sont dits résolveurs. Les serveurs qui portent l'information relative à chaque zone sont dits autoritaires.

Lorsqu'un résolveur a récupéré l'adresse d'une machine, d'un site web ou autre, ce serveur va mettre l'adresse en cache, en mémoire, et ce pour la durée de validité des données, indiquée par le serveur autoritaire sous le nom de TTL ou Time To Live.

Cette durée de validité implique un délai de propagation, le temps que les différents résolveurs mettent à jour les informations de la zone considérée. Plus le TTL est élevé, plus les délais de propagation des informations d'une zone seront importants, mais plus le trafic réseau sera réduit. C'est donc un choix d'équilibre.

DNSSEC

Il y a quelques années, des gens très intelligents ont commencé à s'inquiéter : DNS étant critique, il était donc important qu'il soit sécurisé.

En fait, il est assez facile, lorsque vous surfez sur le web, de vous envoyer sur de fausses adresses. On a donc cherché à s'assurer que le DNS ne délivre que des adresses authentiques, autrement dit, dont on soit sûr qu'elles sont vraies.

Pour ce faire, chaque détenteur d'un nom de domaine écrit sa zone DNS, puis la signe à l'aide d'un algorithme cryptographique.

Les résolveurs sont alors chargés de vérifier que ces signatures sont bien valides.

Logique non ?

Concrètement, ça permet à chacun d'être sûr d'être sur le bon site web, pas sur celui d'un pirate.

On peut aussi y publier des informations sûres : c'est le principe de DANE/TLSA qui consiste à publier les empreintes des certificats de chiffrements TLS (sites web, serveurs mail).

Ces notions sont revues et approfondies sur cet article de lord.re.

Exemple de zone

Les fichiers de zone DNS suivent un format standard, que tous les serveurs de noms autoritaires suivent, à quelques exceptions près.

On va montrer ici la zone d'exemple typique (un truc idéal qui n'arrive jamais dans la réalité).

Voici un fichier type de zone "/var/nsd/zones/chezmoi.tld" :

$TTL 1D
@           IN SOA    maitre.chezmoi.tld. hostmaster.chezmoi.tld. (
          ; domaine A du serveur DNS autoritaire
          ; suivi de l'adresse mail pour
          ; contacter le responsable du serveur.
          ; Ici, cette adresse
          ; est hostmaster@chezmoi.tld. 
          ; Oui, le "@" est remplacé par un "."
                    2014110502      ; numero de serie à augmenter
                                    ; à chaque modification.
                    86400           ; Refresh
                    7200            ; Retry
                    3600000         ; Expire
                    172800 )        ; Negative Cache TTL
$ORIGIN chezmoi.tld.
@           IN NS       maitre
@           IN NS       secondaire
@           IN MX       10 mail1
@           IN MX       20 mail2
maitre      IN A        192.0.2.2
maitre      IN AAAA     2001:db8:1:1::2
mail1       IN A        192.0.2.10
mail2       IN A        192.0.2.11
ipv4only    IN A        192.0.2.15
ipv6only    IN AAAA     2001:db8:1:1::400
dualstack   IN A        192.0.2.200
dualstack   IN AAAA     2001:db8:1:1::200
passerelle  IN AAAA    %%ipv6_passerelle
maitre      IN A       %%ip_pub_maitre
maitre      IN AAAA    %%ipv6_maitre
secondaire  IN A       %%ip_pub_second
secondaire  IN AAAA    %%ipv6_second
...

Les enregistrements DNS et comment les utiliser

Les enregistrements DNS sont (généralement) structurés ainsi (entre parenthèse le nom anglais officiel du champ) :

NOM(NAME)    CLASSE(CLASS)    TYPE    TTL    DONNÉE(RDATA)

Le nom correspond à ce que vous cherchez lors d'une requête à un résolveur.

La classe désigne internet (IN). Au début d'internet, d'autres classes étaient utilisées. Aujourd'hui de nombreuses documentations omettent la classe du fait qu'il n'y en a qu'une seule en activité, et que la plupart des résolveurs fonctionnent bien sans. Néanmoins, il arrive que certains programmes ou processus de résolution DNS plantent si la classe n'est pas présente.

Le type désigne le type de donnée du champ.

Le TTL désigne le Time To Live soit le temps pour lequel la donnée est considérée comme valide.

Enfin la donnée correspond à l'information désignée par le nom de type TYPE.

Les Types : @, $ORIGIN, $TTL

"$ORIGIN" fait normalement référence au nom complet de la zone. Par exemple, chezmoi.tld.

Dans le cas où le fichier de zone ne comporte pas de directive "$ORIGIN", le serveur de nom va en produire une avec le nom de la zone.

"@" sera remplacé par "$ORIGIN".

Si vous souhaitez davantage d'informations à propos de cette directive, vous pouvez lire cette documentation.

"$TTL" est la durée de validité par défaut des données. La valeur recommandée est de 1 jour (1D).

Chaque enregistrement DNS peut avoir son propre TTL (MX et NS sont normalement très stables, et peuvent donc par exemple avoir des TTL d'une semaine voir plus, ceci permet de réduire la charge réseau).

"$ORIGIN" et "$TTL" doivent être placés en premier dans le fichier de zone.

SOA

Le premier enregistrement avec "$ORIGIN" et "$TTL" s'appelle le SOA, pour Source Of Authority. C'est un élément très important. Le premier champ après SOA désigne le serveur de nom d'origine, en l'occurrence maitre.chezmoi.tld. et le dernier champ désigne l'adresse de l'administrateur du domaine. hostmaster.chezmoi.tld. se transformera en hostmaster@chezmoi.tld . Le premier point sera transformé en @. Vous avez dû mettre un alias sur hostmaster lors de la mise en place du serveur mail. Si vous ne pouvez pas et devez utiliser un point dans la partie "username" (avant @) de l'adresse (Vous vous compliquez vraiment la vie ! 😲), vous devrez alors mettre un "\" devant :

jean\.perrin.chezmoi.tld.

Il faut bien voir que le serveur source d'autorité et l'adresse de l'administrateur du domaine ne sont pas forcément situés dans le domaine en question.

Le numéro de série peut-être de diverses formes, mais il doit toujours aller en augmentant à chaque mise à jour de la zone. Ça permet aux serveurs secondaires de repérer qu'il existe une version plus récente de la zone. Certains administrateurs utilisent la date suivie d'un numéro incrémenté (2017021312 pour une zone modifiée le 13/02/2017 pour la 12è fois - oui, ça peut arriver 😁). D'autres utilisent le timestamp du moment de l'édition (horodatage unix à la seconde près). D'autres se contentent de commencer à 1 et d'incrémenter. Chaque méthode a ses avantages.

Les valeurs du SOA (refresh, retry, expire, négative), indiquées ici, ainsi que celle du TTL, sont celles recommandées par les normes (RFC). Il est tout-à-fait possible de mettre d'autres valeurs, toutefois celles indiquées ici ont fait leurs preuves.

Les valeurs sont par défaut en secondes. On peut aussi indiquer les valeurs en heures (H) jours (D) ou semaines (W).

Refresh et retry indiquent au bout de combien de temps les serveurs secondaires (esclaves), mais néanmoins toujours autoritaires pour la zone, doivent renouveler la zone. Aujourd'hui beaucoup de serveurs de noms signalent à leurs esclaves qu'ils doivent récupérer les nouvelles informations. Ces valeurs ont donc moins d'importance.

Expire indique la date limite d'utilisation des informations pour le cas où les serveurs de noms de la zone ne sont plus accessibles. C'est bien différent du TTL.

La valeur negative est en fait le temps durant lequel une réponse NXDOMAIN (non existence de la donnée recherchée) sera conservée en cache.

A, AAAA

Un des enregistrements les plus importants. Il suivent encore une fois : {NOM, TTL, CLASSE, TYPE, RDATA}.

Les adresses de la machine maitre.chezmoi.tld sont donc enregistrées sous cette forme :

maitre          IN A        192.0.2.2
maitre          IN AAAA     2001:db8:1:1::2

Rappelez-vous bien que le dernier point dans les adresses, implicite dans la plupart des documentations avec des adresses Internet, devient ici très important. Il représente la zone racine. Si une donnée d'adresse ne se termine pas par un point, elle sera complétée ou provoquera un bug.

CNAME

CNAME, pour Canonical NAME est un alias.

Dans l'exemple suivant, le nom canonique (réel) de www est maitre.

www IN CNAME maitre

C'est ce qu'on fait dans le cas des hôtes virtuels (ex : blog.chezmoi.tld, webmail.chezmoi.tld...).

NS

Une zone DNS devrait avoir au minimum 2 enregistrements NS d'après les règles communément admises puisqu'il s'agit des adresses des serveurs de noms autoritaires. Techniquement la zone fonctionnera très bien avec un seul, pour autant que le serveur de nom derrière cet enregistrement n'ait jamais de problème.

Il n'y a pas de limite technique au nombre de serveurs NS (autoritaires) dans une zone. Si vous en avez 2, c'est déjà bien : votre serveur et celui d'un ami à qui vous rendez la pareille 😉.

chezmoi.tld.   IN  NS   maitre.chezmoi.tld.

Cet enregistrement signifie : pour la zone chezmoi.tld, le serveur de nom autoritaire (NS) est maitre.chezmoi.tld. On aurait pu aussi l'écrire comme ça :

@     IN NS   maitre

Dans ce cas, le @ se trouve remplacé par le $ORIGIN de la zone, soit en fait son nom (complet, jusqu'à la racine, c'est à dire avec un point final) et maitre est complété avec "$ORIGIN" puisqu'il n'a pas de point soit : "maitre.chezmoi.tld".

Pour que les serveurs de noms soient connus du reste du monde, il vous faut les enregistrer dans le registre. C'est d'ailleurs un des deux seuls enregistrements à faire sur le registre, avec l'enregistrement des clés DNSSEC. En effet, une fois que les serveurs autoritaires sont publiés, tout se passe directement sur votre serveur.

Lors de l'enregistrement des NS sur le registre (via le bureau d'enregistrement, ou registrar), on fournit en général deux champs : le nom d'hôte complet de la machine, maitre.chezmoi.tld en l'occurrence, et l'adresse(s). On parle dans ce cas de Glue Record. Comment faire pour connaître l'adresse de maitre.chezmoi.tld puisque c'est lui-même qui a les adresses de la zone chezmoi.tld ? Dans ce cas, exceptionnellement, l'adresse sera écrite directement dans le registre.

Pour enregistrer des serveurs de noms autoritaires sur le registre, il vous faut vous connecter chez votre bureau d'enregistrement.

Chez GANDI, c'est facile (20% de réduction avec ce lien).

Vous trouverez une interface "GLUE" dans le paneau de gestion de votre domaine.

Une fois le nouveau GLUE enregistré, vour pouvez modifier la liste des serveurs de noms pour votre domaine.

Au sujet des registres, vous pouvez lire cet article.

MX

MX, c'est un peu comme NS, ça indique un service pour la zone, en l'occurrence le dépôt du courrier. L'enregistrement est un peu conçu de la même manière :

@     IN MX 10   mail1
@     IN MX 20   mail2

Pour la zone chezmoi.tld, le serveur de mail (MX) est mail1.chezmoi.tld.

Seule différence, le 10, qui indique la priorité. Quand on a plusieurs serveurs dans la zone, quel est le serveur qui doit recevoir le courrier en priorité ? Celui qui a le poids le plus faible.

En auto-hébergement, vous pouvez vous contenter d'utiliser le nom de domaine seul plutôt que de créer un sous-domaine mail correspondant à un champ A. Tout simplement :

@     IN MX 10   chezmoi.tld.

MX et NS ne peuvent pas être des redirections (CNAME), ils doivent pointer vers des enregistrements A ou AAAA.

Tout au plus accepte-t-on, avec réticence, des adresses IP. Mais normalement, les champs MX et NS pointent sur des noms d'hôtes, soit des enregistrements A et AAAA.

TXT

Les enregistrements TXT permettent de publier des informations variées concernant votre zone. Ce sera pratique pour rendre disponible des clés de vérification par exemple.

Cela peut par exemple ressembler à ceci :

@    IN TXT    "v=spf1 a mx ~all"

Le mot de la fin

Ce sera tout pour cette longue description d'une zone. N'hésitez pas à y revenir en cas de besoin.

Il est évidemment possible d'en faire bien davantage (SRV, SSHFP, ...), il en sera fait mention plus tard selon les cas.

Résolveur validant : unwind

Unwind est présent par défaut dans OpenBSD. Il permet en l'état de résoudre les noms de domaines et de garder le résultat en cache pour de meilleures performances. Votre serveur peut le faire lui-même plutôt que de compter sur le résolveur de votre fournisseur d'accès à internet (FAI). En plus, cela permet de gagner quelques millisecondes avec la mise en cache 😎.

Notez toutefois qu'unwind ne propose pas de faire des résolutions pour d'autre machines. Tournez-vous vers unbound pour proposer ce genre de service.

Pour utiliser unwind, activez-le avec les commandes habituelles :

# rcctl enable unwind
# rcctl start unwind

Pour indiquer au serveur de demander la résolution des noms de domaines à son instance d'unwind, on édite le fichier "/etc/resolv.conf" pour y mettre :

nameserver 127.0.0.1

Dans le cas où votre serveur se connecte via dhcp, vous n'avez normalement rien à faire, le démon "resolvd" se charge tout seul de détecter unwind.

Et voilà, votre serveur se débrouille maintenant tout seul pour résoudre des noms de domaine.

Vous pouvez tester l'efficacité d'unwind avec la commande dig qui nous montre les résultats d'une résolution DNS :

$ dig si3t.ch
[...]
;; Query time: 61 msec

Il a fallu ici 61 millisecondes pour avoir une réponse. Relancez une deuxième fois cette commande pour voir la différence :

$ dig si3t.ch
[...]
;; Query time: 0 msec

L'adresse a été mise en cache, et sera vérifiée régulièrement (à l'issue d'une durée égale au TTL). C'est toujours un gain de performance bienvenu !

Pour aller plus loin, je vous conseille les lectures suivantes :

Manuel d'unwind(8)

Manuel d'unwind.conf(5)

Manuel d'unbound(8)

Serveur de noms autoritaire avec nsd

Il y a encore un service que vous pouvez administrer par vous-même plutôt que de le laisser entre des mains extérieures : le serveur DNS autoritaire. C'est justement ce pourq uoi est fait NSD, présent par défaut dans une installation d'OpenBSD. Un pas de plus vers l'indépendance 😏.

Configuration simple de NSD

Pour configurer NSD, on édite le fichier "/var/nsd/etc/nsd.conf".

server:
        hide-version: yes
        zonesdir: "/var/nsd/zones"
        ip-address: 192.168.1.2
        ip-address: 2001:db8:1:1::2
        debug-mode: no
        verbosity: 2
## master zones
zone:
        name: "chezmoi.tld"
        zonefile: "master/chezmoi.tld"

Ici NSD suit cette organisation : les zones sont classées selon si le serveur est autoritaire (master) ou esclave (slave). Chaque zone correspond à un fichier portant le nom du domaine. Par exemple "/var/nsd/zones/master/chezmoi.tld". Vous pouvez bien sûr vous organiser différemment.

N'oubliez pas de modifier cet exemple avec l'adresse IP locale du serveur.

Une fois configuré, vous pouvez finalement lancer nsd comme d'habitude :

rcctl enable nsd
rcctl start nsd

Pensez à ouvrir et rediriger le port 53 (domain) en UDP et TCP, c'est celui utilisé par nsd.

Lorsque la configuration de NSD est correcte, vous pouvez alors ajouter dans le registre les adresses publiques de votre serveur (ipv4 et/ou ipv6) à la liste des serveurs autoritaires pour votre zone.

Un exemple de configuration complet est disponible à la fin du présent document.

Signer son domaine avec DNSSEC

Quelques détails sur la signature des zones DNS

DNSSEC utilise deux sortes de clés : ZSK (Zone Signing Key), légères et de courte durée et KSK (Key Signing Key) plus lourdes et de longue durée d'utilisation.

Pourquoi la différence ?

Il est recommandé que les clés qui signent les zones soient renouvelées régulièrement (approximativement tous les mois, certains le font toutes les semaines). Mais d'un autre côté, on peut difficilement mettre ça à jour tous les mois dans le registre.

On a donc créé en plus d'autres clés qui vont signer les premières, mais qu'on n'utilisera que pour cela, pas pour signer les zones en elles-mêmes. Ces clés seront plus solides, plus lourdes (on peut se permettre, puisqu'elles sont peu utilisées) et d'une plus longue durée de vie. Ce sont ces clés qui seront enregistrées dans le registre.

En fait, on ne va pas les enregistrer, mais mettre un condensat, une empreinte cryptographique, dans la zone supérieure. C'est le même principe que pour les serveurs de noms : chaque zone publie ses serveurs de noms (NS) dans la zone supérieure.

Il est important aussi que vous réalisiez ici les notions de temps. Entre le TTL, la durée de vie et de validité des clés et des signatures, vous ne pouvez plus faire des changements et regarder le truc marcher immédiatement.

En particulier, vous devez publier à l'avance les clés qui seront utilisées prochainement. Ceci amène de nombreux administrateurs à avoir en permanence deux ZSK : une qui est utilisée actuellement et une autre qui sera utilisée à la fin de la période de validité de la clé actuelle. C'est d'ailleurs cette solution qui est présentée en dessous. Les clés KSK sont elles aussi publiées à l'avance (quoique rarement en double).

Mise en place avec ldnscripts

Comme décrit plus tôt, signer votre domaine DNS vous permet de préserver son intégrité.

Cette opération doit être renouvelée régulièrement (les signatures DNSSEC ont une date de fraîcheur limite). Ceci requiert l'installation d'un signeur ainsi qu'un peu d'automatisation.

On va décrire ici la solution ldnscripts qui est un script simple réalisé par 22decembre.

Notez qu'il existe des outils plus complets/complexes comme OpenDNSSEC (beaucoup plus complexe à installer et administrer) ou KNOT.

ldnscripts ne nécessite pas d'ajouter d'outils particuliers mis à part ldns :

# pkg_add ldns-utils

Le reste sera géré en utilisant les outils déjà présents de base dans OpenBSD, à savoir les scripts /etc/weekly, /etc/monthly...

Nous allons suivre la méthode proposée par l'auteur de ce script et installer ldnscripts à partir de l'archive que l'on décompresse :

$ cd /tmp
$ ftp https://framagit.org/22decembre/ldnscripts/-/archive/master/ldnscripts-master.tar.gz
$ tar xvzf ldnscripts-master.tar.gz
$ cd ldnscripts-master* 
# make install

La configuration se déroule dans le fichier "/etc/ns/ldnscripts.conf". Vous avez un modèle dans l'archive téléchargée précédemment qui ressemble à ça :

# repository where to find unsigned zone file and specific conf
NS_REP=/etc/ns
# serial : unixtime
SERIAL=unixtime
# algorithm to use. They are listed : ldns-keygen -a list
ALG=ECDSAP384SHA384
# length of the zsk
ZSK_BITS=1024
KSK_BITS=2048
# validity of signatures in days
VALIDITY=9
#NSEC3
NSEC3_ALG=SHA-384
RUN=24
# Verbose - set to 1 if needed
VERBOSE=1

Les paramètres sont les suivants :

Si vous souhaitez utiliser une configuration par domaine, c'est tout à fait possible en créant un fichier de configuration portant le nom "/etc/ns/domaine.com.conf".

C'est tout pour la configuration 😊

Pour commencer à utiliser ldnscript, on lance l'action init qui va créer tout le nécessaire: structure, premières clés... La commande à lancer est :

# ldnscript init chezmoi.tld

Vous verrez alors des messages ressemblant à ceci (le VERBOSE est actif ci-dessous) :

This script will initialize your zone chezmoi.tld with the general configuration or the
one set at /etc/ns/chezmoi.tld.conf.
If you are not happy with it, modify your configuration (by copying the conf file to /etc/ns/chezmoi.tld.conf and then editing it) and run this script again.
The script will create one KSK and two ZSK and finally sign the zone (which will triger a reload of your NSD server on the chezmoi.tld zone).
The key Kchezmoi.tld.+010+25115 has been generated with these arguments : -a RSASHA512 -b 1024 chezmoi.tld
The key Kchezmoi.tld.+010+34655 has been generated with these arguments : -a RSASHA512 -b 1024 chezmoi.tld
The key Kchezmoi.tld.+010+12321 has been generated with these arguments : -k -a RSASHA512 -b 2048 chezmoi.tld
A new KSK key has been generated.
Make sure to update the DS record in your registrar quickly.
The key is Kchezmoi.tld.+010+12321
DS content : 
chezmoi.tld. IN      DS      12321 10 2 f6f91afd522680a3c459e1956e75f8eda078f99b8cf07114f0d299161bff0145
create a complete zone file for chezmoi.tld with the current time as SOA
Signing zone
Zone is verified and complete

Un dossier "/var/ldnscripts/chezmoi.tld/" est créé, il contient les clés ZSK et KSK.

Le fichier de zone signé est présent dans /var/nsd/zones/signed/chezmoi.tld. Adaptez donc la configuration de nsd pour l'utiliser :

server:
	zonesdir: "/var/nsd/zones"
	...
## master zones
zone:
    name: "chezmoi.tld"
    zonefile: "signed/chezmoi.tld"

À noter que NSD est un serveur statique. Heureusement, ldnscript le relance après chaque signature.

Attention, vous devez publier chez votre registre les clés publiques que vous trouverez dans les fichiers portant l'extension .key disponibles dans "/var/ldnscript/chezmoi.tld/ksk". Selon votre registre, il faut aussi publier les enregistrements DS qui sont dans le fichier .ds (pas pour GANDI).

Nous n'avons pas fini, il faut maintenant mettre en place une routine de signature avec renouvellement des clés lorsque c'est nécessaire. Tout est prévu, rassurez-vous 😊.

Parmi les actions proposées par ldnscript, on trouvera :

Concrètement, voici ce que vous allez faire. Éditez le fichier "/etc/monthly.local" pour y ajouter :

/usr/local/sbin/ldnscript rollover all

Ensuite, nous devons nous assurer que les signatures sont renouvelées avant la fin du paramètre VALIDITY du fichier de configuration. On a mis 9 jours auparavant, afin de lancer la signature chaque semaine avec 2 jours d'avance. Éditez le fichier "/etc/weekly.local" :

/usr/local/sbin/ldnscript sign all

Enfin, tous les ans, vous créerez une nouvelle KSK ainsi :

/usr/local/sbin/ldnscript ksk chezmoi.tld

Si vous avez peur d'oublier, ajoutez un crontab pour vous envoyer un message le 2 mai:

# crontab -e
0 0 2 5 * echo 'renew ksk' | mail -s "ALERT KSK" root

N'oubliez pas de publier cette clé chez votre registre. Le script rollover se chargera de supprimer l'ancienne automatiquement. Vous pourrez à ce moment-là retirer son enregistrement chez le serveur.

Et voilà, ça suffit, tout le reste est géré par ldnscript. C'est finalement long seulement la première fois. Notez que dans l'exemple, on gère toutes les zones.

Ajouter ou enlever des clés au registre

Lorsque vous renouvelez les KSK, vous devez publier la clé publique dans votre registre. Il faut le faire assez tôt pour qu'elle soit bien répandue avant que la précédente soit révoquée.

Lors de la création de la clé, ldnscript vous indiquera le numéro de la nouvelle clé (keytag) ainsi que son condensat (DS) qui vous servira pour la publication dans le registre.

La clé publique se situe dans le fichier "/var/ldnscripts/zones/chezmoi.tld/ksk/Kchezmoi.tld*.key".

On présente comment ajouter cette clé dans le système du bureau d'enregistrement Gandi (20% de réduction avec ce lien).

Dirigez-vous dans votre tableau de bord :

gandi ajout ksk 1

On voit ici la page d'entrée de Gandi pour le domaine si3t.ch. Vous avez un onglet vers la gestion DNSSEC.

gandi ajout ksk 2

Ici on voit la clé KSK enregistrée par Gandi. Ceci correspond au contenu du fichier "/var/ldnscripts/zones/si3t.ch/ksk/Ksi3t.ch.*.key". On voit le numéro de l'algorithme et le keytag qui correspondent avec le numéro du fichier.)

Pour enregistrer une nouvelle clé chez Gandi, cliquez sur "Ajouter une clé". Vous devez copier la clé publique dans la grande zone de texte Clé publique. Vérifiez aussi la correspondance avec l'algorithme.

gandi ajout ksk 3

À la fin du processus, Gandi aura calculé le DS (Condensat) de votre clé. Vous devriez vérifier qu'il correspond bien avec celui qui se trouve sur votre serveur, dans le fichier "/var/ldnscripts/zones/chezmoi.tld/ksk/Kchezmoi.tld.*.ds".

Certains bureaux d'enregistrements vont également vous proposer de récupérer automatiquement les clés et vous demander de valider qu'il s'agit bien *de celle-ci*. Cette méthode est assez sûre (pas de risque d'erreur lors d'un copier-collé de votre part) mais requiert que vous soyez très attentif à ce que le bureau ne vous propose pas une autre clé (ce qui constituerait un cas d'empoisonnement du DNS). C'est par contre une méthode très sûre dans le cadre du renouvellement des clés. En effet la zone, une fois signée, est sûre et on peut récupérer et enregistrer sereinement les nouvelles clés.

Quelle que soit la méthode utilisée pour enregistrer les clés sur les registres, il est fréquent que le bureau d'enregistrement vérifie automatiquement la clé avec celles qui sont publiées par votre serveur. Vous devez donc vous assurez que vos clés soient effectivement publiques avant cette étape.

Une fois qu'une clé est révoquée, l'enregistrement DS de la clé précédente peut être enlevé.

Ajouter un serveur DNS esclave

Que signifie ajouter un serveur DNS esclave ? Il n'y a pas là de racisme ou autre référence à une période bien sombre de l'histoire.

Il s'agit d'ajouter un serveur de nom (NS) dans votre domaine (chez le registre et dans votre zone) et le configurer pour qu'il serve lui aussi votre zone (qu'il fournisse les informations à propos de votre domaine). Il est un esclave (il obéit), mais il n'en est pas moins autoritaire (les informations qu'il délivre sont toutes aussi valables que celles que délivrerait votre premier serveur).

On parle aussi de serveur secondaire.

Ceci permet, si votre serveur principal (serveur maître) est inaccessible (coupure de réseau, le démon NSD est planté, pluie de météorites, pénurie de crêpe...), à votre zone d'être toujours annoncée.

Vous pouvez donc demander à un ami qui aurait un serveur de nom déjà installé (pas forcement OpenBSD, et pas forcement NSD non plus, bien que ce soit cette solution qui sera décrite) de se mettre en esclave sur votre domaine. Ou vous pouvez installer vous-même ce serveur, sur une machine virtuelle louée à openbsd.amsterdam par exemple 😊. L'important étant qu'ils ne soient pas dans le même réseau, voire d'une manière générale, assez éloignés l'un de l'autre : quelques centaines de km constituent une bonne protection contre les coupures de réseau/d'électricité simultanées 😉.

Notez qu'il est tout à fait possible d'être maître et esclave l'un de l'autre, en échange de bons procédés.

On va décrire ici les deux côtés du système. Vous pouvez donc être l'administrateur du serveur maître, du serveur esclave, ou bien des deux à la fois. Ceci étant assez standard, il est possible d'utiliser d'autres logiciels, il suffit de lire la documentation relative et d'adapter (monter un serveur Bind secondaire, etc…).

Commençons par prévoir un peu d'authentification.

Oui, je sais, c'est laborieux. En même temps, on veut faire les choses bien, non ? 😉 En l'occurrence l'authentification va permettre de garantir à nouveau que notre zone est mise à jour par le bon serveur.

Il s'agit de créer un secret partagé et identique sur les deux serveurs (maître et secondaire). Cette opération peut-être réalisée sur l'un ou l'autre serveur, voire sur un autre ordinateur.

Nous allons utiliser la commande ldns-keygen disponible dans le paquet ldns-utils que vous devriez déjà avoir installé si vous avez suivi la partie précédente. Il va nous permettre de créer une paire de clés qui contiendra un code "secret".

$ cd /tmp
$ ldns-keygen -a hmac-sha256 -b 160 chezmoi.tld

Vous avez deux fichiers créés, affichez le contenu de la clé privée :

$ cat Kchezmoi.tld.+159+54791.private
Private-key-format: v1.2
Algorithm: 159 (HMAC_SHA256)
Key: H8D/Ka9RerEtmC0jN5hSQeATxNI=

Copiez la chaîne de caractère "Key" dans la configuration de nsd pour le maître et l'esclave dans la partie secret. N'oubliez pas de préciser le bon algorithme :

key:
        name: "transfert"
        algorithm: hmac-sha256
        secret: "H8D/Ka9RerEtmC0jN5hSQeATxNI="

Le nom de la clé ("transfert ici") n'est pas important en soi, c'est juste pour se repérer.

Vous pouvez supprimer les fichiers de clé situés dans /tmp sans problème désormais.

Sur le serveur maître:

Dans la configuration du serveur de nom, on rajoute deux lignes pour informer le serveur esclave qu'il doit récupérer la zone du domaine. Pour ça, on rajoute les instructions notify et provide-xfr.

# master zone 
zone:
       name: "chezmoi.tld"
       zonefile: "signed/chezmoi.tld"  
       notify: 192.0.2.1 transfert
       provide-xfr: 192.0.2.1 transfert
key:
        name: "transfert"
        algorithm: hmac-sha256
        secret: "H8D/Ka9RerEtmC0jN5hSQeATxNI="

À chaque fois que la zone sera mise à jour sur votre serveur de nom primaire, celui-ci informera le serveur à l'adresse 192.0.2.1 et la zone sera mise à jour sur ce dernier.

De nombreux services en ligne (bureau d'enregistrement notamment, par exemple GANDI) vous proposent d'héberger gratuitement votre zone en esclave. Mais dans ce cas, ça ne sert à rien de les notifier : les serveurs pêchent la zone à intervalle régulier. Conservez juste le provide, sans authentification : NOKEY à la place du nom de la clé.

Pour utiliser le serveur secondaire de gandi.net, suivez ce lien.

Ça permet de retrouver l'IP du serveur secondaire de GANDI :

$ dig ns6.gandi.net +short
217.70.177.40

Reste plus qu'à indiquer dans votre zone et dans le registre (voir plus haut) que les serveurs secondaires sont bien là et fourniront l'info. (NS)

$ORIGIN chezmoi.tld.
$TTL 86400
@           IN SOA    maitre.chezmoi.tld. hostmaster.chezmoi.tld. (
                        2014110502      ;
                        86400           ; refresh
                        7200            ; retry
                        3600000         ; expire
                        172800 )        ; negative
@               IN NS       maitre.chezmoi.tld.
@               IN NS       secondaire.chezmoi.tld.
@               IN NS       autre.domaine.tld.   ; on a un autre ami 
                                                 ; qui nous aide !
maitre          IN A        192.0.2.2
maitre          IN AAAA     2001:db8:1:1::2
secondaire      IN A        192.0.2.3

Sur le serveur secondaire maintenant :

Il s'agit juste d'un peu de configuration:

# slave zone 
zone:
       name: "chezmoi.tld"
       zonefile: "slave/chezmoi.tld"
       allow-notify: 192.0.2.2 transfert
       request-xfr: 192.0.2.2 transfert
key:
        name: "transfert"
        algorithm: hmac-sha256
        secret: "H8D/Ka9RerEtmC0jN5hSQeATxNI="

Remarquez bien que les clés de transfert ont une configuration rigoureusement identique sur les deux serveurs.

Les fichiers de zones ne doivent pas être édités ou manipulés sur le secondaire. Ils seront mis à jour tout seuls. Si vous voulez les faire changer de place dans le système de fichiers, éditez la configuration et relancez NSD. Ce dernier va re-télécharger la zone depuis le serveur maître et créer les nouveaux fichiers tout seul.

Vous pouvez tester la synchronisation des zones avec dig :

$ dig -q @maitre.chezmoi.tld chezmoi.tld
$ 192.0.2.10
…
$ dig -q @secondaire.chezmoi.tld chezmoi.tld
$ 192.0.2.10

N'oubliez pas d'ajouter le serveur secondaire dans la liste des serveurs de noms chez le registre.

Vérifier que la zone fonctionne

Vous pouvez utiliser les sites suivants pour vérifier que votre zone se propage correctement, ne génère pas d'erreurs et que la mise en place de DNSSEC est correcte :

Vérification de la zone

Vérification de la zone et tests divers

Où en est la propagation ?

Vérification DNSSEC

Vérifications complètes et visuelles.

Exemple complet et gratuit avec nic.eu.org

nic.eu.org propose depuis 1996 des noms de domaines gratuits terminant par eu.org.

Nous allons voir ici la mise en place d'une zone avec ce registre.

Tout d'abord, consultez la liste des domaines ouverts à l'enregistrement, puis choisissez-en un qui vous plaît.

Pour l'exemple, nous prendrons "chezmoi.tld.fr.eu.org"

Créez la zone de ce domaine. Puisque par la suite, nous utiliserons "ldnscripts" décrit plus tôt pour activer DNSSEC, on crée directement le fichier "/etc/ns/chezmoi.tld.fr.eu.org" :

$TTL 1D
$ORIGIN chezmoi.fr.eu.org.
@       IN SOA ns1.chezmoi.fr.eu.org. batman.chezmoi.tld. (
                              2017111301
                              1D
                              2H
                              2W
                              2D )
@                             IN NS     ns1.chezmoi.fr.eu.org.
@                             IN A      192.0.2.2
@                             IN AAAA   2001:db8:1:1::2
ns1                           IN A      192.0.2.2
ns1                           IN AAAA   2001:db8:1:1::2
ns2                           IN A      192.0.2.3

La zone est basique, on ne précise pour l'instant que deux serveur de noms, "ns1" et "ns2", dont le second est uniquement accessible en IPV4.

On ajoute une section pour nsd sur "ns1" :

# cat /var/nsd/etc/nsd.conf
key:
    name: "transfert"
    algorithm: hmac-sha256
    secret: "Hsd/Ka9RerEtmC0jsd5d5eATxNI="
zone:
    name: "chezmoi.tld.fr.eu.org"
    zonefile: "signed/chezmoi.tld.fr.eu.org"
    provide-xfr: 192.0.2.3 transfert
    notify: 192.0.2.3 transfert

Faîtes de même sur le serveur secondaire "ns2" :

# cat /var/nsd/etc/nsd.conf
key:
  name: "transfert"
  algorithm: hmac-sha256
  secret: "Hsd/Ka9RerEtmC0jsd5d5eATxNI="
zone:
  name: "chezmoi.tld.fr.eu.org"
  zonefile: "slave/chezmoi.tld.fr.eu.org"
  allow-notify: 192.0.2.3 transfert
  request-xfr: 192.0.2.3 transfert

On recharge nsd :

# rcctl reload nsd

On active la zone avec ldnscripts tout en préparant pour DNSSEC.

# ldnscript init chezmoi.tld.fr.eu.org

Et voilà, c'est prêt. On peut maintenant enregistrer le domaine puisqu'il est géré.

Créez un compte puis connectez-vous après avoir validé le mail d'inscription.

Choisissez ensuite de créer un Nouveau domaine.

Il vous est alors demandé le nom de domaine complet souhaité ainsi que des informations sur votre personne.

exemple niceuorg 1

Ensuite, vous devez remplir la section "Serveurs de noms". Il s'agit ici d'associer le nom de domaine et l'IP des serveurs de noms gérant la zone du domaine souhaité. Il est important que la zone soit déjà gérée par ces serveurs quand vous remplissez ce champ. Vous pouvez préciser des IPV4 et IPV6.

Plus simplement dit, il faut préciser les enregistrements "NS" qui sont dans votre zone.

exemple niceuorg 2

Finalement, validez. Vous verrez apparaître si tout va bien un message de la sorte :

  ---- Servers and domain names check
  Accepted IP for NS1.CHEZMOI.FR.EU.ORG: 2001:db8:1:1::2 192.0.2.2
  Accepted IP for NS2.CHEZMOI.FR.EU.ORG: 192.0.2.3
  ---- Checking SOA records for chezmoi.fr.eu.org
  SOA from NS1.CHEZMOI.FR.EU.ORG at 2001:db8:1:1::2: serial
  2019100702 (21.005 ms)
  SOA from NS1.CHEZMOI.FR.EU.ORG at 192.0.2.2: serial 2019100702 (6.006 ms)
  SOA from NS2.CHEZMOI.FR.EU.ORG at 192.0.2.3: serial
  2019100702 (73.715 ms)
  ---- Checking NS records for chezmoi.fr.eu.org
  NS from NS1.CHEZMOI.FR.EU.ORG at 2001:db8:1:1::2: ok (20.674 ms)
  NS from NS1.CHEZMOI.FR.EU.ORG at 192.0.2.2: ok (5.953 ms)
  NS from NS2.CHEZMOI.FR.EU.ORG at 192.0.2.3: ok (65.559 ms)
  No error, storing for validation...
  Saved as request 20191007195509-arf-42318
  Done

Surveillez votre boîte mail. Vous allez bientôt recevoir un message confirmant la création de votre zone.

Une fois que cela est fait, vous pouvez activer DNSSEC. Dirigez-vous dans l'interface de gestion puis sélectionnez votre domaine fraîchement créé. Cliquez alors sur "DNSSEC"

Vous voyez un champ vous permettant de coller l'enregistrement DS. Avec ldnscripts présenté plus tôt, c'est très simple.

cat /var/ldnscript/chezmoi.tld.fr.eu.org/ds

Copiez le contenu de ce fichier dans le champ puis validez.

Vous pouvez maintenant vérifier que DNSSEC est bien activé sur votre zone.

C'est quoi virtualiser ? (vmd)

C'est de plus en plus facile de virtualiser un système dans OpenBSD grâce à vmd.

Euh, ok, mais ça veut dire quoi virtualiser ?

Pour faire fonctionner plusieurs systèmes d'exploitation, vous imaginez peut-être qu'il est nécessaire d'avoir plusieurs ordinateurs. Que nenni 😁. Vous pouvez héberger des systèmes virtuels sur votre serveur

Le disque du nouveau système est un simple fichier, et le virtualiseur fait comme s'il était une vraie machine pour éxécuter le système d'exploitation présent dans ce fichier.

Plus simplement, il vous est possible d'avoir plusieurs OpenBSD dans une OpenBSD (openbsdception 😁), comme s'il s'agissait de plusieurs machines indépendantes.

Cela présente de nombreux avantages :

Toutefois, cela consomme davantage de ressources.

Avant d'aller plus loin, afin de bien nous comprendre, il faut préciser à quoi fera référence le vocabulaire suivant :

OpenBSD nous propose trois outils pour virtualiser un système :

Vérifiez tout d'abord si votre matériel prend en charge la virtualisation avec la commande suivante :

$ dmesg | egrep '(VMX/EPT|SVM/RVI)'

Si le résultat n'est pas vide, c'est tout bon 😊.

N'oubliez pas de mettre à jour les firmwares si besoin : "# fw_update".

Activez vmd avant de passer à la suite :

# rcctl enable vmd
# rcctl start vmd

Pour ajouter une machine virtuelle, nous procéderons toujours dans l'ordre suivant :

1. Installation d'un système dans une machine virtuelle sur un fichier disque avec vmctl ;

2. Configuration de vmd pour qu'il gère cette machine automatiquement.

Virtualisation d'OpenBSD

Installation d'une machine virtuelle

Nous allons créer en exemple une machine virtuelle avec OpenBSD dessus. Pour nous simplifier la vie, nous créons nos machines virtuelles dans le dossier "/var/vm" :

# mkdir /var/vm

Tout d'abord, créez une image disque de 50G par exemple :

# vmctl create -s 50G /var/vm/obsdvm.qcow2 
vmctl: qcow2 imagefile created

Vous pouvez voir qu'il y a un nouveau fichier obsdvm.qcow2 : c'est le disque de la machine virtuelle.

Maintenant, installez OpenBSD sur cette image. Trois possibilités :

1 : Si vous avez téléchargé une image d'installation de tyle "installXX.iso":

# vmctl start -c -m 1G -L -i 1 -r installXX.iso -d /var/vm/obsdvm.qcow2 openbsdvm 

Voici la signification des diverses options :

2 : Si vous avez une image disque installXX.img (ou minirootXX.img)

# vmctl start -c -m 1G -L -i 1 -d installXX.img -d /var/vm/obsdvm.qcow2 openbsdvm

3 : Si vous avez juste le fichier /bsd.rd (sans doute déjà présent sur votre machine) :

# vmctl start -c -m 1G -L -i 1 -b /bsd.rd -d /var/vm/obsdvm.qcow2 openbsdvm 

Attention, ce type d'installation nécessite un accès à internet pour votre machine virtuelle. Configurez-le avant 😉 :

Voir le paragraphe "Accès au réseau pour toutes les machines virtuelles"

L'installation d'OpenBSD se passe comme d'habitude.

Une fois l'installation terminée, choisissez "Halt" puis quittez la console de la machine virtuelle en appuyant successivement sur "~" et ".". Attention si vous utiliser une connexion SSH, il faudra alors entrer la séquence "~~." au risque de vous déconnecter de votre session SSH en même temps que la console de la machine virtuelle.

Arrêtez proprement la machine virtuelle ainsi :

# vmctl stop openbsdvm

Maintenant que l'installation est terminée, on va simplifier la gestion de la machine virtuelle.

Ajout de la machine virtuelle dans vmd

Laissons vmd gérer automatiquement la machine virtuelle désormais.

Éditez le fichier "/etc/vm.conf" qui sera lu par vmd afin de préciser quelques informations concernant la machine virtuelle :

vm "openbsdvm" {
    memory 1G
    enable
    disk /var/vm/obsdvm.qcow2
    local interface
    owner batman 
}

Veillez à bien adapter les options "disk" et "owner" selon la configuration souhaitée. "owner" permet de pouvoir gérer votre machine virtuelle en tant que simple utilisateur, sans avoir à devenir root, et ça c'est cool 😎. Vous pouvez de cette façon dédier une machine virtuelle à certains utilisateurs.

Relancez vmd pour profiter de cette configuration. Ce dernier va démarrer automatiquement la machine virtuelle. Vous pouvez toujours vous y connecter avec la commande :

vmctl console obsdvm

Accès au réseau pour toutes les machines virtuelles

Par défaut, les machines virtuelles sont "enfermées" sur le serveur. Si vous souhaitez leur autoriser un accès à internet, quelques manipulations sont à réaliser.

Tout d'abord, ajoutez ceci dans la configuration du parefeu (/etc/pf.conf) pour autoriser le flux sortant des machines virtuelles:

# utilisation d'un resolveur DNS public
pass in quick proto { tcp udp } from 100.64.0.0/10 to any port domain \
    rdr-to 9.9.9.9 port domain
match out on egress from 100.64.0.0/10 to any nat-to (egress)

Ici, on utilise un résolveur DNS public pour les machines virtuelles.

Vous voudrez sans doute modifier cette partie, notamment "9.9.9.9" par un résolveur qui vous convient peut-être davantage.

Dans le cas où vous avez configuré le résolveur unwind sur l'hôte (et c'est une excellente idée 😎), vous pouvez faire en sorte que les machines virtuelles puissent s'en servir plutôt que d'utiliser le résolveur précédent :

# Utilisation du résolveur unwind(8) de l'hôte pour les VM
pass in proto { tcp udp } from 100.64.0.0/10 to any port domain \
    rdr-to localhost port domain
match out on egress from 100.64.0.0/10 to any nat-to (egress)

Si vous avez configuré votre parefeu de façon à ce qu'il bloque tout par défaut, vous devrez ajouter ceci afin d'autoriser l'interface servant à communiquer avec les machines virtuelles :

pass on tap0 from 127.0.0.1 to any
pass on tap0 from 100.64.0.0/10 to any

Dans tous les cas, il faudra activer l'"ip forwarding" dans le fichier "/etc/sysctl.conf" :

net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1

Ainsi, les requêtes sont correctement redirigées vers (ou depuis) les machines virtuelles.

Après avoir pris en compte ces modifications, c'est tout bon 😊.

Dédier une machine virtuelle à une tâche

Vous voudrez certainement attribuer à chacune de vos machines virtuelles un rôle bien précis : l'une pour servir les sites web, une autre pour les mails... C'est bien entendu tout à fait possible, mais nécessite une configuration réseau différente de celle présentée jusqu'ici.

Ajout d'une interface virtuelle côté hôte

Sur votre serveur, créez une nouvelle interface de type "vether" (ethernet virtuel...)

# echo 'inet 10.0.0.1 255.255.255.0' > /etc/hostname.vether0
# sh /etc/netstart vether0

Ensuite, créez une interface de type bridge (qui fait le "pont" entre l'hôte et les machines virtuelles).

# echo 'add vether0' > /etc/hostname.bridge0
# sh /etc/netstart bridge0

Désormais, la redirection dans le parefeu se fait ainsi :

# match out on egress from 100.64.0.0/10 to any nat-to (egress) # ancienne ligne
match out on egress from vether0:network to any nat-to (egress)
# necessaire pour resolutions DNS
pass in quick proto { udp tcp } from vether0:network to any port domain \
    rdr-to 9.9.9.9 port domain
#pass on tap0 from 127.0.0.1 to any
#pass on tap0 from 100.64.0.0/10 to any
pass on vether0 from 127.0.0.1 to any
pass on vether0 from 10.0.0.0/24 to any
# ou pour ne pas s'embeter :
# pass on vether0

Afin de lancer une machine virtuelle, nous n'utiliserons plus l'option "-L" avec vmctl ni l'option "local interface" dans "/etc/vm.conf". À la place, on configure une adresse bien précise pour chaque machine virtuelle dans le fichier "/etc/vm.conf" :

switch "my_switch" {
    interface bridge0
}
vm "openbsdvm" {
    memory 1G
    enable
    disk /var/vm/obsdvm.qcow2
    owner batman 
    interface { switch "my_switch" }
}

Configuration du réseau côté machine virtuelle

Sur la machine virtuelle, vous pouvez configurer une IP dans la plage 10.0.0.0/24 : c'est ce qu'on a mis dans le fichier "/etc/hostname.vether0". Par exemple : "10.0.0.2", "10.0.0.3"...

La route par défaut à indiquer est 10.0.0.1. Cela donnera :

# cat /etc/hostname.vio0
inet 10.0.0.2 255.255.255.0 10.0.0.255
!route add default 10.0.0.1
# cat /etc/resolv.conf
nameserver 10.0.0.1

Redirection du trafic vers les machines virtuelles

Selon la nature de la demande, vous enverrez le flux sur la machine virtuelle concernée. Prenons l'exemple suivant :

Sur le serveur hôte, vous configurerez le parefeu de cette façon :

pass in on egress proto tcp from any to (egress) port { 80 443 } rdr-to 10.0.0.2
pass in on egress proto tcp from any to (egress) port 22 rdr-to 10.0.0.3

Remarquez que pour plusieurs sites web, vous voudrez plutôt utiliser relayd afin de répartir la charge.

Virtualisation de debian

On télécharge debian puis on l'installe après avoir créé le disque :

ftp "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.5.0-amd64-netinst.iso"
vmctl create -s 50G /var/vm/debian.qcow2 
vmctl start -c -m 1G -L -i 1 -r debian*.iso -d /var/vm/debian.qcow2 debianvm

Choissez le menu "Install" SANS VALIDER ⚠.

Appuyez sur TAB puis modifiez la ligne qui apparaît pour entrer à la place :

/install.amd/vmlinuz vga=off initrd=/install.amd/initrd.gz --- quiet console=ttyS0,115200n8 

Vous devez modifier les options vga et ajouter "console=...." Merci à PengouinBSD pour l'astuce.

La suite, c'est comme d'habitude sous debian.

Il est impératif de modifier les options de démarrage de debian une fois l'installation terminée. Au redémarrage, éditer le fichier de configuration de grub (le gestionnaire de démarrage). Il s'agit du fichier "/etc/default/grub" où vous veillerez à avoir ces lignes :

GRUB_TIMEOUT=1
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="console=tty1 console=ttyS0,115200"
GRUB_TERMINAL="console serial"
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"

Ensuite, reconstruisez la configuration de grub :

# update-grub

On peut maintenant configurer la machine virtuelle sur le serveur dans "/etc/vm.conf".

switch "my_switch" {
    interface bridge0
}
vm "debianvm" {
    memory 200M
    enable
    disk /var/vm/debian.qcow2
    interface { switch "my_switch" }
    owner batman
}

Et voilà, vous avez debian virtualisée par OpenBSD 😊.

Vous voudrez sans doute configurer les interfaces réseau de la machine virtuelle debian par la suite.

Configuration de l'accès réseau pour l'hôte debian

Remplissez sur la machine virtuelle le fichier "/etc/network/interfaces" selon l'interface détectée par debian.

Voir la documentation debian à ce sujet.

Virtualisation d'Alpine Linux

Alpine Linux est une distibution très légère, qui sera un choix appréciable si vous avez juste besoin d'un système Linux à virtualiser.

L'installation et la virtualisation de ce système minimaliste ne devrait poser aucune difficulté.

Téléchargez une image d'installation ".iso" alpine, puis procédez comme si vous virtualisiez OpenBSD :

# vmctl create -s 50G /var/vm/linux.qcow2 
# vmctl start -c -m 1G -L -i 1 -r image.iso -d /var/vm/linux.qcow2 linux

Lorsque la machine virtuelle démarre, appuyez sur "TAB" pour voir quel est l'image disponible. Ça peut être "lts". Indiquez alors au prompt l'image que vous voulez démarrer suivi de l'option concernant la console. Par exemple :

lts console=ttyS0,115200

Ou encore, avec l'image optimisée pour les systèmes virtualisés (notre cas):

virt console=ttyS0,115200

Validez avec Entrée puis poursuivez l'installation.

Aller plus loin avec vmd

Vous pouvez consulter les liens suivants :

FAQ officielle

openbsd.amsterdam propose des machines virtuelles et reverse une partie des gains à OpenBSD (1/6e tout de même ! 😊).

Détails de l'infrastructure d'OpenBSD.amsterdam

Qu'est-ce qu'un VPN ?

VPN signifie "virtual private network" que l'on peut traduire par réseau virtuel privé. Comme son nom l'indique, cela permet de créer un réseau entre plusieurs machines qui sera "caché" au reste de l'internet mondial (d'où le "privé").

En pratique, un VPN sert souvent à contourner les restrictions ou utilisations plus ou moins abusives qu'un fournisseur d'accès, d'un réseau WiFi public, ou un gouvernement peuvent mettre en place sur votre accès à internet. Vous retrouvez ainsi un accès sain.

Il existe plusieurs sortes de VPN, chacun présentant des avantages et inconvénients selon l'utilisation souhaitée.

Nous présenterons donc plusieurs solutions dans cette partie : Wireguard, OpenIKED, et un tunnel SSH.

Un peu de vocabulaire

Par la suite, nous appelerons :

Nous configurerons principalement des "roadwarriors".

roadwarrior... c'est censé avoir du sens?

Ce terme décrit une l'utilisation du tunnel VPN permettant à un client, peu importe son adresse IP, de faire passer tout ou partie de son traffic au travers du VPN pour le faire sortir par le serveur. De cette façon, pour les autres, tout semble venir du serveur, le client étant "caché" derrière la facade du serveur. Le serveur, quant à lui, ne fait qu'attendre qu'un client se connecte pour faire le relai.

Un peu plus loin, nous proposerons aussi la possibilité d'utiliser un VPN pour proposer votre serveur derrière une nouvelle IP fixe, pratique pour les serveurs nomades ou si votre fournisseur d'accès à internet ne vous propose pas d'IP fixe ou bien une IP à mauvaise réputation.

Wireguard

Wireguard est un VPN très pratique à mettre en place tout en restant sécurisé puisqu'il n'accepte que les dernières méthodes de chiffrement existantes. De plus, il fonctionne même si l'IP de votre appareil change (passage d'une connexion filaire à un réseau sans-fil par exemple). Il permet un accès tant en IPv4 qu'IPv6, ce qui peut permettre d'obtenir une IP fixe en IPv6 si votre FAI n'en donne pas. Il est supporté de base à partir d'OpenBSD 6.8. Avec les version précédentes, il faudra installer un port ("# pkg_add wireguard-go").

Site officiel de Wireguard

Il existe des clients wireguard sur de multiples plateformes (android, MacOS...) ce qui facilite son utilisation.

C'est certainement le choix le plus simple et utile si on veut mettre en place un VPN sur un serveur auto-hébergé.

Principe de fonctionnement

On retrouve les mêmes idées qui ont déjà fait leurs preuves pour chiffrer des mails ou encore publier les signatures DKIM : la paire de clés.

Pour faire simple, chaque morceau de données envoyé au travers du VPN est mis dans un coffre et fermé avec un cadenas qui ne peut s'ouvrir qu'avec la clé échangée pendant la poignée de mains. La poignée de main est quant à elle chiffrée avec les clés publiques la première fois.

Mise en place d'un point de sortie ("roadwarrior")

Je vous propose l'organisation suivante :

Dans cet exemple, nous utiliserons dans le VPN des IP situées dans le sous réseau 10.0.0.0/24 :

En savoir plus sur les adresses sous-réseau

Voici à quoi cela va ressembler :

   +-------------+
    |   serveur   | wg0: 10.0.0.1 port 4545
    |             |---------------+
    +-------------+               |
           | IP Publique          |
           | 192.0.2.2            |
           |                      |
           |                      |
    /\/\/\/\/\/\/\                |WireGuard
    |  internet  |                |VPN
    \/\/\/\/\/\/\/                |
           |                      |
           |                      |
           |rdomain 1             |
    +-------------+               |
    |   client    |---------------+
    +-------------+ wg0: 10.0.0.2
                    rdomain 0 (defaut)

Par défaut, le traffic passera par 10.0.0.2 à moins que vous demandiez précisément à passer par une autre route. (ex : "route -T1 exec ping openbsd.org")

Le VPN se met en place par la création d'interfaces wgN, où "N" peut être un chiffre de 0 à 9 par exemple. Sous OpenBSD, une telle interface peut être obtenue en remplissant un fichier "/etc/hostname.wgN".

Le serveur écoutera sur le port 4545 en UDP. N'importe quel autre port peut-être utilisé. Vérifiez tout de même que celui choisi ne soit pas déjà réservé en consultant "/etc/services".

Création de clés

Pour créer une clé privée robuste, utilisez la commande suivante :

openssl rand -base64 32

Cela retourne par exemple : "uA1ggvRv66QslZ0ygorWvcLVTxzFauffqMigXTrmLVY="

Ce n'est qu'une fois une clé privée attribuée à une interface que vous pourrez récupérer la clé publique correspondante avec la commande

# ifconfig wgN

Sur le serveur

On crée une clé privée :

# openssl rand -base64 32
r8uSGD6vyycE5n5/atU9/NX9JQPo4SJryNGpjbQG+rA=

On crée l'interface en précisant la clé précédente

# ifconfig wg0 create wgkey r8uSGD6vyycE5n5/atU9/NX9JQPo4SJryNGpjbQG+rA= wgport 4545

Maintenant, vous pouvez récupérer la clé publique correspondant à cette nouvelle interface :

# ifconfig wg0
wg0: flags=8082<BROADCAST,NOARP,MULTICAST> mtu 1420
        index 5 priority 0 llprio 3
        wgport 4545
        wgpubkey x9VXlh4AMa2YRjTMRVE39pQRsFHRJHUYrATL6vkqFmU=
        groups: wg

La ligne commençant par "wgpubkey" vous renseigne sur la clé publique utilisée par le serveur. Il faudra la préciser pour les clients, prenez-en note.

Prenez-bien note aussi de la clé privée du serveur : on l'utilisera tout à l'heure dans un fichier pour automatiser toute la procédure en cours.

Sur un client

On fait la même chose que sur le serveur, c'est à dire créer une clé privée puis une interface wg0 associée (nul besoin de préciser le port):

# openssl rand -base64 32
    q/7uIx6wBIRUIdxOi5D6OWEQRVUt2AXhMj7j29W/s3s=
# ifconfig wg0 create wgkey q/7uIx6wBIRUIdxOi5D6OWEQRVUt2AXhMj7j29W/s3s=
# ifconfig wg0 |grep wgpubkey
    wgpubkey V3pCAhxnRl0QEL8luB9D4EvTVxGT7QGDDCZ3O26kY3A=

Redirection du traffic à travers le serveur

Ici, on souhaite que le serveur se constitue comme une sorte de relai entre le client et le reste du réseau.

On doit pour cela activer la redirection d'IP sur les paquets passant par le serveur :

# sysctl net.inet.ip.forwarding=1

Pour que ça soit automatique, ajoutez cette ligne dans "/etc/sysctl.conf" :

net.inet.ip.forwarding=1

Si vous voulez faire de même en IPv6, utilisez plutôt:

net.inet6.ip6.forwarding=1

De plus, il faudra ajouter une règle pour faire du nat avec le parefeu :

# Ouverture du port 4545 en UDP
pass in proto udp from any to any port 4545 keep state
# Ce qui vient du VPN (wg0) est NATté vers l'interface "publique" du
# serveur
match out on egress from (wg0:network) to any nat-to (egress)
# la règle match doit être avant un "pass out on egress..." final
pass on egress from (wg0:network) to any
pass in on wg0

Creusons le tunnel

Maintenant qu'on dispose de tout le nécessaire pour identifier client et serveur, on peut creuser le tunnel. Pour ça, on va notamment ajouter les clés publiques des clients sur le serveur, et inversement. On va aussi indiquer les IP autorisées à utiliser le tunnel.

Afin de gagner du temps pour la suite et rendre les choses plus simples, nous allons désormais directement éditer les fichiers "/etc/hostname.wg0". Ainsi, lors d'un futur redémarrage, la configuration sera intacte.

Prêtez bien attention aux clés utilisées, ce sont les mêmes que celles obtenues juste avant pour vous aider à vous repérer. 😉

Sur le serveur :

Le fichier "/etc/hostname.wg0" contient maintenant:

inet 10.0.0.1/24
wgkey r8uSGD6vyycE5n5/atU9/NX9JQPo4SJryNGpjbQG+rA=
wgport 4545
wgpeer V3pCAhxnRl0QEL8luB9D4EvTVxGT7QGDDCZ3O26kY3A= wgaip 10.0.0.2/32
up

Quelques explications :

Vous pouvez ajouter autant de lignes "wgpeer" que vous voulez. C'est bon à savoir si vous souhaitez proposer un accès à plusieurs machines 😉. Cependant, chaque client disposera de sa propre IP. Par exemple :

wgpeer V3pCAhxnRl0QEL8luB9D4EvTVxGT7QGDDCZ3O26kY3A= wgaip 10.0.0.2/32
wgpeer m7K/gfmMPYRJx1IOP01zYrNbEuMnnZ29xN4OBgRoRXo= wgaip 10.0.0.3/32
wgpeer qnuq5MgezCDHXsYYGmrcegPCNcJvz9EOIG3XyHp1DBk= wgaip 10.0.0.4/32

Sur le client :

Le fichier "/etc/hostname.wg0" du client fonctionne comme pour le serveur, à ceci près qu'on doit notamment préciser où trouver le serveur ("wgendpoint") et modifier les routes par défaut pour que le traffic passe par le tunnel.

wgkey q/7uIx6wBIRUIdxOi5D6OWEQRVUt2AXhMj7j29W/s3s=
wgpeer x9VXlh4AMa2YRjTMRVE39pQRsFHRJHUYrATL6vkqFmU= wgendpoint chezmoi.tld 4545 wgaip 0.0.0.0/0
inet 10.0.0.2/24
wgrtable 1
!route add -net default 10.0.0.1
up

Ouvrez le tunnel avec la commande suivante sur le serveur et le client :

# sh /etc/netstart wg0

Modifiez la configuration correspondant à l'interface du client pour lui préciser de passer par la table de routage 1. Par exemple, dans "/etc/hostname.em0" :

dhcp
rdomain 1
up

Vous pouvez désormais vérifier que lorsque vous naviguez sur internet, votre nouvelle IP est celle du serveur.

Configuration de clients utilisant d'autres systèmes d'exploitation

Comme je le disais plus haut, Wireguard est bien supporté par la plupart des systèmes. Cherchez "Client wireguard -nom-de-votre-plateforme-" pour trouver votre bonheur. Par exemple, pour Android, on peut trouver un client dans les dépôts F-droid.

Système supportés par Wiregard

F-droid

Voici le minimum à préciser :

Interface :

Pair :

Pour aller plus vite

On a précisé ici comment déployer le VPN avec les outils de base dans OpenBSD. Sachez que vous pouvez installer le port "wireguard-tools" qui pourra vous faire gagner du temps sur la gestion des clés.

Ressources

Ce tutoriel est très largement inspiré des liens suivants :

Je souligne l'importance du travail de Solène qui a eu la judicieuse idée d'utiliser "rdomain" plutôt que modifier les routes par défaut.

Un VPN avec OpenIKED

OpenIKED est une implémentation libre du protocole IKEv2 qui permet de mettre en place des VPN de type IPSec.

Ce protocole permet, comme Wireguard, de s'assurer des éléments de sécurité suivants :

Sous OpenBSD, le nom du démon qui gère les connexions IKEv2 s'appelle iked.

Vous pouvez dores et déjà consulter la FAQ17 qui couvre officiellement le sujet, puisque cette partie en suit les grandes lignes en guise de traduction détaillée.

Configuration des paires de clés

Par défaut, iked utilise une identification par jeton de clés (publique/privée), un peu comme pour ssh. Vous pouvez les stocker dans des dossiers bien précis pour faciliter l'organisation (au format PEM), iked les prendra automatiquement en charge. Selon si les sources (srcid) et les destinations (dstid) sont écrites sous la forme d'adresses IP ou de noms de domaines, les clés publiques seront à enregistrer sous :

Ce qui est génial, c'est qu'iked saura les retrouver comme un grand.

Dans le cadre de ce tutoriel, nous allons présenter la méthode la plus simple, à savoir se servir des clés publiques présentes par défaut sur une installation d'OpenBSD. Libre à vous de créer de nouvelles paires de clés avec la commande openssl si vous le souhaitez afin de changer l'algorithme de chiffrement. La partie privée des clés générées sera dans "/etc/iked/private", mais vous l'auriez deviné tout seul 😉.

Pour l'exemple, nous allons copier les clés déjà prêtes. C'est facile de les trouver, il s'agit du fichier "/etc/iked/local.pub".

Configuration réseau pour iked

Sur le serveur et le client, activez l'interface enc0 :

# echo up > /etc/hostname.enc0
# sh /etc/netstart enc0

Ensuite, insérez dans le fichier "/etc/sysctl.conf" les lignes suivantes, toujours sur le serveur et le client.

net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1

Sur le serveur et le client, vous ajouterez :

net.inet.ipcomp.enable=1

Activez directement ces fonctionnalités sans avoir à redémarrer :

# while read -r line; do sysctl $line; done < /etc/sysctl.conf

Configuration du pare-feu pour iked

Afin de pouvoir établir la liaison entre le client et le serveur, vous devez ouvrir et rediriger ports 500 (isakmp) et 4500 (ipsec-nat-t) sur le serveur.

De plus, on redirige le traffic passant par le VPN en sortie pour qu'il apparaisse avec l'IP du serveur et non celle du client. Ce flux est repéré par l'étiquette "ROADW" définie plus loin dans la configuration d'OpenIKED. Le fichier "/etc/pf.conf" du serveur ressemblera à ceci (lisez les commentaires) :

# On rassemble les paquets
set reassemble yes
# Petite precaution
antispoof quick for enc0
# On laisse entrer le traffic IKE et IKE NAT-Traversal pour l'authentification
pass in log on egress proto udp from any to <ip-du-serveur> port {isakmp, ipsec-nat-t} tag IKED
pass in log on egress proto esp from any to <ip-du-serveur> tag IKED
# On laisse passer le traffic encapsule avec l'etiquette ROADW
pass log on enc0 tagged ROADW
# On redirige le traffic avec l'etiquette ROADW vers la sortie
match out log on egress inet tagged ROADW nat-to (egress)

Configuration d'IKED

Tous les fichiers iked.conf doivent avoir des droits bien choisis. Que ce soit sur le client ou le serveur, vous entrerez :

# touch /etc/iked.conf
# chmod 600 /etc/iked.conf

Sur le serveur

Voici le contenu du fichier "/etc/iked.conf" sur le serveur :

ikev2 "warrior" passive ipcomp esp \
from 0.0.0.0/0 to 10.0.5.0/24 \
peer any local <ip.publique.du.serveur> \
srcid "chezmoi.tld" \
tag "ROADW"

Ce dernier crée un flux à partir du traffic venant de n'importe où (0.0.0.0) et le redirige vers le réseau 10.0.5.0/24 auquel appartiendront les clients. Au passage, il donne l'étiquette "ROADW" à ce flux pour le repérer ensuite.

Pensez à bien modifier l'IP publique du serveur et le nom de domaine. Le paramètre srcid servira à identifier le certificat à utiliser pour l'authentification (ça peut donc aussi être une adresse IP selon ce que vous avez préféré.

Tu crois t'en sortir comme ça ? Nous on veut savoir ce que ça veut dire ces trucs bizarres dans la configuration.

Et c'est parti pour des détails, ligne par ligne :

Sur le client

La configuration est quasiment identique, mais inversée 😉

ikev2 "warrior" active ipcomp esp \
from 0.0.0.0/0 to 0.0.0.0/0 \
peer "<ip.publique.du.serveur>" \
srcid "batman@cacahuete.tld" \
dstid "chezmoi.tld"

Les paramètres auxquels vous devez être attentifs sont srcid et dstid :

Si vous êtes perdus, retournez lire la partie sur les clés un peu plus haut. 😉

Le client doit aussi configurer son IP pour qu'elle appartienne au réseau 10.0.5.0/24. Vous pouvez le faire ainsi en éditant sur le client le fichier de configuration "/etc/pf.conf" :

match out log on enc0 inet all nat-to 10.0.5.2

Cela associe tout le flux sortant sur l'interface enc0 à l'adresse 10.0.5.2. Si vous utilisez plusieurs client, vous devrez modifier cette adresse. N'oubliez pas de recharger le parefeu.

Attention : tout le flux du client passe désormais par le tunnel chiffré. Cela peut être embêtant notamment pour la résolution de domaine, ou si vous utilisez des démons locaux. Ajoutez seulement cette ligne au fichier "/etc/ipsec.conf" :

flow from 127.0.0.1/32 to 127.0.0.1/32 type bypass

Activez cette règle avec la commande

# ipsecctl -f /etc/ipsec.conf

En cas d'erreur concernant les permissions, entrez :

# chmod 600 /etc/ipsec.conf

Afin de ne pas avoir à lancer cette commande lors d'un redémarrage, entrez :

rcctl enable ipsec

Attention 2 : La résolution de noms (DNS) ne pourra pas se faire en local. Idéalement, il faudrait indiquer dans le fichier "/etc/resolv.conf" un résolveur accessible via le VPN, et dans l'idéal le résolveur du serveur s'il en propose. Dans le doute, indiquez dans "/etc/resolv.conf" un résolveur publique :

nameserver 9.9.9.9

Mise en route

C'est parti ! 😊

Sur le serveur, rechargez le parefeu et activez/démarrez iked :

# pfctl -f /etc/pf.conf
# rcctl enable iked
# rcctl start iked

Sur le client, lancez pour commencer iked sans le mettre en arrière-plan :

# iked -vvd

Vous allez voir un tas de choses s'afficher. Si vous voyez une ligne qui ressemble à la suivante, c'est tout bon 😉 :

sa_state: VALID -> ESTABLISHED from 46.23.92.147:4500 to 192.168.100.122:4500 policy 'warrior'

Par la suite, vous pourrez activer iked sur le client avec rcctl.

Pour vérifier que cela fonctionne, vous pouvez consulter un des sites permettant de connaître son IP publique. Si elle est différente de d'habitude et correspond à celle du serveur, c'est réussi 😊. Vous pouvez plus simplement le vérifier avec la commande suivante :

# ipsecctl -sa
FLOWS:
flow esp in from 0.0.0.0/0 to 192.168.0.0/16 peer 46.23.92.147 srcid UFQDN/prx@moria.lan dstid FQDN/reiva.xyz type use
flow esp out from 192.168.0.0/16 to 0.0.0.0/0 peer 46.23.92.147 srcid UFQDN/prx@moria.lan dstid FQDN/reiva.xyz type require
flow esp out from ::/0 to ::/0 type deny
SAD:
esp tunnel from 46.23.92.147 to 192.168.100.122 spi 0x7958b1de auth hmac-sha2-256 enc aes-256
esp tunnel from 192.168.100.122 to 46.23.92.147 spi 0xe7d244a8 auth hmac-sha2-256 enc aes-256

En cas de problème, avant d'arrêter le processus iked, lancez la commande suivante pour fermer le tunnel :

# ikectl decouple

Gérer le VPN

À partir du client:

Utilisation avec des clients n'utilisant pas OpenBSD

Strongswan Sous Linux ou avec un smartphone android, vous aurez besoin d'utiliser l'application strongswan pour configurer la connexion à votre VPN.

Il faudra toutefois configurer un accès par certificats.

Sinon, MacOS et Windows peuvent le gérer nativement, mais il faudra demander à leurs experts.

Ressources sur Openiked

FAQ 17

man iked.conf

man ikectl

Avoir une IP fixe grâce à un VPN

Si votre FAI ne vous fournit pas d'adresse IP fixe, alors vous pouvez mettre en place un tunnel VPN comme décrit dans cette partie. Votre serveur sera alors accessible au public via l'IP du VPN, l'IP de votre serveur étant "cachée" derrière.

Cela s'avère particulièrement utile si :

Voici schématiquement ce que l'on cherche à faire:

+-----------+        +---------------------+      +--------------+
| Serveur   +<------>+ Serveur avec une    +<-----+              |
| Personnel |  VPN   | IP fixe             |      |   Visiteur   |
| -sniper-  |        |    -tank-           |      |              |
+-----------+        +---------------------+      +--------------+
   IP cachée             IP Publique

Peu importe votre IP, pour accéder à votre serveur, il suffira d'utiliser l'IP publique du serveur intermédiaire.

Pour mieux se comprendre ensuite, j'appelerai "sniper" le serveur caché derrière le VPN et "tank" le serveur dont on veut utiliser l'IP publique.

Avertissement sur le parefeu

⚠ Pensez à adapter la configuration de votre parefeu de votre serveur.

Désormais, le traffic parviendra à votre serveur par l'interface du VPN, c'est à dire "wg0" si vous l'avez configuré avec Wireguard ou bien "enc0" si c'est avec Iked.

Mise en place

On suppose par la suite que sniper et tank sont reliés par un VPN Wireguard.

Vous n'aurez qu'à éditer le parefeu de tank pour ajouter une règle "binat-to" :

serv_int = "10.0.0.2"
serv_ext = "192.0.2.2"
[...]
pass quick on egress from $serv_int to any binat-to $serv_ext
[...]
# ligne déjà présente:
match out on egress from (wg0:network) to any nat-to (egress:0)
[...]
pass on wg0

Prenez bien soin de modifier les IP dans les variables "serv_*".

Rechargez le parefeu. Et voilà, c'est terminé 😊

Certains voudront peut-être plus finement paramétrer leur parefeu. C'est possible avec les règles rdr-to :

serv_int = "10.0.0.5"
ports_tcp = "{ ssh www https smtp submission imaps domain }"
ports_udp = "{ domain spamd-sync }" 
pass in on egress proto tcp from any to egress port $ports_tcp rdr-to $serv_int
pass in on egress proto udp from any to egress port $ports_udp rdr-to $serv_int

Modification des interfaces d'écoute

Les services hébergés sur sniper n'écoutent plus sur la même interface. Pensez à modifier leur interface d'écoute pour "wg0". Normalement, si vous avez modifié les routes par défaut, alors "wg0" appartient au groupe "egress", mais vérifiez au moins deux fois votre configuration.

À titre d'exemple, la configuration d'httpd ressemblera à ça :

server "chezmoi.tld" {
		listen on wg0 port 80
		root "htdocs"
}

Modification des DNS

Désormais, dans votre zone DNS, votre nom de domaine doit pointer vers l'IP de tank.

Obtenir une IPv6 grâce au VPN

Malgré l'année dans laquelle nous vivons, certains fournisseurs d'accès ne proposent toujours pas de connectivité IPv6. Vous pouvez heureusement proposer vos services en IPv6 après avoir configuré un VPN vers un fournisseur qui en dispose : openbsd.amsterdam, vultr... (voir il y a quelques chapitres la partie "Quelqu'un peut-il héberger OpenBSD pour moi?").

On va pour cela mettre en place un VPN avec wireguard comme vu précédemment, en y ajoutant la connectivité ipv6.

Prérequis

Ce site vous aide à générer une rangée ipv6 privée

Sur le serveur distant :

Pensez à activer l'option d'ip forwarding pour l'ipv6 dans "/etc/sysctl.conf":

net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1

Le fichier "/etc/hostname.wg0" servant à configurer wireguard doit désormais préciser l'ipv6 du point de sortie du VPN. Ici, c'est "fd9c:f774:0bfa:acfc::1/64".

Chaque client doit pouvoir disposer aussi de son ipv6. On ajoute tout simplement une nouvelle option "wgaip" en plus de l'ancienne. La configuration ressemble alors à ceci :

# cat /etc/hostname.wg0
inet 10.0.0.1/24
inet6 fd9c:f774:0bfa:acfc::1/64
wgkey [...snip...]
wgport 4545
# peer 1
wgpeer [...snip...] wgaip 10.0.0.2/32 wgaip fd9c:f774:0bfa:acfc::2/128
# peer 2
wgpeer [...snip...] wgaip 10.0.0.3/32 wgaip fd9c:f774:0bfa:acfc::3/128
# peer 3
wgpeer [...snip...] wgaip 10.0.0.4/32 wgaip fd9c:f774:0bfa:acfc::4/128
up

⚠ C'est important que chaque ipv6 des clients soit bien précisée avec à la fin "/128".

Sur la machine qui veut récupérer une ipv6 :

Dans le fichier "/etc/hostname.wg0", on doit ajouter quelques éléments par rapport à précédemment :

La configuration de wireguard ressemble à ceci :

# cat /etc/hostname.wg0
wgkey [...snip...]
wgpeer [...snip...] \
	wgendpoint <XX.XX.XX.XX> 4545 \
	wgaip 0.0.0.0/0 # <--- ! \
	wgaip ::0/0 \
	wgpka 25
inet 10.0.0.3/24
inet6 fd9c:f774:0bfa:acfc::3/64 # <--- !
wgrtable 1
up
!route add -inet default 10.0.0.1
!route add -inet6 default fd9c:f774:0bfa:acfc::1 # <--- !

Et voilà, vous disposez désormais d'un accès ipv6 au travers du VPN.

Vérifiez-le par exemple avec cette commande :

curl -6 https://ifconfig.co

Serveur de stockage

Aussi appelé NAS, ces serveurs permettent de stocker et partager des fichiers dans un réseau domestique.

Pour mettre en place cette fonctionnalité, nous verrons deux solutions : l'une basée sur SSH et l'autre sur NFS.

Serveur de stockage basé sur SSH

Si vous avez déjà configuré SSH, vous pouvez utiliser l'outil sshfs qui permet de monter dans un dossier les fichiers contenus sur le serveur, un peu comme avec une clé USB. Cette solution fonctionnera quel que soit l'endroit qui vous sert de point d'accès à Internet et restera sûr.

Admettons que vous souhaitez monter le dossier "/mnt/partage" du serveur dans votre dossier "/home/toto/serveur". Vous utiliserez alors la commande suivante :

sshfs utilisateur_ssh@chezmoi.tld:/mnt/partage /home/toto/serveur

On demandera le mot de passe de l'utilisateur connecté via SSH, ensuite vous pourrez voir les documents du serveur dans "/home/toto/serveur" comme s'ils étaient sur votre ordinateur.

Serveur de stockage reposant sur NFS

NFS veut dire "Network File System", autrement dit "Système de fichiers en réseau". 😁

Cependant, nous n'allons pas ouvrir le partage NFS au monde entier comme on peut le faire pour d'autres services, car nous ne pouvons pas restreindre l'accès à certains utilisateurs. L'utilisation de NFS sera donc adaptée à un partage local, c'est à dire pour toutes les machines utilisant votre routeur pour se connecter.

Tout d'abord, nous devons activer sur le serveur les services nécessaires. On s'en occupe avec rcctl :

# rcctl enable portmap mountd nfsd

Afin que le partage NFS fonctionne comme prévu, nous allons configurer les options pour le lancer. Remplacez dans la commande ci-dessous le chiffre 4 par le nombre de connexions maximales vers le serveur que vous souhaitez :

# rcctl set nfsd flags -tun 4

Nous avons activé ici les protocoles TCP (-t), UDP (-u), ainsi que 4 connexions maximales vers le serveur NFS.

Maintenant, il faut préciser qui aura le droit d'accéder au NFS. Pour cela, il faut éditer le fichier "/etc/exports" pour préciser les adresses IP qui pourront s'y connecter. Éditez ce fichier pour y mettre par exemple :

/mnt/partage -alldirs -network=192.168.1 -mask=255.255.255.0 

Ici, nous souhaitons restreindre l'accès au réseau local, c'est à dire tous les appareils connectés au même routeur que votre serveur. La difficulté ici est de connaître l'ensemble des adresses IP que votre modem attribue aux appareils qui s'y connectent.

Si vous souhaitez accéder à ce partage de n'importe où, retirez les options -network et -mask. ⚠ Cependant, notez bien que cela donnera accès au NFS à tout le monde.

On peut maintenant démarrer les services avec :

# rcctl start portmap mountd nfsd

Dans le cas où vous modifiez le fichier "/etc/exports", pensez à recharger la configuration avec :

# rcctl reload mountd

Pensez à ouvrir les ports 111 et 2049 en TCP et UDP dans le parefeu afin qu'une machine du réseau local puisse accéder au partage NFS. Pour voir la liste des ports utilisés, entrez "# rpcinfo -p 127.0.0.1". Ces ports peuvent changer lors d'un redémarrage. Pour un partage local, vous pouvez ouvrir votre NAS à tout le réseau local avec cette ligne dans "/etc/pf.conf" :

pass in on egress from 192.168.1.0/24

Vous pourrez maintenant monter le partage NFS sur votre système. La démarche dépend du système d'exploitation, mais dans la plupart des cas, ajouter une entrée dans le fichier "/etc/fstab" de l'ordinateur qui doit monter le NFS suffit. Cette entrée ressemblera à :

192.168.1.2:/mnt/partage /mnt nfs rw,nodev,nosuid 0 0

Remplacez l'IP par celle du serveur bien sûr 😉 (l'IP privée).

Gemini avec vger

Gemini est un nouveau protocole internet qui se veut plus simple et plus léger que http. Il bénéficie des "bonnes" limitations de gopher et évite les problèmes inhérents à http (javascript, publicités, tracage des visiteurs...).

C'est un moyen idéal pour publier ses écrits en privilégiant d'abord le contenu plutôt que le contenant.

Cette documentation est d'ailleurs disponible aussi via le protocole gemini. 😁

Il existe plusieurs serveurs, mais je voudrais donner quelques éléments pour installer vger, un serveur gemini spécialement concu pour OpenBSD qui met à profit ses méthodes de sécuisation (unveil, pledge...).

Afin de garder vger aussi simple que possible, solene (développeuse de vger) a eu la brillante idée d'utiliser des éléments déjà présents dans OpenBSD; à savoir :

Voici donc comment installer vger.

# pkg_add vger

La lecture du readme nous apprend la suite de la procédure.

Éditez le fichier "/etc/inetd.conf" pour y indiquer la façon dont vger sera invoqué :

127.0.0.1:11965 stream tcp nowait _vger /usr/local/bin/vger vger

Par défaut, vger ira chercher les fichiers dans "/var/gemini".

Vous pouvez préciser des options, par exemple pour changer le dossier dans lequel est situé la capsule/le site (-d), activer l'auto-indexation des dossiers ne contenant pas de fichier index.gmi (-i) ou encore permettre le support des "virtualhosts" (-v). Ce dernier point est intéressant si vous souhaitez servir plusieurs domaines : vger ira ouvrir un dossier "chezmoi.tld" situé dans "/var/gemini" si un client demande "gemini://chezmoi.tld". Vous pouvez donc ainsi héberger plusieurs capsules en utilisant un dossier portant le nom du domaine à servir.

# serve files in /var/gemini/chezmoi.tld
localhost:11965 stream tcp6 nowait _vger /usr/local/bin/vger vger -v -d /var/gemini/ -i
localhost:11965 stream tcp nowait _vger /usr/local/bin/vger vger -v -d /var/gemini/ -i

Si vous avez été attentif à la ligne ci-dessus, vous aurez remarqué qu'inetd écoute en local (localhost) sur le port 11965 et renvoie la requête vers vger, invoqué en tant qu'utilisateur "_vger". Cela permet de restreindre les possibilités de vger s'il devait être compromis.

De plus, une ligne supplémentaire avec "tcp6" a été ajoutée : cela permet de servir aussi en IPv6. Il faut toutefois avoir correctement rempli le fichier "/etc/hosts" :

127.0.0.1   localhost
::1         localhost

Ensuite, on ajoute une configuration à relayd dans "/etc/relayd.conf":

ext_ip4 = "192.0.2.2"
ext_ip6 = "2001:db8::2"
log connection
tcp protocol "gemini" {
        tls keypair chezmoi.tld
}
relay "gemini" {
        listen on $ext_ip4 port 1965 tls
        protocol "gemini"
        forward to localhost port 11965
}
relay "gemini6" {
        listen on $ext_ip6 port 1965 tls
        protocol "gemini"
        forward to localhost port 11965
}

Quelques explications :

Il ne reste plus qu'à activer et lancer les services :

# rcctl enable inetd relayd
# rcctl start inetd relayd

Enfin, ouvrez le port 1965 en TCP dans "/etc/pf.conf".

Quelques liens pour aller plus loin:

Site officiel Gemini

Analyse de vger point de vue sécurité

Code source de vger

Gopher

J'en entends déjà rire en lisant ce titre. Non, le protocole gopher n'est pas mort. Bien que peu utilisé, on y trouve encore quelques trésors et sa simplicité est rafraichissante. Gopher vous permettra de partager des textes et des documents sans difficultés.

Que ce soit par utilité ou par jeu, nous allons voir comment installer un serveur gopher sous OpenBSD.

Il vous faudra ouvrir et rediriger le port 70 (gopher).

Vous déposerez vos fichiers textes, vos images, vos vidéos (...) dans le dossier "/var/gopher", ils seront automatiquement disponibles à l'adresse gopher://chezmoi.tld .

geomyidae

geomyidae Le serveur geomyidae est écrit en C par un des développeur chez suckless. C'est donc un gage de qualité 😊.

L'installation est toute bête :

# pkg_add geomyidae
# rcctl enable geomyidae
# rcctl start geomyidae

Et voilà, plus qu'à remplir votre site dans "/var/gopher". 😊

Cependant, je vous conseille de lire le man et d'éditer les options par défaut. Par exemple, on pourra souhaiter :

# rcctl set geomyidae flags -e -h chemoi.tld -b /var/gopher/chezmoi.tld

Vous pourrez consulter les logs dans "/var/log/geomyidae.log".

mlmmj : Liste de diffusion

À l'heure où il existe des réseaux sociaux en tous genres, avec leurs interfaces spécifiques, ainsi que des applications de messagerie instantanées, des forums, ..., rappelons que les listes de diffusion sont géniales.

Oui, je le dis et je l'assume, les mailing lists, c'est l'avenir car :

Je suis convaincu que les listes de diffusion ont de belles années devant elles.

Ici, je vous propose d'utiliser mlmmj puisqu'il fonctionne bien avec OpenBSD et répond à des exigences fortes en terme de performance, de sécurité et de simplicité.

Site officiel mlmmj

Installer mlmmj

C'est plus long à écrire qu'à faire :

# pkg_add mlmmj

Ajouter une liste de diffusion

Utilisez la commande "mlmmj-make-ml" fourni avec le port, puis laissez-vous guider.

Voici un exemple pour créer la liste "pizza" sur le domaine "list.chezmoi.tld", soit "pizza@list.chezmoi.tld".

# mlmmj-make-ml
Creating Directorys below /var/spool/mlmmj. Use '-s spooldir' to change
What should the name of the Mailinglist be? [mlmmj-test] : pizza
The Domain for the List? [] : chezmoi.tld
The emailaddress of the list owner? [postmaster] : batman@chezmoi.tld
For the list texts you can choose between the following languages or
give a absolute path to a directory containing the texts.
Available languages:
ast   cs    de    en    fi    fr    gr    it    pt    sk    zh-cn
The path to texts for the list? [en] :
Don't forget to add this to /etc/aliases:
pizza:  "|/usr/local/bin/mlmmj-receive -L /var/spool/mlmmj/pizza/"
If you're not starting mlmmj-maintd in daemon mode,
don't forget to add this to your crontab:
0 */2 * * * "/usr/local/bin/mlmmj-maintd -F -L /var/spool/mlmmj/pizza/"
 ** FINAL NOTES **
1) The mailinglist directory have to be owned by the user running the
mailserver (i.e. starting the binaries to work the list)
2) Run newaliases

Assurez-vous que les permissions sont bonnes :

# chown -R _smtpd:_smtpd /var/spool/mlmmj/pizza

Éditez le crontab de root ("# crontab -e") pour ajouter la ligne donnée précédent :

0 */2 * * *  /usr/bin/mlmmj-maintd -F -L /var/spool/mlmmj/pizza

Préparer smtpd

Éditez le fichier "/etc/mail/smtpd.conf" pour qu'il traite correctement les mails destinés à votre liste de diffusion :

table aliases "/etc/mail/aliases"
[...]
action local_mail maildir alias <aliases>
[...]
match from any for domain "list.chezmoi.tld" action local_mail

Il est important que l'action PRENNE EN COMPTE les alias.

Il faut justement éditer le fichier "/etc/mail/aliases" pour envoyer à mlmmj les messages destinés à votre liste :

pizza:"|/usr/local/bin/mlmmj-receive -L /var/spool/mlmmj/pizza/"

Terminez avec la commande "newaliases" ou en redémarrant smtpd.

Personnaliser une liste

Comme vous vous en doutez, les fichiers concernant votre liste sont situés dans "/var/spool/mlmmj/pizza".

mlmmj se configure en éditant seulement quelques fichiers situés dans le répertoire "control". Dans notre cas, cela donne "/var/spool/mlmmj/pizza/control".

Voici quelques éléments de configuration non exhaustifs en ajoutant les fichiers suivants :

deny !^Content-Type: text/plain
allow
Quitter la liste: pizza+unsubscribe@list.chezmoi.tld
Anciens messages (N: un nombre): pizza+get-N@list.chezmoi.tld
Aide: pizza+help@list.chezmoi.tld

On peut aussi modifier le contenu des modèles de message en allant les chercher dans "/var/spool/mlmmj/pizza/text".

Consultez la documentation pour d'autres éléments de configuration

Monitoring

Voici quelques possibilités pour surveiller la charge de votre serveur.

systat

Systat est présent par défaut dans OpenBSD. Vous pouvez obtenir des informations sur le système en temps réel en saisissant la commande systat vm. Vous aurez alors des informations sur l'utilisation de la mémoire, des processeurs, des disques...

Pour avoir des informations sur le débit montant et descendant, tapez systat ifstat. Vous observerez en temps réel la quantité de données entrantes (IBYTES) et sortantes (OBYTES).

Pour des informations concernant la température du matériel (si vous craignez la surchauffe!), tapez systat sensors.

cpu0.temp0          51.00 degC
acpitz0.temp0       26.80 degC      zone temperature

À chaque fois, appuyez sur la touche q pour quitter.

vmstat

Lui aussi présent par défaut, vmstat donne un aperçu rapide sur la charge du système :

$ vmstat
 procs    memory       page                    disks    traps          cpu
 r   s   avm     fre  flt  re  pi  po  fr  sr sd0 sd1  int   sys   cs us sy id
 1 274 1500M   1253M  657   0   0   0   0   0   1   4  190 15482 1826  2  1 97

symon

Symon va vous permettre d'obtenir des statistiques sur les ressources utilisées par votre serveur et de les consulter sur une page web.

Commençons par installer le nécessaire :

# pkg_add symon symux syweb

On modifie ensuite la configuration de symon qui va surveiller le système. Pour cela, on modifie le fichier "/etc/symon.conf" et on garde les informations qui nous intéressent :

monitor { cpu(0),  mem,
          if(lo0),
          if(re0),
          pf,
          mbuf,
          sensor(cpu0.temp0),
          proc(httpd),
          io(wd0),
          io(wd1),
          df(sd1b)
} stream to 127.0.0.1 2100

De la même façon, on configure symux qui va analyser les données recueillies par symon. On édite le fichier "/etc/symux.conf" :

mux 127.0.0.1 2100
source 127.0.0.1 {
  accept { cpu(0),  mem,
      if(lo0),
      if(re0),
      pf,
      mbuf,
      sensor(cpu0.temp0),
      proc(httpd),
      io(wd0),
      io(wd1),
      df(sd1b)
  }
  datadir "/var/www/symon/rrds/localhost"
}

On ne fait que reproduire les mêmes éléments que dans "/etc/symon.conf". Attention à bien indiquer le chemin vers les données datadir. On va d'ailleurs le créer dès maintenant :

# mkdir -p -m 0755 /var/www/symon/rrds/localhost

On crée maintenant les fichiers rrd :

# /usr/local/share/examples/symon/c_smrrds.sh all

Puisque le serveur web est dans un chroot, il faut lancer la commande suivante pour installer l'outil d'analyse des données et ses dépendances (rddtool) :

# /usr/local/share/examples/rrdtool/rrdtool-chroot enable

Une fois ceci fait, il faut préciser dans la configuration de syweb où trouver l'outil rrdtool. Dans le fichier "/var/www/htdocs/syweb/setup.inc", modifiez si nécessaire la ligne contenant $symon['rrdtool_path'] ainsi :

$symon['rrdtool_path']='/usr/local/bin/rrdtool';

Reste une dernière modification à apporter. Puisque le serveur web est dans un chroot, il faut lui donner accès au shell /bin/sh afin que PHP puisse lancer rrdtool qui génère les graphiques :

# mkdir -p /var/www/bin
# cp /bin/sh /var/www/bin

On recharge tous les nouveaux démons après les avoir activés :

# rcctl enable symon
# rcctl enable symux
# rcctl start symon
# rcctl start symux

On ajoute la configuration convenable pour le serveur http, dans le fichier "/etc/httpd.conf" (c'est du PHP) :

server "statistiques.chezmoi.tld" {
        listen on * port 80  
        root "/htdocs/syweb"
        directory index index.php
        location "*.php*" {
                fastcgi socket "/run/php-fpm.sock"
        }
}

Reste à recharger ce dernier avec "# rcctl reload httpd" puis à aller sur le site définit pour voir les beaux graphiques.

monit

Monit est un outil léger open source (licence AGPL) permettant de superviser un système Unix. Il est capable d’exécuter des actions en cas de détection de défaillance ou de dépassement de seuil. Une interface web permet de superviser en temps réel les différents services paramétrés.

Installation

Commençons par installer le nécessaire et activer le démon monit :

# pkg_add monit
# rcctl enable monit

Configuration

Ensuite, la configuration centrale de Monit se fait au sein du fichier monitrc localisé sous /etc/. Dans ce fichier, vous pouvez notamment modifier l’adresse email qui recevra les alertes.

Enfin, les configurations complémentaires sont dans le répertoire "/etc/monit.d/".

Nous allons maintenant configurer le serveur d'administration sur un socket TCP local. Éditez le fichier "/etc/monitrc" puis décommentez tout en bas la ligne

include /etc/monit.d/*

Nous pouvons maintenant procéder à la configuration en ajoutant des fichiers dans le dossier /etc/monit.d qu'il faut créer :

# mkdir -p /etc/monit.d

Placez dans ce dossier un fichier que l'on appellera par exemple admin.conf.

set daemon  60 with start delay 240
set logfile syslog facility log_daemon
set mailserver localhost
set mail-format {
from: monit@$HOST
subject: Monit Alert -- $SERVICE $EVENT --
message:
Hostname:       $HOST
Service:        $SERVICE
Action:         $ACTION
Date/Time:      $DATE
Info:           $DESCRIPTION
}
set alert root@localhost

L'instruction "set daemon" permet de définir la durée d'un "cycle" monit. Un cycle correspond à l'intervalle (en secondes) entre deux vérifications. Dans cet exemple, il commence à analyser votre serveur toutes les minutes après un délai de 4 minutes.

Cette partie permet de préciser que monit devra enregistrer ses journaux dans les logs système. Ensuite, on configure l'apparence du mail que monit enverra à l'adresse root@localhost. Assurez-vous d'avoir fait en sorte de recevoir les mails que votre serveur est susceptible de vous envoyer.

Avant de lancer Monit, vérifiez bien que la syntaxe des fichiers de configuration est bonne avec la commande :

# monit -t

Vous devez obtenir une belle réponse « Control file syntax OK ».

En cas de dysfonctionnement, Monit vous enverra un mail d’alerte (attention à bien configurer votre mail et serveur dans le fichier monitrc).

Lancement de monit

Le démarrage de monit est simple :

# rcctl start monit

Utilisation

La commande suivante permet d'obtenir le status détaillé de votre serveur :

# monit status
Monit uptime: 0m
System 'openheb.fritz.box'
  status                       Running
  monitoring status            Monitored
  monitoring mode              active
  on reboot                    start
  load average                 [0.08] [0.11] [0.08]
  cpu                          0.1%us 0.1%sy
  memory usage                 81.1 MB [4.0%]
  swap usage                   0 B [0.0%]
  uptime                       2d 21h 30m
  boot time                    Tue, 14 Mar 2017 19:06:34
  data collected               Fri, 17 Mar 2017 16:37:25

Il est possible de consulter l'interface web de Monit sur votre serveur car il intègre un petit service http. Cependant, ce n'est pas très pratique car cela suppose que vous ouvrez les ports de votre serveur vers Monit...

À la place, je vous propose de passer par un tunnel SSH. Sur votre ordinateur de bureau, créez un tunnel qui va "relier" le port de Monit vers le port 9999 de votre ordinateur (le port d'écoute du serveur SSH est le 222 dans l'exemple) :

$ ssh -L 9999:127.0.0.1:2812 -p 222 toto@chezmoi.tld

Vous pouvez maintenant ouvrir dans un navigateur sur votre ordinateur la page http://127.0.0.1:9999 afin de consulter Monit.

Configuration avancée des alertes

Monit peut aussi envoyer des e-mails d'alerte en cas d'utilisation de ressources anormales, comme une mémoire vive faible ou un taux d'utilisation du CPU trop important.

Nous allons maintenant compléter notre configuration afin de surveiller la charge de notre serveur. Pour cela, nous allons ajouter les lignes suivantes à notre fichier de configuration:

check system localhost
    if loadavg (1min) > 4 then alert
    if loadavg (5min) > 2 then alert
    if memory usage > 75% then alert
    if swap usage > 25% then alert
    if cpu usage (user) > 70% then alert
    if cpu usage (system) > 30% then alert
    if cpu usage (wait) > 20% then alert

Puis, il faut recharger la configuration :

# rcctl reload monit

Ainsi, une alerte par courriel sera envoyée dès que le système utilisera plus de 30% des capacités du ou des processeurs.

Plus d'infos, sur le site de Monit.

L'ensemble des applications de votre serveur peuvent être facilement monitorées. Regardez les exemples à la fin du document.

Webradio

Dans cette partie, nous allons voir comment proposer une radio web sans prendre toutes les ressources du serveur.

L'idéal serait de pouvoir diffuser des émissions en direct. Lorsque personne ne parle sur la radio, de la musique sera automatiquement jouée à partir d'une liste de lecture.

Nous allons utiliser les outils icecast et mpd.

Configuration d'icecast et mpd

Commençons par les installer :

# pkg_add icecast mpd

On va copier l'exemple de configuration d'icecast avant de l'éditer :

# cp /usr/local/share/examples/icecast/icecast.xml.dist /var/icecast/icecast.xml

Configurez ce fichier à votre goût. Voici un exemple de ce que j'ai modifié :

<location>Sur Mars</location>
<authentication>
  <source-password>motdepasse</source-password>
  <relay-password>motdepasse</relay-password>
  <admin-user>admin</admin-user>
  <admin-password>adminpw</admin-password>
</authentication>
<hostname>chezmoi.tld</hostname>
<!-- You may have multiple <listener> elements -->
<listen-socket>
  <port>8000</port>
  <bind-address>0.0.0.0</bind-address>
</listen-socket>
<mount>
    <mount-name>/play.ogg</mount-name>
    <no-mount>1</no-mount>
</mount>
<mount>
    <mount-name>/live.ogg</mount-name>
    <fallback-mount>/play.ogg</fallback-mount>
    <fallback-override>1</fallback-override>
</mount>

On voit bien dans cette configuration que lorsqu'un "live" est en cours, il est diffusé, sinon ça bascule automatiquement sur la playlist.

On active icecast puis on le lance :

# rcctl enable icecast
# rcctl start icecast

Ensuite, nous allons configurer le lecteur de musique, qui sera ici mpd. Éditez le fichier "/etc/mpd.conf" de cette façon :

# Dossier contenant toute la musique
music_directory      "/mnt/Musique"
# Pour icecast. Pensez à modifier le mot de passe
audio_output {
    type        "shout"
    encoding    "ogg"
    name        "Ma super radio"
    host        "localhost"
    port        "8000"
    mount       "/play.ogg"
    password    "motdepasse"
    bitrate     "128"
    format      "44100:16:2"
}

Je n'ai listé ci-dessus seulement ce que j'ai eu besoin de modifier. Changez bien le mot de passe pour envoyer la musique à icecast.

Enfin, activez mpd et lancez-le :

# rcctl enable mpd
# rcctl start mpd

Vous pouvez lancer la lecture en utilisant un client mpd, comme mpc. Il s'installe tout simplement :

# pkg_add mpc

Voici quelques commandes bien pratiques :

Avant d'essayer d'écouter votre musique, ouvrez et redirigez le port 8000 dans votre pare-feu et routeur.

Pour tester votre radio, ouvrez l'adresse suivante avec un lecteur de musique (vlc par exemple) : http://chezmoi.tld:8000/live.ogg.

Diffuser une émission

Afin de diffuser une émission, il faudra utiliser n'importe quel logiciel capable de communiquer avec icecast. La seule différence sera que l'on diffusera sur "/live.ogg" directement et non plus sur "/play.ogg".

Prenons pour exemple vlc qui va jouer ce que vous voulez pour l'envoyer sur le serveur.

Une fois vlc ouvert, cliquez sur "Media" > "Flux". Ajoutez un fichier puis cliquez sur diffuser.

Cliquez sur "Next", puis choisissez dans "Nouvelle destination" "IceCast". Cliquez sur "Ajouter".

Remplissez ensuite les différents champs :

L'utilisateur ici est source, à moins d'avoir modifié le fichier de configuration sur ce point.

Vous pouvez activer le transcodage si vous le souhaitez. Audio Vorbis (OGG) fonctionne bien en général. Il vous reste à valider la suite.

Afficher sur un site ce qui est joué

Vous voudrez peut-être afficher sur votre site web ce que la radio est en train de jouer. Mettez alors ceci dans "/var/icecast/web/all.xsl"

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="*">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>

Ensuite, dans un fichier "/var/icecast/web/onair.xsl", mettez :

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/icestats">
<!-- only show the first source -->
<xsl:apply-templates select="source[1]"/>
</xsl:template>
<xsl:template match="source">
<xsl:choose>
<xsl:when test="title or artist">
<xsl:if test="artist"><xsl:value-of select="artist" /> - </xsl:if>
<xsl:value-of select="title" />
</xsl:when>
<xsl:otherwise>Unknown</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

Les personnes allant sur http://chezmoi.tld:8000/onair.xsl pourront voir ce qui est joué. Dans votre code html, il suffirait alors de rajouter ceci pour l'afficher sur une page:

<h3>Now playing</h3>
<iframe id="icecast" src="http://chezmoi.tld:8000/onair.xsl">
</iframe>
<audio src="http://chezmoi.tld:8000/live.ogg" controls="controls"></audio>

Seedbox

Ce chapitre décrit comment mettre en place une seedbox, afin de partager et télécharger des fichiers torrent.

Seedbox avec rtorrent

rtorrent est un client efficace et très léger.

Il dispose d'une interface en console pour le contrôler, que certains préfèrent à l'interface web de transmission. En effet, seul un accès SSH est nécessaire pour l'utiliser.

On commence par l'installer :

# pkg_add rtorrent

Ajoutez ensuite un utilisateur _rtorrent dont l'unique tâche sera de faire tourner rtorrent (ce n'est pas obligé, mais j'aime bien séparer les processus 😊).

Nous pouvons maintenant nous connecter en tant qu'utilisateur _rtorrent :

# su _rtorrent

Nous allons créer les dossiers qui serviront à télécharger les torrents, ainsi qu'un dossier dans lequel tous les fichiers .torrent ajoutés seront directement pris en charge par rtorrent :

$ mkdir -p Telechargements/{download,session,torrents}

On crée maintenant le fichier ~/.rtorrent.rc. Vous pouvez copier l'exemple fourni avec le paquet :

$ cp /usr/local/share/examples/rtorrent/rtorrent.rc ~/.rtorrent.rc

On modifie la configuration selon nos besoins. Seules les lignes ne commençant pas par "#" sont prises en comptes. Les autres correspondent souvent aux valeurs par défaut.

# Global upload and download rate in KiB. "0" for unlimited.
download_rate = 0
upload_rate = 20
directory = ~/Telechargements/download 
session = ~/Telechargements/session
# Ajoute ou supprime les fichiers torrents present
schedule = watch_directory,5,5,load_start=~/Telechargements/torrents/*.torrent
schedule = untied_directory,5,5,stop_untied=~/Telechargements/torrents/*.torrent
# Pour utiliser les magnets, il est parfois necessaire d'ouvrir le port d'ecoute
# en tcp seulement
#port_range = 6890-6999
#port_random = no
check_hash = yes
use_udp_trackers = yes
# Ces options permettent l'utilisation des magnets
encryption = allow_incoming,try_outgoing,enable_retry
# Important pour ne pas necessiter le besoin de trackers
dht = auto
# dht_port = 6881
peer_exchange = yes
# Avertissement des chargements termines
system.method.set_key = event.download.finished,notify_me,"execute=~/.rtorrent_mail.sh,$d.get_name="
# Ajout de noeuds dht si besoin après un délai : 
schedule2 = dht_node_1, 5, 0, "dht.add_node=router.utorrent.com:6881"
schedule2 = dht_node_2, 5, 0, "dht.add_node=dht.transmissionbt.com:6881"
schedule2 = dht_node_3, 5, 0, "dht.add_node=router.bitcomet.com:6881"
schedule2 = dht_node_4, 5, 0, "dht.add_node=dht.aelitis.com:6881"

Afin d'être averti lorsqu'un téléchargement est terminé, on crée le script "~/.rtorrent_mail.sh" :

#!/bin/sh
echo "$(date) : $1 - Download completed." | mail -s "[rtorrent] - Download completed : $1" root

Notez que tous les fichiers .torrents qui seront déposés dans le dossier ~/Telechargements/torrents seront directement téléchargés par rtorrent. Si vous voulez ajouter un fichier torrent à partir de votre ordinateur habituel, vous pouvez utiliser un client SFTP ou la commande scp :

$ scp *.torrent _rtorrent@chezmoi.tld:/home/_rtorrent/Telechargements/torrents/

Reste à lancer rtorrent en arrière-plan à chaque démarrage du serveur. Éditez le crontab de l'utilisateur _rtorrent en entrant "crontab -e" puis indiquez la ligne suivante :

@reboot /usr/bin/tmux new -s rtorrent -d /usr/local/bin/rtorrent

On utilise tmux installé par défaut sur OpenBSD pour envoyer rtorrent en arrière-plan.

Si vous souhaitez administrer rtorrent par la suite, connectez-vous en SSH avec l'utilisateur _rtorrent, et affichez rtorrent avec la commande "tmux a -t rtorrent". Appuyez successivement sur "ctrl-b" puis la touche d pour vous détacher de rtorrent.

Pour ajouter un lien magnet, vous pouvez appuyer sur "backspace" (effacer) puis collez le lien magnet (Shift-Inser). Il semble que certains ont besoin d'ouvrir le port d'écoute configuré dans rtorrent (en tcp) afin d'utiliser les magnets sans trackers. Avec la configuration en exemple ci-dessus, ça devrait fonctionner dans problèmes 😁.

Si vous ne vous souvenez plus des touches permettant de contrôler rtorrent, saisissez cette commande :

$ rtorrent -h

Notez que ^s correspond à Ctrl-s. 😉

Seedbox avec transmission

Transmission se montre très efficace et devrait convenir à la plupart de vos besoins.

Il dispose d'interfaces graphiques ainsi que d'une interface dans un navigateur, ce qui le rend très facile à contrôler.

Nous configurerons transmission de façon à télécharger les torrents dans le dossier "/mnt/transmission". Adaptez les chemins du tutoriel selon vos besoins.

La commande habituelle permet de l'installer :

# pkg_add transmission

On va ensuite activer le service. On le démarre puis l'arrête aussitôt afin de créer les fichiers de configurations dont on aura besoin :

# rcctl enable transmission_daemon
# rcctl start transmission_daemon
# rcctl stop transmission_daemon

Nous allons créer des dossiers spécifiques afin d'enregistrer les téléchargements effectués par transmission et stocker les fichiers .torrent :

# mkdir -p /mnt/transmission/{downloads,incomplete,torrents}

Modifiez les propriétaires de ces répertoires afin d'en autoriser l'accès à transmission :

# chown -R _transmission:_transmission /mnt/transmission

Si vous souhaitez que d'autres utilisateurs puissent consulter ces répertoires, modifiez les permissions sur ces derniers :

# chmod a+rX /mnt/transmission

Afin de configurer transmission, éditez le fichier suivant :

/var/transmission/.config/transmission-daemon/settings.json

À l'intérieur, vous pourrez adapter la configuration selon vos besoins. Voici les lignes que j'ai modifiées :

"download-dir": "/mnt/transmission/downloads",
"incomplete-dir": "/mnt/transmission/incomplete",
"incomplete-dir-enabled": true,
"peer-port-random-on-start": true,

Je vous propose d'ajouter les lignes suivantes afin que chaque fichier .torrent ajouté dans le dossier /mnt/transmission/torrents (par SFTP par exemple) soit automatiquement téléchargé par transmission.

"watch-dir": "/mnt/transmission/torrents",
"watch-dir-enabled": true

Afin de recevoir un mail lorsque le téléchargement d'un torrent est terminé, ajoutez ces lignes :

"script-torrent-done-enabled": true,
"script-torrent-done-filename": "/var/transmission/dl-done.sh",

Le script "dl-done.sh" peut par exemple contenir ceci :

#!/bin/sh
echo "$(date) : $TR_TORRENT_NAME - Download completed." | mail -s "[transmission] - Download completed : $TR_TORRENT_NAME" toto@example.com

N'oubliez pas de rendre ce dernier éxécutable :

# chmod +x /var/transmission/dl-done.sh

Une fois vos modifications terminées, rechargez la configuration de transmission avec la commande suivante :

# rcctl start transmission_daemon

Transmission dispose d'une interface web. Le plus simple afin d'y accéder est d'utiliser un tunnel SSH. À partir de l'ordinateur avec lequel vous souhaitez consulter transmission, lancez la commande suivante :

ssh -N -L 9999:127.0.0.1:9091 utilisateurssh@chezmoi.tld

Une fois identifié, vous pouvez ouvrir un navigateur à l'adresse http://localhost:9999 afin d'accéder à transmission.

Syncthing

Syncthing permet de sauvegarder ses données et facilement les répartir sur plusieurs appareils.

Il dispose de plusieurs clients (logiciels permettant de l'utiliser) pour Windows, Linux, Android et aussi OpenBSD. Par défaut, tout est chiffré ce qui est tout de même rassurant. C'est, à mon avis, un excellent outil 😋.

Installation et configuration

Notez qu'il a été empaqueté pour OpenBSD, on peut donc l'installer en une simple commande :

# pkg_add syncthing

Nous allons le laisser tourner en arrière-plan sur notre serveur afin que vous puissiez à tout moment synchroniser vos documents et les sauvegarder. Pour cela, lancez ces commandes :

# rcctl enable syncthing
# rcctl start syncthing

Par défaut, syncthing va stocker sa configuration et les fichiers synchronisés dans "/var/syncthing". Ce dossier contient :

Nous pourrions configurer syncthing en éditant ces fichiers, cependant, l'ajout d'autres appareils avec lesquels se synchroniser va vite devenir insupportable. Heureusement, il existe une interface d'administration pour syncthing. Elle n'est disponible qu'à partir du serveur, ce qui n'est pas pratique pour s'en servir car on a besoin d'un navigateur web pour y accéder.

Heureusement, SSH est là 😊.

En effet, nous allons créer un tunnel SSH qui va relier votre ordinateur au serveur. En passant par ce tunnel, nous pourrons accéder à l'interface d'administration de syncthing très facilement.

À partir de votre ordinateur, lancez la commande suivante :

ssh -N -L 9999:127.0.0.1:8384 utilisateurssh@chezmoi.tld

Tant que la session est ouverte, vous pouvez ouvrir un navigateur sur votre ordinateur et aller à l'adresse http://localhost:9999 afin d'administrer syncthing.

Vous pouvez maintenant ajouter des machines avec lesquelles le serveur restera synchronisé, comme si vous étiez sur le serveur. Je vous laisse visiter le site officiel pour éventuellement télécharger la toute dernière version du client OpenBSD et en savoir plus si vous le souhaitez.

Les transferts ne démarrent pas

Normalement, syncthing se débrouille tout seul pour trouver les machines à qui il doit envoyer des données.

Si toutefois, il y avait un problème, référez-vous à la documentation officielle qui propose quelques solutions.

En voici quelques unes:

Parefeu

Si l'UPnP n'est pas supporté par votre routeur, vous devriez ouvrir les ports suivant dans le pare-feu :

Il vous faudra aussi rediriger ces ports dans votre routeur.

Tunnel SSH

Vous pouvez relier deux appareils par un tunnel SSH puis indiquer à syncthing de n'écouter qu'en local. Ainsi, il ne se fatiguera plus à chercher les appareils partout, vous aurez déjà établi la connexion entre les 2.

Tout d'abord, creusez le tunnel SSH :

ssh \
   -L 127.0.0.1:22001:127.0.0.1:22000 \
   -R 127.0.0.1:22001:127.0.0.1:22000 \
   batman@chezmoi.tld

L'utilisation de clés peut s'avérer utile... 😉

Un tunnel est donc établi entre les ports 22000 et 22001.

Ensuite, dans la configuration de syncthing, section "Connexions", désactivez toutes les options pour ne laisser que cette adresse d'écoute:

tcp://127.0.0.1:22000

Ensuite, modifiez la configuration des appareils associés pour leur attribuer l'adresse suivante :

tcp://127.0.0.1:22001

Ces deux manipulations sont à faire sur chaque machine.

Utilisation de syncthing

Partager des documents avec Syncthing est relativement simple. Pour commencer, sur l'ordinateur qui a les documents "sources", cliquez sur "Ajouter un partage" :

syncthingshare 1

Choisissez ensuite un nom au partage afin de vous repérer. Laissez l'ID proposé puis précisez le chemin racine du partage. Ce chemin correspond à l'emplacement des données à sauvegarder, par exemple "/home/jean-eudes/Documents". Si vous aviez déjà ajouté un appareil avec lequel partager, vous pouvez le cocher en bas :

syncthingshare 2

Sinon, ajoutez l'appareil avec lequel partager vos documents. Pour cela, dans la partie "Autres appareil", cliquez sur "Ajouter un appareil" :

syncthingshare 3

syncthingshare 4

Il faut juste coller l'ID de l'appareil que vous pouvez trouver à l'emplacement indiqué.

L'appareil ajouté recevra une notification à accepter, et le partage peut alors commencer.

Aller plus loin

Lisez la FAQ de syncthing, très complète et pleine d'astuces 😊

TOR

Tor est un logiciel libre permettant de renforcer la vie privée de ses utilisateurs et ainsi passer outre les surveillances subies lors de l'utilisation d'Internet.

Lorsqu'on l'utilise, les communications sont réparties à travers une maille de serveurs, afin d'obtenir un onion router. En gros, ce que vous demandez sur le web circule entre une série de serveurs (les couches de l'oignon), ce qui rend très difficile de savoir d'où viennent les paquets, et donc de vous localiser.

Configurer un relais tor

Il vous est possible de participer à ce réseau en étant un serveur relais. Qui plus est, cela rendra d'autant plus difficile de déterminer vos propres activités, puisque vos centres d'intérêt seront noyés parmi le trafic sortant de votre connexion.

Tor peut avoir besoin d'ouvrir de nombreuses connexions. Réduire les limitations peut alors être une bonne idée. Ajoutez dans le fichier "/etc/sysctl.conf"

kern.maxfiles=20000

Installez et activez Tor ainsi :

# pkg_add tor
# rcctl enable tor

Assurez-vous d'ouvrir dans votre pare-feu, et de rediriger dans votre routeur le port 9001.

Ensuite, éditez le fichier "/etc/tor/torrc" , afin d'obtenir ces quelques lignes :

SOCKSPort 0
ORPort 9001
Nickname Surnom
RelayBandwidthRate 75 KB  
RelayBandwidthBurst 100 KB 
ContactInfo votrenom <adresse AT email dot fr>
ExitPolicy reject *:* # no exits allowed

Modifiez les valeurs pour RelayBandwidthRate et RelayBandwidthBurst selon votre accès à Internet. Il s'agit de la bande passante que vous laissez disponible pour Tor. C'est une bonne idée de préciser votre adresse mail aussi pour être averti en cas de problème ou de mise à jour importante.

Enfin, démarrez Tor avec rcctl start tor et attendez de voir apparaître dans le fichier "/var/log/messages" :

May 12 12:20:41 chezmoi Tor[12059]: Bootstrapped 80%: Connecting to the Tor network
May 12 12:20:41 chezmoi Tor[12059]: Bootstrapped 85%: Finishing handshake with first hop
May 12 12:20:42 chezmoi Tor[12059]: Bootstrapped 90%: Establishing a Tor circuit
May 12 12:20:44 chezmoi Tor[12059]: Tor has successfully opened a circuit. Looks like client functionality is working.
May 12 12:20:44 chezmoi Tor[12059]: Bootstrapped 100%: Done
May 12 12:20:44 chezmoi Tor[12059]: Now checking whether ORPort 109.190.xxx.xxx:9001 is reachable... (this may
take up to 20 minutes -- look for log messages indicating success)
May 12 12:21:10 chezmoi Tor[12059]: Self-testing indicates your ORPort is reachab

Configurer un service caché tor

Vous pouvez proposer votre site web (ou n'importe quel autre service) au travers du réseau Tor. Ceux qui voudront y accéder utiliseront une adresse se terminant par ".onion", comme "5rud2tr7sm3oskw5.onion".

⚠ Avant d'aller plus loin, notez qu'il est très fortement déconseillé d'héberger un relais et un service caché en même temps.

Ceci étant dit, vous pouvez activer votre site caché en éditant le fichier "/etc/tor/torrc". Décommentez les lignes correspondantes ou ajoutez-les :

SOCKSPort 0
HiddenServiceDir /var/tor/hidden/
HiddenServicePort 80 127.0.0.1:80

Relancez Tor pour activer ce service caché : "# rcctl restart tor". Deux nouveaux fichiers vont apparaître dans le dossier "/var/tor/hidden/" : "hostname" et "private_key". L'adresse de votre site en .onion se trouve dans le fichier hostname. Notez-la :

# cat /var/tor/hidden/hostname
5rud2tr7sm3oskw5.onion

Cependant, ne communiquez jamais le contenu de private_key.

Il ne nous reste plus qu'à configurer httpd pour lui dire de recevoir les connexions vers l'adresse en ".onion" et de les servir. Le fichier "/etc/httpd.conf" pourra alors contenir ceci :

server "5rud2tr7sm3oskw5.onion" {
        listen on 127.0.0.1 port 80
        # emplacement du site
        root "/htdocs/chezmoi.tld"     
        directory index index.html
        [...]
}

Vous pouvez tester votre site (après un rcctl reload httpd bien sûr) avec le navigateur torbrowser.

Mais, ce n'est pas chiffré dans une adresse https! Est-ce vraiment sécurisé?

Bonne remarque. Le chiffrement TLS n'est pas nécessaire ici, puisque le tunnel ouvert par Tor pour accéder au site est entièrement chiffré. De plus, le navigateur devrait valider le certificat, or, ce dernier n'est pas enregistré pour un domaine en ".onion". Notez que si vous pouvez obtenir un certificat pour cette adresse, c'est alors possible de configurer un accès en https.

XMPP avec prosody

Pourquoi choisir une messagerie instantanée XMPP?

Vous connaissez peut-être déjà IRC pour la messagerie instantanée dans des salons de discussions. Cependant, XMPP présente des avantages devant IRC non négligeables pour communiquer :

De tous ces points, c'est principalement la question de la vie privée et de la possibilité de chiffrer les communications qui, à ma grande surprise, semblent d'un seul coup peu intéressants pour des libristes habituellement scrupuleux sur ces questions. Pourtant, n'importe quel participant d'un salon sur IRC peut connaître votre IP. Certes, ça ne fait pas tout, mais ça reste énorme comme "fuite".

D'autres ont écrit sur le sujet, en préférant par exemple lister les défauts d'IRC :

IRC's flaws

Mise en place de prosody

Prosody est un serveur XMPP à la fois léger et facile à configurer.

Voici quelques éléments à propos de sa mise en place pour les détails relatifs à OpenBSD.

Tout d'abord, on installe le port :

# pkg_add prosody

Ajout de champs DNS

Vous avez besoin d'ajouter à votre zone de nouveaux champs :

Un champ A:

xmpp.chezmoi.tld

Ce champ doit correspondre à celui définit ensuite dans les champs SRV suivants.

Des champs SRV:

_xmpp-client._tcp.chezmoi.tld. 18000 IN SRV 0 5 5222 xmpp.chezmoi.tld.
_xmpp-server._tcp.chezmoi.tld. 18000 IN SRV 0 5 5269 xmpp.chezmoi.tld.

Il faudra en ajouter pour les services proposés par le serveur xmpp s'il y en a, comme les MUC :

_xmpp-server._tcp.conference.chezmoi.tld. 18000 IN SRV 0 5 5269 xmpp.chezmoi.tld.

Configuration

Editez "/etc/prosody/prosody.cfg.lua"

Il n'y a rien à faire si ce n'est préciser l'adresse de l'admin ajouter un virtualhost et préciser l'emplacement du certificat:

VirtualHost "chezmoi.tld"
	ssl = {
		certificate = "/etc/prosody/certs/chezmoi.tld.crt";
        key = "/etc/prosody/certs/chezmoi.tld.key";
	}

Le certificat doit être lisible par l'user _prosody.

Puisque dans cette documentation on suggère d'obtenir les certificats avec acme-client, installez-les ainsi après avoir lancé acme :

install -g _prosody -o _prosody -m 400 /etc/ssl/private/chezmoi.tld.key /etc/prosody/certs/
install -g _prosody -o _prosody -m 400 /etc/ssl/chezmoi.tld.crt /etc/prosody/certs/

Si les certificats sont renouvelés automatiquement, pensez à ajouter les lignes précédentes au script appelé périodiquement 😎.

Ajoutez l'administrateur :

# prosodyctl adduser batman@chezmoi.tld

On vérifie que la config est correcte:

prosodyctl check config

Ouverture des ports

Ouvrez les ports 5222 (xmpp-client) et 5269 (xmpp-server)

Archivage des logs

Éditez "/etc/newsyslog.conf" :

/var/prosody/prosody.log                644  5     300  *     Z
/var/prosody/prosody.err                644  5     300  *     Z

Vérifiez la configuration du serveur

Remplacez "chezmoi.tld" par le domaine de votre serveur :

https://xmpp.net/result.php?domain=chezmoi.tld&type=server

Configuration avancée

Ça se passe sur le site officiel 😉

À propos de l'apu2

L'apu2 est une carte très économe en terme d'énergie qui supporte très bien OpenBSD.

Toutefois, elle ne peut se configurer que via le port série, pas avec un écran, ce qui représente en fait un avantage car il suffit d'un ordinateur portable pour administrer le serveur, nul besoin d'y brancher un clavier et un écran. Ici, on parlera donc de quelques astuces concernant l'apu2 et OpenBSD.

Pour l'anecdote, cette documentation est hébergée sur un apu2d0 😎.

Où/quoi acheter ?

Regardez la liste des revendeurs sur le site du fabriquant.

Veillez à acheter au moins les éléments suivants si vous ne prenez pas un pack :

Montage

Pour assembler votre serveur, regardez là aussi la documentation officielle.

Accéder à la console

Reliez l'apu2 à un ordinateur via le port série. Si ce dernier est démarré sous OpenBSD, accédez à la console avec la commande suivante :

cu -s 115200 -l /dev/cuaU0

Cette commande est à exécuter en tant que root ou bien après vous être ajouté au groupe dialer : "doas usermod -G dialer $(whoami)".

Installer OpenBSD sur l'APU2

Procédez comme d'habitude en branchant une clé USB d'installation sur l'APU2 puis en le mettant sous tension. Dans la console, avant de démarrer l'installation vous procéderez aux réglages suivants :

boot> 
stty com0 115200
set tty com0

Il ne sera pas nécessaire de le refaire ensuite.

Mettre le bios à jour

Vous pouvez flasher le firmware avec l'outil flashrom :

# pkg_add flashrom

Vous aurez sans doute lu le fichier "/usr/local/share/doc/pkg-readmes/flashrom" qui précise la procédure pour mettre à jour le BIOS.

Voici pas à pas comment faire.

Tout d'abord, récupérez la dernière version du du firmware.

Souvenez-vous bien où elle est enregistrée. Pour l'exemple, on va considérer qu'elle est stockée dans "/home/batman".

Ensuite, il faut redémarrer en mode "single user". C'est tout simple, il faut juste indiquer l'option "-s" au prompt de démarrage:

boot> boot -s

Vous verrez apparaître le message suivant:

Enter pathname of shell or RETURN for sh: 

Validez avec entrée pour pouvoir obtenir l'invite de commandes. Montez les systèmes de fichiers dont vous aurez besoin.

mount /usr
mount /usr/local
mount /var
mount /usr/X11R6 #si ldconfig rale sans
mount /home

Il faut ensuite faire appel à ldconfig pour que flashrom puisse accéder à des bibliothèques dont il a besoin.

ldconfig -m /usr/local/lib

Vous pouvez alors flasher le bios:

# flashrom -p internal:boardmismatch=force -w /home/batman/apu2_*.rom
flashrom v1.1 on OpenBSD 6.6 (amd64)
flashrom is free software, get the source code at https://flashrom.org
Calibrating delay loop... delay loop is unreliable, trying to continue OK.
coreboot table found at 0x7eed0000.
Found chipset "AMD FCH".
Enabling flash write... OK.
Found Winbond flash chip "W25Q64.V" (8192 kB, SPI) mapped at physical address 0.
Reading old flash chip contents... done.
Erasing and writing flash chip... Erase/write done.
Verifying flash... VERIFIED.

Redémarrez avec reboot.

Ainsi, le BIOS est mis à jour 😉

Vérifier une somme de contrôle

Lorsqu'un fichier est transféré, c'est plus prudent de s'assurer que tous les octets ont bien été copiés. De cette façon, les données sont bien authentiques et ça vous évite des tracas.

Le plus pratique est de vérifier la somme de contrôle du fichier d'origine puis du fichier copié. Pour cela, la commande sha256 est bien pratique. Il suffit de lui donner le fichier à "manger" :

$ sha256 debian-9.6.0-amd64.qcow2.gz
SHA256 (debian-9.6.0-amd64.qcow2.gz) = 91831ba15446f3ab418ae8a5c2a8ac0d852dc5d43bd595a70b88bd6ea4ded397

Reproduisez la même manipulation sur le fichier copié puis comparez cette série de chiffres et lettres : ils doivent être identiques. 😉

Notez que sous GNU/Linux, la commande sha256 n'existe pas. Son équivalent est sha256sum.

Si la somme de contrôle ne vous convainc pas, et si vos données sont particulièrement sensibles, vous pouvez pousser le vice plus loin avec l'outil signify.

Comment changer le mot de passe ?

Vous pouvez changer le mot de passe de n'importe quel utilisateur avec la commande passwd. Exemple :

# passwd toto

Pour changer le mot de passe du superutilisateur, c'est un poil plus délicat. Il faut absolument être entièrement identifié en tant que root (dans un shell placé dans le dossier de root avec les bonnes variables d'environnement...). Pour cela, utilisez l'option "'-l" :

# su -l
# passwd root

Tâches périodiques (cron)

Tout est prévu dans OpenBSD pour vous permettre d'exécuter des commandes régulièrement. Il vous suffit d'éditer un des fichiers suivant :

Il faut seulement faire attention à mettre le chemin complet vers les commandes à exécuter à l'intérieur de ces fichiers. Par exemple, pour envoyer un message à l'administrateur, on ne notera pas :

echo "Tu es le plus beau" | mail -s "Coucou" root

mais

echo "Tu es le plus beau" | /usr/bin/mail -s "Coucou" root

Vous trouverez le chemin absolu de vos commandes en utilisant "which commande".

Pour une configuration plus précise des périodes entre chaque lancement des commandes, il faut utiliser cron. Entrez "crontab -e" (pas besoin des droits superutilisateur) puis ajoutez par exemple pour démarrer une commande toutes les heures :

0 * * * * /chemin/vers/la/commande

Avec l'exemple ci-dessous, la commande est lancée toutes les 5 minutes:

*/5 * * * * /chemin/vers/la/commande

Pour en apprendre plus, lisez la page de manuel appropriée avec "man 5 crontab".

Voici un site qui vous aidera à bien comprendre la syntaxe cron.

Les crontabs, c'est vraiment pratique 😃.

Partitionnement d'un disque

Pour une sauvegarde ou un espace de stockage supplémentaire, vous pourriez vouloir ajouter un disque dur externe. Nous allons décrire ci-dessous pour l'exemple la création de deux parties sur disque.

⚠ Notez que tout ceci peut se réaliser après avoir chiffré le disque et créé un RAID identifié par exemple par "sd1" ensuite.

Identifier le périphérique

Branchez le disque dur au serveur. Si vous lancez la commande dmesg, vous verrez apparaître quelque chose comme ça :

umass0 at uhub0 port 1 configuration 1 interface 0 "Western Digital Ext HDD 1021" rev 2.00/20.21 addr 2
umass0: using SCSI over Bulk-Only
scsibus2 at umass0: 2 targets, initiator 0
sd1 at scsibus2 targ 1 lun 0: <WD, Ext HDD 1021, 2021> SCSI2 0/direct fixed serial.10581021383235373034
sd1: 1907727MB, 512 bytes/sector, 3907024896 sectors

Ces messages nous apprennent que le disque branché sera identifié par sd1. Modifiez la suite selon votre cas.

Partitionnement

On crée des "slices" avec disklabel en mode édition :

# disklabel -E sd1

Maintenant, on peut créer les partitions l'une après l'autre. En cas de doute, appuyez sur "p" pour afficher l'état actuel du disque.

Pour créer la première partition, on saisit "a a". Cela signifie "ajouter une partition a".

Laissez l'offset par défaut. Réglez la taille de la partition selon vos besoins. Notez que vous pouvez définir une taille avec :

Choisissez le système de fichier "4.2BSD".

Créez la deuxième partition de la même façon avec cette fois-ci la combinaison "a d".

⚠ Notez qu'on ne peut pas créer une partition "c", cette lettre étant réservée pour désigner le disque entier. De même, je préfère ne pas utiliser "b" ici, car c'est souvent (mais pas obligatoirement) utilisé pour une partition d'échange "swap". Toutes les autres lettres de l'alphabet restent valables.

Une fois terminé, utilisez la lettre q pour quitter et appliquer les changements.

Regardons maintenant l'état du disque en entrant disklabel sd1 :

# /dev/rsd1c:
type: SCSI
disk: SCSI disk
label: Ext HDD 1021
duid: 782f1ddb783cdd13
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 255
sectors/cylinder: 16065
cylinders: 243201
total sectors: 3907024896
boundstart: 64
boundend: 3907024065
drivedata: 0
16 partitions:
#            size       offset  fstype [fsize bsize  cpg]
  a:    629153472           64  4.2BSD   4096 32768    1
  d:   3277870464    629153536  4.2BSD   8192 65536    1 
  c:   3907024896            0  unused

Au secours, c'est quoi tout ça???

Pas de panique, tout n'est pas important. Commençons pour une fois par les dernières lignes. Chaque partie décrit une caractéristique de la partition.

Partition   Taille 	    Début       Système de fichier 	Divers
a: 	        629153472 	64 	        4.2BSD 	            4096 3...
d: 	        3277870464 	629153536 	4.2BSD 	            8192 6...

L'autre point important (parce qu'il faut l'avouer, il y a beaucoup d'informations qui ne nous serviront pas), c'est le "duid".

duid: 782f1ddb783cdd13

Cet élément nous permettra d'identifier le disque lorsqu'on voudra le monter. Si vous voulez le retrouver, vous pouvez aussi entrer :

# sysctl hw.disknames
hw.disknames=wd0:bfb4775bb8397569,cd0:,wd1:56845c8da732ee7b,wd2:f18e359c8fa2522b

Nous avons presque terminé, il faut maintenant formater les deux partitions créées (a et d) :

# newfs /dev/rsd1a
# newfs /dev/rsd1d

N'oubliez pas le "r" 😉

Vous pouvez désormais ajouter dans le fichier "/etc/fstab" un nouveau montage pour chacune de ces partitions. Remarquez l'utilisation du duid précédent :

...
782f1ddb783cdd13.a /home/prx/musique/ ffs rw,softdep,noatime,nodev,nosuid,noauto 0 0
782f1ddb783cdd13.d /mnt/backup/ ffs rw,softdep,noatime,nodev,nosuid 1 2

Cela fait beaucoup d'options, je vous l'accorde. Lisez le man de fstab(5) pour bien comprendre.

Dans cet exemple :

Pour monter chaque point listé dans "/etc/fstab", vous entrerez :

# mount -a

Comment trouver mon interface réseau ?

Afin de trouver le nom de votre interface réseau (le câble ethernet par exemple), on saisit la commande "ifconfig". Prenez le temps de lire le retour de cette commande, votre interface doit avoir une adresse attribuée que vous pouvez lire après le mot inet, et appartient certainement au groupe egress.

Par exemple :

$ ifconfig                                                   
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 32768
        priority: 0
        groups: lo
        inet 127.0.0.1 netmask 0xff000000
re0: flags=218843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,MPSAFE,AUTOCONF6> mtu 1500
        lladdr fc:aa:14:65:5f:86
        priority: 0
        groups: egress
        media: Ethernet autoselect (100baseTX full-duplex,rxpause,txpause)
        status: active
        inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255
enc0: flags=0<>
        priority: 0
        groups: enc
        status: active
pflog0: flags=141<UP,RUNNING,PROMISC> mtu 33144
        priority: 0
        groups: pflog

Ici, lo0 ne nous intéresse pas. C'est l'interface dite "locale", utilisée par certains programmes pour communiquer entre eux au sein du serveur. enc0 et pflog0 ne nous intéressent pas non plus ici, car correspondent respectivement à une interface pour monter un VPN et pour récupérer les journaux du parefeu.

Il vous reste re0, votre interface Ethernet (c'est écrit dans la section media 😉)

Je n'ai pas d'IP fixe

Mon fournisseur d'accès ne me donne pas une adresse IP fixe.

C'est effectivement embêtant. Car dans ce cas, l'adresse IP associée à votre domaine "chezmoi.tld" doit régulièrement être mise à jour.

Sachez qu'il existe pour ça DynDNS. C'est un service qui permet de réaliser cette opération, et la plupart des *box ont une option pour le configurer.

Cela peut toutefois être fastidieux, et vous préférerez peut-être changer de fournisseur d'accès. FDN par exemple?

Il vous est aussi tout à fait possible d'obtenir une IP fixe en configurant un VPN, par exemple en louant un serveur virtuel puis en mettant votre serveur derrière le VPN.

Les journaux (logs)

Votre serveur garde des enregistrements de son activité. Le tout est rassemblé dans des fichiers texte appelés journaux ou plus souvent "logs". On les trouve dans le dossier "/var/log" pour les journaux système et dans "/var/www/logs" pour tout ce qui concerne la partie serveur web.

On regardera notamment :

Je vous conseille de les consulter de temps en temps afin de vérifier que tout fonctionne comme prévu. Vous pouvez les afficher avec la commande :

tail -f /var/journal.log

Vous remarquerez bien vite l'apparition de fichiers se terminant par .0.gz, .1.gz. Ce sont les archives des journaux. Afin d'éviter qu'ils ne prennent trop de place, OpenBSD se charge chaque jour de lancer la commande newsyslog. Cet outil compresse les archives si besoin.

Pour le configurer, jetez un oeil au fichier "/etc/newsyslog.conf". C'est dans ce dernier que vous devrez ajouter des lignes si une de vos applications crée ses journaux dans un fichier qui n'est pas listé ci-dessus. Il se décompose ainsi :

...
/var/log/messages                       644  5     300  *     Z
/var/log/authlog        root:wheel      640  7     *    168   Z
...

Avec dans l'ordre :

On peut préciser ensuite si besoin :

Pour d'autres informations, regardez les pages man de newsyslog et newsyslog.conf.

$ man newsyslog
$ man newsyslog.conf

Suggestions d'améliorations avec lynis

Lynis est un outil qui va analyser votre système pour y détecter d'éventuelles erreurs de configuration pouvant entacher la sécurité de votre serveur.

De plus, il peut vous proposer des idées d'amélioration.

Afin de l'utiliser, installez-le puis lancez le premier scan :

# pkg_add lynis
# lynis audit system

Vous pourrez voir de nombreux messages apparaître. Consultez le fichier "/var/log/lynis-report.dat" afin de lire le rapport calmement :

# less /var/log/lynis-report.dat

On pourra lire par exemple comme suggestions :

suggestion[]=SSH-7408|Consider hardening SSH configuration|AllowTcpForwarding (YES --> NO)|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|ClientAliveCountMax (3 --> 2)|-|
suggestion[]=SSH-7408|Consider hardening SSH configuration|Compression (YES --> NO)|-|

Pour voir uniquement les suggestions, utilisez :

# grep suggestion /var/log/lynis-report.dat

Où vont mes mails si mon serveur est éteint ?

Quand on héberge ses mails, que se passe-t-il quand le serveur de mail est, pour une raison quelconque, inaccessible ?

Voilà une question qu'on se pose forcément à un moment donné. Lorsque le serveur est inaccessible, il se passe à peu près la même chose que lorsque le facteur doit délivrer un recommandé : le serveur expéditeur essaie une première fois et échoue. Il va repasser une fois suivante un peu plus tard. En cas de second échec, il réessaie à nouveau plus tard.

Bien évidemment, après plusieurs échecs, il abandonne.

Vous devez vous demander combien d'essais et quels intervalles entre chaque essai ? À cela je n'ai pas de réponse précise, car ça dépend de la configuration du serveur expéditeur. On peut toutefois raisonnablement considérer que les essais peuvent se poursuivre pendant une dizaine de jours.

Pour pallier à la pire des situations, vous devriez penser à mettre en place un backup, c'est à dire un autre serveur qui gardera vos mails le temps que votre serveur redevienne disponible. Un ami disposant de son propre serveur peut s'en charger 😎. C'est décrit dans la partie sur les mails.

Le modem de mon fournisseur suffit ?

Est-ce qu’une « bête » *Box (Freebox) suffit pour assurer convenablement un tel service sur la durée ?

Oui ! Si vous préférez, vous pouvez bien entendu utiliser votre propre routeur.

Comment connaître l'utilisation et les vitesses réseau ?

Vous pouvez installer les ports iftop ou bwm-ng.

Sinon, présent de base sur OpenBSD, il y a la commande systat :

# systat states

Utiliser les portages de logiciels d'OpenBSD

Vous le savez déjà, OpenBSD dispose de nombreux paquets vérifiés avec soin. Vous pourrez alors installer un programme grâce au système de ports.

Il s'agit d'un arbre contenant toutes les instructions pour compiler et installer vous même les paquets. Pas de panique, vous aurez besoin uniquement de la commande make. En effet, le nécessaire pour compiler un paquet, les petites modifications au code source apportées par les développeurs d'OpenBSD et un tas d'autres détails sont précisés dans les ports, si bien que vous n'avez pas à vous en préoccuper.

Nous supposons par la suite que vous utilisez OpenBSD en branche -stable. Vous disposerez ainsi des correctifs de sécurité pour les programmes dans le cas d'une éventuelle faille.

Voici la marche à suivre :

On récupère les ports. Pour cela, on se déplace dans le dossier /usr puis on lance la commande suivante :

# cd /usr
# cvs -z9 -qd anoncvs@anoncvs.fr.openbsd.org:/cvs get -rOPENBSD_X_X -P ports

Remplacez "X_X" par votre version d'OpenBSD (par exemple "6_7").

On vous demande de valider ce serveur, acceptez avec yes en toutes lettres :

The authenticity of host 'anoncvs.fr.openbsd.org (145.238.209.46)' can't be established.
ECDSA key fingerprint is SHA256:WXN4m8Nxd4vcTqxxxxMMVenxxxgp8060nv39JIiCSss.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'anoncvs.fr.openbsd.org,145.238.209.46' (ECDSA) to the list of known hosts.

Si vous aviez déjà récupéré les ports, vérifiez qu'il n'y a pas eu de changements avec la commande :

# cd /usr/ports && cvs -z9 -q up -rOPENBSD_X_X -Pd

Cherchez le paquet qui vous intéresse. Par exemple, pour compiler PHP, je vais chercher où se trouve son port en utilisant la commande make search key=ma_recherche dans le dossier "/usr/ports". Puisqu'il risque d'y avoir beaucoup de résultats, on filtre avec la commande grep pour ne voir que ce qui contient la version 7.3

# cd /usr/ports
# pkg_add portslist
# make search key=php | grep 7.3

On constate alors que le port se trouve dans le dossier (on le repère avec le mot Path) "/usr/ports/lang/php/7.3".

Afin de compiler et installer ce port, il ne reste plus qu'à entrer make install dans ce dossier :

# cd /usr/ports/lang/php/7.3
# make install clean

Toutes les dépendances sont alors récupérées et installées sous forme de paquets.

Afin d'installer tous les "sous-paquets", c'est-à-dire les extension de PHP (php-curl, php-gd…), on lance :

# make install-all

Que faire face aux coupures de courant ?

Plusieurs astuces sont possibles :

Dans le cas où l'interruption du serveur est due à un bug quelconque, sachez que tous les jours, OpenBSD génère un rapport de sécurité qui peut dire : "ce service devrait être en route mais ne l'est pas". Ainsi, vous pouvez aller vérifier assez rapidement quel est le problème.

En somme, pas de quoi s'alarmer outre mesure.

Que faire en cas de problème ?

Un service ne veut plus démarrer ? Votre site web n'est plus accessible ? Voici quelques astuces :

Service

Un service ne démarre plus : vous pouvez démarrer ce service manuellement et voir les messages d'erreurs qu'il retourne. Par exemple, avec httpd, vous pouvez saisir cette commande pour avoir plus d'informations :

rcctl -d start http

Manuels

Vérifiez le manuel de programme problématique avec man.

Aller voir aussi dans le dossier "/usr/local/share/doc/pkg-readmes" s'il y a des précisions sur le programme posant problème.

Installation de port

Si c'est un paquet qui ne veut pas correctement s'installer, utilisez la commande pkg_check qui va nettoyer votre installation.

Les journaux

Consultez les journaux du système avec la commande tail :

# tail -f /var/log/messages /var/log/daemon

Pour un site web :

# tail -f /var/www/logs/*

Pour un problème d'identification :

# tail -f /var/log/authlog

Lancez la commande dmesg qui peut vous donner une information sur un périphérique.

Parefeu

Si c'est le pare-feu qui pose problème, vous pouvez analyser le trafic avec tcpdump : "tcpdump -n -e -ttt -i pflog0".

Système de fichier corrompu ou redémarrages intempestifs

Vous pouvez essayer de démarrer sur un noyau chargé en mémoire (ramdisk) : le bsd.rd, ceci afin de réinstaller les sets en choisissant "U: Upgrade" ou bien en accédant au système de fichier corrompu pour le réparer.

Pour cela, juste avant le démarrage, entrez bsd.rd à l'invite suivante :

boot>

Sinon, préparez une clé USB à partir d'une image minirootXX.img et démarrez sur cette clé.

Ensuite, choisissez d'accéder au Shell en sélectionnant S. Vous pouvez alors changer le mappage du clavier en français avec la commande "kbd fr".

Pour accéder à votre disque, vérifiez qu'il est bien identifié avec la commande dmesg. Dans l'exemple, on considérera que ce disque est sd1.

Ensuite, assurez-vous que le périphérique est prêt à être utilisé avec :

cd /dev && sh MAKEDEV sd1

Vous pourrez vérifier le système de fichier avec la commande fsck :

fsck -y sd1a
fsck -y sd1d

Faîtes-le pour chaque morceau (slice ou "partition") dans le disque. Pour toutes les retrouver, entrez "disklabel sd1".

Demander de l'aide

Vous pouvez :

Discuter sur le salon XMPP francophone.

Discuter sur le salon XMPP.

Demander de l'aide sur la liste de diffusion officielle.

Demander de l'aide sur la liste de diffusion française.

Demander de l'aide sur le forum OpenBSD français.

Générer de bons mots de passe aléatoires

Faire des pieds et des mains pour sécuriser son système ne sert à rien si on choisit des mots de passe de 5 lettres. En effet, pour les mots de passe, il n'y a qu'une chose à retenir 😋 :

Plus c'est long, plus c'est bon !

Ce n'est qu'une question de mathématique : un pirate va tenter toutes les combinaisons possibles de mots de passe. Pour l'exemple, imaginons qu'il y ait 26 caractères possibles (on simplifie en oubliant le chiffres, les majuscules et les caractères spéciaux).

Jusque là, un ordinateur fini par trouver le bon mot de passe par essais successifs en quelques secondes voire quelques minutes. Mais si on allonge encore un peu le mot de passe :

Ça commence à faire beaucoup ! 😎 Ajoutez les majuscules et les chiffres, on passe de 26 à 62 possibilités par caractères. Cela donne un peu plus de 800 000 000 000 000 000 combinaisons possibles pour un mot de passe de 10 caractères! Finalement, il faut tellement de temps pour tenter toutes les possibilités que cela n'arrive jamais. Et qui plus est, vous aurez certainement ajouté des règles anti-bruteforce dans votre parefeu.

Oubliez donc les histoires de symboles spéciaux à inclure absolument, ce n'est pas utile de torturer vos méninges.

Quelques idées :

Ou alors, si vous aimez avoir mal à la tête, vous pouvez utiliser une des commandes suivantes pour générer des mots de passe aléatoires (Remplacez le "15" par le nombre de caractères souhaités):

$ openssl rand 15 -base64

ou plus classique mais plus long :

$ dd if=/dev/urandom count=128 bs=1M 2>&1 | md5 | cut -b-15

ou encore avec jot :

$ jot -rcs '' 20 32 126

ou enfin avec /dev/random

$ tr -cd ' -~' < /dev/urandom 
# ou pour n'avoir que des caractères alphanumériques
$ tr -cd '[:alnum:]' < /dev/urandom

Pour rire,

Cette petite BD en provenance d'xkcd explique très bien cette partie avec humour 😊.

image provenant de xkcd.com pour trouver un bon mot de passe

On même trouve en ligne des services qui proposent de suivre ce principe (il en existe certainement d'autre).

Découper et rassembler des fichiers

Peut-être aurez-vous besoin de découper de gros fichiers pour les transférer sur votre serveur. Voici comment faire :

$ gzip -c gros_fichier | split -b 100m - gros_fichier.gz

Cela vous donne plusieurs fichiers d'une taille maximale de 100m rangés par ordre alphabétique:

$ ls -l
-rw-r--r--  1 xavier  xavier  104857600 Dec 12 16:52 gros_fichier.gzaa
-rw-r--r--  1 xavier  xavier  104857600 Dec 12 16:52 gros_fichier.gzab
-rw-r--r--  1 xavier  xavier   88204071 Dec 12 16:52 gros_fichier.gzac

Afin de les rassembler, utilisez la commande suivante :

cat gros_fichier.gz_* | gunzip -c > gros_fichier

Avouez-le, c'est plutôt cool non? 😎

C'est quoi un sous-domaine ?

Réponse rapide : un domaine c'est chezmoi.tld. Un sous-domaine c'est sousdomaine.chezmoi.tld.

Réponse longue : Le domaine principal est enregistré chez votre registre par un champ A pointant vers l'adresse IP de votre serveur. Ensuite, vous pouvez ajouter autant de sous-domaines que vous voulez en créant dans la zone des champs de type CNAME, qui renvoient vers le champ A précédent. En gros, les visiteurs sont toujours dirigés vers votre serveur, mais selon le domaine/sous-domaine entré dans la barre d'adresse, votre serveur leur fourni un contenu différent.

Un champ CNAME se présente donc sous cette forme :

sousdomaine    IN CNAME  domaine.net.

Le point final est important !

Comment créer/supprimer un utilisateur ?

Créer un utilisateur

Créer des utilisateurs peut vous servir à plusieurs choses, notamment :

Selon les cas, vous ne configurerez pas l'utilisateur de la même façon. En résumé :

Pour ajouter un utilisateur, utilisez la commande adduser. Cette dernière est interactive et pose des questions petit à petit pour ne rien oublier au contraire d'useradd (oui, la différence est mince...).

Voici à quoi ressemblera la création d'un utilisateur, qui n'a pas le droit de lancer de commandes :

root@votreserveur[~] # adduser
Use option ``-silent'' if you don't want to see all warnings and questions.
Reading /etc/shells
Check /etc/master.passwd
Check /etc/group
Ok, let's go.
Don't worry about mistakes. There will be a chance later to correct any input.
Enter username []: toto
Enter full name []: Jean-Eudes
Enter shell csh ksh nologin sh [nologin]: nologin
Uid [1005]:
Login group toto [toto]:
Login group is ``toto''. Invite toto into other groups: guest no
[no]:
Login class authpf bgpd daemon default dovecot pbuild staff unwind
[default]:
Enter password []:
Enter password again []:
Name:        toto
Password:    ***************
Fullname:    Jean-Eudes
Uid:         1005
Gid:         1005 (toto)
Groups:      toto
Login Class: default
HOME:        /home/toto
Shell:       /sbin/nologin
OK? (y/n) [y]: y
Added user ``toto''
Add another user? (y/n) [y]: n
Goodbye!

Bien sûr, vous aurez choisi un mot de passe de qualité.

Supprimer un utilisateur

Pour supprimer un utilisateur, c'est très rapide :

# userdel toto
# groupdel toto

Et voilà ! 😊

Tunnel SSH : Proxy ou VPN

SSH vous permettr de mettre en place un rapide PROXY pour encapsuler certaines connexions, voire même de mettre en place un VPN rudimentaire.

Proxy SOCKS

Un tunnel SSH est très facile à mettre en place. Il permet d'apparaître avec l'IP du serveur sortant.

On supposera que votre serveur dispose d'un accès SSH fonctionnel.

Depuis une machine cliente (votre ordinateur de bureau par exemple), vous entrerez cette commande :

ssh -D 9999 -NT batman@chezmoi.tld

Quelques explications :

Ensuite, toutes les applications peuvent être configurées pour utiliser un proxy de type SOCKS vers le port 9999.

Par exemple, avec le navigateur Firefox, vous pouvez configurer le proxy dans les préférences "Paramètres réseau".

VPN avec SSH

Voir le man ssh(1) partie "SSH-BASED_VIRTUAL_PRIVATE_NETWORKS".

/etc/dovecot/local.conf

# listen both ipv4 and ipv6
listen = *, [::]
# imap c'est mieux que pop
protocols = imap 
# securisation via ssl
ssl = yes
ssl_cert = </etc/ssl/chezmoi.tld.crt
ssl_key = </etc/ssl/private/chezmoi.tld.key
# pas de plaintext
disable_plaintext_auth = yes
# Modification des permissions pour limiter la lecture du fichier des mots de passe
# au groupe _maildaemons
service auth {
  user = $default_internal_user
  group = _maildaemons
}
# Identification par fichier
passdb {
    args = scheme=blf-crypt /etc/mail/passwd
    driver = passwd-file
}
userdb {
    driver = static
    args = uid=_vmail gid=_vmail home=/mnt/bigstorage/_vmail/%d/%n/ 
}
# Plugins
mail_plugins = $mail_plugins quota zlib
# Activation des plugins : 
# - Support des quotas
# - zlib limite la bande passante par compression
# - sieve pour filtres personalises. **Il faut le paquet dovecot-pigeonhole**
protocol imap {
    mail_plugins = $mail_plugins imap_quota imap_zlib imap_sieve
}
# Configuration des plugins
plugin {
        #plugin quota
  quota = maildir:User quota
  quota_rule = *:storage=1G
  quota_rule2 = Trash:storage=+100M
  quota_grace = 50%%
  quota_status_success = DUNNO
  quota_status_nouser = DUNNO
  quota_status_overquota = "552 5.2.2 Mailbox is full"
  # Compression maxi
  zlib_save_level = 9 # 1..9; default is 6
  zlib_save = gz # or bz2, xz or lz4
        # Sieve
        # -----
  sieve_plugins = sieve_imapsieve sieve_extprograms
        # Script sieve execute par defaut (antispam)
        sieve_default = /usr/local/lib/dovecot/sieve/default.sieve
  # Scripte pour enregistrer comme spam quand mails deplace dans dossier Junk
  imapsieve_mailbox1_name = Junk
  imapsieve_mailbox1_causes = COPY
  imapsieve_mailbox1_before = file:/usr/local/lib/dovecot/sieve/report-spam.sieve
  # Enregistrer mail comme pas-spam si retire du dossier Junk
  imapsieve_mailbox2_name = *
  imapsieve_mailbox2_from = Junk
  imapsieve_mailbox2_causes = COPY
  imapsieve_mailbox2_before = file:/usr/local/lib/dovecot/sieve/report-ham.sieve
  sieve_pipe_bin_dir = /usr/local/lib/dovecot/sieve
  sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
}

/etc/httpd.conf

types { include "/usr/share/misc/mime.types" }
default type text/plain
server "default" {
    listen on * port 80 
    root "/htdocs/chezmoi.tld" 
} 
server "chezmoi.tld" {
    listen on * port 80
    block return 301 "https://$SERVER_NAME$REQUEST_URI"
}
server "chezmoi.tld" { 
    alias "www.chezmoi.tld"
    listen on * tls port 443 
    root "/htdocs/chezmoi.tld" 
    directory index index.html
    log style combined
    hsts preload
    tls {
        certificate "/etc/ssl/chezmoi.tld.crt"
        key "/etc/ssl/private/chezmoi.tld.key"
    }
    location "/.well-known/acme-challenge/*" {
        root "/acme"
        request strip 2
    }
    location "/Blog/" {
        directory index index.php
    }
    location "*.php*" {
        fastcgi socket "/run/php-fpm.sock"
    }
    location "/DL/PDF/" {
        directory auto index
    }
    location "/private/" {
        authenticate "education" with "/htdocs/private.htpw"
        directory auto index
    }
}
server "site2.chezmoi.tld" { 
    alias "www.site2.chezmoi.tld"
    listen on * port 80 
    listen on * tls port 443 
    root "/htdocs/site2" 
    directory index index.html
    log access "site2.log"
    hsts 
    tls {
        certificate "/etc/ssl/chezmoi.tld.crt"
        key "/etc/ssl/private/chezmoi.tld.key"
    }
    location "/.well-known/acme-challenge/*" {
        root "/acme"
        request strip 2
    }
    location "*.php*" {
        fastcgi socket "/run/php-fpm.sock"
    }
    location "/downloads/" {
        directory index index.php
    }
} 

/etc/monitrc

# Vérifie qu'un site est accessible
check host chezmoi.tld with address chezmoi.tld
      if failed port 80 protocol http for 2 cycles then alert
      if failed port 443 protocol https for 2 cycles then alert
    # alerte si le certificat SSL arrive à expiration
      if failed
         port 443
         with protocol https
         and certificate valid > 30 days
         use ssl options {verify: enable}
      then alert
# Disponibilité du serveur mail
check host chezmoi.tld with address chezmoi.tld
      if failed port 25 with protocol smtp for 2 cycles then alert
# ressources utilisées
check system localhost
  if cpu > 75% for 2 cycles then alert
  if memory usage > 75% then alert
  if swap usage > 30% then alert
  if disk read > 10 MB/s for 2 cycles then alert
check filesystem rootfs with path /
              if space usage > 90% then alert
check filesystem var with path /var
              if space usage > 90% then alert

/var/nsd/etc/nsd.conf

server:
        hide-version: yes
        verbosity: 2
        database: "" # disable database
        zonesdir: "/var/nsd/zones/"
        ip-address: 46.23.92.148
        ip-address: 2a03:6000:9137::148 
remote-control:
        control-enable: yes
key:
        name: "secretkey"
        algorithm: hmac-sha256
        secret: "i8f4FgDsldD11pHAqo9Ko="
zone:
        name: "reiva.xyz"
        zonefile: "signed/reiva.xyz"
        provide-xfr: 109.190.128.23 secretkey
        notify: 109.190.128.23 secretkey
      # GANDI
        provide-xfr: 217.70.177.40 NOKEY
        notify: 217.70.177.40 NOKEY
# slaves
zone:
        name: "si3t.ch"
        zonefile: "slave/si3t.ch"
        allow-notify: 109.190.128.23 secretkey
        request-xfr:  109.190.128.23 secretkey
zone:
        name: "ouaf.xyz"
        zonefile: "slave/ouaf.xyz"
        allow-notify: 109.190.128.23 secretkey
        request-xfr:  109.190.128.23 secretkey
zone:
        name: "3hg.fr"
        zonefile: "slave/3hg.fr"
        allow-notify: 109.190.128.23 secretkey
        request-xfr:  109.190.128.23 secretkey

/etc/pf.conf

# See pf.conf(5) and /etc/examples/pf.conf
## Configuration générale ##
http_ports = "{ www https }            # ports http(s)
mail_ports = "{ submission imaps }"    # ports mails 
tcp_pass = "{ domain }"                # ports tcp ouverts
udp_pass = "{ domain }"                # ports udp ouverts
set block-policy drop                  # bloque silencieusement
set skip on lo                         # Pas de filtre en local
set limit table-entries 400000   
set limit states 100000
## tables pour les vilains bruteforceurs
table <bruteforce> persist
table <vilain_bruteforce> persist
# antispam avec greylisting
table <nospamd> persist file "/etc/mail/nospamd"
table <spamd-white> persist
table <bgp-spamd-bypass> persist
# table blockzone
table <t_badips> persist file "/var/blockzones/badips_ipv4"
table <t_badips6> persist file "/var/blockzones/badips_ipv6"
table <t_bogons> persist file "/var/blockzones/bogons_ipv4"
table <t_bogons6> persist file "/var/blockzones/bogons_ipv6"
## Traitement des paquets ##
# Paquets partiels
match all scrub (max-mss 1440 no-df random-id reassemble tcp)
antispoof quick for egress         # Protection vol d'ip
antispoof quick for lo0            # Protection vol d'ip
block in log quick from urpf-failed
# Pour relayd
anchor "relayd/*"
## Les règles pour pf ##
# on bloque tout par défaut 
# puis on continue de lire la suite
block 
# on bloque les ip blacklistées   pour de bon (quick)
# on ajoute un label pour se repérer dans les [logs :10-tips:logs]
block log quick from <bruteforce> label "brutes"
block log quick from <vilain_bruteforce>  label "vilain"
# blocage des blockzones
block log quick from { <t_bogons>, <t_bogons6> } label "bogons" 
block log quick from { <t_badips>, <t_badips6>} label "badips"
# NFS local
pass in quick on egress from 192.168.1.0/24
## Anti bruteforce
### SSH
#### Limit 15 connexions par IP source
#### Limit 15 tentatives de connexion toutes les 5 minutes
pass in on egress proto tcp to port ssh modulate state \
  (max-src-conn 15, max-src-conn-rate 15/5, overload <bruteforce> flush global)
# web, avec redirection vers relayd
pass in on egress proto tcp to port www divert-to 127.0.0.1 port 8080 modulate state \
    (max-src-conn 100, max-src-conn-rate 25/60, overload <bruteforce> flush global)
pass in on egress proto tcp to port https divert-to 120.0.0.1 port 8443 modulate state \
    (max-src-conn 100, max-src-conn-rate 25/60, overload <bruteforce> flush global)
# mails
## antispam
pass in on egress proto tcp to port $mail_ports modulate state \
  (max-src-conn-rate 10/5, overload <bruteforce> flush global) \
  divert-to 127.0.0.1 port spamd
pass in on egress proto tcp from <nospamd> to any port smtp
pass in log on egress proto tcp from <spamd-white> to any port smtp
pass in quick on egress proto tcp from <bgp-spamd-bypass> to port smtp
pass out log on egress proto tcp to any port smtp
# on autorise le ping
pass quick inet6 proto ipv6-icmp all 
pass quick inet proto icmp all 
# on ouvre les autres ports
pass in quick on egress proto tcp to port $tcp_pass modulate state
pass in quick on egress proto udp to port $udp_pass 
# tout ouvert en sortie
pass out on egress proto { tcp udp icmp icmp6 } all modulate state 

/etc/relayd.conf

Fichier /etc/relayd.conf :

ext_ip4 = "192.0.2.2"
ext_ip6 = "2001:db8::2
tcp protocol "tlsrelay" {
	tls keypair si3t.ch
	tcp { nodelay, sack }
}
relay "gemini" {
	listen on $ext_ip4 port 1965 tls
	protocol "tlsrelay"
	forward to 127.0.0.1 port 11965
}
relay "gemini6" {
	listen on $ext_ip6 port 1965 tls
	protocol "tlsrelay"
	forward to ::1 port 11965
}
http protocol "http" {
	include "/etc/relayd.proxy.conf"
}
http protocol "https" {
	include "/etc/relayd.proxy.conf"
	match query hash "sessid"
	tls keypair si3t.ch
}
relay "http" {
	listen on $ext_ip4 port 80
	protocol "http"
	forward to 127.0.0.1 port 80
}
relay "http6" {
	listen on $ext_ip6 port 80
	protocol "http"
	forward to ::1 port 80
}
relay "https" {
	listen on $ext_ip4 port 443 tls
	protocol "https"
	forward with tls to 127.0.0.1 port 443
}
relay "tlsforward6" {
	listen on $ext_ip6 port 443 tls
	protocol "https"
	forward with tls to ::1 port 443
}

Fichier /etc/relayd.proxy.conf :

# block par défaut, puis ouvre cas par cas
return error
# apparence de l'erreur
return error style "body { background: silver; color: black; text-align:center } hr {border:0;
background-color:silver; color:silver; height:1px; width:30%; margin-top:50px;}"
# Pour garder l'IP source
match request header set "X-Forwarded-For" \
    value "$REMOTE_ADDR"
match request header set "X-Forwarded-By" \
    value "$SERVER_ADDR:$SERVER_PORT"
# Pour https
match header set "Keep-Alive" value "$TIMEOUT"
# anti robots sur wordpress que je n'ai pas
block quick path "/wp-*" label '<em>Stop scanning for wordpress</em>.'
# Securite
match request header remove "Proxy"
match response header set "X-Xss-Protection" value "1; mode=block"
match response header set "Frame-Options" value "SAMEORIGIN"
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 "Referrer-Policy" value "no-referrer"
match response header set "Content-Security-Policy" value "upgrade-insecure-requests"
match response header set "Permissions-Policy" value "interest-cohort=()"
# fun
match response header set "X-Powered-By" value "Powered by OpenBSD"
# etiquettes pour gestion du cache
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 request path "/*.html" tag "CACHE"
match request path "/*.gmi" tag "CACHE"
match request path "*/" tag "CACHE"
match response tagged "CACHE" header set "Cache-Control" value \
    "public, max-age=86400"
# etiquette pour utf-8 
match request path "/*.html" tag "HTML"
match response tagged "HTML" header set "Content-Type" value "text/html; charset=utf-8"
match request path "/*.txt" tag "TXT"
match request path "/*.md" tag "TXT"
match request path "/*.gmi" tag "TXT"
match response tagged "TXT" header set "Content-Type" value "text/plain; charset=utf-8"
pass

/etc/mail/smtpd.conf

Exemple de configuration avec gestion de plusieurs domaines.

Exemple 1 (rspamd)

# install :
#   opensmtpd-filter-rspamd
#   opensmtpd-filter-senderscore
table aliases "/etc/mail/aliases"
table domains "/etc/mail/domains"
table passwd "/etc/mail/passwd"
table virtuals "/etc/mail/virtuals"
pki chezmoi.tld key "/etc/ssl/private/chezmoi.tld.key"
pki chezmoi.tld cert "/etc/ssl/chezmoi.tld.crt"
pki domaine2.net key "/etc/ssl/private/domaine2.net.key"
pki domaine2.net cert "/etc/ssl/domaine2.net.crt"
pki autredomaine.xyz key "/etc/ssl/private/autredomaine.xyz.key"
pki autredomaine.xyz cert "/etc/ssl/autredomaine.xyz.crt"
# certificat par defaut
pki "*" key "/etc/ssl/private/chezmoi.tld.key"
pki "*" cert "/etc/ssl/chezmoi.tld.crt"
filter senderscore \
         proc-exec "filter-senderscore -junkBelow 70 -slowFactor 2000"
filter rspamd proc-exec "filter-rspamd"
## LISTEN ##
# RECEPTION DE MESSAGES
listen on all tls pki chezmoi.tld \
    filter { senderscore, rspamd }
# ENVOI DE MESSAGES #
listen on all port submission tls-require pki chezmoi.tld auth <passwd> \
    filter rspamd
## ACTIONS ##
action "relay" relay
action relaybackup relay backup tls helo "si3t.ch"
action "local_mail" maildir alias <aliases>
action virtual_maildir maildir "/home/_vmail/%{dest.domain:lowercase}/%{dest.user:lowercase}/Maildir" junk virtual <virtuals>
## MATCH ##
# RECEPTION
match from any for domain <domains> action virtual_maildir
match from any for local action local_mail
# ENVOI
# backup
match from any for domain friend.eu action relaybackup
match auth from any for any action "relay"
match for any action "relay"

Exemple 2 (spamassassin + dkimproxy)

Tous les domaines sont gérés par un seul certificat ici, pour plus de simplicité.

On ajoute des options sur la file d'attente, parce que.

# Configuration generale
## Tables 
table aliases "/etc/mail/aliases"
table passwd "/etc/mail/passwd"
table virtuals "/etc/mail/virtuals"
table domains "/etc/mail/domains"
## Certificats
pki chezmoi.tld key "/etc/ssl/private/chezmoi.tld.key"
pki chezmoi.tld cert "/etc/ssl/chezmoi.tld.crt"
## options sur la file d'attente
queue compression # less disk space
queue encryption 7dbecabecabeca45bce4aebc # encrypt all o/
filter senderscore \
         proc-exec "filter-senderscore -junkBelow 70 -slowFactor 2000"
### Ecoute pour messages signes avec dkimproxy
listen on lo0 port 10028 tag DKIM   
### Messages verifies par spamassassin
listen on lo0 port 10026 tag SPAMASSASSIN
### Reception
listen on all tls pki chezmoi.tld filter { senderscore }
### Envoi avec client de messagerie
listen on all port submission tls-require pki chezmoi.tld auth <passwd> 
# ACTIONS
action "envoi" relay 
action dkimproxy relay host smtp://127.0.0.1:10027 
action spamassassin relay host smtp://127.0.0.1:10025 
action local_mail maildir alias <aliases>
action relaybackup relay backup mx "chezmoi.tld" helo "chezmoi.tld"
action virtual_maildir maildir "/var/vmail/%{dest.domain:lowercase}/%{dest.user:lowercase}/Maildir" junk virtual <virtuals>
# Correspondances
## Reception
### Message pour les utilisateurs locaux
match for local action local_mail
### Message pour les utilisateurs virtuels
match tag SPAMASSASSIN from any for domain <domains> action virtual_maildir
### Messages a faire verifier par spamassassin
match from any for domain <domains> action spamassassin
## Envoi
### Mail sortant portant une signature DKIM
match tag DKIM for any action "envoi"
match auth tag DKIM from any for any action "envoi"
### backup pour les copains
match from any for domain copain.eu action relaybackup
### Mail en envoi pas encore signe avec DKIM
match auth from any for any action dkimproxy
match for any action dkimproxy

/etc/mail/domains

Indiquez ici tous vos champs MX.

chezmoi.tld 
domaine2.net 
autredomaine.xyz 

/etc/mail/spamd.conf

all:\
        :nixspam:bgp-spamd:bsdlyblack:whitelist:
# Nixspam recent sources list.
# Mirrored from http://www.heise.de/ix/nixspam
nixspam:\
        :black:\
        :msg="Your address %A is in the nixspam list\n\
        See http://www.heise.de/ix/nixspam/dnsbl_en/ for details":\
        :method=http:\
        :file=www.openbsd.org/spamd/nixspam.gz
bsdlyblack:\
        :black:\
        :msg="Your address %A is in the bsdly.net list":\
        :method=http:\
        :file=www.bsdly.net/~peter/bsdly.net.traplist
bgp-spamd:\
         :black:\
         :msg="Your address %A has sent mail to a spamtrap\n\
          within the last 24 hours":\
         :method=file:\
         :file=/var/spamd.black
whitelist:\
        :white:\
        :method=file:\
        :file=/etc/mail/whitelist.txt

/etc/webalizer.conf

  LogFile        /var/www/logs/access.log
  OutputDir      /var/www/htdocs/chezmoi.tld/stats
  ReportTitle    Statistiques pour 
  HostName  chezmoi.tld
  HTMLHead <style type="text/css"> body { background: white }
  HTMLHead tr:nth-child(even) {background: #333}
  HTMLHead tr:nth-child(odd) {background: #222}
  HTMLHead </style>
  LinkReferrer  yes
  TopSites        75
  TopURLs         50
  TopReferrers    100
  AllSites  yes
  AllURLs   yes
  AllReferrers  yes
  AllSearchStr  yes
  AllErrors      yes
  HideSite  *chezmoi.tld
  HideReferrer  chezmoi.tld
  HideURL       *.gif
  HideURL       *.GIF
  HideURL       *.jpg
  HideURL       *.JPG
  HideURL       *.png
  HideURL       *.PNG
  HideURL       *.ra
  HideURL       *.css
  HideURL       *.woff
  GroupReferrer google. Google Intl
  HideReferrer google.
  IgnoreURL /favicon.ico
  IgnoreURL /robots.txt
  ColorBackground           ECEDEE
  ColorText              eeeeee
  ColorLink              28952D
  ColorVLink             336799
  ColorALink             28952D
  ColorHeadline          444444
  ColorCounter           555555
  ColorHit          172C39
  ColorFile         072F63
  ColorSite         50504A
  ColorKbyte            BCB2A0
  ColorPage         7B717D
  ColorVisit            DCB647
  ColorMisc              95B8D4
  ChartBackgroundColor   333333
  ChartLegendColor       eeeeee
  ChartShadowColor1      333333
  ChartShadowColor2      333333
  TableBorder     0
  ChartBorder    0

Version à imprimer / PDF

Suivez ce lien pour voir toute cette documentation sur une seule page.

Si vous souhaitez lire ce document hors-ligne, l'imprimer en entier ou en garder une copie, vous pouvez utiliser le menu "Imprimer" de votre navigateur pour obtenir un fichier PDF de qualité (le code CSS est prévu pour 😉).

Contribuer

Vous pouvez si vous le souhaiter contribuer en faisant un petit don :

Via Paypal

Ou par un autre moyen 😉

Merci de bien vouloir m'aider !

Archive des sources

Si vous remarquez une erreur ou voulez proposer une modification, merci de respecter les conventions suivantes pour garder une certaines cohérence:

Envoyez vos modifications à prx@si3t.ch.

Remerciements

Solène Rapenne

Vincent Finance

Stéphane aka 22decembre

PengouinBSD

Péhä

Fred Galusik

Merci à Stéphane aka 22décembre (contributeur infatiguable sur les DNS et le réseau), PengouinBSD, Péhä (à l'origine des dessins), Fred Galusik, kuniyoshi, Vincent Finance, Solène Rapenne, (j'en oublie certainement 😅), mon ami JB que j'aime malgré son OS.

Et puisque j'aime garder le meilleur pour la fin, un merci rien que pour ma super geekette qui reboote le serveur quand il est down en mon absence et fait semblant de s'intéresser à ce que raconte ce manuel.