Réseau de test isolé sur un serveur Linux exécutant un serveur web (lightttpd) et des clients (curl)

StackOverflow https://stackoverflow.com//questions/12671587

Question

J'écris un outil de test qui nécessite que le trafic connu soit capturé à partir d'une carte réseau (à l'aide de libpcap), puis introduit dans l'application que nous essayons de tester.

Ce que j'essaie de configurer, c'est un serveur Web (dans ce cas, lighttpd) et un client (curl) fonctionnant sur la même machine, sur un réseau de test isolé.Un script pilotera l'ensemble de la configuration, et l'objectif est de pouvoir spécifier un certain nombre de clients ainsi qu'un ensemble de fichiers pour chaque client à télécharger depuis le serveur Web.

Mon approche initiale consistait simplement à utiliser l'interface loopback (lo)...exécutez le serveur Web sur 127.0.0.1, demandez aux clients de récupérer leurs fichiers depuis http://127.0.0.1, et exécutez mon outil basé sur libpcap sur l'interface lo.Cela fonctionne bien, mis à part le fait que l'interface de bouclage n'émule pas une véritable interface Ethernet.Le principal problème est que les paquets sont tous de tailles incohérentes...32 Ko et plus, et quelque peu aléatoire...il n'est pas non plus possible de baisser le MTU sur lo (enfin, vous pouvez, mais cela n'a aucun effet !).

J'ai également essayé de l'exécuter sur ma vraie interface (eth0), mais comme il s'agit d'un client Web interne parlant à un serveur Web interne, le trafic ne quitte jamais l'interface, donc libpcap ne le voit jamais.

Alors je me suis tourné vers Tun/Tap.J'ai utilisé socat pour lier deux interfaces tun avec une connexion TCP, donc en fait, j'avais :

10.0.1.1/24 <-> tun0 <-socat-> tcp connection <-socat-> tun1 <-> 10.0.2.1/24

Cela semble être une solution vraiment intéressante...Les appareils tun/tap émulent de vrais appareils Ethernet, je peux donc exécuter mon serveur Web sur tun0 (10.0.1.1) et mon outil de capture sur tun0, et lier mes clients à tun1 (10.0.2.1)...Je peux même utiliser tc pour appliquer des règles de mise en forme à ce trafic et créer un WAN virtuel dans ma machine Linux...mais ça ne marche tout simplement pas...

Voici les commandes socat que j'ai utilisées :

$ socat -d TCP-LISTEN:11443,reuseaddr TUN:10.0.1.1/24,up &
$ socat TCP:127.0.0.1:11443 TUN:10.0.2.1/24,up &

Ce qui produit 2 interfaces Tun (tun0 et tun1), avec leurs adresses IP respectives.

Si je cours ping -I tun1 10.0.1.1, il n'y a pas de réponse, mais quand je tcpdump -n -i tun0, je vois les requêtes d'écho ICMP arriver de l'autre côté, mais aucun signe de retour de réponse.

# tcpdump -i tun0 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 65535 bytes
16:49:16.772718 IP 10.0.2.1 > 10.0.1.1: ICMP echo request, id 4062, seq 5, length 64
<--- insert sound of crickets here (chirp, chirp)

Alors, est-ce que j'ai raté quelque chose d'évident ou est-ce une mauvaise approche ?Y a-t-il autre chose que je peux essayer (par ex.2 interfaces physiques, eth0 et eth1???).

Le moyen le plus simple est simplement d'utiliser 2 machines, mais je veux que tout cela soit autonome, afin que tout puisse être scripté et automatisé sur une seule machine, sans aucune autre dépendance...

MISE À JOUR:

Il n'est pas nécessaire que les 2 socats soient connectés avec une connexion tcp, il est possible (et préférable pour moi) de faire ceci :

socat TUN:10.0.1.1/24,up TUN:10.0.2.1/24,up &

Mais le même problème existe toujours...

Était-ce utile?

La solution

OK, j'ai donc trouvé une solution utilisant les espaces de noms réseau Linux (netns).Il y a un article utile sur la façon de l'utiliser ici : http://code.google.com/p/coreemu/wiki/Namespaces

C'est ce que j'ai fait pour ma configuration....

Tout d'abord, téléchargez et installez CORE : http://cs.itd.nrl.navy.mil/work/core/index.php

Ensuite, exécutez ce script :

#!/bin/sh

core-cleanup.sh > /dev/null 2>&1
ip link set vbridge down > /dev/null 2>&1
brctl delbr vbridge > /dev/null 2>&1

# create a server node namespace container - node 0
vnoded -c /tmp/n0.ctl -l /tmp/n0.log -p /tmp/n0.pid > /dev/null
# create a virtual Ethernet (veth) pair, installing one end into node 0
ip link add name veth0 type veth peer name n0.0
ip link set n0.0 netns `cat /tmp/n0.pid`
vcmd -c /tmp/n0.ctl -- ip link set n0.0 name eth0
vcmd -c /tmp/n0.ctl -- ifconfig eth0 10.0.0.1/24 up

# start web server on node 0
vcmd -I -c /tmp/n0.ctl -- lighttpd -f /etc/lighttpd/lighttpd.conf

# create client node namespace container - node 1
vnoded -c /tmp/n1.ctl -l /tmp/n1.log -p /tmp/n1.pid > /dev/null
# create a virtual Ethernet (veth) pair, installing one end into node 1
ip link add name veth1 type veth peer name n1.0
ip link set n1.0 netns `cat /tmp/n1.pid`
vcmd -c /tmp/n1.ctl -- ip link set n1.0 name eth0
vcmd -c /tmp/n1.ctl -- ifconfig eth0 10.0.0.2/24 up

# bridge together nodes using the other end of each veth pair
brctl addbr vbridge
brctl setfd vbridge 0
brctl addif vbridge veth0
brctl addif vbridge veth1
ip link set veth0 up
ip link set veth1 up
ip link set vbridge up

Cela configure essentiellement 2 réseaux virtuels/isolés/à espacement de noms sur votre hôte Linux, dans ce cas, le nœud 0 et le nœud 1.Un serveur Web est démarré sur le nœud 0.

Il ne vous reste plus qu'à exécuter curl sur le nœud 1 :

vcmd -c /tmp/n1.ctl -- curl --output /dev/null http://10.0.0.1

Et surveillez le trafic avec tcpdump :

tcpdump -s 1514 -i veth0 -n

Cela semble plutôt bien fonctionner...j'expérimente toujours, mais il semble que cela résoudra mon problème.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top