--- title: Vérification indépendante du fonctionnement d'IPSec sous FreeBSD authors: - author: David Honig email: honig@sprynet.com trademarks: ["freebsd", "opengroup", "general"] --- = Vérification indépendante du fonctionnement d'IPSec sous FreeBSD :doctype: article :toc: macro :toclevels: 1 :icons: font :sectnums: :sectnumlevels: 6 :source-highlighter: rouge :experimental: :images-path: articles/ipsec-must/ ifdef::env-beastie[] ifdef::backend-html5[] include::shared/authors.adoc[] include::shared/mirrors.adoc[] include::shared/releases.adoc[] include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists.adoc[] include::shared/{{% lang %}}/urls.adoc[] :imagesdir: ../../../images/{images-path} endif::[] ifdef::backend-pdf,backend-epub3[] include::../../../../shared/asciidoctor.adoc[] endif::[] endif::[] ifndef::env-beastie[] include::../../../../../shared/asciidoctor.adoc[] endif::[] [.abstract-title] Résumé Vous avez installé IPSec et cela semble fonctionner. Comment pouvez-vous en être sûr? Je décris une méthode pour vérifier expérimentalement le fonctionnement d'IPSec. Version française de Marc Fonvieille ``. ''' toc::[] == Le problème Tout d'abord, supposons que vous avez <>. Comment savez-vous si cela <>? Bien sûr, votre connexion ne fonctionnera pas si elle est mal configurée, et fonctionnera quand vous l'aurez enfin correctement configurée. man:netstat[1] le fera apparaître. Mais pouvez-vous le confirmer de façon indépendante? == La solution Tout d'abord, quelques informations théoriques relatives à la cryptographie: . Les données chiffrées sont uniformément distribuées, i.e., ont une entropie maximale par symbole; . Les données brutes, non compressées sont en générale redondantes, i.e., n'ont pas une entropie maximale. Supposez que vous pourriez mesurer l'entropie des données à destination et en provenance de votre interface réseau. Alors vous pourriez voir la différence entre données non-chiffées et données chiffrées. Cela serait vrai même si certaines des données en "mode chiffré" n'étaient pas chiffrées --- comme l'en-tête IP externe, si le paquet doit être routable. [[MUST]] === MUST L'"Universal Statistical Test for Random Bit Generators"(http://www.geocities.com/SiliconValley/Code/4704/universal.pdf[MUST]) d'Ueli Maurer, ou encore le "test statistique universel pour les générateurs aléatoires de bits", mesure rapidement l'entropie d'un échantillon. Il utilise une sorte d'algorithme de compression. <> pour une variante qui mesure les morceaux (environ un quart de mégaoctet) successifs d'un fichier. [[tcpdump]] === Tcpdump Nous avons également besoin d'une manière de capturer les données réseau brutes. Un programme appelé man:tcpdump[1] vous permet de faire cela, si vous avez activé l'interface _Berkeley Packet Filter_ (Filtre de Paquet de Berkeley) dans votre <>. La commande [source,shell] .... tcpdump -c 4000 -s 10000 -w dumpfile.bin .... capturera 4000 paquets bruts dans le fichier _dumpfile.bin_. Dans cet exemple jusqu'à 10000 octets par paquets seront capturés. == L'expérience Voici l'expérience: [.procedure] ==== . Ouvrez une fenêtre sur un hôte IPSec et une autre sur un hôte non sécurisé. . Maintenant commencez à <>. . Dans la fenêtre "sécurisée", lancez la commande UNIX(R) man:yes[1], qui fera défiler le caractère `y`. Au bout d'un moment, arrêtez cela. Passez à la fenêtre non sécurisée, et faites de même. Au bout d'un moment, arrêtez. . Maintenant lancez <> sur les paquets capturés. Vous devriez voir quelque chose de semblable à ce qui suit. Ce qui est important de noter est que la connexion non sécurisée a 93% (6,7) de valeurs attendues (7,18), et la connexion "normale" a 29% (2,1) de valeurs attendues. + [source,shell] .... % tcpdump -c 4000 -s 10000 -w ipsecdemo.bin % uliscan ipsecdemo.bin Uliscan 21 Dec 98 L=8 256 258560 Measuring file ipsecdemo.bin Init done Expected value for L=8 is 7.1836656 6.9396 -------------------------------------------------------- 6.6177 ----------------------------------------------------- 6.4100 --------------------------------------------------- 2.1101 ----------------- 2.0838 ----------------- 2.0983 ----------------- .... ==== [[caveat]] == Mise en garde Cette expérience montre qu'IPSec _semble_ distribuer les données utiles _uniformément_ comme un chiffrement le devrait. Cependant, l'expérience décrite ici _ne peut pas_ détecter les problèmes possibles dans un système. Ceux-ci peuvent être la génération ou l'échange d'une clé faible, des données ou clés visibles par d'autres, l'utilisation d'algorithmes faibles, code du noyau modifié, etc... Etudiez les sources, maîtrisez le code. [[IPsec]] == IPSec - Définition Extensions de sécurité au protocole internet IPv4, requises pour l'IPv6. Un protocole pour le chiffrement et l'authentification au niveau IP (hôte à hôte). SSL sécurise uniquement une socket d'application; SSH sécurise seulement une session; PGP sécurise uniquement un fichier spécifique ou un message. IPSec chiffre tout entre deux hôtes. [[ipsec-install]] == Installation d'IPSec La plupart des versions récentes de FreeBSD ont le support IPSec dans leurs sources de base. Aussi vous devrez probablement ajouter l'option `IPSEC` dans votre configuration de noyau et, après la compilation et l'installation du noyau, configurer les connexions IPSec en utilisant la commande man:setkey[8]. Un guide complet sur l'utilisation d'IPSec sous FreeBSD est fourni dans le extref:{handbook}security[Manuel de Freebsd, ipsec]. [[kernel]] == src/sys/i386/conf/KERNELNAME Ce qui suit doit être présent dans le fichier de configuration du noyau afin de pouvoir capturer les données réseau avec man:tcpdump[1]. Soyez-sûr de lancer man:config[8] après avoir rajouté la ligne ci-dessous, et de recompiler et réinstaller. [.programlisting] .... device bpf .... [[code]] == Test statistique universel de Maurer (pour une longueur de bloc=8 bits) Vous pouvez trouver le même code source http://www.geocities.com/SiliconValley/Code/4704/uliscanc.txt[ici]. [.programlisting] .... /* ULISCAN.c ---blocksize of 8 1 Oct 98 1 Dec 98 21 Dec 98 uliscan.c derived from ueli8.c This version has // comments removed for Sun cc This implements Ueli M Maurer's "Universal Statistical Test for Random Bit Generators" using L=8 Accepts a filename on the command line; writes its results, with other info, to stdout. Handles input file exhaustion gracefully. Ref: J. Cryptology v 5 no 2, 1992 pp 89-105 also on the web somewhere, which is where I found it. -David Honig honig@sprynet.com Usage: ULISCAN filename outputs to stdout */ #define L 8 #define V (1< #include int main(argc, argv) int argc; char **argv; { FILE *fptr; int i,j; int b, c; int table[V]; double sum = 0.0; int iproduct = 1; int run; extern double log(/* double x */); printf("Uliscan 21 Dec 98 \nL=%d %d %d \n", L, V, MAXSAMP); if (argc < 2) { printf("Usage: Uliscan filename\n"); exit(-1); } else { printf("Measuring file %s\n", argv[1]); } fptr = fopen(argv[1],"rb"); if (fptr == NULL) { printf("Can't find %s\n", argv[1]); exit(-1); } for (i = 0; i < V; i++) { table[i] = 0; } for (i = 0; i < Q; i++) { b = fgetc(fptr); table[b] = i; } printf("Init done\n"); printf("Expected value for L=8 is 7.1836656\n"); run = 1; while (run) { sum = 0.0; iproduct = 1; if (run) for (i = Q; run && i < Q + K; i++) { j = i; b = fgetc(fptr); if (b < 0) run = 0; if (run) { if (table[b] > j) j += K; sum += log((double)(j-table[b])); table[b] = i; } } if (!run) printf("Premature end of file; read %d blocks.\n", i - Q); sum = (sum/((double)(i - Q))) / log(2.0); printf("%4.4f ", sum); for (i = 0; i < (int)(sum*8.0 + 0.50); i++) printf("-"); printf("\n"); /* refill initial table */ if (0) { for (i = 0; i < Q; i++) { b = fgetc(fptr); if (b < 0) { run = 0; } else { table[b] = i; } } } } } ....