Nous répondons au vandalisme des câbles rapidement, partout et sans pièges physiques

Salut

Il y a une volonté de partager avec la communauté une idée qui est mise en œuvre chez l'entreprise prestataire pour répondre rapidement aux dommages du câble cuivre. Il s'agit de paires torsadées et d'Ethernet. Bien sûr, je ne prétends pas être des solutions élégantes, mais le service a donné de bons résultats.

image

Pour ceux qui sont trop paresseux pour lire. Comment ça marche: surveiller la chute des séances sur le rayon, grouper par interrupteurs, tester la ligne, notification casque.

Je ne peux pas donner l'intégralité du code du projet pour des raisons professionnelles, mais je vais supprimer celui qui se trouve sous les spoilers pour les personnes intéressées. Oui, et la mise en œuvre pour chaque fournisseur variera. L'objectif est plutôt de partager une idée qui pourrait aider quelqu'un.

L'équipement de l'entreprise est à 99% D-Link, donc les MIB SNMP sont répertoriés pour ce fournisseur. Certains d'entre eux sont des RFC et devraient convenir à d'autres fabricants.

Un peu d'histoire sur la façon dont tout cela est sorti.

Tout a commencé au printemps 2018. La charge sur le groupe de support technique (TP) a augmenté. En plus de traiter les appels des abonnés, TP a également coordonné les installateurs lors de la connexion de nouveaux abonnés, ainsi que lors du départ pour la restauration et le débogage des clients existants. Il a fallu décharger un peu le TP et donner quelques outils aux installateurs. Il a été décidé de composer un «bot» de messagerie qui accepterait la connexion / le contrat de l'abonné et l'installateur pourrait effectuer le débogage minimum directement dans les champs.

Je ne voulais pas intégrer toutes les fonctionnalités dans une seule application, car en fait, une telle fonctionnalité serait utile également dans le navigateur du même CRM lors du traitement d'un appel, il a donc été décidé de mettre les mécanismes d'interaction avec l'équipement réseau, la facturation, le rayon dans un service distinct, d'en faire une API et de connecter à la fois le bot et le CRM via l'API et c'est tout peu importe.

Maintenant, un peu de code et passons à l'essence de la publication.

Et donc, de quoi un installateur peut-il avoir besoin dans les domaines:

  1. Test de câble bien sûr
  2. Afficher les erreurs de port
  3. Afficher l'état du port
  4. Vérifiez s'il y a des adresses MAC sur le port. (soudainement, l'abonné a branché le câble sur le port LAN au lieu de WAN)
  5. Abonnement IPTV
  6. Afficher les journaux d'autorisation
  7. Statut du solde

Nous interagirons avec les commutateurs via SNMP, et à certains endroits via telnet.

J'ai utilisé Bottle comme framework web.

Et donc

nous importons le nécessaire
#!/usr/bin/python # -*- coding: utf_8 -*- from bottle import route, run, template, auth_basic, request, error from lib import crm, snmp, gis, billing import time 


Nous ajoutons une feuille avec des clés API et des décorateurs pour vérification, mais nous ne donnerons pas de données à tout le monde de suite).

code
 apikeys = ['RANDOM_KEY1', 'RANDOM_KEY2'] api_error = '{"error":"apikey invalid"}' host_down_error = '{"error":"host down"}' def apikey_checker(fn): def wrapper(*args, **kwargs): if not check_apikey(): return api_error return fn(*args, **kwargs) return wrapper def check_apikey(): return 'apikey' in request.query and request.query['apikey'] in apikeys 


Eh bien, en fait, quelques fonctions pour interagir avec l'équipement.

code
 @route('/port_status/<ip>/<port>') @apikey_checker def get_port_status(ip=' ', port=' '): return snmp.port_status(ip, port) @route('/cable_test/<ip>/<port>') @apikey_checker def get_cable_test(ip, port): return snmp.cable_test(ip, port) 


À l'intérieur de snmp, nous avons un dictionnaire avec l'interprétation des statuts SNMP retournés de la paire sur le port.

Dictionnaire d'état

 pair_status = { '0': 'ok', '1': 'open', '2': 'short', '3': 'open-short', '4': 'crosstalk', '5': 'unknown', '6': 'count', '7': 'no-cable', '8': 'other' } 


Préparation du dictionnaire pour le résultat de la mesure du port. Nous le copierons pour ne pas en refaire un à chaque fois.

Texte masqué
 pair_result = { 'pairs': { 1: { 'status': '-', 'length': '-' }, 2: { 'status': '-', 'length': '-' }, 3: { 'status': '-', 'length': '-' }, 4: { 'status': '-', 'length': '-' }, } } 


Fonction

test de câble
 def cable_test(ip, port): if not check_ip(ip): #        IP return {'error': "IP %s invalid" % (ip)} host_status = check_host(ip) #       if host_status['status'] == 'down': return {'error': u" "} result = copy.deepcopy(pair_result) #   ,   UP, ..     #     . if port_status(ip, port)['status'] == 'down': try: mib = '.1.3.6.1.4.1.171.12.58.1.1.1.12.%s' % str( port) #      #         snmp_int_set(ip, mib, 1) time.sleep(1) #    result['pairs'][1]['status'] = pair_status[ snmp_get(ip, '.1.3.6.1.4.1.171.12.58.1.1.1.4.%s' % str(port))] result['pairs'][2]['status'] = pair_status[ snmp_get(ip, '.1.3.6.1.4.1.171.12.58.1.1.1.5.%s' % str(port))] result['pairs'][3]['status'] = pair_status[ snmp_get(ip, '.1.3.6.1.4.1.171.12.58.1.1.1.6.%s' % str(port))] result['pairs'][4]['status'] = pair_status[ snmp_get(ip, '.1.3.6.1.4.1.171.12.58.1.1.1.7.%s' % str(port))] result['pairs'][1]['length'] = snmp_get( ip, '.1.3.6.1.4.1.171.12.58.1.1.1.8.%s' % str(port)) result['pairs'][2]['length'] = snmp_get( ip, '.1.3.6.1.4.1.171.12.58.1.1.1.9.%s' % str(port)) result['pairs'][3]['length'] = snmp_get( ip, '.1.3.6.1.4.1.171.12.58.1.1.1.10.%s' % str(port)) result['pairs'][4]['length'] = snmp_get( ip, '.1.3.6.1.4.1.171.12.58.1.1.1.11.%s' % str(port)) return result except Exception as e: print(e) return {'error': u'    '} else: return {'error': u'    .   Link UP.'} 


la fonction reviendra

résultat
 { "pairs": { "1": { "status": "other", "length": "0" }, "2": { "status": "open", "length": "4" }, "3": { "status": "open", "length": "4" }, "4": { "status": "other", "length": "0" } } } 


Plus tard, il a ajouté une autre fonction similaire, exclusivement pour le script, il reçoit une liste de ports en entrée, et pas un, et ne vérifie pas l'état du port avant de tester, ce n'est pas nécessaire avec une baisse massive des liens.

Voilà à quoi ressemblait le bot

image

Passons maintenant à l'essentiel du poste.

Avant l'implémentation du débogage du serveur, une technologie similaire à celle décrite dans le post habr.com/post/188730 était utilisée . Boucle sur port avec échelle SNMP activée. Lorsque «l'avion» est tombé au port, un message à ce sujet est tombé dans la surveillance.

Tout d'abord, j'ai vissé le script de sorte que lorsque le lien de suivi est tombé, le serveur de débogage est allé au commutateur, a vérifié si le port était vraiment couché, et pas seulement clignoté, et les paires sur celui-ci étaient ouvertes ou court-circuitées, puis j'ai envoyé un message aux opérateurs.

Cependant, seulement environ 10% des commutateurs avaient de tels pièges physiques, et cela s'est avéré insuffisant.

Plus tard, est venu avec un rayon de moniteur. Et cela a permis d'augmenter le pourcentage de couverture de surveillance jusqu'à 100%. Et ici, tout diffère déjà de l'infrastructure du fournisseur.

Nous examinons périodiquement le nombre de sessions clientes tombées d'un commutateur particulier. Ceci est facile à faire si circuit_id est activé sur les commutateurs, qui a la forme

D4: CA: 6D: 0A: 66: C9 :: 192.168.20.86 :: 20

Ici, nous avons le MAC de l'abonné, le commutateur IP, le numéro de port de l'abonné. C'est-à-dire tout ce dont vous avez besoin pour le débogage.
Nous regroupons les sessions terminées par commutateur IP, s'il y a plus de quelques sessions de ce type (nous avons un déclencheur défini à 2 sessions par minute), le script contacte le serveur de débogage et teste les ports des sessions abandonnées. Si les ports sont toujours allongés et que les paires de câbles sont ouvertes ou court-circuitées et que la longueur d'au moins deux ports est la même (+ - 2 mètres), ce qui correspond exactement à la coupe du câble aux yeux du commutateur, nous considérons la situation comme suspecte et envoyons un message à l'opérateur.

Bien sûr, il y aura des faux positifs lorsque la lumière de la maison clignote, ou il coïncide simplement que les abonnés éteignent le câble en même temps et que la longueur est la même, mais c'est le cas, comme on dit, quand il vaut mieux en faire trop. De plus, vous pouvez limiter la longueur (ne répondre qu'aux courtes longueurs), le nombre de baisses simultanées, etc.

Voici le vrai rapport d'un événement suspect.

image

Et les résultats du traitement de ces messages

image

Il y a eu un cas où le script a envoyé un message similaire, et après quelques secondes, le commutateur s'est déconnecté, car optique endommagée, et sans la vitesse du logiciel, la situation aurait été confondue avec une panne de courant typique dans la maison.

Une autre fois, la société de gestion a commencé à réparer le toit sans avertissement, et VOKhR avec des mitrailleuses a survolé, stress soudain pour les serruriers.

Ainsi, le script a commencé à montrer de bons résultats et plus de 4 mois de travail, VOKhR, la police et les employés du fournisseur ont eux-mêmes mené à bien plus de 10 cas de vandalisme. J'ai donc décidé de partager le concept d'une telle surveillance.

Désormais, le script surveille environ 15 000 commutateurs sans aucun «piège» physique ni piège SNMP.

Bonne chance à tous dans la nouvelle année!

Source: https://habr.com/ru/post/fr434674/


All Articles