Jeedom : être alerté quand y a plus de piles!

Jeedom c’est super, pour les capteurs intelligents qui remontent l’info sur leur batterie tu es alerté passé un certain seuil (enfin j’imagine, moi j’ai que des capteurs qui remontent toujours « ok » comme info batterie alors j’ai pas vraiment testé).

image_jeedom_batterie
Paramétrage des seuils d’alerte

 

 

 

Mais pour les capteurs idiots, ou les infos étranges venues d’ailleurs (par exemple, je chope la pollution via un grep bien crado sur https://www.atmo-auvergnerhonealpes.fr/monair/commune/69123 et j’ai pu du coup voir que ça passait plus au changement de nom de domaine puis au passage en https (sans redirection (oui, c’est une parenthèse dans une parenthèse dans une parenthèse, pour remarquer la parenthèse  dans la parenthèse du niveau du dessous.) parce que les 301 à la région, c’est pas leur truc)).

C’est pas très compliqué, il suffit de faire un scenario qui se déclenche quand un délai donné est dépassé.

Scenario d'envoi sms sur perte de la sonde de température du salon
Scenario d’envoi sms sur perte de la sonde de température du salon

Petite explication de texte, on prend l’heure courante au format Unix avec  #timestamp# puis on soustrait l’heure du dernier contact, stockée dans jeedom via CollectDate.

On transforme cette heure au format Unix aussin via le « ,U » (cf http://php.net/manual/fr/function.date.php ) puis on vérifie si c’est supérieur à 3600 (soit 1h).

Pour une raison que j’ignore, je n’ai pas réussi à afficher la valeur de CollectDate(#[Maison][Températures][Salon]#) directement dans mes messages d’avertissement d’ou mes deux actions, d’abord j’initialise la variable délai salon, puis je l’envoi dans mon message.

Forcer le https avec haproxy devant varnish (devant apache et/ou nginx)

Bon, étant assez bordélique de nature, je vais parler de comment tripatouiller varnish que j’ai un peu présenté dans le Billet de présentation de mon infra  et haproxy (dont j’ai pas encore beaucoup causé), pour forcer le https.

Donc en fait, devant Varnish j’ai un service haproxy qui tourne pour servir de terminaison TLS mais un (fort joli) dessin valant mieux qu’un long discours, voici à quoi ressemble une requête arrivant chez moi.

Schéma d'une requêtte http(s)
Paint 4 ever

Ce que j’ai essayé de (mal) représenter c’est le parcours d’une requête http(s) arrivant chez moi.
Si c’est du http, le client cause directement à Varnish qui cause au serveur « backend ».
Si c’est du https, le client cause à haproxy qui cause à Varnish qui cause au serveur « backend », c’est donc pas du TLS de bout en bout ce qui est sans doute un péché mortel chez les pastafariens.

Ceci étant dit, si je veux maintenant forcer le https, j’ai quand même un petit soucis (en fait plusieurs).
1. Le serveur de backend ne voit pas qu’il sait causer en https (en tout cas joomla et wordpress ont tendance à être comme saint thomas, si leur serveur web ne cause pas sur le port 443, ils pensent être inaccessibles en https.)
2. Varnish ne peut pas systématiquement rediriger sur haproxy, puisque haproxy lui renvoie tout, ça ferait donc une boucle de redirection, ça devient lassant et pas très efficace pour servir une page web.

La solution c’est d’ajouter un header spécifique aux requêtes passant par haproxy, et de ne rediriger dans varnish que celles n’ayant pas ce header.

Alors la config dans haproxy est hyper basique, on ajoute juste une ligne dans la partie frontend : http-request set-header X-I-CAN-HAS-TLS ON

Dans varnish c’est un tout petit peu plus compliqué, il faut d’abord détecter si ce header est présent dans la partie vcl_recv :
if (req.http.X-I-CAN-HAS-TLS != « ON ») {
set req.http.x-redir = « https:// » + req.http.host + req.url;
return(synth(007, « Moved permanently »));
}

Puis dans vcl_synth on redirige à coup de http 301 :
if (resp.status == 007) {
   set resp.http.Location = req.http.x-redir;
   set resp.status = 301;
   return (deliver);
}

Ainsi, on a une redirection permanente et les moteurs de recherche se mettent à jour pour remplacer les liens de http vers https, et bien, sur on peut filtrer pour exclure certains hôtes (genre wordpress ^^) temporairement ou pas (procrastination rulez).

 

 

 

 

 

 

 

Une seule IP publique avec plusieurs machines ou services.

Il y a (déjà) un mois, je présentais mon infra perso aujourd’hui suite à des papotages sur irc, je vois qu’il peut être nécessaire de rentrer un peu plus dans les détails concernant Varnish, qui semble pouvoir aider plus de gens que prévu.

Bon dans la vraie vie, on utilise plutôt nginx ou le mod_proxy d’apache pour faire ça mais Varnish est moins gourmand qu’apache et permet plein de choses en plus.

Et puis quand on y a gouté on a du mal à s’en passer…

Pour cette présentation, on va dire que mon adresse IP publique est 127.0.0.1 parce que c’est facile à retenir.
Et coté dns va dire que tous mes trucs sont en *.bazar.4ze.win

Je ne sais pas si c’est le cas partout mais chez Gandi en tout cas, on peut faire des enregistrements DNS « wildcard » (génériques en français).
J’ai donc pour le nom de domaine 4ze.win une ligne de config dns :
*.bazar 1080 IN A 127.0.0.1
En français ça veut dire quelque chose comme « quelque soit le machin qu’on met avant .bazar.4ze.win, faut répondre 127.0.0.1 ».

L’intérêt est double : permettre de rendre accessible en quelques secondes un service via un nouveau nom (juste une modif de varnish) et aussi de pouvoir afficher un site par défaut en cas de faute de frappe par exemple.

Voici un petit schéma, avec Varnish qui reçoit tout le trafic du port 80 (http donc) et redirige ensuite vers d’autres machines suivant le nom demandé.

Un superbe?! schéma du fonctionnement de varnish
Paint rulez! ^^

Maintenant que j’ai présenté le principe, on va rentrer dans le vif du sujet avec la config de Varnish (la version 4 en l’occurrence)…
Le fichier de config par défaut (chez debian en tout cas) est /etc/varnish/default.vcl et il est commenté ce qui est plutôt gentil.

Tout d’abord on définit un « backend », c’est à dire le serveur final auquel on veut causer :
backend jeedom {
    .host = « 172.16.32.9 »;
    .port = « 80 »;
}

Ensuite, dans la partie sub vcl_recv on définit quand est-ce que les requêtes sont envoyées à ce serveur :

if ( req.http.host == « jeedom.bazar.4ze.win » ) {
set req.backend_hint = jeedom;
}

Et puis c’est tout!
Quand on ajoute un service ou une machine on a juste à créer un nouveau backend et à dire quand il doit être sollicité.

En bonus, on peut aussi ajouter des headers du genre :

sub vcl_deliver {
#on empêche iframe et XSS
set resp.http.X-Frame-Options =  « SAMEORIGIN »;
set resp.http.X-Xss-Protection =  « 1; mode=block »;
set resp.http.X-Content-Security-Policy = « sript-src ‘self' »;
set resp.http.Content-Security-Policy = « sript-src ‘self' »;
set resp.http.X-Content-Type-Options = « nosniff »;
}

On peut aussi nettoyer les « user-agent » (il y a des failles au moins pour joomla qui tourne avec ça) :

sub normalize_user_agent {
if (req.http.user-agent ~ « Android ») {
set req.http.user-agent = « Android »;
}  else if (req.http.user-agent ~ « Opera ») {
set req.http.user-agent = « Opera Mini »;
} else if (req.http.user-agent ~ « MSIE ») {
set req.http.user-agent = « MSIE »;
} else if (req.http.user-agent ~ « iPhone ») {
set req.http.user-agent = « iPhone »;
} else if (req.http.user-agent ~ « Firefox ») {
set req.http.user-agent = « firefox »;
} else if (req.http.user-agent ~ « Chrome ») {
set req.http.user-agent = « Chrome »;
} else if (req.http.user-agent ~ « Safari ») {
set req.http.user-agent = « Safari »;
} else {
set req.http.user-agent = « truc louche »;
}
}

Bref, varnish c’est le bien et la doc est bien faite Doc Varnish (en)

 

Petite présentation de mon infra

Puisqu’il y a quand même de grandes chances que pas mal des articles ici concernent plus ou moins un bout de mon « infrastructure perso », je vais commencer par la présenter un peu.

Cables en bazar
Hum non, j’espère pas

Donc j’ai une machine physique chez Online (à l’époque, ils avaient des stocks ^^) avec une vm Pfsense en frontal.

Tout le trafic HTTP est envoyé vers une VM sur laquelle tourne Varnish qui redirige ensuite vers différences machines virtuelles suivant la demande.

Le HTTPS (quand il existe) passe par haproxy qui redirige ensuite vers Varnish.

Bon tout ça n’est sans doute pas super optimisé mais le but c’est plus de jouer avec des machins différents et de me faire la main que les perfs (on est de toute façon sur une machine à ~20€/mois hein).

Dans les machines virtuelles que j’ai ici, j’ai un Cozy Cloud bien sur pour les fichiers, sauvegarde de tel…
J’ai aussi une machine virtuelle pour la domotique avec l’excellent Jeedom dont je risque de reparler.

Ça c’était pour la partie pas à la maison mais le reste suivra bientôt.