Internet of Things : une Grotte Connectée

On y a retrouvé des ossements d'ours vieux de 40'000 ans av. J.-C ! Et cette grotte s'est évidemment formée bien avant cela encore. Pourtant, la vieille dame s'est récemment équipée de la dernière technologie disponible. On parle de Cloud Computing, d'Internet-of-Things, de Monitoring, de Data Analytics... 

Grâce à cela, il est désormais possible de surveiller la montée des eaux en temps réél (presque) et d'annuler de longues expéditions avant d'être confrontés aux dangers que représentent les crues. En corrélant les données de pluviométrie régionale avec les relevés issus de la cavité, nous avons pu visualiser le temps s'écoulant entre le début des précipitations et la montée des eaux souterraines.

Cet article présente uniquement la solution mise en oeuvre du point de vue informatique.

Dashboard Grafana

Exemple d'une crue

L'outil permet d'afficher une crue spectaculaire : cette sonde de pression mesure habituellement 1m10 d'eau... La grotte est noyée en très grande partie !

Montée du Lac Titanic, 30m en quelques heures.

 

Montée rapide, même événement, avec les relicas

Exoscale

Exoscale est la plateforme de Cloud Computing choisie pour ce serveur. Arguments:

  • SLA élevé et qualité du support reconnue
  • Données en Suisse (le serveur est à Genève, backups à Zürich, sur l'object storage S3)
  • Très bon rapport Prix/Performances, voir le calculateur
  • Mon serveur est fourni avec une adresse IP publique (ou plusieurs)
  • Self-service
  • Provider Terraform existant, support de Cloud-Init, hosting zone DNS, Object-Storage S3 disponible et bon marché.
  • Plus simple et plus sérieux comparé à un Raspberry Pi.

Terraform & Exoscale

Avoir documenté la solution via Terraform et l'utilisation d'Exoscale facilitent les scénarios suivants:

  1. Tests (une machine similaire est générée rapidement)
  2. Changements / Lifecycle (Snapshots de la VM avant changements)
  3. Upgrade (une machine est générée, puis les données sont migrées. On évite le risque du patching)
  4. Récupération en cas d'avarie (une machine identique est réinstallée, puis les données et la configuration sont récupérées depuis le backup)

Les composants

  1. Cavelink : créé par Felix Ziegler, il s'agit d'un équipement radio qui collecte les données collectées (sondes, dans la grotte) et transmet périodiquement ces informations à travers des centaines de mètres de roche. Les données sont ensuite mise à disposition sur un serveur web (HTML)
  2. speleo-OWDL : un scraper écrit en Python, qui récupère les données Cavelink et les envoie dans une base de données (Time Series DB). Il est basé sur la librairie "Cavelink" (Open Source également).
  3. Service NetAtmo : NetAtmo propose des stations météo connectées, très design et heureusement assez répandues. Certains utilisateurs publient gratuitement leurs données sur le site WeatherMap. Les données de pluviométrie sont également collectées par Speleo-OWDL.
  4. Serveur InfluxDB : sur Exoscale, cette machine collecte les données, les conserve sur le long terme et les restitue avec de bonnes performances. Le choix d'InfluxDB me vient du conseil d'un collègue. Plus simple à mettre en place, m'avait-il-dit. Et c'est vrai !
  5. Serveur Grafana : une application de Dashboarding qui permet de visualiser les données sous forme de graphiques, de corréler les informations et de surveiller les évolutions. De plus, Grafana permet de déclencher des alertes en cas de dépassement de seuils.
  6. Service Telegram : une application mobile de messagerie, qui supporte la création de Bots. Un bot reçoit les alertes Grafana et les adresse à la communauté de spéléologues intéressés.
  7. Projet (pas encore réalisé) : une application Lametric qui permet de suivre les évolutions et notifier le début de crues, le moment de changer les piles, etc.
  8. Projet (pas encore réalisé) : implémentation de HashiCorp Vault, de façon à aller plus loin avec le plan Terraform. Ainsi, les "secrets" seront bien gardés et l'injection de clés d'API "à la volée" évitera les leaks dans des repos GitHub.

Collecte de métriques via Telegraf

Telegraf est un membre de la suite InfluxDB. Il se charge de la collecte de données, via des plugins (entrées/processing/sorties).

Je l'utilise pour la surveillance des données systèmes (CPU, RAM, Disk), mais également pour suivre fail2ban.

Avec la v2 d'InfluxDB, on remarque que les composants clés se retrouvent intégrés dans InfluxDB. Encore plus simple à déployer! Ainsi, InfluxDB arrive avec un outil graphique de génération/visualisation de requêtes (ex-Chronograf) prêt à l'emploi. On retrouve même un peu d'alerting (ex-Kapacitor). De quoi bâtir une solution simple très rapidement !

 

Monitoring Fail2Ban, janv. 2021
Monitoring Fail2Ban

Installation du serveur InfluxDB / Grafana via Terraform

L'installation de cette machine est documentée (infrastructure-as-code), générée via Hashicorp Terraform. On notera particulièrement la partie Cloud-init, supportée par Exoscale pour l'installation des prérequis. Le code est stocké sur GitHub, de façon à conserver les différentes versions. Il s'agit d'un repository privé, mais un extrait est livré ci-dessous. Ce plan Terraform permet de récupérer une machine prête en quelques minutes.

data "exoscale_compute_template" "debian" {
  zone = "ch-gva-2"
  name = "Linux Debian 10 (Buster) 64-bit"
}

# Create instance and install:
# - InfluxDB 2.0.3
# - grafana v.7.3.6
# - lego v4.1.3

resource "exoscale_compute" "influxDB" {
  zone         = "ch-gva-2"
  display_name = "InfluxDB"
  template_id  = data.exoscale_compute_template.debian.id
  size         = "Small"
  disk_size    = 10
  key_pair     = "Sebastien Pittet"
  state        = "Running"
  reverse_dns = "influx.pittet.org."
  affinity_groups = []
  security_groups = ["default", "Influx DB and Grafana"]
  ip6 = true
  user_data = <<EOF
#cloud-config
timezone: Europe/Zurich
manage_etc_hosts: localhost

package_update: true
package_upgrade: true
package_reboot_if_required: true

packages:
 - fail2ban
 - unattended-upgrades
 - apt-transport-https
 - software-properties-common
 - gnupg2
 - python3
 - python-pip
 - virtualenv
 - git
 - jq
 - adduser
 - libfontconfig1
 - figlet
 - s4cmd

runcmd:
 - figlet $HOSTNAME -c -t -w 80 -f block > /etc/banner
 - sed -i 's/#MaxAuthTries 6/MaxAuthTries 2/g' /etc/ssh/sshd_config
 - sed -i 's/#MaxSessions 10/MaxSessions 2/g' /etc/ssh/sshd_config
 - sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
 - sed -i 's/#AllowAgentForwarding yes/AllowAgentForwarding yes/g' /etc/ssh/sshd_config
 - service ssh restart
 - rm /bin/pyton
 - ln -s /bin/python3 /bin/python
 - echo unattended-upgrades unattended-upgrades/enable_auto_updates boolean true | debconf-set-selections
 - dpkg-reconfigure -f noninteractive unattended-upgrades
 - [ wget, "https://dl.influxdata.com/influxdb/releases/influxdb2_2.0.3_amd64.deb", -qO, /root/influxdb2_2.0.3_amd64.deb ]
 - dpkg -i /root/influxdb2_2.0.3_amd64.deb
 - [wget, "https://dl.grafana.com/oss/release/grafana_7.3.6_amd64.deb", -qO, /root/grafana_7.3.6_amd64.deb ]
 - dpkg -i /root/grafana_7.3.6_amd64.deb
 - mkdir /root/lego
 - [wget, "https://github.com/go-acme/lego/releases/download/v4.1.3/lego_v4.1.3_linux_amd64.tar.gz", -qO, /root/lego/lego-v4.1.3.tar.gz ]
 - cd /root/lego
 - tar -xvzf /root/lego/lego-v4.1.3.tar.gz
 - mv /root/lego/lego /usr/bin
 - systemctl daemon-reload
 - systemctl enable grafana-server.service
 - systemctl start grafana-server
 - systemctl start influxdb

final_message: "The system is finally up, after $UPTIME seconds"
EOF

  timeouts {
    create = "60m"
    delete = "2h"
  }
}

# create / update DNS record
resource "exoscale_domain_record" "influx4-pittet-org" {
  domain      = exoscale_domain.pittet-org.id
  name        = "influx"
  record_type = "A"
  content     = exoscale_compute.influxDB.ip_address
  ttl         = 3600
}

# create / update DNS record for IPv6
resource "exoscale_domain_record" "influx6-pittet-org" {
  domain      = exoscale_domain.pittet-org.id
  name        = "influx"
  record_type = "AAAA"
  content     = exoscale_compute.influxDB.ip6_address
  ttl         = 3600
}

# Exoscale Firewall, allow traffic for InfluxDB and Grafana
resource "exoscale_security_group" "influx-security" {
  name        = "Influx DB and Grafana"
  description = "InfluxDB (8086), Grafana(3000)"
}

resource "exoscale_security_group_rules" "influx-security-rules" {
  security_group_id = exoscale_security_group.influx-security.id

  ingress {
    protocol  = "TCP"
    ports     = ["8086"]
    cidr_list = ["0.0.0.0/0", "::/0"]
  }

  ingress {
    protocol  = "TCP"
    ports     = ["3000"]
    cidr_list = ["0.0.0.0/0", "::/0"]
  }
}

Certificate Renew 

EXOSCALE_API_KEY=EXO...
EXOSCALE_API_SECRET=4q...
lego   --email="asdf@asdf.org" --domains="influx.pittet.org" --dns="exoscale" --path="/usr/local/share/lego" renew

 

Haut de page