Aller au contenu

Bash - script de tests réseau


Messages recommandés

Salut,

 

Bien. Voici mon premier script shell d'une taille conséquente, réalisé pour mon stage en réseau. L'objectif est d'améliorer la qualité du réseau, dispersé sur plusieurs sites, concernant quelques points précis (voir ci-aprés). Il est donc crée d'aprés mes quelques bases, des sources internet et un peu d'aide extérieur. Mon but est de tester les performances (bande passante) d'un réseau pour en détecter les faiblesses concernant :

- le D/L FTP

- le D/L HTML

- le D/L HTML avec proxy

- le D/L via SMB (partage linux/windows)

- le D/L via NCP (netware core protocol)

 

J'ai donc réalisé 2 scripts :

- une liste de "ping(s)" simples avec un log complet (différentes tailles de paquets)

- celui que vous trouverez ci-dessous, testant le reste (ftp, http, http+proxy, smb, ncp)

 

Si vous voulez tester, il vous faut d'abord créer une machine qui fera serveur, avec un dossier nommé "FTP", en partage simple (autorisations : tout le monde), dans lequel vous déposerez un fichier nommé "fake" (130 Mo pour le mien). Vous installez le composant IIS (serveur HTTP et FTP), vous les paramétrez pour prendre ce même répertoire ("FTP") comme dossier source. Finalement, vous y installez Kperf 2.0 (Version la plus récente de Iperf sous windows, en java). La configuration linux est indiquée dans le script (fedora 5 + update + package 'ncpfs' et 'iperf').

 

Pour les mesures de référence, lancer le script sur le client linux, elle aussi proche du coeur de réseau. Ensuite, déplacer le client linux en divers endroits du réseau et lancer le script, comparer les logs une fois les tests achevés, afin d'en tirer les conclusions.

 

#!/bin/bash
# bash script - Fedora Core 5
# nécessite les packages 'ncpfs' et 'iperf'
# -----------------------------------------------------------------------------
# /!\ Doit être lancé en root pour le montage du partage NCP (netware)
# -----------------------------------------------------------------------------
clear

# Localisation Fr
export LC_ALL="fr_FR.utf8"
export LESSCHARSET="latin1"

# Ajout du chemin "/sbin" à la variable "$PATH" (pour 'ifconfig')
export PATH="$PATH:/sbin"

# Exportation de l'adresse IP du proxy (variable d'environnement)
export http_proxy="http://10.1.x.x:8080"

# Déclaration de variables (utilisés souvent par la suite)
ip=$1
logname=$2
fichier="fake"

# Message d'indication si aucun paramètre
if [ $# != 2 ]
then
clear
echo "---------------------------------------------------------------"
echo "Veuillez entrer le(s) paramètre(s) manquant(s)."
echo "Utilisation : $(basename $0) <server ip> <log name>"
echo "---------------------------------------------------------------"
exit 0
fi

# Utilise le retour de la fonction testant la validité de l'IP
function wrong(){
echo "Notation décimale IPv4 requise."
exit 0
}

# Test de validité IPv4 de l'adresse entrée (expression régulière)
function isIPv4(){
if [ $# = 1 ]
then
	printf $1 | grep -Eq '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-4]|2[0-4][0-9]|[01]?[1-9][0-9]?)$'
	return $?
else
	return 2
fi
}
isIPv4 $ip && echo "IP validée." || wrong

# Récupération de l'ip, du masque de sous-réseau et de l'adresse de broadcast de l'hôte
function hostip(){
for i in $(seq 4)
  do
	  mask[$i]="$(ifconfig $1|grep Masque|cut -d ':' -f4|cut -d '.' -f$i)"
	octet[$i]="$(ifconfig $1|grep Masque|cut -d ':' -f2|cut -d '.' -f$i|cut -d ' ' -f1)"
done

# Variable donnant l'IP de l'hôte
adress=${octet[1]}"."${octet[2]}"."${octet[3]}"."${octet[4]}

# Variable donnant le masque de sous-réseau
subnet=${mask[1]}"."${mask[2]}"."${mask[3]}"."${mask[4]}

# Variable donnant l'adresse du réseau
network=$[${mask[1]} & ${octet[1]}]"."$[${mask[2]} & ${octet[2]}]"."$[${mask[3]} & ${octet[3]}]"."$[${mask[4]} & ${octet[4]}]

echo "IP de l'hôte : $adress"
echo "Sous-réseau : $subnet"
echo "Réseau : $network"
}

# Création du log et aiguillage vers le type de mesure adéquat.
function mesure(){
# Indication à l'écran pour patienter
echo "Veuillez patienter svp..."

# Récupération des paramètres
log="$logname.log" # variable temporaire pour le nom du log

# Liste la date et l'heure
echo "---------------------------------------------------------------" > $log
echo $(date '+%d %B %Y %T') >> $log
echo "---------------------------------------------------------------" >> $log
echo "" >> $log

# Ajoute le nom d'hôte et l'adresse IP de l'interface 0
echo "Nom de l'hôte : $(hostname)" >> $log
hostip 'eth0' >> $log
echo "" >> $log
echo "---------------------------------------------------------------" >> $log
echo "" >> $log

# Appel avant chaque mesure pour que le log soit lisible
function header(){
	echo "" >> $log
	echo "Mesure : $1"
	echo "---------------------------------------------------------------" >> $log
	echo "Mesure : $1" >> $log
	echo "---------------------------------------------------------------" >> $log
}

function calcul(){
	# /!\ L'emplacement de la cmd '/usr/bin/time' diffère d'un linux à l'autre
	secondes=$(/usr/bin/time -f "%e" $commande 2>&1 |tail -1) # Temps de copie

	Koctets=$(ls -s $fichier |cut -d' ' -f1) # Nombre de Ko (KBytes)
	Kbits=$(echo "$Koctets*8"|bc) # Conversion en Kilobits
	Mbits=$(echo "$Kbits/1000"|bc) # Conversion en Megabits

	Kbs=$(echo "$Kbits/$secondes"|bc) # Résultat en Kbits/sec
	Mbs=$(echo "$Mbits/$secondes"|bc) # Résultat en Mbits/sec
	echo "$Kbs Kbits/s" >> $log
	echo "$Mbs Mbits/s" >> $log

	rm fake > /dev/null
	rm -rf /tmp/* # Pour laisser un répertoire temporaire propre
}

# Fonction permettant de monter le NCP et d'envoyer le calcul
function monter(){
	header "partage ncp sur $1"

	# Emplacement du point de montage temporaire
	point="/mnt/ncp"
	chemin="$point/userdisk/cdc/gip1/"

	# /!\ montage en root uniquement
	mkdir $point > /dev/null
	ncpmount -S $1 -A $1 -U gip1 -P gip $point

	# Instructions de calcul sur la commande "cp" (copy)
	commande="cp $chemin$fichier $fichier"
	calcul

	# Enlever le point de montage
	ncpumount $point
	rm -rf $point > /dev/null
}

# Choix entre les 2 réseaux NCP : 10.1 ou 10.2
function Mncp(){
	while [ "$input" != 1-2 ]
	do
		echo "NCP (netware) sur quel réseau : 10.1.x.x (1) ou 10.2.x.x (2) ? [1/2]"
		read input
		case $input in
			"1")
			monter 10.1.x.x
			break;;
			"2")
			monter 10.2.x.x
			break;;
		esac
	done
}

# Mesures d'un téléchargement FTP
function Mftp(){
	header "wget ftp"
	commande="wget -nH -4 -O $fichier --progress=dot:mega --proxy=off --cache=off --no-passive-ftp --user anonymous --password anonymous@test.com ftp://$ip/$fichier"
	calcul
}

# Mesures d'un téléchargement HTTP
function Mhttp(){
	header "wget http"
	commande="wget -nH -4 -O $fichier --progress=dot:mega --proxy=off --cache=off --no-dns-cache http://$ip/$fichier"
	calcul
}

# Mesures d'un téléchargement HTTP via un proxy
function Mhttpp(){
	header "wget http avec proxy"
	commande="wget -nH -4 -O $fichier --progress=dot:mega --proxy=on --cache=off --no-dns-cache http://$ip/$fichier"
	calcul
}

function Msmb(){
	header "partage smb"
	commande="smbget -u partage -p partage -w workgroup smb://$ip/FTP/$fichier"
	calcul
}

# Mesures en client/serveur iperf
function Miperf(){
	header "iperf"
	iperf -c $ip -P 0 -i 10 -f m -t 60 >> $log # sur 60 sec en TCP, 1 mesure/10sec.
	echo "" >> $log
}

# Les mesures complètes dans un seul log
function Mall(){
	# Choix entre les 2 réseaux NCP : 10.1 ou 10.2
	while [ "$input" != 1-2 ]
	do
		echo "NCP (netware) sur quel réseau : 10.1.x.x (1) ou 10.2.x.x (2) ? [1/2]"
		read input
		case $input in
			"1")
			ipncp=10.1.x.x
			break;;
			"2")
			ipncp=10.2.x.x
			break;;
		esac
	done

	# Mesures effectuées une à une
	function boucle(){
		case $k in
			1) nom="wget HTTP" mesure="Mhttp";;
			2) nom="wget HTTP avec le proxy" mesure="Mhttpp";;
			3) nom="wget FTP" mesure="Mftp";;
			4) nom="partage SMB" mesure="Msmb";;
			5) nom="partage NCP" mesure="monter $ipncp";;
			6) nom="client iperf" mesure="Miperf";;
		esac
		$mesure
	}
	for k in $(seq 6)
	do
		boucle $k
		echo "" >> $log
	done
}

# Test suivant le retour du menu pour lancer les instructions appropriées
M$1

# Instructions pour indiquer la fin des mesures dans le log
echo "---------------------------------------------------------------" >> $log
echo "Fin du script à $(date '+%T')" >> $log
echo "---------------------------------------------------------------" >> $log		
}

# Libre choix : visualisation immédiate du log (ou non) 
function lire(){
echo "Mesures terminées. Bonne journée !"
echo ""
function indicateur(){
	echo "---------------------------------------------------------------"
	echo "Les résultats sont dans le fichier '$(pwd)/$log'"
	echo "---------------------------------------------------------------"
	exit 0
}

while [ "$input" != yYnN ]
do
	echo "Souhaitez-vous visualiser le fichier $log ? [y/n]"
	read input
	case "$input" in
		[yY])
		less $log
		indicateur;;

		[nN])
		indicateur;;
	esac
done
}

# Gestion du menu de choix pour le type de mesures à effectuer
function menu(){
clear
echo "---------------------------------------------------------------"
echo "|				   Choix du protocole de test				|"
echo "---------------------------------------------------------------"
echo "Appuyez sur une touche, puis validez. Touche [8] pour quitter."
echo ""
select j in 'HTTP' 'HTTP proxy' 'FTP' 'SMB' 'NCP' 'IPERF' 'ALL' 'QUIT'
	do
		case $j in
			FTP|HTTP|IPERF|SMB|NCP|ALL)
			mesure $(echo $j|tr '[A-Z]' '[a-z]')
			lire
			exit 0;;

			'HTTP proxy')
			mesure httpp
			lire
			exit 0;;

			QUIT)
			clear
			echo "Script terminé. Bonne journée."
			exit 0;;

			*)
			echo "Veuillez entrer un chiffre entre 1 et 7. Merci."
			echo "Touche '8' pour quitter, 'ctrl+d' pour interrompre";;
		esac
done 
}
menu

 

[edit : code modifié]

Lien vers le commentaire
Partager sur d’autres sites

  • 2 weeks later...

J'ai amplement modifié le script, je l'ai pas mal optimisé en comprenant comment fonctionnait le Bash au fur et à mesure. Du coup, le message d'origine ne sert plus. Vu que je n'ai pas eu de retours ici, je peux donc affirmer qu'il n'y a pas des masses d'utilisateurs Linux avertis sur le forum BH.

;-)

 

Je poste le résultat d'un log, histoire que vous ayez un aperçu. J'espère que le script pourra au moins aider les 'google|nautes' à récupérer des bouts de ce script pour faire du test réseau (par exemple l'expression régulière pour tester une adresse IPv4).

 

---------------------------------------------------------------

09 juin 2006 15:39:21

---------------------------------------------------------------

 

Nom de l'hôte : atelier

IP de l'hôte : 10.1.x.x

Sous-réseau : 255.255.0.0

Réseau : 10.1.0.0

 

---------------------------------------------------------------

 

 

---------------------------------------------------------------

Mesure : wget http

---------------------------------------------------------------

82854 Kbits/s

82 Mbits/s

 

 

---------------------------------------------------------------

Mesure : wget http avec proxy

---------------------------------------------------------------

42920 Kbits/s

42 Mbits/s

 

 

---------------------------------------------------------------

Mesure : wget ftp

---------------------------------------------------------------

88678 Kbits/s

88 Mbits/s

 

 

---------------------------------------------------------------

Mesure : partage smb

---------------------------------------------------------------

80770 Kbits/s

80 Mbits/s

 

 

---------------------------------------------------------------

Mesure : partage ncp sur 10.1.x.x

---------------------------------------------------------------

16330 Kbits/s

16 Mbits/s

 

 

---------------------------------------------------------------

Mesure : iperf

---------------------------------------------------------------

------------------------------------------------------------

Client connecting to 10.1.x.x, TCP port 5001

TCP window size: 0.02 MByte (default)

------------------------------------------------------------

[ 3] local 10.1.160.148 port 55275 connected with 10.1.x.x port 5001

[ 3] 0.0-10.0 sec 108 MBytes 90.3 Mbits/sec

[ 3] 10.0-20.0 sec 107 MBytes 90.1 Mbits/sec

[ 3] 20.0-30.0 sec 107 MBytes 89.4 Mbits/sec

[ 3] 30.0-40.0 sec 106 MBytes 89.0 Mbits/sec

[ 3] 40.0-50.0 sec 106 MBytes 89.0 Mbits/sec

[ 3] 50.0-60.0 sec 107 MBytes 89.9 Mbits/sec

[ 3] 0.0-60.0 sec 641 MBytes 89.6 Mbits/sec

 

 

---------------------------------------------------------------

Fin du script à 15:42:33

---------------------------------------------------------------

 

:biere:

Lien vers le commentaire
Partager sur d’autres sites

Re,

 

Personnellement, je trouve cela au contraire trés utile pour automatiser les tâches sous Linux. C'est là que tu te rends compte que tu n'as aucun contrôle sous win (cmd pauvres, et si tu veux te démerder, faut apprendre le vb et... payer), et tout pouvoir sous nux. Je pense que Linux est difficile à comprendre dés qu'on se plonge dans l'administration, la configuration, mais quelle souplesse, quelle puissance... qu'il faut apprendre à maîtriser (et va me falloir du temps... quand est-ce qu'on invente les journées de 35 heures, lol ?).

 

Voici un autre script pour fainéants, un ping "automatisé" avec log, testant différentes tailles de paquet (pour provoquer la fragmentation) et un test sur le champ tos pour la qualité de service :

#!/bin/bash
# bash script - Fedora Core 5
clear

# Localisation Fr
export LC_ALL="fr_FR.utf8"
export LESSCHARSET="latin1"

# Déclaration de variables 
ip=$1

# Message d'indication si aucun paramètre
if [ $# != 1 ];
then
clear
echo "Veuillez entrer un paramètre."
echo "Utilisation : $(basename $0) [IP du serveur]"
echo "---------------------------------------------------------------"
exit 0
fi

# Utilise le retour de la fonction testant la validité de l'IP
function wrong {
echo "Notation décimale IPv4 requise."
exit 0
}

# Test de validité IPv4 de l'adresse entrée (expression régulière)
function isIPv4 {
if [ $# = 1 ]
then
	printf $1 | grep -Eq '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-4]|2[0-4][0-9]|[01]?[1-9][0-9]?)$'
	return $?
else
	return 2
fi
}
isIPv4 $ip && echo "IP validée." || wrong

# Récupération de l'ip, du masque de sous-réseau et de l'adresse de broadcast de l'hôte
function hostip {
way=$1 #chemin de ifconfig ('sbin/ifconfig')
eth=$2 #numéro d'interface ('eth0')

for i in $(seq 4)
  do
	  mask[$i]="$($way $eth|grep Masque|cut -d ':' -f4|cut -d '.' -f$i)"
	octet[$i]="$($way $eth|grep Masque|cut -d ':' -f2|cut -d '.' -f$i|cut -d ' ' -f1)"
done

# Variable donnant l'IP de l'hôte
adress=${octet[1]}"."${octet[2]}"."${octet[3]}"."${octet[4]}
#echo "$adress"

# Variable donnant le masque de sous-réseau
subnet=${mask[1]}"."${mask[2]}"."${mask[3]}"."${mask[4]}
#echo "$subnet"

# Variable donnant l'adresse du réseau
network=$[${mask[1]} & ${octet[1]}]"."$[${mask[2]} & ${octet[2]}]"."$[${mask[3]} & ${octet[3]}]"."$[${mask[4]} & ${octet[4]}]
#echo "$network"

echo "IP de l'hôte : $adress"
echo "Sous-réseau : $subnet"
echo "Réseau : $network"
}

# Création du log et aiguillage vers le type de mesure adéquat.
function mesure () {
# Indication à l'écran pour patienter
echo "Veuillez patienter svp..."

# Création du nom de fichier log
log=$1

# Liste la date et l'heure
echo "---------------------------------------------------------------" > $log
echo $(date) >> $log
echo "---------------------------------------------------------------" >> $log
echo "" >> $log

# Ajoute le nom d'hôte et l'adresse IP de l'interface 0
echo "Nom de l'hôte : $(hostname)" >> $log
hostip '/sbin/ifconfig' 'eth0' >> $log
echo "" >> $log

# Ligne de séparation avant mesures
echo "---------------------------------------------------------------" >> $log
echo "" >> $log

# Mesures ping - différentes tailles de paquets
function Mping(){
	ping -n -c 10 -s$(expr $1 - 8) $ip >> $log
	echo "" >> $log
}		

# Mesures ping - Quality of Service
function Mqos(){
	ping -c 1 $ip > /dev/null #pour ne pas mesurer le premier délai (faussé)
	function loop(){
		case $1 in
			1) arg="-Q 0x02" type="QoS coût minimal";;
			2) arg="-Q 0x04" type="QoS fiabilité";;
			3) arg="-Q 0x08" type="QoS débit";;
			4) arg="-Q 0x10" type="QoS bas délai";;
		esac

		echo "Ping '$type' 'champ tos : $(echo $arg|cut -d' ' -f2)'" >> $log
		echo "---------------------------------------------------------------" >> $log
		ping -n -c10 -pff $arg $ip >> $log
		echo "" >> $log
		echo "" >> $log
	}
	for l in $(seq 4)
	do
		loop $l
		echo "" >> $log
	done
}

# Mesures complètes, une à une.
function Mall(){
	function boucle(){
		case $1 in
			1) nom="Ping (64)" mesure="Mping 64";;
			2) nom="Ping (512)" mesure="Mping 512";;
			3) nom="Ping (1024)" mesure="Mping 1024";;
			4) nom="Ping (2048)" mesure="Mping 2048";;
			5) nom="Ping QoS" mesure="Mqos";;
		esac

		echo "" >> $log
		echo "Mesure $1 : $nom"
		echo "---------------------------------------------------------------" >> $log
		echo "Mesure $1 : $nom" >> $log
		echo "---------------------------------------------------------------" >> $log
		$mesure
	}
	for k in $(seq 5)
	do
		boucle $k
		echo "" >> $log
	done
}

# Test sur la partie significative de '$log' pour lancer les instructions appropriées
valeur=${log:7}
case $valeur in
	64|512|1024|2048) Mping $valeur;;
	qos) Mqos;;
	all) Mall;;
esac

# Instructions pour indiquer la fin des mesures dans le log
echo "---------------------------------------------------------------" >> $log
echo "Fin du script $(basename $0)" >> $log
echo "---------------------------------------------------------------" >> $log		
}

# Libre choix : visualisation immédiate du log (ou non) 
function lire(){
echo ""
while test "$input" != [yYnN]
do
	echo "Souhaitez-vous visualiser le fichier $log ? [y/n]"
	read input
	case "$input" in
		[yY])
		less $log
		echo "---------------------------------------------------------------"
		echo "Les résultats sont dans le fichier '$(pwd)/$log'"
		echo "---------------------------------------------------------------"
		exit 0;;

		[nN])
		echo "---------------------------------------------------------------"
		echo "Les résultats sont dans le fichier '$(pwd)/$log'"
		echo "---------------------------------------------------------------"
		exit 0;;
	esac
done
}

# Gestion du menu de choix pour le type de mesures à effectuer
function menu(){
clear
echo "---------------------------------------------------------------"
echo "|					 Choix du type de ping				   |"
echo "---------------------------------------------------------------"
echo "Appuyez sur une touche, puis validez. Touche [8] pour quitter."
echo ""
select j in  'Ping64' 'Ping512' 'Ping1024' 'Ping2048' 'PingQoS' 'PingALL' 'QUIT'
	do
		case $j in
			'Ping64'|'Ping512'|'Ping1024'|'Ping2048'|'PingQoS'|'PingALL')
			mesure log$(echo $j|tr '[A-Z]' '[a-z]')
			echo "Mesures terminées. Bonne journée !"
			lire
			exit 0;;

			QUIT)
			clear
			echo "Script terminé. Bonne journée."
			exit 0;;

			*)
			echo "Veuillez entrer un chiffre entre 1 et 7. Merci."
			echo "Touche '8' pour quitter, 'ctrl+d' pour interrompre";;
		esac
done 
}
menu

 

Comme d'habitude, "chmod u+x <nom du script>" et pour le lancer "./<nom du script>"

:biere:

Lien vers le commentaire
Partager sur d’autres sites

  • 3 years later...

Rejoindre la conversation

Vous pouvez publier maintenant et vous inscrire plus tard. Si vous avez un compte, connectez-vous maintenant pour publier avec votre compte.

Invité
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

×
×
  • Créer...