Depuis un an et demi, ma maison est complètement équipée en ampoules et accessoires Philips Hue. Et j'en suis ravi.

Les lieux de passage sont couverts par des Hue Motion Sensor qui y commandent les lampes. Plus d'interrupteurs à actionner dans les escaliers ou le couloir, luminosité variable suivant l'heure, c'est top.

Mais depuis quelques semaines, les lampes ne se rallumaient plus après qu'elles se soient éteintes. En fonctionnement normal, le capteur détecte un mouvement, déclanche les lumières, qui s'éteignent après une minute si aucun mouvement n'est détecté. Et rebelote si un nouveau mouvement est détecté.

Las, ces derniers temps, les lampes ne se rallumaient pas dans les 2-3 minutes après l'extinction.

J'ai tenté de réinitialiser les capteurs. Sans succès. 😕 À cette occasion, j'ai constaté que l'appli avait du mal à associer le capteur à une pièce.

Donc j'ai changé les piles. Sans succès. 😐

J'ai échangé le capteur de la cuisine qui fonctionne bien avec celui du couloir. Sans succès. 😑 J'ai contacté le support Philips pour tenter de faire échanger un des capteurs au cas où il s'agissait quand même d'une panne. Le mec du support m'a alors appris que le pont Hue ne supporte que 10 accessoires (en fait 12 😒). J'ai 16 accessoires au total...

J'ai acheté un nouveau pont que j'ai ajouté à mon installation. Sans succès. 😣 À cette occasion, j'ai appris que l'appli ne permet pas de gérer plusieurs ponts à la fois. Il faut basculer de l'un à l'autre, et je ne peux pas faire interagir les lampes et accessoires de l'un avec les lampes et accessoires de l'autre... Pire encore, on ne peut associer un compte Philips qu'à un pont Hue, donc pour accéder au deuxième pont à distance, il faut un deuxième compte... Et on touche le fond avec le fait que la skill Alexa ne peut s'associer qu'avec un seul compte Philips...

J'avais dans l'idée de séparer mes équipements par étage, mais là j'ai séparé entre lumières automatiques (lieux de passage), et lumières manuelles (pièces). Je peux donc encore commander les lumières des pièces de vie à la voix, et les lumières automatiques vivent seules (dans ce cas un peu trop seules mais bon 😒).

À ce point, j'ai pris quelques niveaux de plus en expertise en Hue. J'ai découvert que le pont avait un serveur web intégré via lequel il peut communiquer avec les applis. Pas juste l'appli officielle, mais aussi des applis tierces, comme Hue Essentials, qui propose des réglages plus avancés que l'appli officielle au prix d'une interface plus... Sobre. 😐 Cerise sur le gâteau, Hue Essentials permet de se connecter à plusieurs ponts simultanément (for a price). Mais Hue Essentials n'a pas de skill Alexa... 🙄

Mais tout ça ne résout pas mon problème... Après avoir trituré le problème dans tous les sens, et cherché sur le net sans avancées majeures - peu de sujet très pointus sur Philips Hue, étant un produit grand public qui marche quasi-seul, j'ai remarqué un point : les capteurs de la salle de bains et des toilettes fonctionnement tous correctement.

La seule différence entre les cateurs des salles d'eau et des lieux de passage, c'est que la salle de bains et les toilettes sont des pièces sans fenêtre, qui doivent s'allumer sans condition de luminosité. Et en effet, si je règle le capteur du couloir pour s'allumer sans s'occuper de la luminosité ambiante, ca marche bien... Mais je ne veux pas que ça s'allume en journée quand il fait clair. 🤔

Maintenant que j'ai une piste sérieuse, je recherche à nouveau avec cette notion de luminosité. Là un fil Reddit m'apprend que les capteurs Hue Motion Sensor mettent à jour la valeur de luminosité ambiante toutes les 2 minutes ou quand un mouvement est détecté. Et le pont récupère la valeur toutes les 2 minutes. Donc soit le capteur n'envoie pas la valeur mise à jour, soit le pont ne récupère pas la dernière valeur, la luminosité est jugée suffisante et la ampe ne s'allume pas.

Le même fil Reddit me suggère d'utiliser une appli tierce comme HomeKit pour paramétrer le comporte du capteur. Mais je n'utilise pas de produit Apple. Heureusement, je connais une très bonne appli tierce partie, Hue Essentials. 😉

Et en effet, Hue Essentials me propose de réinitialiser les valeurs de déclanchement, que je programme à l'identique de mes réglages de l'appli officielle.

Et les lampes fonctionnent comme je veux ! 😄

Après des semaines, et 50 € de pont Hue, mon problème est réglé par une appli tierce gratuite... 😒

Je soupçonne une mise à jour de Philips d'avoir causé le problème au départ. Soit l'appli officielle (qui a un nouveau réglage de sensibilité dans les capteurs), soit le pont (le nouveau pont a reçu une mise à jour bien qu'il soit flambant neuf - je ne connais pas la date de fabrication toutefois). Vu que Hue Essentials considérait les réglages des capteurs issus de l'appli officielle comme caviardés, il est possible que l'appli officielle soit en cause...

Ça fait bientôt 10 ans que j'ai pas changé d'ordinateur.

Enfin un peu moins, parce que j'ai fait une connerie, il y a quelques années, j'ai flashé le BIOS de ma carte mère MSI (je ne me rappelle plus du modèle), et les mecs de chez MSI n'ont pas jugé nécessaire de me prévenir que ça apportait la compatibilité avec les processeurs série 3000 de chez Intel, et qu'il fallait un tel processeur pour finir la mise à jour. En la faisant avec un i7 2600, ça foire le BIOS, et ça foire la carte. Elle ne reprend pas même en remettant un processeur série 3000... 😑

Apparté plus tard, donc j'avais un i7 2600. Après ce malheureux incident, j'ai dû acheter un i5 6600 (moins cher possible au plus proche des perfs). Depuis donc 10 ans, j'ai peu ou prou la même machine. Juste la carte graphique qui a changé deux fois, pour à chaque fois presque doubler de perf.

Mais depuis, j'ai un nouveau hobby. 😅 Je rippe mes Blu-Ray. 😁 Je rippe mes Blu-Ray 4K, même. Mais sur un i5 6600, 2h de film sont encodés en 24 heures... 😑

Depuis 10 ans, j'avais accepté la notion de stagnation des CPU. Chez Intel, à moins de prendre un modèle vendu 1000 $, je n'avais pas de CPU qui avait le double de perfs de mon i7 2600 ou de mon i5 6600.

Mais.

Il y a 3 ans, AMD est revenu en force, avec Ryzen. Ils avaient enfin à nouveau des CPU très performants, à des fractions de prix chez Intel. Les premiers modèles étaient très bons en calculs et multithreading mais en recul sur les jeux. La 3e génération s'avère plus équilibrée, et j'ai sauté le pas. J'ai acheté un Ryzen 7 3700x. C'est un processeur 8 cores 16 threads qui fait de l'ombre aux modèles Intel presque deux fois plus chers. C'est un truc de brute. 😁 

Dans mon usage, le réencodage de Blu-Ray, la différence est immédiatement visible. Je passe de 24 heures d'encodage en x265 pour 2 heures de film à 12 ou même 8 heures ! Incroyable. 🤩

Qui dit changement de processeur dit changement de carte mère. Surtout quand on change de marque. 😅 Et honnêtement je ne comprends pas le délire des constructeurs à proposer des  cartes mères à plus de 200 €, même jusqu'à 500 €, en ajoutant des cartes WiFi et autres...

J'ai fait au plus simple, mon seul impératif était le chipset X570, qui supporte le PCI-e 4.0 avec les Ryzen 3000. J'ai pris une Asus Prime X570-P, qui a l'avantage d'avoir pas mal de ports USB sur le panneau arrière. Moi qui en fais grande consommation, c'est tout bon !

Et enfin, la RAM, qui passe de DDR3 à DDR4. Le i5 6600 fonctionne normalement avec de la DDR4, mais à l'incident précédent j'avais essayé de ruser et de réutiliser ma RAM existante en rachetant juste le processeur et une carte mère qui support le DDR3. Mais j'ai fini par en racheter... 😑 Amazon avait une promo intéressante sur un kit de 2 x 8 Go HyperX Fury à 50 €, j'ai sauté dessus. Elles n'ont pas des fréquences de folie (2666 MHz), mais pour le peu que la vitesse de RAM apporte, ça me suffit amplement.

Voilà, au bout de presque 10 ans, je suis à nouveau (presque) au top. Juste la carte graphique qui pourrait être meilleur, mais une GeForce GTX 1070 c'est pas la rue non plus. 😉 Avec une GeForce RTX je serais monté en classe MDP, mais bon. 😅

Dans une autre vie, j'avais expliqué comment implémenter un Postgrey sur un Postfix (bon je me suis rendu compte que la page qui m'a expliqué comment faire un Postfix avait disparu, va falloir trouver un remplacement, ou en réécrire une... 🤔).

Là je me suis rendu compte qu'au boulot, en utilisant un serveur mail hébergé chez OVH, Google avait tendance à rejeter certains mails (on fait de la pub pour nos activités...). Je suppose que des gens mal intentionnés abusent des offres d'OVH pour faire nimp. 😑

Mais Google est sympa, il m'indique comment éviter de me faire bloquer : Pourquoi Gmail a-t-il bloqué mes messages ? et Envoyer des messages en masse Consignes pour les expéditeurs.

Dans les consignes pour les expéditeurs d'envoi en masse, il recommande l'authentification des messages, en utilisant SPF, DKIM et DMARC.

SPF

SPF, pour Send Policy Framework, sert à vérifier le nom de domaine d'un expéditeur de mail, avec un enregistrement DNS. C'est le plus facile. 😉

Normalement, seul le propriétaire d'un domaine peut en modifier les enregistrements DNS. Donc si on consulte le DNS pour savoir quelles sont les adresses autorisées à envoyer du mail, on peut facilement discriminer les envois bidons (dons les spams).

Et ça se fait aussi simplement qu'en ajoutant ça au fichier hôte :

valken.org   IN   TXT   "v=spf1 include:_spf.google.com ~all"

En gros ça dit que pour le domaine valken.org, les hôtes autorisés à envoyer du mail sont seulement ceux indiqués. Ici _spf.google.com, vu que c'est GMail qui gère mes mails.

On peut vérifier que l'inscription est correcte en interrogeant le DNS (blabla édité) :

$ dig txt valken.org

;; QUESTION SECTION:
;valken.org. IN TXT

;; ANSWER SECTION:
valken.org. 3600 IN TXT "v=spf1 include:_spf.google.com ~all"

On obtient bien la même chose qu'on a mis, donc c'est good !

Dorénavant, les mails présentant le domaine valken.org qui ne provient pas des adresses précisées pourront être suspectées de spam.

DKIM

DKIM, ou DomainKeys Identified Mail, sert à garantir l'origine d'un message en joignant une signature numérique à chaque message.

Comme on est sur FreeBSD, on installe le port adéquat, opendkim :

$ portinstall opendkim

Ne pas oublier de choisir STOCK_RESOLVER dans les options, sinon ça installe un unbound en dépendance, pas forcément nécessaire.

Vu que DKIM est un système de signature, il faut un clé. opendkim fournit un outil, opendkim-genkey :

# opendkim-genkey -D /var/db/dkim -d valken.org -s valkenorg

Là c'est une simulation, le mien a été fabriqué par Google. 😅 On spécifie où placer les fichers de sortie avec -D, ici /var/db/dkim, le domaine concerné avec -d, ici valken.org, et on nomme la clé avec -s, ici valkenorg.

Ça créée deux fichiers, valkenorg.private qui contient la clé de signature, et valkenorg.txt, qui est l'entrée à inscrire dans le DNS.

Le fichier private est une clé RSA, rien de bien folichon, le fichier txt est plus intéressant (édité bien sûr, faut pas mettre ses clés privées sur le net 😋) :

valkenorg._domainkey IN TXT ( "v=DKIM1; k=rsa; p=ABCDEF1234567890abcdef1234567890" ) ; ----- DKIM key valkenorg for valken.org

Comme pour SPF, on ajoute cette ligne au fichier hôte du domaine.

Si tout va bien, après propagation correcte de la nouvelle entrée, on obtient ça (encore blabla édité) :

$ dig +norec -t TXT valkenorg._domainkey.valken.org

;; QUESTION SECTION:
;valkenorg._domainkey.valken.org. IN TXT

;; ANSWER SECTION:
valkenorg._domainkey.valken.org. 3600 IN TXT "v=DKIM1; k=rsa; p=ABCDEF1234567890abcdef1234567890"

C'est bon du côté DNS, ça permet aux serveurs destinataires de vérifier notre signature.

Maintenant il faut s'intéresser à la configuration de opendkim. Son fichier de configuration opendkim.conf est dans /usr/local/etc/mail. Le fichier par défaut est très complet et long, on va juste changer les paramètres qui nous intéressent :

AutoRestart yes : Permet le redémarrage de opendkim en cas de plantage.

Background Yes : Lance le process en tâche de fond (défaut mais ça mange pas de pain de le préciser).

Canonicalization relaxed/simple : Là on précise que la signature de l'en-tête sera fera sur une version normalisée (relaxed - voir DKIM signatures), et sur le corps du message non modifié (simple).

Domain valken.org : Pour quel domaine on doit signer. Si le serveur gère plusieurs domaines, on peut spécifier un nom de fichier qui comportera un domaine par ligne.

InternalHosts 127.0.0.1 : Quelles adresses IP on doit considérer comme les nôtres, donc que signer. Les autres adresses auront leur signature DKIM vérifiées. Valeur par défaut 127.0.0.1.

KeyFile /var/db/dkim/valkenorg.private : Clé à utiliser. En cas de domaines multiples, il faut utiliser les paramètres KeyTable et SigningTable en leur donnant les fichiers de correspondance. Si KeyTable et SigningTable sont utilisés, KeyFile est ignoré. Il est obligatoire d'avoir soit KeyFile soit KeyTable renseigné.

LogWhy yes : Ecrit dans le log l'explication derrière chaque décision de opendkim. Utile en debug, déconseillé en production.

ReportAddress "Toto" <Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.> : Adresse où envoyer les rapports d'échec (en plus des expéditeurs) si SendReports est activé. envoyés depuis l'adresse de l'utilisateur qui a lancé le processus.

Selector valkenorg : Le Selector à utiliser pour la signature. Le nom qu'on a défini lors de la génération de la clé. Obligatoire, pas de valeur par défaut.

SendReports yes : opendkim enverra des rapports d'échec aux expéditeurs.

Socket inet:8891@localhost : Spécifie la méthode d'écoute de opendkim. Peut être un socket.

Syslog Yes : Envoyer des messages dans Syslog.

SyslogSuccess yes : Envoyer des messages de succès dans Syslog.

Il faut maintenant activer le lancement de opendkim dans /etc/rc.conf :

milteropendkim_enable="YES"

Et lancer opendkim :

# /usr/local/etc/rc.d/milter-opendkim start

Si tout va bien, on devrait obtenir :

Starting milteropendkim.

On peut voir le daemon tourner avec ps :

# ps ax | grep opendkim
33868 - Ss 0:00.00 /usr/local/sbin/opendkim -l -u mailnull:mailnull -P /var/run/milteropendkim/pid -x /usr/local/etc/mail/opendkim.conf
33869 - S 0:00.00 /usr/local/sbin/opendkim -l -u mailnull:mailnull -P /var/run/milteropendkim/pid -x /usr/local/etc/mail/opendkim.conf

Finalement, on va dire à Postfix de faire passer les messages par opendkim. Editons le fichier main.cf dans /usr/local/etc/postfix, et ajoutons les lignes suivantes :

milter_default_action = accept : Par défaut on accepte les mails. Vu que DKIM n'est pas (encore ?) le défaut dans les configurations des mailers, on va éviter de rejeter presque tous les mails... 😅

milter_protocol = 6 : La version du Milter. Après la version 2.6, Postfix utilise la version 6 par défaut.

smtpd_milters = inet:localhost:8891 : On fait passer les mails par ce filtre.

non_smtpd_milters = $smtpd_milters : On fait tout passer par les mêmes filtres. 😋

On relance Postfix :

# postfix reload

Et si tout va bien, on a ce genre de lignes dans les logs en réception :

Nov 27 12:50:52 polaris opendkim[39136]: A5FE42D63F0: no signing domain match for 'gmail.com'
Nov 27 12:50:52 polaris opendkim[39136]: A5FE42D63F0: no signing subdomain match for 'gmail.com'
Nov 27 12:50:52 polaris opendkim[39136]: A5FE42D63F0: DKIM verification successful

Google a des enregistrement DKIM, il est donc vérifié. Les deux premières lignes indiquent que gmail.com ne fait pas partie des domaines qu'on doit signer. Ça marche bien donc.😉

Et en envoi, on aura :

Nov 27 12:49:09 polaris opendkim[33869]: 5F59122578B: DKIM-Signature field added (s=valkenorg, d=valken.org)

Signature ajoutée. 😉

DMARC

DMARC, ou Domain-based Message Authentication, Reporting & Conformance, est un protocole d'authentification de stratégie et de reporting de mails, reposant sur SPF et DKIM.

D'abord, on a besoin d'un enregistrement DNS. Pour valken.org, on aurait :

_dmarc.valken.org. TXT "v=DMARC1; p=reject; sp=reject; rua=mailto:Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.; ruf=mailto:Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.; fo=0; adkim=r; aspf=r; pct=100; rf=afrf; ri=86400;"

 Que veut dire tout ça :

p : Politique à appliquer pour les échecs DMARC, reject, quarantine ou none.

sp : Politique à appliquer pour les sous-domaines, mêmes paramètres que p.

rua, ruf : Adresses où envoyer les rapports (rua), et les échecs (ruf). Doit être une URI (mailto:).

fo : Options de rapport d'échec. 0 pour rien, 1 pour tout échec, d pour les erreurs DKIM, s pour les erreurs SPF.

adkim, aspf : Mode de gestion DKIM et SPF. r pour relaxed, s pour strict. Le mode relaxed autorise les Organizational Domain communs à passer la validation, strict demande une correspondance exacte.

pct : Pourcentage de messages testés par DMARC. Nécessite une politique reject ou quarantine.

rf : Format des rapports, pour DMARC1, uniquement AFRF.

ri : Laps de temps entre les rapports en secondes. 1 jour par défaut.

Si tout va bien, on a ça :

$ dig -t TXT _dmarc.valken.org

;; QUESTION SECTION:
;_dmarc.valken.org. IN TXT

;; ANSWER SECTION:
_dmarc.valken.org. 3600 IN TXT "v=DMARC1; p=reject; sp=reject; rua=mailto:Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.; ruf=mailto:Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.; fo=0; adkim=r; aspf=r; pct=100; rf=afrf; ri=86400;"

Maintenant on installe le port idoine, opendmarc :

# portinstall opendmarc

Ça ramène un paquet de dépendances.

 Editons le fichier de configuration, opendmarc.conf. Sur FreeBSD, il est dans /usr/local/etc/mail (recopier le .sample en .conf au besoin).

Encore une fois le fichier est long, modifions uniquement ce dont on a besoin :

AuthservID mailer.valken.org : Le nom du serveur, pour les rapports.

AutoRestart true : Pour redémarrer le daemon si'il se plante.

AutoRestartCount 5 : Limiter le nombre de redémarrages automatiques en cas de problème.

Background true : Tourner en tâche de fond.

BaseDirectory /var/run/opendmarc : Où opendmarc démarrera. Pour retrouver facilement les dumps au cas où.

HistoryFile /var/run/opendmarc/opendmarc.dat : Le fichier où est inscrit l'activité de openmarc pour générer les rapports.

IgnoreHosts /usr/local/etc/mail/ignore.hosts : Fichier listant les serveurs à ne pas filtrer, nos serveurs.

PidFile /var/run/opendmarc.pid : Fichier PID.

RejectFailures false : Rejeter ou non les messages en échec. On accepte dans le doute avec false.

Socket inet:8893@localhost : Adresse et port à utiliser.

Syslog true : Ecrire dans Syslog.

TrustedAuthservIDs mailer.valken.org : Noms des serveurs dignes de confiance, normalement les notres.

Il faut maintenant activer le lancement de opendmarc dans /etc/rc.conf :

opendmarc_enable="YES"

Et lancer opendmarc :

# /usr/local/etc/rc.d/opendmarc start

Si tout va bien, on devrait obtenir :

Starting opendmarc.

On peut voir le daemon tourner avec ps :

$ ps ax | grep opendmarc
99335 - Is 0:00.00 /usr/local/sbin/opendmarc -l -P /var/run/opendmarc/pid -c /usr/local/etc/mail/opendmarc.conf -p
99336 - S 0:00.01 /usr/local/sbin/opendmarc -l -P /var/run/opendmarc/pid -c /usr/local/etc/mail/opendmarc.conf -p

Et on dit à Postfix de faire passer les messages par opendmarc. Editons encore le fichier main.cf dans /usr/local/etc/postfix, et complétons la ligne suivante :

smtpd_milters = inet:localhost:8891 

On y ajoute le milter opendmarc :

smtpd_milters = inet:localhost:8891, inet:localhost:8893

Bien sûr, si votre port/socket est différent, il faut adapter en conséquence.

On relance Postfix :

# postfix reload

Et si tout va bien, on aura des lignes comme ça dans le log :

Nov 28 11:52:02 mailer.valken.org opendmarc[1877]: BD7A32D6412: gmail.com pass

Et voilou. C'était pas trop compliqué. 😉

Comme le dit si bien Simon Pegg dans Mission Impossible Ghost Protocol (je crois ?), c'est un rêve inatteignable de vivre des aventures comme Ethan Hunt.

Mais comme la réalité rejoint très vite la fiction, les masques Mission Impossible sont maintenant disponibles :

Hyper-realistic masks can fool us just like in Mission: Impossible

Ça coûte même pas cher, dans les 1000 €.

J'aurais dû me douter qu'après les Google Glass reproduisant les lunettes d'Ethan Hunt dans le film Mission Impossible, tout serait très vite possible... 😀