Je découvre le monde merveilleux de l'Arduino à travers un petit projet perso, et j'ai besoin de vos conseils pour aller plus loin :
Je souhaite pouvoir commander facilement via mon iphone ma porte de garage à l'aide du arduino DIno (carte à 4 relais).
Grace au forum après avoir fais quelques tests avec succès de commande à travers UDP, serveur web & touchOSC j'ai choisis les pistes suivantes :
Programme :
commander l'arduino via touchosc
commander l'arduino via une application Wifigarage sur l'appstore aprés avoir modifié le code coté arduino pour l 'utiliser en ethernet simple
Réseau :
utiliser le wifi local uniquement (ajout d'un AP que je pourrais capter de ma voiture)
utiliser le 3g (via une redirection de port de ma box)
utiliser les 2 wifi et 3G
-utiliser le protocole osc vous semble t il suffisamment sécurisé pour être utilisé avec l'extérieur ? car à part le nom qu'on donne au bouton de contrôle(au lieux de l'appeler button1 ou pourrais lui donner un nom sur 10 caractères) je ne vois pas comment on peut implémenter de la sécurité. On pourrait peut être trapper l'adresse MAC du demandeur au niveau du Arduino ?
Si vous avez un avis sur la question il est le bien venu !
Pourquoi aller chercher des applis spécifiques sur iPhone ?
Pourquoi pas une simple page Web ?
Tu parles de Wifi donc je suppose que tu considères aussi un shield Ethernet ou Wifi sur ton Arduino ?
Tu peux donc faire un micro-site à 1 page web sur ton Arduino avec un gros bouton Ouvrir et un gros boutton Fermer !
Pas besoin de protocole OSC ou autre.
Pour la sécurité, déjà si ton Wifi est verrouillé, seul ceux qui ont accès au Wifi pourront avoir accès à la page Web.
C'est déjà pas mal.
Oui en fait la DIno est une carte "low cost" avec ethernet intégré.
Pour le microsite je pense effectivement en faire un en "secours" en cas de pbs, j'en ai fait en proto ca marche plutôt bien.
Mais je ne veux pas avoir besoin de signer avec un login et mdp a chaque fois que je veux ouvrir ma porte.
Pour le wifi effectivement si j'utilise uniquement en solution "locale" pas besoin de sécurité autre que le wpa.
Mais je voudrais surtout pouvoir l'utiliser en passant par internet, et là juste planquer la page au fin fond d'une url .... ca me semble pas top.
C'est pour ca que je voulais éventuellement détourner l'interface de wifigarage puisque qu'elle intègre des variables pour la securité et que le code coté arduino est libre.
Sécurité et protocole OSC n'ont jamais fait bon ménage.
Le protocole OSC n'ayant jamais prévu la moindre sécurité c'est comme vouloir mettre une rustine sur un pneu éventré.
Si tu veut concevoir un systéme sécurisé le mieux et de concevoir une application utilisant un protocole fait maison.
Protocole dans lequel tu intégreras une méthode connexion :
(quelques exemples classiques)
classique identifiant / mot de passe
clef à usage unique ("one time token") + algo de génération maison
clef "maitre" en dure dans ton programme
Ainsi que divers méthode "anti replay", anti injections, etc ... :
code tournant ("rolling code")
checksum CRC (en utilisant un polynôme de calcul non standard)
cryptage (RC4 ça passe sans probléme même sur une carte arduino)
systéme de "handshake" (poignée de mains) et de session, pour éviter que plusieurs personnes utilise le même identifiant simultanément (ou qu'une personne mal intentionné récupère au vol une session déja ouverte).
malphodo:
Pour le microsite je pense effectivement en faire un en "secours" en cas de pbs, j'en ai fait en proto ca marche plutôt bien.
Mais je ne veux pas avoir besoin de signer avec un login et mdp a chaque fois que je veux ouvrir ma porte.
Pour le wifi effectivement si j'utilise uniquement en solution "locale" pas besoin de sécurité autre que le wpa.
Mais je voudrais surtout pouvoir l'utiliser en passant par internet, et là juste planquer la page au fin fond d'une url .... ca me semble pas top.
Si ton application est disponible en dehors de ton intranet il faudra prévoir :
anti bruteforce (pour éviter qu'une personne test tout les combinaisons de login possible)
anti robots / scanner (pour éviter qu'un robots ne vienne foutre la merde en détectant un port ouvert)
A mon avis vouloir utiliser une carte arduino telle quelle en ethernet pour une application "critique" c'est ce tirer une balle dans le pied.
Pour un systéme domotique en intranet ça passe (tu est chez toi il y a peu de risque que quelqu'un viennent foutre la m*rde ... enfin c'est vite dit).
Pour un systéme connecté au web il serait préférable d'utiliser un mini serveur web (routeur reconditionné, etc ...) afin de mettre en place un systéme solide.
La sécurité informatique ne consiste pas à cacher les choses derrière une URL introuvable (= méthode de la "boite noir").
Du reste même une URL bien caché ne résiste pas longtemps à un pentester utilisant les bons outils.
Donc c'est décide je laisse tomber l'OSC pour l'utilisation en WAN.
Par contre l'idée d'utiliser le client Wifigarage est intéressant puisque qu'il intègre login/mdp + clé maitre.
Donc coté client : login/mdp + clé maitre. Coté Arduino : login/mdp + clé maitre + anti brute force + filtrage MAC
Si j'arrive à faire tout çà je serai déjà bien content pour une première application
D'autant plus que je ne trouve rien comme exemple de "trappage" des mac accédant au serveur web.
Dans un second temps je verrais pour implémenter éventuellement une "vraie" sécurité en plaçant l'Arduino sur un VLAN spécifique qui passera par un firewall + certificat
malphodo:
Par contre l'idée d'utiliser le client Wifigarage est intéressant puisque qu'il intègre login/mdp + clé maitre.
Connais pas ce logiciel, à voir.
malphodo: Donc coté client : login/mdp + clé maitre. Coté Arduino : login/mdp + clé maitre + anti brute force + filtrage MAC
Si tu utilise un login/mdp tu n'est pas obligé d'avoir une clef maitre, c'est quand tu n'as rien d'autre que c'est intéréssant.
malphodo:
Si j'arrive à faire tout çà je serai déjà bien content pour une première application
D'autant plus que je ne trouve rien comme exemple de "trappage" des mac accédant au serveur web.
Pour le bruteforce il suffit de faire un compteur de temps et un compteur de tentative.
Si il y trop de tentative en x temps tu ban.
Pour le ban justement c'est avec ton firewall qu'il faudrait discuter.
Perso j'utiliserai iptable pour capturer la réponse "BANNED" de l'arduino et ajouter la mac / ip au régles de ban.
ça éviterai cote arduino à stocker une liste d'ip/mac et iptables est bien plus puissant qu'un truc fait main.
Regarde les exemples pour bannir les "w00tw00t" c'est le même principe mais en sortant (arduino -> internet).
En fait le firewall c'etait plutot dans un deuxieme temps .... ma baie de serveur étant en cours de modification.
Iptable ca tourne sur Linux çà ...? je regarderait mais j'ai rien pour le moment qui tourne en linux.
Et si je prend le sujet dans l'autre sens :
J'autorise une liste de MAC dans l'arduino + antibrute force 3 niveaux (exemple pas plus de 3 tests en 10 minutes + 2 série d'échec désactivation du compte + 2 séries d'échecs sur 2 comptes = désactivation complet du service)
Dans un deuxième temps je pourrais remplacer la fonction de "désactivation complet du service" par un ban via le FireWall.
Par contre j'ai encore passé du temps ce matin je trouve rien sur le filtrage mac via arduino ... je vais regarder du coté code pour serveur dhcp
Bon je commence doucement en utilisant la librairie ethershield et en modifiant quelques exemples.
Ci dessous le code sur lequel je commence à bosser.
Mais je bloque j'ai un peu de mal à comprendre le principe des duffers…
Dans mon loop dans ma condition if (buf[IP_PROTO_P]==IP_PROTO_UDP_V j'aimerai retourner la totalité de mon paquet UDP reçus sous forme de string pour le travailler, pour en faire un serial.print par exemple.
Si vous aviez une piste
Bon me revoilà ... entre temps j'ai découvert la différence entre serial.print et serial.write :*
Bref avec ce bout de code :
void loop(){
// read packet, handle ping and wait for a tcp packet:
dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
// Serial.println(buf[IP_PROTO_P]);
if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){
udp_length=buf[39]-8; // calculate UDP data lenght
for (int i = 0; i < udp_length; i++)
{
Serial.write(buf[42+i]);
}
Serial.println();
Relay_Control();
Status_Reply();
es.ES_make_udp_reply_from_request(buf,reply,8,12345);
buf[IP_PROTO_P]=0;
} }
} // end loop
Sans savoir exactement où tu veux en venir, quel est le problème ca va être dur de t'aider.
Où est documenté le protocole de WifiGarage ?
Que t'attends tu a recevoir ?
Je ne connais pas la lib Ethernet mais ca me parait bizarre d'utiliser une fonction de réception TCP pour ensuite traiter un paquet UDP.
Tu es en UDP ou en TCP ?
Effectivement j'avais donné plein de pistes au début et j'ai oublié de preciser la direction XD
En gros mon principale problème est que j'utilise une carte un peu exotique a base d'enc28j60 résultat les exemples intéressant intégrant de l'authentification poussée que je trouve en TCP / UDP sont à retraduire pour les librairies Ethershield ou Ethercard qui marchent avec ma carte.
N'ayant pas encore le niveau j'ai un peu lâché l'affaire et je suis repartit sur un code plus simple laissant l'aspect sécurité au niveau WIFI local.
J'ai donc décidé dans un premier temps d'utiliser TouchOSC + fonctions UDP de la lib ethershield.
J'ai essayé d'utiliser différentes librairies OSC mais celles ci nécessitent aussi de grosses modif car utilisent la librairie Ethernet qui n'est pas compatible avec mon shield.
Bon ci dessous la partie principale de mon code actuel :
J'ai besoin d'aide sur 2 sujets tous bêtes :
J'aimerai bien retourner le contenu de myip[4] sur le port serie hors je n'arrive pas a avoir l'adresse en claire malgrés toutes mes tentatives de format et de convertion
for (int i = 0; i < udp_length; i++)
{
Serial.write(buf[42+i]);
}
-> je voudrai passer çà dans une string pour la retravailler ensuite, mais je bloque =(
J'ai bien essayer un truc du genre :
char UDPmsg [udp_length];
et
for (int i = 0; i < udp_length; i++)
{
UDPmsg = UDPmsg + (buf[42+i]);
}
mais ca marche pas
for (int i = 0; i < udp_length; i++)
{ //Serial.write(buf[42+i]);
c = buf[42+i];
UDPMsg += c;
}
Serial.println(UDPMsg);
Marche bien pour passer le contenu de mon message udp dans une string.
Reste la partie adresse ip, pas vraiment nécessaire mais pour le fun et progresser XD
J'ai bien essayé la emme technique :
for (int i = 0; i < myip[4]; i++) //boucle concatenation message
{ //Serial.write(buf[42+i]);
c = myip[4+i];
IPAdresse += c;
}
mais ca retourne pas ce que je veux
D'autre par j'essaye de renvoyer un message UDP contenant /1/label1 "ok" avec les fonctions d'ethershield, hors je n'arrive à faire passer le " dans le char*