Home Assistant – Le SSL
Préambule
Alors autant le dire tout de suite en préambule, je me me suis lancé dans une aventure folle et vous allez être les témoins de la chose !
Le but est simple : Passer ma connexion en SSL pour améliorer ma sécurité, anticiper une possible exposition du serveur HA à internet, et être d’avantage conforme aux standards.
Le hic, c’est que cette aventure se trouve être bien plus technique et coriace que ce que j’imaginais.
Passer sa connexion en SSL alors que je suis (pour le moment) 100% local n’a pas trop de sens car le risque de piratage se trouve dans… dans votre foyer ou juste à coté : voisins.
Certes, c’est possible… Mais le risque est bien moindre que les armées de bots sur internet qui scannent nuits et jours la moindre faiblesse de M. et Mme Michue !
Donc le SSL en local, c’est overkil.
Le réseau local est considéré comme sûre, c’est la raison pour laquelle certains mécanismes de sécurité sont levés et/ou n’ont pas de sens.
Mais… c’est un bon challenge et ça va permettre de mettre en place certains systèmes qui serviront surtout plus tard. Donc je prends juste un peu d’avance en fait.
Mise en situation – Illustration
Imaginez deux machines, Alice et Bob, qui souhaitent communiquer de manière sécurisée sur un réseau domestique.
-
Initiation de la communication : Alice, le client, souhaite envoyer une requête à Bob, le serveur. Cependant, au lieu de contacter Bob directement, elle envoie sa requête à un intermédiaire appelé Reverse Proxy. Ce Reverse Proxy agit comme un gardien, gérant les requêtes entrantes et les distribuant de manière efficace.
-
Rôle du Reverse Proxy : Le Reverse Proxy reçoit la requête d’Alice. Il peut gérer plusieurs tâches, comme l’équilibrage de charge entre plusieurs serveurs, la mise en cache de contenu pour des réponses plus rapides, et surtout, il peut gérer le chiffrement SSL/TLS pour sécuriser les communications.
-
Établissement de la connexion sécurisée : Pour sécuriser la communication, le Reverse Proxy utilise SSL/TLS. Alice envoie une demande de connexion sécurisée au Reverse Proxy. Le Reverse Proxy répond en envoyant son certificat numérique, qui a été émis par une Autorité de Certification (CA).
-
Vérification du certificat : Alice vérifie le certificat numérique reçu. Ce certificat, émis par une CA de confiance, garantit que le Reverse Proxy est bien celui qu’il prétend être. Les CA sont des entités de confiance qui vérifient l’identité des serveurs et émettent des certificats pour le prouver.
-
Chiffrement des données : Une fois le certificat vérifié, Alice et le Reverse Proxy établissent une connexion chiffrée en utilisant SSL/TLS. Toutes les données échangées entre Alice et le Reverse Proxy sont maintenant cryptées, assurant que même si quelqu’un interceptait les données, il ne pourrait pas les comprendre sans la clé de déchiffrement.
-
Transmission des données : Le Reverse Proxy, après avoir reçu la requête chiffrée d’Alice, la déchiffre et la transmet à Bob, le serveur final. Bob traite la requête et envoie sa réponse au Reverse Proxy.
-
Réponse sécurisée : Le Reverse Proxy reçoit la réponse de Bob, la chiffre à nouveau avec SSL/TLS, et l’envoie à Alice. Alice peut alors déchiffrer la réponse et obtenir les informations demandées de manière sécurisée.
En résumé, le Reverse Proxy agit comme un intermédiaire sécurisé, utilisant SSL/TLS pour chiffrer les communications et des certificats émis par des CA pour vérifier l’identité des parties, assurant ainsi une communication sécurisée et efficace entre Alice et Bob.
J’avais posée cette question à chat.mistral.ia :
Est-ce que utiliser un reverse proxi (nginx proxy manager) est utile si notre serveur Proxmox n’est pas exposé publiquement sur internet ?
Et puis à l’avenir, il y aura certainement quelques services qui seront ouverts à internet donc autant prendre le pas dès le début et éviter de bidouiller des certificats comme le suggère l’autre matou de ChatGPT….
Point sur ma situation
J’administre mon homelab relié à ma Freebox Ultra. Ce homelab sert d’hyperviseur Proxmox (192.168.0.11) lequel contient une VM pour Home-Assistant (192.168.0.100) mais aussi Pi-hole dans un conteneur LXC (192.168.0.101).
- La connexion à home-assistant se fait pour le moment via les url :
- http://192.168.0.11:8123
- http://homeassistant.local:8123 (hostname)
- Je n’utilise que mon PC (192.168.0.13) pour joindre Home-Assistant depuis un navigateur Firefox.
- J’ai aussi mon téléphone portable Android (192.168.0.30) avec l’application officiel de HA.
- Pour le moment tout est 100% local.
- Dans le futur, d’autres terminaux se connecteront à HA.
- Je passe par un VPN Wireguard intégré à ma Freebox pour joindre mon Home-Assistant au besoin depuis l’extérieur.
- J’ai déjà paramétré un accès SSH pour faire fonctionner le SFTP et ainsi accéder aux fichiers de Home-Assistant.
Résumé
Auto-signer des certificats SSL et les incorporer à ses serveurs/sites/URL, ok a on sait faire et avec Windows en prime, le certificat du CA (organisme certificateur) est facile à prendre en compte.
Mais là où c’est impossible, c’est avec Android (non root) dans le cadre d’une infrastructure 100% locale.
Vous verrez comment trouver un compromis et comment mettre en place les différentes mesures nécessaire à mettre en oeuvre autour d’une sécurisation de votre connexion par protocole TLS/SSL.
Android – SSL
Le cas d’Android avec sa gestion scrict des certificats SSL est LE maillon important à prendre en considération lorsque l’on met en place une stratégie de se sécurisation entre clients/serveur.
Parlons : protocoles SSL/TLS
Préparons-nous à devoir faire un peu de paperasse… Accrochez vous car ce n’est forcément le plus facile et les pièges sont très nombreux. Je vous résume ci-dessous ce qui a fonctionné chez moi.
Maintenant, il faut s’atteler aux certificats SSL/TLS pour venir… comme présenter ses papiers d’identité à un gendarme ^^
Seulement, ces papiers, ce n’est pas tout le monde (non non) qui peut les obtenir. Il faut en passer par un organisme de certification, dénommé « CA« .
Selon que notre site (adresse IP) se trouve accessible uniquement en local ou pas (www), le certificat ne sera pas le même car l’organisme de contrôle (CA) sera nécessairement différent.
Pour des besoins uniquement limités et restreints en interne (développement, pré-production), un CA tel que mkcert sera suffisant car très permissif… A défaut d’une machine exposée sur internet (www) où l’exigence de sécurité et accrue et où mkcert est totalement décrédibilisé et non sécurisé. On lui préfèrera Let’s Encrypt (ou autres !) qui pour le coup, a besoin d’une ouverture vers l’extérieur pour fonctionner.
Voici tout d’abord quelques notions à prendre en compte afin de comprendre ce que nous allons faire.
L’art du compromis…
- Ouvrir les ports de sa box pour laisser Let’s Encrypt (organisme CA reconnu par Android) : c’est comme ouvrir grand son portail et mettre un vigile juste devant la porte d’entrée. Pas sécurisé pour le reste des ouvertures et je ne suis même pas sûre que Let’s Encrypt certifie un nom de domaine .local (RFC 6762).
- Le « challenge DNS » : c’est au prix d’un sous-domaine ou d’une dépendance à un tiers comme DuckDNS.org, CloudFlare ou tout autre organisme. Je perds mon adresse minimal bien sympa « homeassistant.local »
- Faire cohabiter http (local) et https (distant) : c’est comme blinder sa porte d’entrée et laisser la petite porte de derrière ouverte avec les clé sur la serrure.
- Ne rien faire et considérer le LAN comme étant une zone sûre : c’est faire l’autruche mais faute de solution à la hauteur, autant rester dans la simplicité (qui fonctionne !).
- Ou alors… le meilleur de chaque solution :
- Mettre en place un reverse proxi sur une url courte style homeassistant.local UNIQUEMENT pour le local.
- Accès sécurisé : parfait mais exclue Android
- Accès non sécurisé : on estime que le réseau LAN local = sûre donc pas besoin d’en faire des caisses.
- Mettre en place un accès externe via
- un challenge DNS
- un VPN Wireguard ou ZeroTier.
- Mettre en place un reverse proxi sur une url courte style homeassistant.local UNIQUEMENT pour le local.
Une vidéo qui reprend ces différents points :
Sécurisé sa connexion client/serveur
Il n’y a pas 36 possibilités :
- Abandonner toute idée de sécurisé l’accès local via TLS/SSL (LAN = sécurisé)
- En passer par une ouverture des ports de sa box pour exposer son serveur afin de le consulter depuis n’importe où son serveur avec une connexion sécurisée. Mais c’est un risque important si on maîtrise mal ce que l’on fait !
- En passer par un tiers de confiance qui fera office de relais/tunnel.
- Ne faire confiance à personne mais avoir besoin que d’un Nom de Domaine pour la certification.
On passe à la pratique : le certificat
Vous décidez de sécuriser votre connexion.
ATTENTION
Pour les utilisateurs d’Android, cette idée s’accompagne de limitations.
Prennez-en connaissance avant !
Android – SSL
Le cas d’Android avec sa gestion scrict des certificats SSL est LE maillon important à prendre en considération lorsque l’on met en place une stratégie de se sécurisation entre clients/serveur.
Comme mentionné précédemment, l’obtention d’un certificat peut se faire de 2 manières :
- Local, auto-signé avec son propre CA (incompatible Android).
Les outils de développement tels que OpenSSl, mkcert, step-ca permettent d’obtenir facilement une chaine de certification mais cela ne fonctionne que pour un serveur accessible uniquement en local et hors Android. - Distant, avec un organisme de certification reconnu.
Le certificateur Let’s Encrypt (d’autres existent) nécessite un accès à un nom de domaine ou du moins à une zone DNS et donc une ouverture sur l’extérieur, plus délicat pour la sécurité.
L’utilisation de certbot est alors indispensable.
1/ LAN = sécurisé
C’est bien souvent comme cela que ça se termine !
On part du principe que les risques sont maîtrisés donc certaines solutions de sécurisation n’ont pas à être appliquées.
Fin.
2/ Ouvrir/redirection de ports de sa box
Opération dans laquelle je ne vais pas aller.
Il parait que c’est plus sûre car il n’y a pas de tiers qui rentre en ligne de compte mais c’est tout de même toucher à un point très stratégique de sa sécurité pour l’ensemble même de son réseau !
3/ Service tier
Puisque l’obtention d’un certificat TLS/SSL ne peut se faire que via une adresse IP publique (un serveur accessible à internet), nous devrons en passer l’intermédiaire d’un tiers qui lui va s’occuper de la partie « sécurisation » (CloudFlare) ou de simple prête-nom (DuckDNS.org). On parlera même de « challenge DNS« .
- DuckDNS.org
Fournis un sous-domaine.duckdns.org permettant d’avoir une adresse valide.
Associé à un addon pour HA, ce moyen est populaire même si n’est pas le plus fiable. - Cloudflare
Va ici servir de tunnel. Il faudra lui ajouter un nom de domaine que vous possédez déjà.
Qu’est-ce qu’un « challenge DNS » ?
Un challenge DNS consiste à prouver la propriété d’un domaine en ajoutant un enregistrement TXT temporaire dans la zone DNS, généralement **acme-challenge.<YOURDOMAIN>**, permettant à Let’s Encrypt de valider la possession du domaine.
DuckDNS.org
CloudFlare
4/ Avoir son propre nom de domaine (NdD)
- Avec un registar qui assure un renouvellement automatique du certificat (ex : OVH.com)
La liste des registars (Organisme de délivrance des Nom de Domaines) compatibles avec Let’s Encrypt est consultable à ce lien. - Avec un registar qui ne permet pas le renouvellement automatique du certificat (ex: o2switch)
Vous serrez obligé de créer manuellement votre certificat à l’aide de certbot et de le renouvellement manuellement tous les 3 mois.
Service compatible
OVH.com
- Noms de sous-domaines illimités ChatGPT.
- Vous pouvez suivre notement les informations contenues dans cette page :
Service non compatible
O2switch.fr
- Obtention du certificat SSL via Certbot (tâche cron non gérée sans API DNS cPanel).
Résumé
Pour la science, je m’y suis amusé et ça a fonctionné avec O2switch.fr. J’ai réussi à faire un certificat pour mon sous-domaine créé pour l’occasion et avec l’aide de ChatGPT j’ai pu certifier tout cela avec Let’s Encrypt via certbot et j’ai obtenu ce que je cherchais : un accès SSL mais via un NdD…
Le problème, O2switch (cPanel) ne fourni aucune API ni méthode pour automatiser la modification manuelle d’information qu’exige le challenge DNS et du coup, il faut renouveler manuellement l’opération tous les 3 mois (durée de validée des certificats Let’s Encrypt).
Petite anecdote :
J’ai eu recours à certbot pour Windows (lien1) (lien2) et pour cela, il a fallu installer Python sur Windows (lien1) [via chat.mistral.ia] avant de se rendre compte qu’il suffisait d’installer certbot depuis le conteneur LXC de NPM !
Pi-hole – Local DNS
Si vous avez un serveur DNS tel que Pi-hole, apprenez à la configurer en fonction.
NPN – Nginx Proxy Manager
Dès lors que vous hébergez un serveur (dans un homelab ou autre) et que son accès est sécurisé par TLS/SSL, il faut mettre en place un reverse proxy qui lui va agir comme intermédiaire / serveur mandataire. C’est lui qui va redistribuer les ressources vers le serveur contacté avec plusieurs règles dont, la gestion des certificats TLS/SSL.
Installation du CA (Windows)
En fonction de l’outil que vous avez employé pour auto-signer votre certificat SSL, vous devriez être en mesure de retrouver le certificat CA (celui pour l’autorité certificatrice de confiance) car c’est de lui dont il est question dans ce chapitre.
Exécution
Bien souvent il s’agit de simplement cliquer sur le fichier pour lancer son installation dans le magasin adéquat de Windows. Il doit être (normalement) ajouté systématiquement lors de la procédure d’obtention du certificat « serveur ».
Pour information, le certificat CA (de l’organisme de certification de confiance) généré via mkcert se trouve dans :
C:\Utilisateurs\Gotcha\mkcert\root.pem
Sur Android
Un article dévolue a été écrit pour ce point.
Tester
En fonction de ce que vous avez fait, vous ne devriez plus besoin avoir de saisir l’adresse IP suivi du numéro de port, juste le nom de l’host.
L’adresse http://192.168.0.100:8123 fonctionne toujours car on bypass tous les mécanismes mis en place. On interroge directement le serveur via son adresse IP ! Pi-hole ne peut rien faire car cette adressage n’est pas de son ressort. Unbound, pour lui, rien d’anormal (l’authenticité est direct). Quand au serveur reverse proxy Nginx il n’intercepte que les URL qu’on lui ont été programmées.
Autrement dit, si on souhaite renforcer encore plus la sécurisation à l’accès de votre home-assistant, il faut rajouter une mesure drastique !
Dépannage
Dans chaque chapitre, à chaque renvoie vers un article, ce dernier doit déjà contenir l’ensemble des informations nécessaire à la bonne compréhension et parfois même déjà une partie de « debugage ».
Ci-après, quelques pistes.
Erreur 502 :
Vérifiez votre fichier configuration.yaml
Erreur 400 :
400: Bad Request
Dialogue avec ChatGPT
Vérifier certificats SSL, vérifier les URL, vérifier la configuration de NPM, forcer les en-têtes et du coté de HA, vérifier la présence du bloc :
yaml
http:
ip_ban_enabled: true
login_attempts_threshold: 5
trusted_proxies:
- 192.168.0.104 #Nginx
use_x_forwarded_for: true
Le bloc ci-après est juste là pour forcer la redirection mais aussi forcer les en-tête. Normalement vous n’en n’aurez pas besoin.
cmd - Nginx
# Redirige explicitement tout vers HTTPS (au cas où "Force SSL" échouerait)
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
# Ajoute les entêtes de sécurité HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'self';" always;
Activer des logs de home-assistant :
(Ils sont consultables ensuite dans /config/homa-assistant.log)
yaml
#Activer les debug-log de HA
logger:
default: info
logs:
aiohttp.access: debug
homeassistant.components.http: debug
homeassistant.components.http.forwarded: debug
Forcer les URL (HA)
Le bloc homeassistant: avec internal_url et external_url permet à Home Assistant de savoir comment il est censé être contacté, en interne et en externe. Ces valeurs sont utilisées :
- pour générer les liens dans les notifications (mobile, mail, etc.)
- pour les intégrations qui envoient des callbacks à Home Assistant
- pour déterminer quelle URL utiliser dans certaines automatisations
Tu peux ajouter ce bloc uniquement si tu veux forcer Home Assistant à utiliser certaines URL, notamment si :
- tu utilises Nginx Proxy Manager ou un autre reverse proxy
- tu as une URL externe différente de l’URL locale
- tu veux que les intégrations (comme Google Assistant, Nabucasa, etc.) utilisent la bonne URL
Remarque utile :
Si tu vas dans l’interface de Home Assistant :
Paramètres → Paramètres généraux (Configuration → Paramètres système), tu peux aussi voir ou modifier les URLs internes/externes depuis l’UI.
Mais si tu les définis dans configuration.yaml, ces champs deviennent grisés dans l’interface (priorité à la config YAML).
yaml
homeassistant:
internal_url: "http://192.168.0.100:8123"
external_url: "https://homeassistant.julien-moreau.fr"
Securité
Attention au faux sentiment de protection…
Mes références :
- HAFR Etape par étape mais avec un NdD
- Novamostra (EN) Local, sans proxy, OpenSSL + Terminal, certificats sur le serveur.
- ChatGPT, conversation complète sur le sujet.
- Nviso Lab, module d’interception (root) des certificats. Profile Pro.
- Shizuku, mais n’est pas efficace, ne va pas assez profondément dans la couche système.



