Je suis Charlie

Autres trucs

Accueil

Seulement les RFC

Seulement les fiches de lecture

Ève

Supervision de serveurs Web .onion (« darquenette »)

Première rédaction de cet article le 4 octobre 2017


Un certain nombre de webmestres configurent leur serveur Web pour être accessible via un nom en .onion. Le but principal est de résister aux tentatives de censure. Un tel service, si on est soucieux de qualité, doit être supervisé comme n'importe quel autre service. J'explique ici comment j'ai configuré cette supervision, avec le logiciel Icinga, et quelques leçons apprises à l'occasion.

Tout site Web peut être accédé via le réseau Tor si le visiteur veut garder son légitime anonymat, ou bien s'il veut échapper à certaines censures (comme un blocage de l'adresse IP du serveur). Il lui suffit d'installer le Tor Browser et hop. Mais cette technique ne protège que le client, elle ne protège pas le serveur. Des attaques côté serveur (saisie du nom de domaine, ou bien saisie du serveur physique) peuvent couper l'accès. D'où les noms de domaines en .onion (ce qu'on appelle parfois, bien à tort, « service caché », alors que ces services sont complètement publics et que même le Googlebot y passe). Avec une telle configuration (utilisée, par exemple, par mon blog), le risque de censure est bien plus faible (mais pas nul, attention, vous courrez quand même des risques). Les journalistes ont inventé le terme sensationnaliste de darknet (qui désignait à l'origine tout à fait autre chose) pour ces services, et les politiciens français l'ont traduit par « Internet clandestin », une traduction d'état d'urgence… (Et vraiment grotesque puisque tout le monde, vous, moi, la NSA, Google, peut visiter ces sites.)

De tels services sont de plus en plus nécessaires, et pas seulement si on est dissident en Iran, en Chine ou en Arabie saoudite. Les pays censés être démocratiques utilisent également la censure de l'Internet comme récemment en Espagne (contre le référendum catalan et donc en partie contre le .cat) ou en France avec la pérennisation de l'état d'urgence.

Donc, il est tout à fait justifié de configurer des services en .onion. Mais si on veut vérifier que ces services marchent bien ? Pour les services plus traditionnels (mettons un site Web classique), on utilise un logiciel de supervision. Mettons qu'on utilise, comme moi, Icinga (mais la technique expliquée ici devrait marcher avec n'importe quel logiciel de supervision compatible avec l'API de Nagios). Le script de test des serveurs HTTP est check_http, qui peut se tester depuis la ligne de commande :

% /usr/lib/nagios/plugins/check_http  -H www.elysee.fr        
HTTP OK: HTTP/1.1 200 OK - 684876 bytes in 0.791 second response time |time=0.791354s;;;0.000000;10.000000 size=684876B;;;0
    

Il est appelé régulièrement par Icinga pour tester le serveur, et déclencher une alarme si quelque chose va mal. Ce script utilise les bibliothèques « normales » du système, et ne connait pas le TLD « spécial » .onion :

% /usr/lib/nagios/plugins/check_http  -H 7j3ncmar4jm2r3e7.onion
Name or service not known
HTTP CRITICAL - Unable to open TCP socket
    

Si on fait tourner le client Tor sur sa machine, il exporte par défaut une interface SOCKS (paramètres SOCKSPort et SOCKSPolicy dans le fichier de configuration de Tor). Cela permet à certains programmes (ici, curl) d'accéder aux services en .onion :

    

% curl -v  7j3ncmar4jm2r3e7.onion 
...
curl: (6) Could not resolve host: 7j3ncmar4jm2r3e7.onion

Et avec la bonne option (Tor écoute par défaut sur le port 9050) :


% curl -v --socks5-hostname localhost:9050 7j3ncmar4jm2r3e7.onion 
...
* SOCKS5 communication to 7j3ncmar4jm2r3e7.onion:80
* SOCKS5 request granted.
* Connected to localhost (127.0.0.1) port 9050 (#0)
> GET / HTTP/1.1
> Host: 7j3ncmar4jm2r3e7.onion
> User-Agent: curl/7.55.1
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Fri, 22 Sep 2017 09:31:32 GMT
< Server: Apache
< Content-Type: text/html
< 
{ [3245 bytes data]
  0  425k    0  3245    0     0   3245      0  0:02:14  0:00:01  0:02:13  2414<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xml:lang="fr" lang="fr" xmlns="http://www.w3.org/1999/xhtml">
<head>
...

(Si vous avez un message d'erreur du genre « * connect to 127.0.0.1 port 9050 failed: Connection refused », c'est que le client Tor ne tourne pas sur votre machine - il ne s'agit pas du Tor Browser, mais d'un démon - ou bien qu'il écoute sur un autre port, vérifiez la configuration.)

Petit problème, le script check_http ne semble pas disposer d'une option SOCKS. Il faut donc utiliser une autre méthode, le programme torsocks qui redirige divers appels système pour que l'application parle à SOCKS en croyant parler directement au serveur HTTP. Pour curl, on aurait pu faire :

% torsocks curl -v 7j3ncmar4jm2r3e7.onion
    

On peut donc lancer le script de test des Monitoring Plugins :

    
% torsocks /usr/lib/nagios/plugins/check_http -H 7j3ncmar4jm2r3e7.onion
HTTP OK: HTTP/1.1 200 OK - 436330 bytes in 3.649 second response time |time=3.648528s;;;0.000000;10.000000 size=436330B;;;0

Maintenant que le test marche en ligne de commande, il n'y a plus qu'à configurer Icinga pour l'utiliser. On écrit un petit script shell :

    
% cat /usr/local/lib/nagios/plugins/check_http_onion
#!/bin/sh

/usr/bin/torsocks /usr/lib/nagios/plugins/check_http $*

Et on dit à Icinga de l'utiliser. Dans commands.conf :

object CheckCommand "http-onion" {

	command = [ PluginContribDir + "/check_http_onion" ]

	arguments = {
		"-H" = {
			value = "$http_vhost$"
			description = "Host name argument for servers using host headers (virtual host)"
		}
[On reprend verbatim les options de check_http, qui sont, sur une
Debian, dans /usr/share/icinga2/include/command-plugins.conf]

	vars.http_address = "$check_address$"
	vars.http_ssl = false
	vars.http_sni = false
	vars.http_linespan = false
	vars.http_invertregex = false
	vars.check_ipv4 = "$http_ipv4$"
	vars.check_ipv6 = "$http_ipv6$"
	vars.http_link = false
	vars.http_verbose = false
}

Et dans services.conf :

apply Service for (http_vhost => config in host.vars.http_onion_vhosts) {
  import "generic-service"

  check_command = "http-onion"

  vars += config
}
   

Avec ces définitions, je peux décider de superviser un service en mettant une entrée dans le vars.http_onion_hosts de la machine :

object Host "serveur-secret" {
  import "generic-host"

  ... [Autres tests]

  vars.http_onion_vhosts["onion"] = {
    http_uri = "/"
    http_vhost = "7j3ncmar4jm2r3e7.onion"
    http_ssl = false
    http_timeout = 15
    }
}
   

Ou bien en créant un host spécial :

object Host "internet-libre" {
  import "generic-host"

  check_command = "always_true"  /* No ping in Tor */

vars.http_onion_vhosts["aeris"] = {
    http_uri = "/"
    http_vhost = "aerisryzdvrx7teq.onion"
    http_ssl = false
    http_timeout = 15
    }

vars.http_onion_vhosts["amaelle"] = {
    http_uri = "/"
    http_vhost = "ozawuyxtechnopol.onion"
    http_ssl = false
    http_timeout = 15
    }

}
   

Ainsi configuré, Icinga va régulièrement tester ces services via Tor, et prévenir de la manière habituelle : icinga-onion.png

Alors, à l'usage, est-ce que ça marche ? Oui, au sens où je suis bien prévenu lorsqu'il y a un problème et Icinga teste bien et enregistre l'historique des pannes. Moins bien au sens où cette supervision révèle que Tor n'est pas parfaitement fiable, en tout cas vu de mon ADSL : les pannes temporaires sont relativement fréquentes (ce qui est logique, la requête étant acheminée par plusieurs nœuds Tor parfois lointains, et pas toujours stables). Cela peut donc valoir la peine de configurer le logiciel de supervision pour être moins prompt à lever une alarme pour ces services. Disons en gros une ou deux pannes d'environ dix minutes par jour, ce qui ne serait pas acceptable pour un serveur Web « normal ».

Ce qui est amusant est que, parfois, pendant une panne, le Tor Browser depuis le même réseau, arrive à se connecter au service. C'est probablement parce que le Tor Browser et le démon Tor utilisé par Icinga ont établi des circuits Tor différents (passant par des nœuds différents), et qu'un seul des circuits déconne.

Mille mercis à Lunar pour m'avoir tout expliqué patiemment (et, en plus, ça marche). Et merci aussi à Amaelle et Aeris pour m'avoir permis d'utiliser leurs serveurs pour les tests. Voici les trois serveurs en .onion qui ont été utilisé (les liens ne marcheront que si vous regardez cet article via Tor) :

Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)

Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)