---
title: Vérification indépendante du fonctionnement d'IPSec sous FreeBSD
authors:
  - author: David Honig
    email: honig@sprynet.com
releaseinfo: "$FreeBSD$" 
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:
:toc-title: Table des matières
:part-signifier: Partie
:chapter-signifier: Chapitre
:appendix-caption: Annexe
:table-caption: Tableau
:example-caption: Exemple

include::shared/fr/urls.adoc[]

[.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 `<blackend@FreeBSD.org>`.

'''

toc::[]

== Le problème

Tout d'abord, supposons que vous avez <<ipsec-install>>. Comment savez-vous si cela <<caveat>>? 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. <<code>> 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 <<kernel>>.

La commande

[source,bash]
....
 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 à <<tcpdump>>.
. 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 <<code>> 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,bash]
....
% 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 link:{handbook}#ipsec[Manuel de Freebsd].

[[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<<L)
#define Q (10*V)
#define K (100   *Q)
#define MAXSAMP (Q + K)

#include <stdio.h>
#include <math.h>

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;
        }
      }
    }
  }
}
....
