266 lines
7.7 KiB
Text
266 lines
7.7 KiB
Text
---
|
|
title: Verificación independiente de la funcionalidad de IPsec en FreeBSD
|
|
authors:
|
|
- author: David Honig
|
|
email: honig@sprynet.com
|
|
releaseinfo: "$FreeBSD$"
|
|
trademarks: ["freebsd", "opengroup", "general"]
|
|
---
|
|
|
|
= Verificación independiente de la funcionalidad de IPsec en FreeBSD
|
|
:doctype: article
|
|
:toc: macro
|
|
:toclevels: 1
|
|
:icons: font
|
|
:sectnums:
|
|
:sectnumlevels: 6
|
|
:source-highlighter: rouge
|
|
:experimental:
|
|
:lang: es
|
|
:toc-title: Tabla de contenidos
|
|
:part-signifier: Parte
|
|
:chapter-signifier: Capítulo
|
|
:appendix-caption: Apéndice
|
|
:table-caption: Tabla
|
|
:figure-caption: Figura
|
|
:example-caption: Ejemplo
|
|
|
|
include::shared/es/urls.adoc[]
|
|
|
|
[.abstract-title]
|
|
Resumen
|
|
|
|
Instaló IPsec y parece estar funcionando. ¿Cómo lo sabe? Describo un método para verificar de forma experimental que IPsec está funcionando.
|
|
|
|
'''
|
|
|
|
toc::[]
|
|
|
|
[[problem]]
|
|
== El problema
|
|
|
|
Primero, asumamos que ha <<ipsec-install>>. ¿Cómo sabe que está <<caveat>>? Claro, su conexión no funcionará si está mal configurada, y funcionará cuando finalmente lo haga bien. man:netstat[1] la listará. ¿Pero puede confirmarlo de forma independiente?
|
|
|
|
[[solution]]
|
|
== La solución
|
|
|
|
Primero, alguna información teórica relevante sobre criptografía:
|
|
|
|
. Los datos cifrados se distribuyen uniformemente, es decir, tienen una entropía máxima por símbolo;
|
|
. Los datos sin procesar y sin comprimir suelen ser redundantes, es decir, tienen una entropía submáxima.
|
|
|
|
Suponga que usted pudiera medir la entropía de los datos que van hacia -y desde- su interfaz de red. Entonces podría ver la diferencia entre los datos no cifrados y los cifrados. Esto sería verdad incluso si algunos de los datos en "modo cifrado" no lo estuvieran---ya que el encabezado IP más externo debe estarlo para que el paquete sea enrutable.
|
|
|
|
[[MUST]]
|
|
=== MUST
|
|
|
|
El "Universal Statistical Test for Random Bit Generators" (https://web.archive.org/web/20011115002319/http://www.geocities.com/SiliconValley/Code/4704/universal.pdf[MUST]) de Ueli Maurer mide rápidamente la entropía de una muestra. Utiliza un algoritmo de compresión. <<code>> para una variante que mide partes sucesivas (~cuarto de megabyte) de un archivo
|
|
|
|
[[tcpdump]]
|
|
=== Tcpdump
|
|
|
|
También necesitamos una forma de capturar los datos de red sin procesar. Un programa llamado man:tcpdump[1] le permite hacerlo, si tiene habilitada la interfaz de _Berkeley Packet Filter_ en el <<kernel>>.
|
|
|
|
El comando:
|
|
|
|
[source,shell]
|
|
....
|
|
tcpdump -c 4000 -s 10000 -w dumpfile.bin
|
|
....
|
|
|
|
capturará 4000 paquetes sin procesar en el fichero _dumpfile.bin_. En este ejemplo se capturarán hasta 10.000 bytes por paquete.
|
|
|
|
[[experiment]]
|
|
== El experimento
|
|
|
|
Aquí está el experimento:
|
|
|
|
[.procedure]
|
|
====
|
|
. Abra una ventana a un host IPsec y otra ventana a un host inseguro.
|
|
. Ahora empiece a <<tcpdump>>.
|
|
. En la ventana "segura", ejecute el comando UNIX(R) man:yes[1], que transmitirá el carácter `y`. Después de un rato, detenga el comando. Cambie a la ventana insegura, y repita. Espere un poco, detenga el comando.
|
|
. Ahora ejecute <<code>> en los paquetes capturados. Debería ver algo como lo siguiente. Lo importante a tener en cuenta es que la conexión segura tiene un 93% (6,7) del valor esperado (7,18), y la conexión "normal" tiene un 29% (2,1) del valor esperado.
|
|
+
|
|
[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]]
|
|
== Advertencia
|
|
|
|
Este experimento muestra que IPsec _parece_ estar distribuyendo los datos de la carga útil __uniformemente__, como debe hacerlo el cifrado. Sin embargo, el experimento aquí descrito _puede no_ detectar muchas de las posibles fallas del sistema (para las cuales no tengo evidencias). Esto incluye la generación o intercambio de claves deficientes, datos o claves visibles para otros, uso de algoritmos débiles, subversión del kernel, etc. Estudie el código; conozca el código.
|
|
|
|
[[IPsec]]
|
|
== IPsec---Definición
|
|
|
|
Extensiones de seguridad del Protocolo de Internet para IPv4; requerido para IPv6. Un protocolo para negociar el cifrado y la autenticación a nivel de IP (host a host). SSL solo protege un socket de aplicación. SSH protege solo el login. PGP protege un archivo o mensaje específico. IPsec encripta todo entre dos hosts.
|
|
|
|
[[ipsec-install]]
|
|
== Instalando IPsec
|
|
|
|
La mayoría de las versiones modernas de FreeBSD soportan IPsec en su código base. Por lo tanto, deberá incluir la opción `IPSEC` en la configuración de su kernel y, después de recompilar y reinstalar el kernel, configure las conexiones de IPsec usando el comando man:setkey[8].
|
|
|
|
En el link:{handbook}#ipsec[Manual de FreeBSD] se proporciona una guía completa sobre cómo ejecutar IPsec en FreeBSD.
|
|
|
|
[[kernel]]
|
|
== src/sys/i386/conf/KERNELNAME
|
|
|
|
Esto debe estar presente en el archivo de configuración del kernel para capturar datos de red con man:tcpdump[1]. Asegúrese de ejecutar man:config[8] después de agregar esto, recompilar y reinstalar.
|
|
|
|
[.programlisting]
|
|
....
|
|
device bpf
|
|
....
|
|
|
|
[[code]]
|
|
== Maurer's Universal Statistical Test (tamaño de bloque=8 bits)
|
|
|
|
Puede encontrar el mismo código fuente en https://web.archive.org/web/20031204230654/http://www.geocities.com:80/SiliconValley/Code/4704/uliscanc.txt[este enlace].
|
|
|
|
[.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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
....
|