Socket tcp ip client server on langace c mouad Lousimi
Les sockets sont des flux de données, permettant à des machines locales ou distantes de communiquer entre elles via des protocoles.
Les différents protocoles sont TCP qui est un protocole dit "connecté", et UDP qui est un protocole dit "non connecté".
Nous allons voir par la suite comment réaliser diverses applications telles qu'un client/serveur TCP
Socket tcp ip client server on langace c mouad Lousimi
Les sockets sont des flux de données, permettant à des machines locales ou distantes de communiquer entre elles via des protocoles.
Les différents protocoles sont TCP qui est un protocole dit "connecté", et UDP qui est un protocole dit "non connecté".
Nous allons voir par la suite comment réaliser diverses applications telles qu'un client/serveur TCP
Le package java.net et les API réseau de Java
Les Sockets Java
Les sockets en mode connecté
Un serveur TCP/IP
Un client TCP/IP
Les échanges de données
Les classes de connexion
Ce deuxième cours aborde la programmation réseau, c'est-à-dire le développement d'applications avec plusieurs composants qui communiquent entre eux via la réseau. Après une rapide présentation des protocoles UDP et TCP, le cours aborde la notion de socket et présente le module Python de même nom. Le cours présente deux applications concrètes : une application de chat (basé sur UDP) et une application echo (basé sur TCP). Le cours se termine par la découverte de la notion de protocole de communication et de la définition du format des messages échangés.
Cette fiche applicative est la suite de la fiche « Génération de certificats SSL ». Elle présente la configuration d’un tunnel OpenVPN SSL entre un routeur WeOS Westermo et le client SecurePoint SSL VPN.
2024 03 27 JTC actualités C Perrot (idele).pdfidelewebmestre
Quelque que soit les secteurs de production, les pyramides des âges des agriculteurs français (chefs et coexploitants) présentent presque toujours un double déséquilibre : i) en faveur des classes d’âges à partir de 50-55 ans, ii) en défaveur des femmes, surtout de moins de 40 ans. Si le secteur caprin est une exception à cette règle, c’est principalement grâce aux producteurs qui transforment du lait à la ferme. Cette sous population présente le même équilibre, en classe d’âge et en sex ratio, que la population active française en emplois tous secteurs économiques confondus. C’est légèrement moins vrai pour les classes d’âge les plus jeunes (moins de 30 ans) : le métier d’éleveur.se est un métier d’indépendant alors que les jeunes actifs français sont salariés. Cet équilibre parfait du secteur caprin fermier s’explique par une forte attractivité. 40% des éleveur.se.s présents en 2020 s’étaient installés depuis 2010 ! Deux fois plus que dans les autres secteurs de l’élevage. Bien que pour l’instant stable (taux de remplacement des départs, entrées/sorties, proche de 100%), la sous population des éleveurs qui livrent du lait de chèvre est plus fragile. Compte tenu d’un très faible taux de renouvellement (nombre d’entrées/nombre de présents), elle vieillit et pourrait finir par diminuer. Néanmoins comme les besoins de recrutement sont bien moins élevés qu’en bovins lait par exemple, les marges de manoeuvre pour la filière semblent plus accessibles.
Contenu connexe
Similaire à Support Cours de Python et Réseaux.pptx
Le package java.net et les API réseau de Java
Les Sockets Java
Les sockets en mode connecté
Un serveur TCP/IP
Un client TCP/IP
Les échanges de données
Les classes de connexion
Ce deuxième cours aborde la programmation réseau, c'est-à-dire le développement d'applications avec plusieurs composants qui communiquent entre eux via la réseau. Après une rapide présentation des protocoles UDP et TCP, le cours aborde la notion de socket et présente le module Python de même nom. Le cours présente deux applications concrètes : une application de chat (basé sur UDP) et une application echo (basé sur TCP). Le cours se termine par la découverte de la notion de protocole de communication et de la définition du format des messages échangés.
Cette fiche applicative est la suite de la fiche « Génération de certificats SSL ». Elle présente la configuration d’un tunnel OpenVPN SSL entre un routeur WeOS Westermo et le client SecurePoint SSL VPN.
2024 03 27 JTC actualités C Perrot (idele).pdfidelewebmestre
Quelque que soit les secteurs de production, les pyramides des âges des agriculteurs français (chefs et coexploitants) présentent presque toujours un double déséquilibre : i) en faveur des classes d’âges à partir de 50-55 ans, ii) en défaveur des femmes, surtout de moins de 40 ans. Si le secteur caprin est une exception à cette règle, c’est principalement grâce aux producteurs qui transforment du lait à la ferme. Cette sous population présente le même équilibre, en classe d’âge et en sex ratio, que la population active française en emplois tous secteurs économiques confondus. C’est légèrement moins vrai pour les classes d’âge les plus jeunes (moins de 30 ans) : le métier d’éleveur.se est un métier d’indépendant alors que les jeunes actifs français sont salariés. Cet équilibre parfait du secteur caprin fermier s’explique par une forte attractivité. 40% des éleveur.se.s présents en 2020 s’étaient installés depuis 2010 ! Deux fois plus que dans les autres secteurs de l’élevage. Bien que pour l’instant stable (taux de remplacement des départs, entrées/sorties, proche de 100%), la sous population des éleveurs qui livrent du lait de chèvre est plus fragile. Compte tenu d’un très faible taux de renouvellement (nombre d’entrées/nombre de présents), elle vieillit et pourrait finir par diminuer. Néanmoins comme les besoins de recrutement sont bien moins élevés qu’en bovins lait par exemple, les marges de manoeuvre pour la filière semblent plus accessibles.
JTC_2024_TC Bâtiment et bien-être estival.pdfidelewebmestre
Le changement climatique s’exprime de plus en plus par la manifestation d’épisodes caniculaires et par la diminution de la ressource fourragère en été, ce qui contraint les éleveurs à rentrer leur troupeau plus fréquemment. Les animaux logés en bâtiment pendant la période estivale sont exposés à un stress thermique qui peut altérer leur bien-être et leurs performances à court et moyen terme. La conception du bâtiment ou certains équipements peuvent permettre de réduire ce stress pour assurer un meilleur confort aux animaux pendant les périodes de fortes chaleurs.
Le comité de filière ovin et les équipes de l’Institut de l’Elevage ont présenté lors d'un webinaire, comment la sélection génétique contribue aux enjeux actuels de la production ovine. Quelles sont les travaux en cours et les perspectives d’étude sur la brebis de demain.
Intervention : La génétique, un levier majeur pour les enjeux à venir (Mathieu Foucault)
L’équipe du projet BeBoP a proposé un webinaire le 30 mai 2024 pour découvrir comment la technologie vidéo, combinée à l’intelligence artificielle, se met au service de l’analyse du comportement des taurillons.
3. Rappels
Comment faire communiquer deux applications, sur la même machine ou à
distantes ?
Par la connexion au réseau local ou à Internet !
En précisant le protocole :
Le protocole TCP (Transmission Control Protocol) :
Pour connecter deux applications et de leur faire échanger des informations.
« Orienté connexion »
Le protocole UDP (User Datagram Protocol):
Envoie des informations au travers du réseau, en spécifiant une cible, sans
vérifier l’effectivité réception. Protocole non connecté.
Dans l'architecture que nous allons voir dans les exemples du cours on
trouve en général un serveur et plusieurs clients.
Le serveur, c'est une machine qui va traiter les requêtes du client.
4. Rappels
Dans les exemples que nous allons voir, nous allons créer deux applications
: l'application serveur et l'application client.
Le serveur écoute donc en attendant des connexions et les clients se
connectent au serveur.
Les différentes étapes
Nos applications vont fonctionner selon un schéma assez similaire.
Voici dans l'ordre les étapes du client et du serveur. Les étapes sont très
simplifiées, la plupart des serveurs peuvent communiquer avec plusieurs
clients mais nous ne verrons pas cela tout de suite.
5. Rappels
Le serveur :
- attend une connexion de la part du client ;
- accepte la connexion quand le client se connecte ;
- échange des informations avec le client ;
- ferme la connexion.
Le client :
- se connecte au serveur ;
- échange des informations avec le serveur ;
- ferme la connexion.
Comme on l'a vu, le serveur peut dialoguer avec plusieurs clients : c'est
tout l'intérêt.
6. Rappels
Établir une connexion
Pour que le client se connecte au serveur, il nous faut deux informations :
- Le nom d'hôte (host name), identifiant une machine sur Internet ou sur un
réseau local. Les noms d'hôtes permettent de représenter des adresses IP de
façon plus claire (on a un nom comme google.fr, plus facile à retenir que
l'adresse IP correspondante 74.125.224.84).
- Un numéro de port, qui est souvent propre au type d'information que l'on va
échanger. Si on demande une connexion web, le navigateur va en général
interroger le port 80 si c'est en http ou le port 443 si c'est en connexion
sécurisée (https). Le numéro de port est compris entre 0 et 65535 et les
numéros entre 0 et 1023 sont réservés par le système (ce n'est pas une très
bonne idée de les utilisées).
7. Les Sockets
Les sockets sont des objets qui permettent d'ouvrir une connexion avec une
machine locale ou distante et d'échanger avec elle.
Ces objets sont définis dans le module socket et nous allons maintenant
voir comment ils fonctionnent.
Commençons par importer notre module socket.
>>> import socket
Nous allons d'abord créer notre serveur puis, en parallèle, un client.
Nous allons faire communiquer les deux. Pour l'instant, nous nous occupons
du serveur.
8. Les Sockets
Construire notre socket
Nous allons pour cela faire appel au constructeur socket. Dans le cas d'une
connexion TCP, il prend les deux paramètres suivants, dans l'ordre :
socket.AF_INET : la famille d'adresses, ici ce sont des adresses Internet ;
socket.SOCK_STREAM : le type du socket, SOCK_STREAM pour le protocole TCP.
>>> connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
9. Les Sockets
Connecter le socket
Pour une connexion serveur, qui va attendre des connexions de clients, on
utilise la méthode bind. Elle prend un paramètre : le tuple (nom_hote,
port).
Question C‘est notre client qui se connectait à notre serveur ou
l'inverse…
Oui mais c‘est notre client qui se connecte à notre serveur , pour que
notre serveur écoute sur un port, il faut le configurer en conséquence.
Donc, dans notre cas, le nom de l'hôte sera vide et le port sera celui que
vous voulez, entre 1024 et 65535.
>>> connexion_principale.bind(('', 12800))
10. Les Sockets
Faire écouter notre socket
Notre socket est prêt à écouter sur le port 12800 mais il n'écoute pas
encore. On va avant tout lui préciser le nombre maximum de connexions
qu'il peut recevoir sur ce port sans les accepter. On utilise pour
cela la méthode listen. On lui passe généralement 5 en paramètre.
Cela veut dire que notre serveur ne pourra dialoguer qu'avec 5 clients
maximum ?
Non. Cela veut dire que si 5 clients se connectent et que le serveur
n'accepte aucune de ces connexions, aucun autre client ne pourra se
connecter. Mais généralement, très peu de temps après que le client
ait demandé la connexion, le serveur l'accepte. Vous pouvez donc avoir
bien plus de clients connectés, ne vous en faites pas.
11. Les Sockets
Accepter une connexion venant du client
Enfin, dernière étape, on va accepter une connexion. Aucune connexion ne
s'est encore présentée mais la méthode accept que nous allons utiliser va
bloquer le programme tant qu'aucun client ne s'est connecté.
Il est important de noter que la méthode accept renvoie deux informations :
le socket connecté qui vient de se créer, celui qui va nous permettre de
dialoguer avec notre client tout juste connecté ;
un tuple représentant l'adresse IP et le port de connexion du client.
12. Les Sockets
Le port de connexion du client… ce n'est pas le même que celui du
serveur ?
Non car votre client, en ouvrant une connexion, passe par un port dit «
de sortie » qui va être choisi par le système parmi les ports
disponibles. Pour schématiser, quand un client se connecte à un
serveur, il emprunte un port puis établit la connexion sur le port du
serveur. Il y a donc deux ports dans notre histoire mais celui
qu'utilise le client pour ouvrir sa connexion ne va pas nous
intéresser.
>>> connexion_avec_client, infos_connexion =
connexion_principale.accept()
13. Les Sockets
Création du client
Commencez par construire votre socket de la même façon :
>>> import socket
>>> connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Connecter le client
Pour se connecter à un serveur, on va utiliser la méthode connect. Elle prend
en paramètre un tuple, comme bind, contenant le nom d'hôte et le numéro du
port identifiant le serveur auquel on veut se connecter.
Le numéro du port sur lequel on veut se connecter, vous le connaissez : c'est
12800. Vu que nos deux applications Python sont sur la même machine, le nom
d'hôte va être localhost.
>>> connexion_avec_serveur.connect(('localhost', 12800))
Maintenant notre serveur et notre client sont connectés !
14. Les Sockets
Création du client (suite)
Si vous retournez dans la console Python abritant le serveur, vous pouvez
constater que la méthode accept ne bloque plus, puisqu'elle vient
d'accepter la connexion demandée par le client. Vous pouvez donc de
nouveau saisir du code côté serveur :
>>> print(infos_connexion)
('127.0.0.1', 2901)
La première information, c'est l'adresse IP du client. Ici, elle vaut
127.0.0.1 c'est-à-dire l'IP de l'ordinateur local. Dites-vous que l'hôte
localhost redirige vers l'IP 127.0.0.1.
15. Les Sockets
Faire communiquer nos sockets
Comment faire communiquer nos sockets ? En utilisant les méthodes send pour
envoyer et recv pour recevoir.
Les informations transmises seront des chaînes de bytes, pas des str !
Donc côté serveur :
>>> connexion_avec_client.send(b"Je viens d'accepter la connexion")
32
La méthode send vous renvoie le nombre de caractères envoyés.
Maintenant, côté client, on va réceptionner le message que l'on vient d'envoyer.
La méthode recv prend en paramètre le nombre de caractères à lire. Généralement,
on lui passe la valeur 1024. Si le message est plus grand que 1024 caractères,
on récupérera le reste après.
16. Les Sockets
Dans la fenêtre Python côté client, donc :
>>> msg_recu = connexion_avec_serveur.recv(1024)
>>> msg_recu
b"Je viens d'accepter la connexion"
Songez que ce petit mécanisme peut servir à faire communiquer des
applications entre elles non seulement sur la machine locale, mais aussi
sur des machines distantes et reliées par Internet.
Le client peut également envoyer des informations au serveur et le serveur
peut les réceptionner, tout cela grâce aux méthodes send et recv que nous
venons de voir.
17. Les Sockets
Fermer la connexion
Pour fermer la connexion, il faut appeler la méthode close de notre
socket.
Côté serveur :
>>> connexion_avec_client.close()
Et du côté client :
>>> connexion_avec_serveur.close()
On va récapituler en présentant dans l'ordre un petit serveur et un client
que nous pouvons utiliser.
Et pour finir, nous allons optimiser un peu notre serveur en lui
permettant de gérer plusieurs clients à la fois.
18. Les Sockets
import socket
hote = ''
port = 12800
connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_principale.bind((hote, port))
connexion_principale.listen(5)
print("Le serveur écoute à présent sur le port {}".format(port))
connexion_avec_client, infos_connexion = connexion_principale.accept()
msg_recu = b""
while msg_recu != b"fin":
msg_recu = connexion_avec_client.recv(1024)
# L'instruction ci-dessous peut lever une exception si le message
# Réceptionné comporte des accents
print(msg_recu.decode())
connexion_avec_client.send(b"5 / 5")
print("Fermeture de la connexion")
connexion_avec_client.close()
connexion_principale.close()
Le code pour le serveur
Voici le code du serveur,
légèrement amélioré. Il
n'accepte qu'un seul
client (nous verrons plus
bas comment en accepter
plusieurs) et il tourne
jusqu'à recevoir du client
le message fin.
À chaque fois que le
serveur reçoit un message,
il envoie en retour le
message '5 / 5'
19. Les Sockets
import socket
hote = "localhost"
port = 12800
connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_avec_serveur.connect((hote, port))
print("Connexion établie avec le serveur sur le port {}".format(port))
msg_a_envoyer = b""
while msg_a_envoyer != b"fin":
msg_a_envoyer = input("> ")
# Peut planter si vous tapez des caractères spéciaux
msg_a_envoyer = msg_a_envoyer.encode()
# On envoie le message
connexion_avec_serveur.send(msg_a_envoyer)
msg_recu = connexion_avec_serveur.recv(1024)
print(msg_recu.decode())
# Là encore, peut planter s'il y a des accents
print("Fermeture de la connexion")
connexion_avec_serveur.close()
Le code pour le
client
Voici le code du
client pouvant
interagir avec notre
serveur.
Il va tenter de se
connecter sur le port
12800 de la machine
locale. Il demande à
l'utilisateur de
saisir quelque chose
au clavier et envoie
ce quelque chose au
serveur, puis attend
sa réponse.
20. Les Sockets
Que font les méthodes encode et décode ?
encode est une méthode de str. Elle peut prendre en paramètre un nom
d'encodage et permet de passer un str en chaîne bytes : le type de chaîne
que send accepte. En fait, encode encode la chaîne str en fonction d'un
encodage précis (par défaut, Utf-8).
decode, à l'inverse, est une méthode de bytes. Elle aussi peut prendre en
paramètre un encodage et elle renvoie une chaîne str décodée grâce à
l'encodage (par défaut Utf-8).
Si l'encodage de votre console est différent d'Utf-8 (ce sera souvent le
cas sur Windows), des erreurs peuvent se produire si les messages que vous
encodez ou décodez comportent des accents.
21. Le Threading
Un serveur plus élaboré
Quel sont les problèmes de notre serveur ?
N'accepter qu'un seul client. Si d'autres clients veulent se connecter,
ils ne peuvent pas.
Attend le message d'un client et qu‘il renvoie immédiatement après
réception. Mais ce n'est pas toujours le cas : parfois vous envoyez un
message au client alors qu'il ne vous a rien envoyé et vis versa.
Les erreurs sont assez mal gérées.
22. Le Threading
Le module select
Permet d’interroger plusieurs clients dans l'attente d'un message à
réceptionner, sans paralyser notre programme.
Pour schématiser, select va écouter sur une liste de clients et retourner
au bout d'un temps précisé. Ce que renvoie select, c'est la liste des
clients qui ont un message à réceptionner. Il suffit de parcourir ces
clients, de lire les messages en attente (grâce à recv).
Sur Linux, select peut être utilisé sur autre chose que des sockets mais,
cette fonctionnalité n'étant pas portable.
23. Le Threading
Comment marche la fonction select
La fonction qui nous intéresse porte le même nom que le module associé,
select. Elle prend trois ou quatre arguments et en renvoie trois. :
rlist : la liste des sockets en attente d'être lus ;
wlist : la liste des sockets en attente d'être écrits ;
xlist : la liste des sockets en attente d'une erreur ;
timeout : le délai pendant lequel la fonction attend avant de retourner. Si
vous précisez en timeout 0, la fonction retourne immédiatement. Si ce
paramètre n'est pas précisé, la fonction retourne dès qu'un des sockets
change d'état (est prêt à être lu s'il est dans rlist par exemple) mais pas
avant.
24. Le Threading
Comment marche la fonction select
Ce qu'on veut, c'est mettre des sockets dans une liste et que select les
surveille, en retournant dès qu'un socket est prêt à être lu. Comme cela
notre programme ne bloque pas et il peut recevoir des messages de plusieurs
clients dans un ordre complètement inconnu.
Maintenant, concernant le timeout : si on ne le précise pas, select bloque
jusqu'au moment où l'un des sockets que nous écoutons est prêt à être lu,
dans notre cas. Si vous précisez un timeout de 0, select retournera tout de
suite. Sinon, select retournera au bout du temps que vous indiquez en
secondes, ou plus tôt si un socket est prêt à être lu.
Donc si on précise un timeout de 1, la fonction va bloquer pendant une
seconde maximum. Mais si un des sockets en écoute est prêt à être lu dans
l'intervalle (c'est-à-dire si un des clients envoie un message au serveur),
25. Le Threading
Considérez cette ligne :
>>> rlist, wlist, xlist = select.select(clients_connectes, [], [], 2)
Cette instruction va écouter les sockets contenus dans la liste
clients_connectes.
Elle retournera au plus tard dans 2 secondes. Mais elle retournera plus
tôt si un client envoie un message. La liste des clients ayant envoyé un
message se retrouve dans notre variable rlist.
On la parcourt ensuite et on peut appeler recv sur chacun des sockets.
26. Le Threading
Le but va être de créer un serveur pouvant accepter plusieurs clients,
réceptionner leurs messages et leur envoyer une confirmation à chaque
réception.
L'exercice ne change pas beaucoup mais on va utiliser select pour
travailler avec plusieurs clients.
La fonction select permet d’écouter plusieurs clients connectés mais va
également nous permettre de savoir si un (ou plusieurs) clients sont
connectés au serveur.
Souvenez que la méthode accept est aussi une fonction bloquante. On va du
reste l'utiliser de la même façon qu'un peu plus haut.
27. Le Threading
Maintenant notre serveur peut accepter des connexions de plus d'un client,
vous pouvez faire le test. En outre, il ne se bloque pas dans l'attente d'un
message, du moins pas plus de 50 millisecondes.
Les commentaires sont assez précis pour vous permettre d'aller plus loin.
Ceci n'est pas encore une version complète mais, grâce à cette base, vous
devriez pouvoir facilement arriver à quelque chose.
Projet : Faire un mini serveur de tchat ?
Les déconnexions fortuites ne sont pas gérées non plus.
Mais vous avez assez d'éléments pour faire des tests et améliorer notre
serveur.
28. Le Threading
Pour aller plus loin
Pour plus de documentation du module socket, de select et de socketserver
aller au niveau de leur page officielle.
Le module socketserver propose une alternative pour monter vos
applications serveur. Il en existe d'autres, dans tous les cas : vous
pouvez utiliser des sockets non bloquants (c'est-à-dire qui ne bloquent
pas le programme quand vous utilisez leur méthode accept ou recv) ou des
threads pour exécuter différentes portions de votre programme en
parallèle.
29. Conclusion
Dans la structure réseau vue, on trouve un serveur pouvant dialoguer avec
plusieurs clients.
Pour créer une connexion côté serveur ou client, on utilise le module
socket et la classe socket de ce module.
Pour se connecter à un serveur, le socket client utilise la méthode
connect.
Pour écouter sur un port précis, le serveur utilise d'abord la méthode
bind puis la méthode listen.
Pour s'échanger des informations, les sockets client et serveur utilisent
les méthodes send et recv..
30. Conclusion
Pour fermer une connexion, le socket serveur ou client utilise la méthode
close.
Le module select peut être utile si l'on souhaite créer un serveur pouvant
gérer plusieurs connexions simultanément ; toutefois, il en existe
d'autres.
31. Les méthodes de l'objet socket
accept() accepte une connexion, retourne un nouveau socket et une adresse client
bind(addr) associe le socket à une adresse locale
close() ferme le socket
connect(addr) connecte le socket à une adresse distante
connect_ex(addr) connect, retourne un code erreur au lieu d'une exception
dup() retourne un nouveau objet socket identique à celui en cours
fileno() retourne une description du fichier
getpeername() retourne l'adresse distante
getsockname() retourne l'adresse locale
getsockopt(level, optname[, buflen]) : retourne les options du socket
gettimeout() retourne le timeout ou none
listen(n) commence à écouter les connexions entrantes
32. Les méthodes de l'objet socket
makefile([mode, [bufsize]]) : retourne un fichier objet pour le
socket
recv(buflen[, flags]) : recoit des données
recv_into(buffer[, nbytes[, flags]]) : recoit des données (dans un buffer)
recvfrom(buflen[, flags]) : reçoit des données et l'adresse de
l'envoyeur
recvfrom_into(buffer[,nbytes,[,flags]) : reçoit des données et l'adresse de
l'envoyeur (dans un buffer)
sendall(data[, flags]) : envoye toutes les données
send(data[, flags]) : envoye des données mais il se peut
que pas toutes le soit
sendto(data[, flags], addr) : envoye des données à une adresse
donnée
33. Python & Réseaux
Initiation à la programmation réseaux
Configuration Réseaux à Distance
avec Netmiko
CC
Pro
Digit
Consulting
Chapitre II
34. Plan
1. Présentation de la Bibliothèque Netmiko
2. Copie sécurisée
3. Netmiko via SSH Proxy
4. Netmiko et TextFSMRappels
35. Pourquoi Netmiko ?
Certain types de problèmes peuvent prendre beaucoup de temps de développement et
de dépannage :
Problèmes similaires avec Python-SSH et les périphériques réseau
les commutateurs HP ProCurve ont des codes d'échappement ANSI dans la sortie
Cisco WLC a un message supplémentaire «connexion en tant que:»
Netmiko a donc été créé pour simplifier cette gestion SSH de niveau inférieur sur
un large éventail de fournisseurs de réseaux et de plates-formes.
Depuis la fin de 2014, Kirk Byers travaille sur une bibliothèque Python open source
qui simplifie la gestion SSH pour les périphériques réseau.
36. Pourquoi Netmiko ?
La bibliothèque est basée sur la bibliothèque Paramiko SSH et s'appelle Netmiko.
Vous pouvez trouver la bibliothèque sur https://github.com/ktbyers/netmiko et la
dernière version publiée du logiciel peut être téléchargée
https://github.com/ktbyers/netmiko/releases .
Les objectifs de cette bibliothèque sont les suivants:
Établir avec succès une connexion SSH à un appareil réseau,
Exécution des commandes show et la récupération des données de sortie,
Simplifiez l'exécution des commandes de configuration,
Simplifiez des actions de validation,
Sur un large éventail de fournisseurs de réseaux et de plates-formes.
37. Pourquoi Netmiko ?
Depuis janvier 2019, Netmiko prend en charge les plates-formes suivantes avec 3
niveaux de test indiqué.
Testé régulièrement:
Arista EOS - Cisco ASA - Cisco IOS / IOS-XE - Cisco IOS-XR - Cisco NX-OS
Cisco SG300 - HP Comware7 - HP ProCurve - Juniper Junos - Linux
Tests limités:
Alcatel AOS6 / AOS8 - Apresia Systems AEOS - Calix B6 - Cisco AireOS (contrôleurs
LAN sans fil) - Dell OS9 (Force10) - Dell OS10 - Dell PowerConnect - Extreme ERS
(Avaya) - VSP extrême (Avaya) - Extreme VDX (Brocade) - Extreme MLX / NetIron
(brocart / fonderie) – Huawei - Infusion IP OcNOS – Mellanox - NetApp cDOT
OneAccess - Palo Alto PAN-OS – Pluribus - Ruckus ICX / FastIron
Ubiquiti EdgeSwitch - Vyatta VyOS
39. TP 1
TP 1: Session SSH simple vers un routeur Cisco
Exécutez et renvoyez la commande 'show ip int brief'.
Tout d'abord, importer la fonction ConnectHandler du module Netmiko.
ConnectHandler sélectionne la classe Netmiko correcte en fonction du type
d'appareil.
>>> from netmiko import ConnectHandler
Définir ensuite un dictionnaire de périphériques réseau composé d'un type de
périphérique, d'une adresse IP, d'un nom d'utilisateur et d'un mot de passe.
>>> cisco = {
...: 'device_type': 'cisco_ios',
...: 'host': 'cisco.domain.com',
...: 'username': 'admin',
...: 'password': 'cisco123',
...: }
40. TP 1
À ce stade, on peut se connecter à l'appareil.
Notez ci-dessus que j'ai spécifié le device_type comme 'cisco_ios'. Tous les
device_types ne sont pas pris en charge.
Pour se connecter, on appelle ConnectHandler et en passant mon dictionnaire de
périphérique défini précédemment:
>>> net_connect = ConnectHandler(**cisco)
Alternativement, je pourrais simplement appeler la fonction ConnectHandler
directement et ne pas utiliser de dictionnaire (comme suit):
>>> net_connect2 = ConnectHandler(device_type='cisco_ios',
host='cisco.domain.com', username='admin', password='cisco123')
41. TP 1
A ce stade, nous devrions avoir une connexion SSH établie.
On peut vérifier cela en exécutant la méthode find_prompt ()
>>> net_connect.find_prompt()
'cisco3#'
On peut également envoyer des commandes sur le canal SSH et recevoir la sortie.
On utilise la méthode .send_command () pour envoyer une commande :
>>> output = net_connect.send_command("show ip int brief")
42. TP 1
>>> print(output)
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0/0 10.10.10.22 YES manual up up
GigabitEthernet0/0/1 unassigned YES NVRAM administratively down down
GigabitEthernet0/1/0 unassigned YES unset down down
GigabitEthernet0/1/1 unassigned YES unset down down
GigabitEthernet0/1/2 unassigned YES unset down down
GigabitEthernet0/1/3 unassigned YES unset down down
Vlan1 unassigned YES unset up down
Essayons également de modifier la configuration de ce routeur.
Tout d'abord, regardons la configuration de journalisation actuelle:
>>> output = net_connect.send_command("show run | inc logging")
43. TP 1
>>> print(output)
logging synchronous
Maintenant, afin de faire des changements de configuration, on peut créer une
liste de commandes de configuration que l’on veut exécuter. Il peut s'agir d'une
seule commande ou de plusieurs commandes.
>>> config_commands = ['logging buffered 19999']
J'exécute ensuite la méthode send_config_set (). Cette méthode entrera en mode de
configuration, exécutera les commandes, puis quittera le mode de configuration
(notez qu'il y aura quelques exceptions à ce comportement en fonction de la
plate-forme - par exemple, IOS-XR ne quittera pas le mode de configuration en
raison de modifications en attente).
>>> output = net_connect.send_config_set(config_commands)
44. TP 1
>>> output = net_connect.send_config_set(config_commands)
>>> print(output)
config term
Enter configuration commands, one per line. End with CNTL/Z.
cisco3(config)#logging buffered 19999
cisco3(config)#end
cisco3#
Vérifier la modification:
>>> output = net_connect.send_command("show run | inc logging")
>>> print(output)
logging buffered 19999
logging synchronous
45. TP 2
TP 2: Exécution de «show arp» sur un ensemble de périphériques réseau composés de
différents fournisseurs et plates-formes.
Tout d'abord, on doit définir
les périphériques réseau
(les adresses IP et les mots de passe réels
ont été masqués):
>>> from netmiko import ConnectHandler
>>> from datetime import datetime
49. TP 2
Ensuite, créer une liste Python qui inclut tous ces appareils:
>>> all_devices = [cisco3, cisco_asa, cisco_xrv, arista8, hp_procurve,
juniper_srx]
Maintenant, on va créer une boucle for qui itère sur tous ces appareils. Chaque
fois dans la boucle: le code se connecte à l'appareil, exécute 'show arp', puis
affiche la sortie. On gardera également la trace du temps nécessaire à
l'exécution du code.
51. TP 2
Voici la sortie de la boucle for (c'est-à-dire toute la sortie "show arp"):
--------- Device cisco_ios ---------
Protocol Address Age (min) Hardware Addr Type Interface
Internet 10.10.10.1 32 0062.ec29.70fe ARPA GigabitEthernet0/0/0
Internet 10.10.10.20 156 c89c.1dea.0eb6 ARPA GigabitEthernet0/0/0
Internet 10.10.10.22 - a093.5141.b780 ARPA GigabitEthernet0/0/0
Internet 10.10.10.37 178 0001.00ff.0001 ARPA GigabitEthernet0/0/0
Internet 10.10.10.38 15 0002.00ff.0001 ARPA GigabitEthernet0/0/0
--------- End ---------
--------- Device cisco_asa ---------
outside 10.10.10.1 0062.ec29.70fe 1949
outside 10.10.10.20 c89c.1dea.0eb6 10226
outside 10.10.10.37 0001.00ff.0001 11606
outside 10.10.10.38 0002.00ff.0001 11636
--------- End ---------
52. TP 2
Voici la sortie de la boucle for (c'est-à-dire toute la sortie "show arp"):
--------- Device cisco_xr ---------
Thu Jan 30 10:45:44.240 UTC
-------------------------------------------------------------------------------
0/0/CPU0
-------------------------------------------------------------------------------
Address Age Hardware Addr State Type Interface
10.10.10.1 00:32:36 0062.ec29.70fe Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.19 02:50:35 0024.c4e9.48ae Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.20 00:30:26 c89c.1dea.0eb6 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.21 03:09:20 1c6a.7aaf.576c Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.22 02:58:54 a093.5141.b780 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.23 01:37:37 502f.a8b1.6900 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.32 02:56:30 5254.abc7.26aa Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.37 - 0001.00ff.0001 Interface ARPA GigabitEthernet0/0/0/0
10.10.10.38 01:55:33 0002.00ff.0001 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.39 00:11:32 6464.9be8.08c8 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.42 00:00:46 ec38.739e.2f08 Dynamic ARPA GigabitEthernet0/0/0/0
10.10.10.43 00:22:35 5254.abda.5495 Dynamic ARPA GigabitEthernet0/0/0/0
--------- End ---------
53. TP 2
--------- Device arista_eos ---------
Address Age (min) Hardware Addr Interface
10.10.10.1 0 0062.ec29.70fe Vlan1, Ethernet1
10.10.10.20 0 c89c.1dea.0eb6 Vlan1, not learned
10.10.10.43 0 5254.abda.5495 Vlan1, not learned
--------- End ---------
--------- Device hp_procurve ---------
IP ARP table
IP Address MAC Address Type Port
--------------- ----------------- ------- ----
10.10.19.1 0062ec-2970fd dynamic 26
10.10.19.20 c07bbc-65272e dynamic 26
--------- End ---------
54. TP 2
--------- Device juniper ---------
MAC Address Address Name Interface Flags
00:62:ec:29:70:fe 10.10.10.1 10.10.10.1 vlan.0 none
c8:9c:1d:ea:0e:b6 10.10.10.20 10.10.10.20 vlan.0 none
Total entries: 2
--------- End ---------
>>> print(total_time)
0:00:42.062773
Comme vous pouvez le voir, l'exécution du code a pris un peu plus de 42 secondes.
Cela pourrait être considérablement amélioré en créant les sessions SSH
simultanément voir le code ici pour quelques exemples utilisant la concurrence.
55. TP 2
Méthodes Netmiko couramment utilisées:
net_connect.send_command () - Envoie la commande sur le canal, retourne la sortie (basée sur le
modèle)
net_connect.send_command_timing () - Envoie une commande sur le canal, retourne la sortie (en
fonction du timing)
net_connect.send_config_set () - Envoie des commandes de configuration au périphérique distant
net_connect.send_config_from_file () - Envoie des commandes de configuration chargées à partir d'un
fichier
net_connect.save_config () - Enregistrez la configuration en cours d'exécution dans la
configuration de démarrage
net_connect.enable () - Entrer en mode d'activation
net_connect.find_prompt () - Retourne l'invite actuelle du routeur
net_connect.commit () - Exécute une action de validation sur Juniper et IOS-XR
net_connect.disconnect () - Ferme la connexion
net_connect.write_channel () - Écriture de bas niveau du canal
net_connect.read_channel () - Écriture de bas niveau du canal
56. Prise en charge de la copie sécurisée
L'extension des capacités de transfert de fichiers Secure Copy incluses dans
Netmiko devrait faciliter les mises à niveau du système d'exploitation et
d'autres opérations de transfert de fichiers.
Code tester sur Cisco IOS, IOS-XE, NX-OS, IOS-XR, Juniper Junos et Arista EOS.
Il s'agit à la fois des opérations de copie sécurisée «get» et «put» et comprend
également des méthodes associées qui vérifient si le fichier existe, qui
vérifient que l'espace disque est disponible et qui effectuent une comparaison
MD5 sur le fichier transféré.
Remarque: Le pilote Netmiko nécessite généralement l'activation d'un serveur SCP
sur le périphérique réseau distant.
57. Prise en charge de la copie sécurisée
En plus d'ajouter la prise en charge de la copie sécurisée pour des plates-formes
supplémentaires, une fonction «file_transfer» de niveau supérieur effectue un
transfert_fichier fiable. Cela devrait maintenant être l'interface principale
pour utiliser la copie sécurisée de Netmiko.
Voici les principaux arguments de la fonction file_transfer dans Netmiko :
def file_transfer(ssh_conn, source_file, dest_file,
file_system = None, direction='put',
disable_md5=False, overwrite_file=False):
En regardant les arguments, nous pouvons voir que 'file_transfer' prend une
connexion Netmiko SSH (ssh_conn), un fichier source et un fichier de destination.
58. Prise en charge de la copie sécurisée
Nous pouvons également voir qui ont un argument facultatif pour spécifier le
système de fichiers. De plus, il existe des systèmes de fichiers par défaut
inclus dans le code Netmiko. Les systèmes de fichiers par défaut sont les
suivants:
Cisco IOS/IOS-XE/IOS-XR Auto detects the file-system
Cisco NX-OS bootflash:
Arista EOS /mnt/flash
Juniper Junos /var/tmp
59. Prise en charge de la copie sécurisée
Le comportement par défaut de la fonction file_transfer est un transfert de
fichier idempotent.
En d'autres termes, Netmiko vérifiera d'abord si le fichier existe déjà, puis
calculera et comparera le MD5 du fichier. Si le fichier existe déjà et a le bon
MD5, alors Netmiko ne transférera pas le fichier.
Par défaut, 'file_transfer' a l'argument overwrite_file défini sur False, donc si
le fichier existe déjà (et que le MD5 ne correspond pas), il n'écrasera pas le
fichier.
On peut modifier ce comportement en spécifiant overwrite_file = True.
On peut également désactiver le calcul MD5. Vous pouvez éventuellement choisir de
le faire car le calcul MD5 sur les gros fichiers est très lent sur certains
périphériques réseau.
60. Prise en charge de la copie sécurisée
La fonction 'file_transfer' retournera un dictionnaire avec la structure
suivante:
{
'file_exists': True,
'file_transferred': True,
'file_verified': True
}
La clé 'file_verified' indiquera si la vérification MD5 a réussi. En général,
cela doit toujours être True ou une exception Python doit être déclenchée (sauf
si vous désactivez explicitement la vérification MD5 à l'aide de disable_md5 =
True).
$ python test_file_transfer.py
61. Prise en charge de la copie sécurisée
La clé 'file_exists' indique que le fichier transféré existe maintenant. Dans le
cas d'une opération «put», cela signifie que le fichier se trouve sur le système
distant. Dans le cas d'une opération «get», cela signifie que le fichier est
maintenant sur le système local (le système qui exécute le script Python).
La clé 'file_transferred' indique si le fichier devait être transféré ou était
déjà correct.
Voici le résultat de l'exécution de ce script. Remarque, j'ai ajouté quelques
commentaires et espacement pour plus de clarté:
62. Prise en charge de la copie sécurisée
Execution test_file_transfer.py
Password:
# Cisco IOS Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
# Arista Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
# Juniper Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
63. Prise en charge de la copie sécurisée
Execution test_file_transfer.py
Password:
# Cisco IOS Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
# Arista Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
# Juniper Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
# NX-OS Device
{'file_exists': True, 'file_transferred': True, 'file_verified': True}
Hit enter to continue:
64. Prise en charge de la copie sécurisée
Voici l'avant et l'après sur chacun de ces appareils:
# Cisco IOS Before
pynet-rtr1#dir flash:/testa.txt
%Error opening flash:/testa.txt (File not found)
# Cisco IOS After
pynet-rtr1#dir flash:/testa.txt
Directory of flash:/testa.txt
67 -rw- 12 Ven 31 2020 11:45:10 -08:00 testa.txt
# Arista Before
pynet-sw1#dir flash:/testa.txt
Directory of flash:/testa.txt