# GNUnet

GNUnet est un réseau informatique pair à pair garantissant l'anonymat, n'utilisant aucun service centralisé ou autre service de confiance. Une première mise en œuvre au-dessus de la couche réseau permet un partage de fichier anonyme et résistant à la censure. GNUnet utilise un système simple utilisant un modèle économique d'allocation des ressources fondé sur l'excès. Les nœuds GNUnet prennent en compte les demandes des autres nœuds avec un respect des ressources disponibles ; les nœuds contribuant au réseau sont récompensés par un service de meilleure qualité.

## Histoire de GNUnet

GNUnet a été lancé fin 2001 avec un ensemble de nouvelles idées techniques, issues d'une publication académique, pour gérer des réseaux pair à pair sécurisés. Ces idées incluent un codage résistant à la censure (ERCS : Encoding for Censorship-Resistant Sharing) et un nouveau protocole pour le routage anonyme (gap). Au démarrage du projet GNUnet, des systèmes existants ont été étudiés (à l'époque en particulier Freenet et mnet) afin de fixer un point de départ. Cependant, il a été conclu que le système envisagé était bien trop loin des codes existants pour pouvoir être construit sur la base de l’un d’entre eux.
Les développeurs de GNUnet avaient l’ambition de créer une bonne infrastructure générale pour développer de nouveaux protocoles pair à pair. C'est pourquoi il a été conçu pour être facilement extensible afin d'intégrer de nouvelles applications pair à pair ou d'ajouter des couches de transport alternatives au système de base.
Le projet continue à évoluer en termes d’idées techniques et d’implémentation, souvent grâce aux discussions avec les développeurs de projets similaires. Le plus connu de ces projets est probablement Tor.
GNUnet reste néanmoins à l'état de version bêta. Des modifications majeures sont toutefois apportées fin 2011 avec notamment le support des architectures multi-processeurs grâce au superviseur ARM ce qui permet à chaque processus dans GNUnet de fonctionner séparément comme dans un système d'exploitation. D'autres nouveautés sont à cette occasion annoncées comme l'utilisation de tunnels VPN qui peuvent désormais encapsuler le trafic dans le protocole HTTPS et opérer sur une topologie mesh.

## Fonctionnement de GnuNet

GnuNet est un réseau P2P anonyme. Sur chaque nœud du réseau, tourne le noyau de GnuNET : gnunetd. Gnunetd est responsable de l'envoi et de la réception de messages (chiffrés) vers les autres pairs. Il est également responsable de l'allocation de la bande passante et de la planification des envois de messages. Enfin, la dernière fonction du noyau est le chargement des modules logiciels. Gnunetd ne fait rien de plus. Les applications (comme le partage de fichiers), sont construites au-dessus du noyau. Ce dernier n'a donc aucune notion de partage de fichiers par exemple.

### Fonctionnement des applications

GNUnet scinde les applications en deux parties principales.
* La première partie se compose de services d'application. Un service (ou module) est une bibliothèque dynamique qui se greffe au noyau. Typiquement, un module définit une unique fonction invoquée au démarrage du noyau. Cette fonction enregistre d'autres fonctions destinées à gérer certains messages pair à pair. La fonction correspondante sera appelée à chaque fois qu'un message pair à pair ayant le bon identificateur sera reçu. Par exemple, l'application de partage de fichiers (FS) utilise le service GAP pour le routage et le service sqstore pour la base de données. Un autre exemple de service est le service RPC (Remote Procedure Call) qui permet de renforcer la fiabilité de la couche réseau.
* La seconde partie de l'application est invoquée par l'utilisateur et fournit une interface au service. L'idée est que l'utilisateur lance un programme bien distinct du noyau gnunetd (exemple gnunet-gtk) pour accéder au service qu'il souhaite. L'interaction avec la première partie se fait via une connexion TCP locale (donc de confiance).

### Les protocoles de communication

Le fonctionnement de GnuNet requiert l'utilisation de protocoles de communication dans trois contextes distincts. Le protocole pair à pair définit la façon dont les nœuds du réseau échangent de l'information. Le protocole Client-Serveur permet à l'utilisateur de dialoguer avec le démon gnunetd de sa machine (via des clients gnunet). Enfin, la troisième famille de protocoles est utilisée par la couche transport et sert à encapsuler les messages pair à pair.

#### Le protocole Pair à pair

Ce protocole est la base du réseau GNUnet. Il définit 7 messages distincts (HELLO, SETKEY, PING, PONG, FRAGMENT, NOISE, HANGUP), qui doivent être supportés par tous les pairs. En général, ces messages ne sont pas tous implémentés par le noyau lui-même, mais plutôt par des greffons internes de services. Néanmoins, le chargement de ces services n’est pas optionnel (le noyau les chargera automatiquement au démarrage).

#### Informer de son existence sur le réseau

Quand un hôte arrive sur le réseau, pour informer de son existence, il envoie d'abord un HELLO à n’importe quel autre hôte pour l’informer de son existence sur le réseau. En effet, un paquet HELLO sert à propager l’information sur les nœuds participant au réseau GNUnet. Chaque nœud de GNUnet est identifié par sa clé publique K (clé RSA de 2048 bits). Le paquet HELLO est une manière pour les nœuds de propager les clés publiques des autres nœuds. De plus, l’identité d’un nœud est liée à une adresse. La façon dont une adresse est spécifiée dépend du mécanisme de transport sous-jacent utilisé. Les nœuds GNUnet peuvent avoir plusieurs adresses et en changer à tout moment, par exemple si l’adresse est attribuée dynamiquement avec DHCP. Le message HELLO est utilisé pour informer les autres hôtes d’un changement d’adresse. Cette adresse est signée avec la clef privée du nœud afin d'éviter la diffusion d'adresses truquées sur le réseau. L'hôte récepteur d’un HELLO retourne un PING pour confirmer qu’il est joignable. Le receveur du PING renvoie alors toujours un PONG pour confirmer la réception. Ce ping-pong a pour but d'éviter que des hôtes envoient des messages HELLO valides et signés avec des adresses IP de machines non participantes. GNUnet se défend contre ce type d’attaques en envoyant un PING au présumé hôte et ne fait confiance qu’au PONG reçu. Ainsi, l’hôte malveillant qui envoie de faux HELLO échouera dans sa tentative de berner GNUnet en le faisant essayer de se connecter de manière répétitive à des hôtes qui ne sont pas connectés.

#### Établir une connexion

Une session entre deux nœuds GNUnet utilise un chiffrement symétrique (AES-256) et consiste en une paire de clés de session de 256 bits. Pour établir la connexion, un des nœuds envoie à l'autre un SETKEY (qui contient une clé de session) et un PING chiffré (qui contient juste un nombre aléatoire). Les SETKEY sont toujours chiffrés avec la clé publique du nœud qui reçoit. L’expéditeur d’une clé de session chiffre non seulement la clé avec la clé publique du récepteur mais la signe également (et ajoute un temps de création) avec sa propre clé privée. La clé transmise est la clé que l’émetteur utilisera dans le futur pour chiffrer ses messages. Le PING est chiffré avec la clef de session transmise. L'autre nœud doit ensuite répondre avec autre un SETKEY (contenant sa clé de session), un PING (chiffré avec cette même clef) et un PONG (chiffré de la même façon que le PING) en réponse au PING qu'il vient de recevoir. Enfin, le premier nœud répond au PING qu'il vient de recevoir par un PONG chiffré avec sa clef de session.
Le message PONG qui répond à un message PING doit contenir le même nombre aléatoire. Le nombre aléatoire a pour but de rendre impraticable pour un adversaire de truquer une réponse PONG à un PING.
Quand un nœud a reçu le PONG qu'il attendait, il peut commencer à communiquer sur le canal chiffré en utilisant sa clef de session.

#### Échange de messages

Quand la connexion est établie, les nœuds peuvent échanger des messages spécifiques. Un paquet échangé entre des hôtes GNUnet peut contenir autant de messages que nécessaire (la limite est fixée par la MTU de la couche transport).
En plus de chiffrer le message, le noyau GNUnet ajoute une somme de contrôle, des informations de limitation de bande passante et des informations de séquence pour éviter que le même message soit traité plusieurs fois. Le chiffrement, le déchiffrement et la vérification sont effectués par le noyau GNUnet ; ni l’application ni le code de transport ne sont concernés. Une session expire si elle reste inactive (typiquement au bout de 15 minutes)

##### Les autres messages noyau

* HANGUP
Message pour fermer la connexion entre 2 nœuds. Il n'est ni acquitté ni nécessaire puisque les sessions expirent.
* FRAGMENT
Message utilisé pour communiquer des messages de taille supérieure à la MTU.
* NOISE
Afin de rendre l’analyse de trafic plus difficile pour les adversaires, les nœuds ajoutent du bruit aux paquets qui sont courts pour rendre tous les paquets de taille uniforme. Certains messages peuvent ne contenir que du bruit et le nœud qui les reçoit doit juste les ignorer en silence.

#### Le protocole Client-Serveur

C'est une connexion TCP locale de confiance car elle est locale. La liste des adresses IP autorisées est présente dans un fichier de configuration. Elle sert pour la communication entre le noyau GNUnet (et les services qu'il a chargé) et la partie interface utilisateur d'une application.

#### Les protocoles de la couche transport

GNUnet emploie un type spécial de messages (HELLO) pour lier des clés publiques à leur adresse courante. Chaque nœud GNUnet doit avoir au moins une adresse. Les mécanismes de transport peuvent employer diverses formes d’adresses. Notez que les nœuds peuvent avoir des adresses multiples pour les divers mécanismes de transport qu’ils utilisent. La couche transport a, comme le protocole internet IP, une sémantique du meilleur effort. Il n’y a pas de garantie qu’un message sera bien acheminé.

##### UDP, TCP et HTTP

Les protocoles UDP, TCP, HTTP, HTTPS sont utilisables en tant que couche transport pour GNUnet. Pour ces protocoles, une adresse consiste en une adresse IPv4 (et/ou IPv6) et un port.

##### SMTP

SMTP peut être utilisé pour envoyer un message à un nœud situé derrière un routeur NAT et qui a un adressage dynamique, pour renseigner le nœud pour qu'il établisse une connexion TCP avec un nœud en dehors du réseau privé virtuel. Même une surcharge extraordinaire du réseau pour ce premier message ne serait pas gênante dans ce type de situation.

##### Autres protocoles

Il est aussi possible d’écrire votre propre mécanisme de transport pour le réseau GNUnet. Les quatre précédemment cités sont pour l'instant les seuls disponibles.
GnuNet comporte aussi un système de nommage alternatif au DNS : le GNU Name System.

## Quelques options de GNUnet

* GNUnet propose bien évidemment une application de partage de fichiers (sécurisée) en pair à pair appelée FS.
* GNUnet propose une option "F2F topology" pour construire des réseaux de type ami à ami.
* En plus de l'utilisation en interface en ligne de commande, GNUnet propose trois interfaces graphiques :
* gnunet-gtk (la plus souvent utilisée)
* gnunet-fuse
* gnunet-qt