---
categories: ['OpenBSD','Réseau','Serveur']
date: 2022-05-01T12:12:22+02:00
description: "Installer le serveur V'Ger, pour voyager sur le protocol Gemini"
draft: false
include_toc: true
show_comments: false
tags: ['Gemini','VGer','OpenBSD','PF','nginx','relayd']
title: "V'Ger Voyager / Gemini (OpenBSD)"
translationKey: 'vger-openbsd'
---
## Description
**V'Ger** est le projet de serveur de publication sur le protocol Gemini,
écrit en C. Écrit pour OpenBSD, il bénéficie des mesures de protections,
liées à pledge(4) et unveil(4).
Dans cet article, nous aborderons l'installation et la configuration de
ce service. Puis nous verrons comment configurer **relayd** ou **nginx**
en tant que proxy relais ; et nous finirons par quelques règles pour
Packet-Filter.
OpenBSD : 6.9 → 7.3
---
- Auteure du projet **V'Ger** : Solène Rapenne
- Disponible en tant que paquet : https://openports.pl/path/net/vger
- URL du dépôt Git : https://tildegit.org/solene/vger
## Installation
Puisque V'Ger est disponible dans les ports,
{{< inside2 l="sys/openbsd/pkg" t="installez" a="installer" >}} le paquet **vger**.
---
*Autrement vous pouvez toujours l'installer depuis le dépôt Git… mais là,
je vous renvoie à la documention du dépôt*.
## Configuration
Pré-requis :
- changez les termes 'addresse_ipv4', 'addresse_ipv6' et 'nom_domaine',
par ce qui correspond à votre contexte de serveur !
### Utilisateur dédié _vger
Créons en tout premier un utilisateur dédié, nommé **_vger** :
`$ doas useradd -d /var/gemini -s /sbin/nologin _vger`
*(dans la documentation officielle, le nom de l'utilisateur est **_gemini**)*.
### Système
Il nous faut créer le répertoire `/var/gemini` puis appliquer les droits
à l'utilisateur dédié :
```sh
$ doas mkdir -p /var/gemini/nom_domaine
$ doas chown -R _vger /var/gemini
```
### inetd
- Fichier de configuraton : `/etc/inetd.conf`
Le service inetd est chargé de l'écoute active sur l'interface localhost
puis appelle le binaire vger pour délivrer le contenu.
Configurons maintenant le service **inetd** :
```cfg
1965 stream tcp nowait _vger /usr/local/bin/vger vger -d /var/gemini -v
1965 stream tcp6 nowait _vger /usr/local/bin/vger vger -d /var/gemini -v
```
- le port d'écoute est le **1965** - *(dans la documentation officielle,
le port par défaut est **11965**)*.
- géré par l'utilisateur **_vger**, appelant le binaire `vger`.
⇒ activons et démarrons le service :
```sh
$ doas rcctl enable inetd && doas rcctl start inetd
```
### certificats SSL
Cet article ne présente pas comment obtenir les certificats SSL, mais vous
pouvez les obtenir, soit depuis le client acme secure, natif sous OpenBSD,
soit à partir du paquet certbot.
En premier, il semble **nécessaire de créer le répertoire `private` dans `/etc/ssl`**.
```sh
$ doas mkdir -p /etc/ssl/private
```
#### acme
La documentation officielle informe de lier les certificats SSL, générés
par le client sécurisé acme sous OpenBSD.
Si c'est votre cas :
```sh
$ doas ln -s /etc/ssl/acme/cert.pem /etc/ssl/nom_domaine.crt
$ doas ln -s /etc/ssl/acme/private/privkey.pem /etc/ssl/private/nom_domaine.key
```
#### certbot
Dans mon contexte de serveur, les certificats sont générés par le client
certbot, disponible officiellement dans les ports. Une fois les certificats
générés par certbot, les liens symboliques à créer sont de cette forme :
```sh
$ doas ln -s /etc/letsencrypt/live/nom_domaine/cert.pem /etc/ssl/nom_domaine.crt
$ doas ln -s /etc/letsencrypt/live/nom_domaine/privkey.pem /etc/ssl/private/nom_domaine.key
```
### relayd
- Fichier de configuration : `/etc/relayd.conf` - chmod **0600** !
**relayd** est le service de relais-proxy natif sous OpenBSD.
La configuration du service relayd peut se faire ainsi - *dans cet exemple,
à la fois pour Ipv4|6* - :
```cfg
log connection
table { 127.0.0.1, ::1 }
tcp protocol "gemini" {
tls keypair nom_domaine
}
relay "gemini" {
listen on nom_domaine port 1965 tls
protocol "gemini"
forward to port 1965
}
```
⇒ Vérification de la configuration :
```sh
$ doas relayd -n
host_dns: nom_domaine resolves to more than 1 hosts
configuration OK
```
⇒ activons et démarrons le service :
```sh
$ doas rcctl enable relayd && doas rcctl start relayd
```
### nginx
- Fichier de configuration : `/etc/nginx.conf`
**nginx** peut lui aussi servir de proxy relais, en lieu et place de **relayd** ;
mais il est nécessaire d'installer en plus le paquet **nginx-stream**.
Puis il faut modifier la configuration pour y ajouter, en début de fichier,
avant la directive `http` :
`load_module "modules/ngx_stream_module.so";`
Ensuite, il est nécessaire de rajouter les déclarations suivantes en utilisant
la directive `stream` :
```cfg
stream {
log_format basic '$remote_addr $upstream_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time';
access_log logs/nom_domaine/access.gemini.log basic;
upstream backend_ipv4 {
hash $remote_addr consistent;
server 127.0.0.1:1965;
}
upstream backend_ipv6 {
hash $remote_addr consistent;
server [::1]:1965;
}
map $server_addr $backend {
addresse_ipv4 backend_ipv4;
addresse_ipv6 backend_ipv6;
}
server {
listen addresse_ipv4:1965 ssl;
listen [addresse_ipv6]:1965 ssl;
ssl_certificate /etc/letsencrypt/live/nom_domaine/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nom_domaine/privkey.pem;
ssl_ciphers TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_ecdh_curve X25519:P-521:P-384:P-256;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.3 TLSv1.2;
proxy_pass $backend;
}
}
```
Quelques petites explications :
- en rapport avec les directives `listen`, si vous ne déclarez pas l'adresse
IP correspondante, tel que `listen 1965 ssl;`, il faudra impérativement
rediriger le port sur un autre numéro de port puis reconfigurer `inetd.conf`
pour qu'il écoute sur ce même autre numéro de port. En effet, si l'adresse
IP d'écoute n'est pas spécifiée dans la directive `listen`, nginx cherchera
à écouter sur toutes les interfaces réseaux configurées et ne pourra redémarrer
car inetd écoute déjà sur l'interface localhost.
- deux directives `upstream` sont déclarées, chacune pour gérer correctement
le protocole IPv4 ou IPv6, et sont mappées pour n'avoir qu'un seul proxy
à appeler.
- un dernier mot, concernant les directives `ssl_ciphers`, `ssl_ecdh_curve`,
`ssl_prefer_server_ciphers`, et `ssl_protocols`, elles ne sont pas strictement
nécessaires mais utiles pour renforcer les préférences d'utilisation.
`ssl_protocols` permet de prioriser la version de TLS, sachant que :
> Servers MUST use TLS version 1.2 or higher and SHOULD use TLS version 1.3 or higher.
### PF
Voici un exemple de règles minimalistes à ajouter à PF :
```cfg
host = adresse_ipv4
host6 = adresse_ipv6
pass in quick on egress proto tcp from any to { $host $host6 } port 1965
```
Pensez à recharger le jeu de règles par PF :
`$ doas pfctl -f /etc/pf.conf`
---
Voilà !
Il ne vous reste plus qu'à créer votre premier fichier `index.gmi` et les
suivants et les déposer dans le répertoire correspondant à votre répertoire
de publication… en n'oubliant pas de poser les droits de l'utilisateur
dédié dessus.
## Surveillance
> Mais qui surveille ?
⇒ L'activité est enregistrée dans les deux logs 'daemon' et 'messages'.
```sh
$ grep vger /var/log/messages
May 1 10:54:28 sh1 useradd[86659]: new group added: name=_vger, gid=1011
May 1 10:54:28 sh1 useradd[86659]: new user added: name=_vger, uid=1011, gid=1011, home=/var/gemini, shell=/sbin/nologin
May 1 12:09:53 sh1 vger: request gemini://huc.fr.eu.org/
May 1 13:00:59 sh1 vger: request gemini://huc.fr.eu.org/
```
⇒ Il est possible de surveiller l'activité de l'utilisateur **_vger**
avec - *mais dans ce cas, franchement peu utile* :
- `top -U _vger`
- `fstat -u _vger -n`
- `ps aux -U _vger`
## Dépannage
⇒ Pour vérifier que le service inetd écoute en local, il est possible de
lui envoyer la requête suivante :
```sh
$ printf '%s\r\n' "gemini://huc.fr.eu.org" | vger -v -d /var/gemini
20 text/gemini;
# huc.fr.eu.org|gemini
(…)
```
- Si la réponse est similaire, c'est que vger écoute bien en local !
- Si vous avez pour réponse `telnet: Unable to connect to remote host: Connection refused`,
c'est certainement soit que le service `inetd` ne peut répondre - est-il
actif ? ou qu'il y a un problème dans sa configuration. Vérifiez !
---
⇒ Vérifier que le port 1965 soit ouvert en écoute sur vos adresses IP :
```sh
$ netstat -ant | grep 1965
tcp 0 0 *.1965 *.* LISTEN
tcp 0 0 46.23.90.29.1965 *.* LISTEN
tcp6 0 0 2a03:6000:6e65:6.1965 *.* LISTEN
tcp6 0 0 *.1965 *.* LISTEN
```
---
⇒ Pour finir, vous pouvez vérifier avec l'outil `telnet` sur le port 1965,
en local et depuis une autre machine que le service écoute.
## Documentations
- l'article de Solène à-propos de [
Nginx as a TCP/UDP relay](https://dataswamp.org/~solene/2021-02-24-nginx-stream.html) *- en anglais*
- la documentation du protocol Gemini : https://gemini.circumlunar.space/docs/ *- en anglais*
- [Readme du paquet certbot](https://openports.pl/path/security/letsencrypt/client)
### Manpages
- {{< man pledge 4 >}}, {{< man unveil 4 >}}
- une fois installé le manpage : `man 8 vger`
- le fichier pkg-readme dans `/usr/local/share/doc/pkg-readmes/vger`
---