P27 Réseau LoRaWAN
Présentation générale du projet
Contexte
Les réseaux bas débits, faible consommation et longue portée sont en plein essor pour des applications variées allant du suivi de troupeaux jusqu'aux villes intelligentes. Il est commun que certaines de ces applications manipulent des données sensibles. Il devient donc essentiel de penser à la sécurité des données échangées.
Description et objectifs
Le protocole LORA est un des protocole disponible actuellement qui permet le développement de réseaux de ce type. Dans ce projet, nous proposons alors de réaliser un réseau LoRaWAN, protocole réseau se basant sur la technologie LoRa. Au sein de cette architecture, nous retrouvons un concentrateur LoRa, qui sera déployé via une Raspberry Pi pour créer une station de base, ainsi que divers capteurs embarquant une radio LoRa qui échangeront avec la station de base. Une fois que ce réseau sera mis en place, nous évaluerons dans un second temps les possibilités d'attaque sur un tel réseau, aussi bien logicielle que radio, pour pouvoir proposer par la suite des contre-mesures à appliquer.
Planning
Phase | Tâche | Sem 1 | Sem 2 | Sem 3 | Sem 4 | Sem 5 | Sem 6 | Sem 7 | Sem 8 |
---|---|---|---|---|---|---|---|---|---|
Appropriation et mise en place des outils de développement | Recherche de matériel complémentaire | x | |||||||
Création et implémentation du shield | x | ||||||||
Découverte des différents protocoles et implémentations | x | x | |||||||
Déploiement du réseau | |||||||||
Évaluation des attaques possibles |
Tableau de bord
Semaine 1 // 08/01/18 - 12/01/18
Jour 1
- Recherche d'un shield réalisant l'interface entre la Raspberry Pi et le module récepteur LoRa permettant de créer une station de base. Cela permettra d'éviter la conception d'un PCB pour réaliser cet interfaçage. Voici quelques liens où l'on retrouve ce type de composant :
https://www.tindie.com/products/gnz/imst-ic880a-lorawan-backplane-kit/
https://shop.coredump.ch/product/ic880a-lorawan-gateway-backplane/
- Nous nous sommes rendus compte que réaliser une commande sur n'importe lequel de ces sites prendrait un temps conséquent puisque les stocks sont épuisés sur chacun de ces sites. Sur l'un d'eux, il était possible de récupérer le schematic de ce shield. J'ai donc été rencontré Thierry Flamen pour savoir si la conception du shield était possible en réutilisant ce schematic. Nous allons donc demander au service EEI de Polytech pour concevoir ce shield.
- Recherche d'une implémentation du protocole LoRaWAN pour pouvoir la flasher sur les différents nœuds du réseau. On veillera à trouver une solution qui ne se base pas sur l'IoT The Things Network puisqu'on ne sait pour le moment pas vraiment quelle est la politique d'utilisation de ce réseau et on souhaite éviter que toutes les informations transitant sur notre réseau LoRaWAN soient accessibles par d'autres utilisateurs ou bien que certaines personnes avec de mauvaises intentions aient accès au réseau.
Jour 2
- Installation de Raspbian et des outils nécessaires sur la Raspberry. Il faut que l'interface SPI soit activée pour que la Raspberry puisse communiquer avec notre station de base. Nous avons également écrit un script sur la Raspberry qui permet de reset notre station de base. Ce script sera appelé à chaque fois que l'on démarre notre Raspberry, pour activer la pin de reset.
- Documentation sur le fonctionnement de l'implémentation LoRaWAN et recherche de différents programmes permettant d'implémenter ce protocole pour pouvoir les tester et déployer notre réseau.
Tutoriel pour la configuration de notre Raspberry pour le bon fonctionnement avec la station de base :
Exemple d'une implémentation LoRaWAN pour notre station de base LoRa :
https://github.com/Lora-net/lora_gateway
Exemple d'une implémentation LoRaWAN pour nos noeuds LoRa :
https://os.mbed.com/teams/Semtech/code/LoRaWAN-demo-76/
Documentation sur l'implémentation LoRaMAC pour faire du LoRaWAN et comprendre le fonctionnement du protocole :
http://stackforce.github.io/LoRaMac-doc/index.html
http://www.ioi-labs.com/technologies/comprendre-reseau-lorawan
https://www.frugalprototype.com/technologie-lora-reseau-lorawan/
Tutoriel pour connaître le mappage des pins entre la Raspberry Pi et notre station de base et pouvoir initialiser notre module récepteur :
- En utilisant le dépôt GIT lora_gateway donné précédemment et le programme (util_pkt_logger) permettant de récupérer les paquets reçus sur notre station, il est possible de faire fonctionner la station de base et de récupérer les paquets transitant vers cette station en stockant toutes les informations associées aux paquets dans des logs sur notre Raspberry.
Jour 3
- On retrouve un exemple de déploiement d'un réseau LoRaWAN avec les liens suivants :
https://www.miscmag.com/lorawan-deploiement-dune-infrastructure-de-test-partie-1-2/
https://connect.ed-diamond.com/MISC/MISCHS-015/LORAWAN-deploiement-d-une-infrastructure-de-test
- Nous voulons maintenant faire fonctionner nos noeuds pour qu'ils puissent communiquer avec la station de base. On flashera nos STM32 avec le programme trouvé sur mbed.com (LoRaWAN-demo-76) en passant par le compilateur en ligne. On récupère ainsi un fichier bin que l'on copie sur notre microcontrôleur et celui-ci peut alors faire tourner notre programme.
- L'envoi des trames par les nodes devraient fonctionner correctement, formatées selon la spécification LoRaWAN. Cependant, du côté de la gateway, les trames reçues n'ont pas vraiment l'air d'être parsées selon cette spécification. Nous recherchons donc un autre moyen d'implémenter notre station de base. Nous avons trouvé quelques exemples qui utilisent un système de "packet forwarding" qui redirige les paquets reçus vers un serveur d'application qui traitera ces paquets, sans passer par le réseau TTN (The Things Network) :
https://github.com/Lora-net/packet_forwarder
https://github.com/gotthardp/lorawan-server
- Les deux premiers liens nous proposent de réaliser ce procédé en redirigeant les paquets vers un serveur personnel via une API appelée Logstash plutôt que de passer par TTN. Le dernier décrit un serveur LoRaWAN qui prend entièrement en charge la redirection de paquets ainsi que le traitement de ceux-ci, ce qui nous permettrait de pouvoir traiter toutes nos données sur la Raspberry. Nous testerons cet exemple en premier lieu.
Jour 4
- Récupération du PCB au service EEI qui est le shield permettant d'interfacer la Raspberry avec notre station de base.
- Soudures des broches sur le PCB pour pouvoir connecter directement les pins du module LoRa à la Raspberry Pi.
- Le shield n'alimente pas correctement notre station de base. Après plusieurs essais, nous nous sommes rendus compte que la broche d'alimentation pouvait être court-circuité ou bien pas suffisamment soudée.
Jour 5
- Nous cherchons à faire fonctionner notre shield. Après avoir discuté avec quelques professeurs, nous avons pu comprendre que tous les vias de notre PCB n'étaient pas effectifs. En effet, les PCBs réalisés au service EEI ne sont pas métallisés, ce qui empêche les vias de pouvoir conduire le courant entre les deux faces de notre PCB, qui est bien évidemment double face. Il a donc fallu dessouder tous les connecteurs pour pouvoir faire passer de fin fils à travers les trous qui doivent faire communiquer les deux faces pour les souder directement sur les pistes. Une fois cette chose faite, nous avons pu souder à nouveau les connecteurs comme il se doit.
- Après toutes ces manipulations concernant notre shield, celui-ci est donc fonctionnel. Nous pouvons à présent nous concentrer sur la partie logicielle du projet, à savoir déployer notre réseau LoRaWAN.
Semaine 2 // 15/01/18 - 19/01/18
Jour 6
- Nous sommes repartis sur nos recherches pour pouvoir déployer un réseau LoRaWAN. Ne comprenant pas pourquoi notre station de base ne recevait presque aucun paquet, nous sommes partis de la base pour comprendre le problème. Nous avons voulu nous assurer que les nodes LoRa fonctionnaient correctement et pour cela nous avons testé un simple programme de ping pong entre deux nodes. Cela s'est révélé être un succès :
- Nous voulons maintenant tester si notre station de base arrive à bien recevoir des paquets. Nous savons déjà qu'elle arrive à en émettre en utilisant un programme de test du projet "lora_gateway" récupéré sur le github officiel Lora-net. Nous avons aussi ajouté une antenne à notre station de base ce qui facilitera grandement les communications radios, ce qui était sûrement la raison d'une réception partielle de paquets. Cependant cette modification ne semble pas apporter de gros changements.
- Après des recherches complémentaires, nous avons trouvé un autre moyen de déployer un réseau LoRaWAN à notre manière sans passer par le réseau TTN (les liens se retrouvent au jour 3), en utilisant un serveur open-source que l'on configure soi-même du début à la fin :
Jour 7
- Nous n'arrivons toujours pas à une réception convenable des paquets sur la station de base. Nous avons modifié la configuration du module pour qu'il ne réceptionne pas que des paquets LoRa avec une en-tête MAC. C'était possible que cela soit une source d'erreur cependant cela ne change pas grand chose. En regardant les retours sur le github de notre programme, nous avons pu remarqué que, comme dans notre cas, des personnes arrivent à émettre avec la station de base mais pas à recevoir. Dans la majorité des cas cela était dû à une alimentation qui ne fournissait pas une tension suffisante. Nous avons alors vérifier que nous avions du 5V aux bornes de notre station, ce qui était bien le cas.
Jour 8
- Après avoir modifié le code du ping pong pour un node en ne faisant qu'envoyer une trame toutes les secondes qui est "COUCOU", on réceptionne bien les paquets sur notre station de base, à quelques détails près.
- En effet, dans notre fichier de logs, on remarque que la taille de la payload est bien de taille 7, ce qui correspond à notre chaîne de caractères. On retrouve bien les mêmes paramètres de communication radio à savoir un Spread Factor de 7 et une bande passante de 250 kHz. Cependant on remarque que notre chaîne de caractères est altéré lors de la communication puisqu'on ne retrouve pas exactement la même chaîne de caractères sur la station de base. Après avoir décodé la payload via la table ASCII, on retrouve certains lettres qui sont correctes, d'autres non.
- De plus, on remarque également sur les timestamps que l'on ne reçoit pas réellement de paquets chaque seconde. Il peut passer un certain temps sans que l'on ne reçoit de trames. La station doit sûrement rejeter certains paquets pour une raison particulière.
Jour 9
- Après avoir été dans l'incompréhension durant toute une journée, nous avons enfin compris le mode de fonctionnement du concentrateur LoRa. En effet, en réutilisant le programme de ping pong basique et juste en jouant avec les paramètres du signal, nous avons réussi à récupérer correctement les trames envoyées par l'émetteur.
- Pour cela, il était indispensable de régler les paramètres de l'émetteur pour qu'ils correspondent à l'une des channels de notre station de base, ce qui signifie une certaine fréquence radio, bande passante et un certain spread factor parfois. On a alors nos trames qui sont réceptionnées au bon moment et avec la bonne payload, à savoir le message "PING" suivi d'octets de padding. De plus, il était nécessaire de permettre au concentrateur de récupérer toutes les trames LoRa qui transitent et pas seulement celles respectant la certification LoRaWAN. Pour cela, on règle le paramètre correspondant dans la configuration du programme.
- En réalisant ces tests, nous avons pu noter également que la modification du spread factor des signaux envoyés entraînait une modification de la puissance d'émission. En effet, au plus le spread factor est grand, au plus les trames envoyées seront facilement "captées" par le concentrateur, c'est-à-dire à une puissance plus élevée.
- Maintenant que nous avons testé le bon fonctionnement de notre matériel, nous pouvons passer à l'implantation du serveur LoRaWAN sur la Raspberry Pi
- Pour cela, nous allons utiliser un ensemble d'outils appelé ELK Stack, qui nous permet finalement de réaliser de l'analyse de logs. Plus précisément, ces outils nous permettront de récupérer les logs ou les payloads des trames reçues pour les envoyer vers un serveur applicatif et ainsi pouvoir traiter ces données. Pour cela, nous allons utiliser un de nos précédents liens (blog trifork) qui propose de découvrir ces outils et de faire une implémentation d'un serveur LoRaWAN sans passer par le réseau TTN, mais aussi le lien suivant qui est un tutoriel pour déployer l'ELK stack sur la Raspberry :
https://logz.io/blog/elk-stack-raspberry-pi/
Jour 10
- Nous continuons sur l'implémentation de notre ELK Stack, qui pose quelques difficultés étant donné que l'on souhaite la réaliser sur une Raspberry. La manière standard de procéder ne s'applique pas vraiment aux architectures ARM comme celle de notre Raspberry. Voici d'autres liens qui nous permettent de mieux comprendre comment procéder sous Raspbian :
http://www.intranetofstuff.com/the_tools/elk-stack.html
https://thesecuritystoic.com/2017/08/home-security-iii-elk-on-a-raspberry-pi/
Semaine 3 // 22/01/18 - 26/01/18
Jour 11
- Après avoir réglé tous les différents problèmes que nous avons pu avoir pour implanter notre ELK stack, celui-ci est désormais opérationnel. Pour rappel, cet procédé nous permet de récupérer, indexer, traiter et analyser nos logs d'une manière conviviale via une interface web, qui permet la réalisation de dashboards et d'analyser les critères que l'on souhaite pour les différentes données reçues. En plus de ce stack, nous utilisons également le service Nginx qui nous permet d'accéder à notre application web Kibana sur le navigateur directement, depuis n'importe quel autre ordinateur si l'on connaît l'adresse IP de notre Raspberry Pi. A la base, nos logs sont fournis par une implémentation TTN pour un gateway LoRaWAN, qui va récupérer les paquets LoRa reçus pour les transformer en logs, plus faciles à lire. Cependant, au lieu de passer par le réseau TTN pour faire transiter nos logs, nous passons par Logstash, un des services du ELK stack, qui permet de récupérer des logs bruts et de faire en sorte que notre stack puisse les comprendre et les interpréter (via ElasticSearch).
- En général, ce genre d'application est utilisé pour faire du cloud sur un serveur à distance, mais nous l'utilisons ici pour faire de la récupération de données sur notre Raspberry localement. De plus, nous allons gérer une quantité limitée de données, à savoir juste les paquets reçus sur notre petit réseau LoRaWAN. Les ressources de la Pi sont donc amplement suffisantes pour notre cas de figure. Ce n'aurait pas pu être possible si nous voulions faire du traitement de données à grande échelle.
- Nous sommes donc maintenant capable de récupérer tous les paquets LoRa transitant vers notre station de base, et d'analyser ces trames directement sur Kibana. Cependant, nous n'arrivons pour le moment pas encore à récupérer les paquets certifiés LoRaWAN. De plus, il sera nécessaire d'ajouter un plugin sur notre ELK stack pour pouvoir décrypter les trames reçues par la station de base. En effet, selon la certification LoRaWAN, les paquets sont cryptés à deux reprises avec deux clés différentes. Pour pouvoir récupérer la payload d'un paquet, il sera nécessaire de décrypter le contenu de ce paquet.
- On récupère bien notre payload envoyé par l'émetteur. Celle-ci est seulement encodée en base64 par notre implémentation de gateway TTN. Après décodage, on récupère bien le bon message.
Jour 12
- Nous arrivons maintenant à récupérer nos paquets LoRaWAN sur notre interface web. Le souci est que l'on n'arrive pas à échanger des données dans nos paquets.
- En effet, en utilisant un décodeur de paquets LoRaWAN pour analyser le contenu d'un paquet ( https://lorawan-packet-decoder-0ta6puiniaut.runkit.sh/ ), on remarque que tous les paquets reçus sont en fait des "join request" exclusivement. Cela signifie que notre node demande à notre station de base une confirmation pour pouvoir échanger, cependant il ne semble pas recevoir de "join accept".
- Après quelques recherches dans les logs système liés au service de "packet forwarder" installé sur la gateway, on remarque que pour tous les paquets envoyés vers notre interface web, on ne reçoit aucun ACK ou acknowledgment via notre service lorsque l'on fait un "PUSH DATA", autrement dit lorsque notre gateway envoie des logs au service Logstash, qui fait la liaison entre la gateway et notre interface web Kibana. Le service semblerait alors ne fournir aucune confirmation au node de ce fait, c'est-à-dire de lui envoyer un "join accept" pour que les deux entités puissent enfin échanger des données.
- Par conséquent, on peut en déduire qu'il est alors normal que notre gateway ne reçoit aucun paquet sur le downstream de la part de Logstash. La gateway ne renverra donc aucun paquet vers notre noeud.
Jour 13
- Après quelques discussions avec les encadrants, nous nous sommes rendus compte que l'implémentation de notre serveur LoRaWAN n'était pas viable et cela ne pouvait correspondre aux attentes du projet.
- Effectivement, cette implémentation ne permet que de transmettre tous les paquets reçus sur la gateway vers notre ELK stack, sans réaliser aucun traitement sur nos paquets, à savoir être capable d'évaluer un join request pour répondre par un join accept par exemple. Nous avions suivi des exemples d'implémentations qui permettaient d'utiliser l'implémentation du serveur LoRaWAN du réseau TTN, mais sans passer par ce réseau et en redirigeant tous les paquets en local.
- Cette configuration était alors fonctionnelle mais il semblerait que le serveur LoRaWAN en tant que tel se retrouve sur le réseau TTN. C'est ce fournisseur d'accès qui s'occupe du traitement des paquets, de les décrypter ...
- Nous nous tournons donc vers une autre implémentation de serveur LoRaWAN en retournant sur nos pas et en utilisant un précédent lien que nous avions trouvé, qui devrait cette fois-ci gérer également le protocole LoRaWAN en plus de jouer le rôle du "packet forwarder" :
Jour 14
- Mise en place de l'implémentation du serveur LoRaWAN avec la référence donnée hier.
- L'interface web est fonctionnelle et accessible en local. On utilise VNC pour pouvoir accéder à cette interface. Les paquets sont bien reçus par notre "packet-forwarder", même service que dans l'ancienne implémentation pour faire l'interface hardware/software sur notre gateway.
- En utilisant le service Mosquitto, on peut également voir le trafic des paquets sur ce MQTT Broker, qui nous permet de récupérer les paquets envoyés par UDP par le "packet-forwarder" et de les transmettre via le protocole MQTT à notre serveur réseau.
- Il faut maintenant administrer nos différents nœuds sur cette interface web pour que des trames de données puissent être échangées entre la gateway et ces nœuds.