Héberger un site web sur un microcontrôleur 8 bits
(maurycyz.com)- Un site web a été hébergé uniquement avec un MCU 8 bits AVR64DD32, dans un environnement minuscule avec un CPU à 24 MHz, 8 KB de RAM et 64 KB de Flash
- Comme générer directement un signal Ethernet est trop exigeant, même pour du 10BASE-T, une liaison USB-série est utilisée comme interface réseau via SLIP, pris en charge par Linux
- SLIP est une méthode simple qui encapsule les paquets avec
0xC0et échappe les octets spéciaux, ce qui convient bien à la connexion entre un MCU et un Linux moderne - L'IP a pu être simplifié grâce à la désactivation de la fragmentation, mais l'implémentation TCP a demandé plusieurs jours en raison de la gestion d'état des connexions, des retransmissions et des cas d'exception, avec encore quelques bugs restants
- L'accès externe repose sur une structure de contournement avec VPS, WireGuard et proxy qui ne transmet que les requêtes vers
/mcu, les coûts de l'IPv4 public et l'absence d'IPv6 apparaissant comme les principales limites
Configuration utilisée pour héberger un site web sur un AVR 8 bits
- L'AVR64DD32 est un MCU 8 bits de la famille AVR, proche de l'Atmega328 connu via Arduino, mais moins cher à capacité mémoire égale, avec une broche de programmation unique et de meilleurs périphériques
- Cœur AVR 8 bits unique jusqu'à 24 MHz
- 8 KB de RAM statique, 64 KB de Flash, 256 octets d'EEPROM
- Plage de tension de 1,8 à 5,5 V, prix autour de $1 à $2
- Pour connecter directement le MCU à Internet, il faudrait générer un signal Ethernet, mais même le 10BASE-T, pourtant le plus lent, reste trop rapide dans cet environnement
- Le 10BASE-T fonctionne à 10 Mbit/s, et avec l'encodage Manchester cela revient à 20 Mbit sur la ligne physique
- Le CPU de l'AVR64DD32 peut monter à 24 MHz, mais les périphériques et les broches d'E/S sont limités à une horloge maximale de 12 MHz, ce qui rend la génération directe du signal difficile
- La méthode classique consisterait à utiliser une puce Ethernet dédiée, mais il aurait fallu attendre plusieurs semaines pour terminer le projet
- Une alternative consiste à utiliser SLIP (Serial Line Internet Protocol, RFC 1055) pour faire passer le réseau sur une liaison série
- Les paquets sont encadrés par des octets
0xC0 - Dans un paquet,
0xC0devient0xDB 0xDC, et0xDBexistant devient0xDB 0xDD, afin d'éviter toute ambiguïté - Cela prolonge l'approche des anciens modems RTC, qui créaient une liaison série sur la ligne téléphonique et laissaient l'ordinateur gérer le réseau au-dessus
- Les Linux modernes prennent toujours en charge SLIP, ce qui permet de transformer un adaptateur USB-série en interface réseau
- Exemple d'utilisation :
stty -F /dev/ttyUSB0 115200 raw cs8,slattach -m -F -L -p slip /dev/ttyUSB0
- Les paquets sont encadrés par des octets
- Côté matériel, le montage MCU est simple et fonctionne même sans composants externes
Implémentation des protocoles et gestion de l'accès public
- L'implémentation IP a été simplifiée grâce aux contraintes de l'environnement moderne
- Pour qu'une page web atteigne l'ordinateur d'un utilisateur, les paquets doivent traverser plusieurs réseaux et chaque paquet a besoin d'un en-tête IP de 40 octets contenant notamment les adresses source et destination
- L'ancien IP demandait beaucoup de mémoire pour gérer correctement des fonctions comme la fragmentation des paquets
- Les systèmes d'exploitation modernes désactivent la fragmentation, et IPv6 l'a supprimée, ce qui évite de devoir la gérer directement
- Il suffit d'inverser la source et la destination du paquet reçu et de réinitialiser le compteur TTL pour construire l'en-tête de réponse
- L'implémentation TCP est bien plus difficile, car elle impose de suivre l'état des connexions, de retransmettre les paquets perdus et de gérer divers cas particuliers
- Il a fallu plusieurs jours pour que cette implémentation TCP maison fonctionne suffisamment bien, et quelques bugs subsistent encore
- HTTP n'a pas été implémenté séparément : le serveur envoie toujours une « réponse » codée en dur au client
- Pour un site à URL unique, cette approche suffit
- Le chargement peut être vu dans Video 3
- L'accès externe nécessite une adresse IPv4 publique routable, mais son coût et la qualité de la connexion Internet domestique posent problème
- La machine disposant d'une adresse publiquement routable est un VPS dans un datacenter près d'Helsinki
- WireGuard sous Linux sert à créer une liaison réseau virtuelle sur Internet, qui fonctionne même si l'un des côtés est derrière un CGNAT
- Le boîtier routeur Linux se connecte au VPS pour obtenir une connectivité Internet plus adaptée
- Le MCU n'a toujours pas sa propre IP publique, donc transférer toutes les requêtes vers l'adresse du VPS casserait le site web existant
- À la place, le serveur est configuré pour ne proxyfier vers le serveur MCU que les requêtes sous
/mcu, en utilisant un bloc d'adresses local - Les visiteurs ne se connectent donc pas directement à la pile TCP/IP du MCU, mais cela fonctionne selon le même principe que Vape Server
- Cela rend les attaques par paquets SYN un peu plus difficiles, mais comme le serveur fonctionne en pratique sur une liaison proche du RTC, il reste vulnérable au DDoS
- À la place, le serveur est configuré pour ne proxyfier vers le serveur MCU que les requêtes sous
- L'absence d'IPv6 reste la cause fondamentale de toute cette architecture de contournement
- IPv6 existe depuis 30 ans, mais reste encore inaccessible pour la plupart des gens
- /mcu : page hébergée sur le MCU
- http://ewaste.fka.wtf/ : Vape Server hébergé sur un MCU 32 bits récupéré dans des déchets électroniques
- https://lcamtuf.substack.com/p/psa-if-youre-a-fan-of-atmega-try : article de lcamtuf sur la gamme AVR Dx
1 commentaires
Commentaires sur Hacker News
Il y a plus de 25 ans, il y a eu une sorte de concours d’esbroufe pour créer le plus petit serveur web : https://web.archive.org/web/20000815063022/http://www-ccs.cs...
La personne qui a utilisé le microcontrôleur ACE1101 a « gagné », mais je n’ai pas retrouvé l’article d’origine ; il y a aussi ceci : https://conceptlab.com/fly/
C’était un serveur web sur une mouche
Réduire le code a été vraiment amusant, et en supprimant le ping j’ai libéré assez de place pour ajouter de l’I2C en bit-banging et un upload UDP vers l’EEPROM, tout en restant sous les 1024 octets
J’aime les séries AVR DD, EA et EB, mais les sorties récentes de Microchip paraissent un peu inquiétantes pour les fans d’AVR : https://www.microchip.com/en-us/products/microcontrollers/32...
Le PIC32 CM reprend l’essentiel des fonctionnalités de l’AVR DD — système d’événements, MVIO, fonctionnement en 5 V, etc. — tout en proposant un cœur ARM 32 bits M0+ plus gros et plus standard
Du coup, on peut craindre que l’AVR DD paraisse un peu dépassé. Les AVR EA et AVR EB semblent plus à l’abri, avec leur ADC 12 bits à gain programmable x16 ; malgré un peu de bruit, ils sont sensibles jusqu’à environ 50 microvolts, ce qui en fait des ADC/capteurs de courant ridiculement bons
À l’inverse, cela pourrait aussi rendre la famille AVR plus populaire. Je me demande si le fait d’avoir un ARM32 Cortex M0+ compatible broche à broche augmente ou réduit la probabilité de construire sur la plateforme AVR
Personnellement, je pense que ce sont surtout les périphériques qui comptent. L’AVR DD consomme peut-être moins, surtout en fonctionnement à 1,8 V, mais je ne sais pas si cela suffit
Le projet lui-même est très intéressant, et l’AVR DD reste quoi qu’il arrive une excellente puce, donc ça fait plaisir de la voir utilisée pour de vrai
Le 10BASE-T fonctionne à 10 mégabits/s et, à cause du codage Manchester, cela fait 20 mégabits sur la ligne ; l’AVR EB possède un timer PLL x2, donc en s’y accrochant assez longtemps il pourrait peut-être sortir du codage Manchester
En combinant les LUT, les périphériques UART et un montage de timer accéléré par PLL, on pourrait probablement pousser un codage Manchester rapide, mais je ne sais pas encore s’il serait possible d’atteindre 20 Mbit
Le fait de tâter la voie Cortex-M0 peut être le signe qu’ils n’ont pas envie de continuer à développer les générations suivantes de plateformes 8 bits après Dx. S’ils reprennent les mêmes fonctionnalités avec un autre cœur CPU, ça me semble acceptable
J’aime bien voir la HTML se streamer en temps réel à l’écran. Ça rappelle l’époque du modem, quand les images se dessinaient lentement de haut en bas
Là-bas, sur FTP puis plus tard sur Napster, on pouvait télécharger plusieurs morceaux en une seule connexion
En voyant le titre, ma première réaction a été : « beaucoup d’appareils embarqués/IoT font déjà ce genre de chose »
Voici un exemple de 8051 avec Ethernet 10/100 intégré : https://www.asix.com.tw/public/index.php/en/product/Microcon...
Il y avait deux choses intéressantes. D’abord, il existe un erratum 2025 de la RFC 1055 qui n’est pas présent dans le www.c ici. Cet erratum montre de façon assez convaincante comment modifier l’algorithme de décodage, et dans ce cas l’autre extrémité du lien est réellement Linux
Ensuite, la prochaine étape sera probablement la RFC 1144
La combinaison ENC28J60 + PIC18 correspond exactement à ce que faisaient les démos que Microchip diffusait couramment il y a 20 ans
J’apprécie que le proxy n’ait pas écrasé l’en-tête server: de la page
J’avais déjà fabriqué quelque chose de similaire avec un Arduino Mega. Ce qui m’avait surpris, c’est que ça pouvait avoir un rendu assez convaincant parce que le client faisait une grande partie du travail, tandis que le contrôleur ne faisait en gros que servir le contenu depuis une carte uSD