--- 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.4 --- - 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 -an | 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` ---