Contrôler l'ESP8266 sans redirection de port : un chemin MQTT sortant
Un broker joignable depuis Internet permet de contrôler un appareil domestique via une connexion qu'il a lui-même ouverte. Ce que cela change pour la mémoire TLS, les thèmes et la relecture.
L'appareil se trouve derrière un routeur domestique sans redirection de port et sans adresse publique, et il doit pourtant recevoir sa configuration en quelques secondes. L'astuce n'est pas un trou dans le pare-feu. C'est une connexion que l'appareil ouvre vers l'extérieur en direction d'un broker qu'il peut joindre, et qui renvoie ensuite les messages par ce même chemin déjà établi. Toutes les qualités que l'on aime dans cette conception, et tous les pièges qu'elle contient, viennent de cette inversion.
Ce qui traverse réellement le NAT
Lorsque l'appareil ouvre une connexion TCP vers le broker, le routeur de la maison crée une correspondance et la maintient vivante pendant toute la durée du flux. Les réponses sur ce flux reviennent à l'appareil parce que la correspondance existe déjà. Le broker n'initie jamais rien vers la maison, il n'y a donc aucun paquet entrant non sollicité que le routeur devrait rejeter. C'est tout l'argument réseau, et c'est pourquoi l'approche fonctionne sur des réseaux que vous ne contrôlez pas.
L'appareil doit maintenir la connexion en vie ou la rétablir, ce qui devient la question de fiabilité une fois l'architecture fixée.
Le broker achemine des thèmes, il ne fait pas office de proxy HTTP
MQTT définit des échanges de publication et d'abonnement : l'appareil s'abonne à un filtre de thèmes qu'il est autorisé à lire, et un contrôleur autorisé publie sur un thème correspondant. Le broker fait correspondre les publications aux abonnements et livre des copies. Il ne sait pas ce qu'est une requête de navigateur et il ne transmettra pas un HTTP GET au serveur web de l'appareil. Si le firmware existant ne parle que HTTP, la conception avec broker exige une modification de l'application ou un composant de traduction délibéré.
Les noms de thèmes ne sont pas non plus une autorisation. La plupart des brokers prennent en charge des listes de contrôle d'accès par client, et les appareils devraient être limités à leurs propres arbres de publication et d'abonnement plutôt que de partager un espace de noms global.
Les ressources de l'appareil décident de la forme de TLS
L'ESP8266 dispose d'une RAM limitée, et la poignée de main TLS est ce qu'il fait de plus coûteux. Le cœur Arduino fournit BearSSL précisément pour cette contrainte, et le choix entre vérifier une CA et épingler une empreinte change à la fois l'empreinte mémoire et ce qu'un attaquant muni d'un certificat valide pour un autre nom peut faire. Vérifier la CA du broker est l'option la plus solide lorsque le tas le permet. La taille de la charge utile compte aussi : le client MQTT détient un tampon, et les messages plus gros sont tronqués en silence à moins d'augmenter le tampon délibérément.
Le keepalive et les délais d'expiration de socket font partie du même budget, car un client qui ne remarque jamais une connexion morte cesse de recevoir des commandes sans signaler d'erreur.
La sémantique des messages qui mord
Un message retenu est stocké par le broker et remis aux abonnés correspondants ultérieurs, ce qui est excellent pour l'état courant et dangereux pour les commandes à usage unique : un appareil qui se reconnecte peut recevoir la commande de la veille comme si elle était nouvelle. QoS 1 garantit une livraison au moins une fois, les doublons sont donc normaux et l'application doit être sûre face aux répétitions, idéalement avec un identifiant ou un horodatage qu'elle peut rejeter. Le dernier testament vous donne un signal d'état lorsque l'appareil tombe, mais seulement si la connexion échoue réellement au lieu de rester suspendue.
Le comportement de session propre décide si le broker conserve vos abonnements pendant votre absence, et se tromper là-dessus explique pourquoi certains appareils ratent le premier message après chaque reconnexion.
TLS protège le tronçon jusqu'au broker. Ce n'est pas un chiffrement de la charge utile de bout en bout face à l'opérateur du broker, qui peut lire tout ce que vous publiez à travers lui.
Bornez le cycle de vie et testez-le avec des données inoffensives
Planifiez la reconnexion avec un retrait progressif plutôt qu'une boucle de nouvelles tentatives serrée, réabonnez-vous explicitement si la session n'est pas persistante, et journalisez le résultat de la connexion pour qu'un appareil hors ligne et silencieux laisse des traces. Testez le chemin de reconnexion avec des charges d'exemple qui ne font rien, car le premier test de production d'un canal de commandes ne devrait pas être une vraie commande. Confirmez ensuite ce que fait un message retenu obsolète à la reconnexion, et décidez si ce comportement est acceptable pour chaque thème.
Ainsi fait, la conception supprime une exigence réseau entrante et laisse le logiciel de l'appareil, la politique du broker et la sémantique des messages comme un travail visible plutôt que des hypothèses cachées.