Sommaire

Reset Domotique : Partie 1

Avant-propos

J’ai reconditionné un PC portable (MSI GS30) en serveur en me fabriquant un boitier pour celui-ci.
Il va donc venir en remplacement de mon Z83II.
Du coup, je ne m’embête pas à migrer d’Ubuntu 18.04 en 20.04 (LTS).

J’en ai donc profité pour tous refaire au propre en utilisant un maximum des conteneurs et avec Traefik comme reverse proxy.
Le tous est bien évidemment orchestré par Ansible (non détaillé ici).

Ayant plus de capacité, je ne me limite plus et vais donc ajouter des services en masse ! Cet article se décomposera donc en plusieurs parties pour pouvoir tous les présenter. Nous allons donc commencé par le cœur du système Home Assistant !
Ce dernier, comme le reste, sera accessible en HTTPS via Traefik.

Home Assistant Container

Principe

Dans un premier temps, je vais installer Home Assistant Container (via Docker). Afin d’assurer une communication de niveau 2 (être dans le même domaine de brodcast) pour que mes équipements communiquent simplement (avec du mDNS par exemple), je vais configurer le réseau de mon conteneur en mode host.

Afin de maximiser les performances d’HA, je vais y ajouté une base de données afin de ne plus utiliser le SQLite par défaut.
J’ai choisi une base PostgreSQL car j’ai plus l’habitude de l’utiliser que MariaDB.

Configuration conteneur

  • Fichier docker-compose.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: '3.8'
services:

  db:
    image: postgres:13-alpine
    container_name: hass-db
    env_file:
        /etc/homeassistant/.postgres.env
    volumes:
      - /var/lib/hass/postgresql/data:/var/lib/postgresql/data
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 127.0.0.1:5432:5432

  homeassistant:
    # Use GitHub Container Registry
    image: ghcr.io/home-assistant/home-assistant:stable
    container_name: homeassistant
    depends_on:
      - db
    #ports:
    #  - 8123:8123
    volumes:
      - /var/lib/hass/config:/config
      - /etc/localtime:/etc/localtime:ro
    restart: unless-stopped
    network_mode: host

J’utilise un fichier de variable d’environnement car je n’aime pas avoir mes mots de passe sur le fichier Docker Compose.

  • Fichier .postgres.env
1
2
3
POSTGRES_DB=sid
POSTGRES_USER=manny
POSTGRES_PASSWORD=diego

Depuis la version 2021.5 d’HA, les images sont aussi disponible sur le registre GitHub, j’ai décidé d’utiliser celle-ci.

We are now using both DockerHub and the new GitHub Container Registry.
If you want to use the new GitHub Container Registry, just use:
ghcr.io/home-assistant/home-assistant
(Instead of homeassistant/home-assistant)
Home Assistant 2021.5 release note

Comme le network d’HA est en mode host, il ne faut pas préciser le port. Pour PostgreSQL, je précise l’adresse IP d’écoute sur 127.0.0.1 afin que seule la machine puisse accéder à la base de données.

Et pour finir, je mappe des dossiers afin d’assurer la persistance des données. C’est plus simple pour y accéder depuis l’hôte (le serveur) pour éditer des trucs qu’en utilisant des volumes Docker.

On peut ainsi lancer notre composition avec un docker-compose up -d.
L’instance est alors accessible via l’adresse IP du serveur sur le port 8123 (ex: http://192.168.17.4:8123). Il suffit alors de suivre le setup de base.

Base de données

La BDD est créée lors du lancement du Docker Compose mais elle n’est pas encore utiliser sur HA. Pour la configurer, on édite le fichier de configuration d’HA pour y ajouter l’intégration Recorder.

  • Fichier configuration.yaml
1
2
3
recorder:
  db_url: postgresql://manny:diego@127.0.0.1:5432/sid
  purge_keep_days: 30

Pour de vrai, j’ai utilisé un secret pour stocker l’URL.

On valide donc la configuration et on redémarre le serveur.
https://my.home-assistant.io/badges/server_controls.svg

Serveur Web

On va maintenant faire le nécessaire pour qu’on puisse utiliser un reverse proxy. On doit alors activer l’analyse de l’en-tête X-Forwarded-For. Cela implique de spécifier l’adresse IP des proxies de confiance.

On précise alors une adresse IP qui va être celle de Traefik. On utilise alors une adresse IP du même type que l’interface docker0 (on évite d’utiliser 172.X.X.1 pour faire simple car cela va être l’adresse de la gateway de ce network). Vous comprendrez cela dans la partie suivante.

1
2
3
4
5
6
http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 172.28.0.10
  ip_ban_enabled: true
  login_attempts_threshold: 5

On valide donc une nouvelle fois la configuration et on redémarre le serveur.

De cette manière, HA peut être atteint en HTTP et en HTTPS quand la configuration du reverse proxy sera faite.

Traefik

Principe

Pour pouvoir fonctionné avec notre notre configuration d’HA, Traefik doit avoir une IP fixe. Nous allons donc faire le nécessaire pour cela.

Configuration conteneur

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
version: '3.8'

services:
  reverse-proxy:
    image: traefik:v2.4
    container_name: traefik
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    env_file:
      - /etc/traefik/.ovh-api.env
    volumes:
      - /etc/traefik/traefik.yml:/etc/traefik/traefik.yml:ro
      - /etc/traefik/dynamic/:/etc/dyn_config/
      - /var/log/traefik/:/var/log/traefik/
      - /etc/traefik/acme.json:/acme.json
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      traefik-net:
        ipv4_address: 172.28.0.10

networks:
  traefik-net:
    external:
      name: traefik-net

Mon DNS étant chez OVH, j’utilise le défi DNS car je ne redirige pas les ports 80 et 443 vers ce serveur.
Plus d’information ici.

Nous avons donc en complément les variables d’environnement pour le provider OVH et le fichier de configuration de Traefik.

  • Fichier .ovh-api.env
1
2
3
4
5
# OVH API credentials used by Certbot
OVH_ENDPOINT=ovh-eu
OVH_APPLICATION_KEY=riri
OVH_APPLICATION_SECRET=fifi
OVH_CONSUMER_KEY=loulou
  • Fichier traefik.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
entryPoints:
  oueb:
    address: ":80"
    http:
      redirections:
        entrypoint:
          to: superoueb
          scheme: https
          permanent: true
  superoueb:
    address: ":443"


log:
  level: ERROR
  filePath: "/var/log/traefik/traefik.log"

accessLog:
  filePath: "/var/log/traefik/access.log"
  bufferingSize: 100

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik-net
  file:
    directory: "/etc/dyn_config/"
    watch: true

certificatesResolvers:
  moncertresolveur:
    acme:
      email: "webmaster@scrample.xyz"
      storage: "/acme.json"
      caServer: "https://acme-v02.api.letsencrypt.org/directory"
      dnsChallenge:
        provider: "ovh"
        resolvers:
          - "1.1.1.1:53"
          - "8.8.8.8:53"

On n’oublie pas d’initier le fichier acme.json avec les bons droits :

1
2
touch /etc/traefik/acme.json
chmod 600 /etc/traefik/acme.json

Lancement du conteneur

Avant de lancer le conteneur, il faut créer le network sur notre machine (car ce dernier est décrit comme externe dans notre configuration).

1
`docker network create --subnet=172.28.0.0/16 traefik-net`

Ainsi, on peut lancer le service (docker-compose up -d). À ce stade rien n’est fait pour que HA doit en HTTPS.

Configuration pour HA

On va donc créer un fichier de configuration que l’on placera dans le dossier /etc/traefik/dynamic/. Je l’ai simplement nommé hass.yml.

  • Fichier hass.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
http:
  routers:
    hass:
      rule: Host(`assistantmaison.scrample.xyz`)
      entrypoints:
        - superoueb
      service: hass
      tls:
        certResolver: moncertresolveur
  services:
    hass:
      loadBalancer:
        servers:
          - url: 'http://192.168.17.4:8123'

En url, on renseigne donc le lien d’accès à HA.

En vue la configuration de Traefik, le fichier ainsi copié dans le dossier se retrouve automatiquement pris en compte pas le service.
Après que le DNS challenge soit finis, HA devrait-être accessible sur son URL en HTTPS (soit https://assistantmaison.scrample.xyz dans cet exemple).

Conclusion

J’ai donc la première base du renouveau de mon système domotique. Il ne me reste plus qu’à refaire toute ma configuration… 😫

Dans la seconde partie, j’expliquerais la mise en place des services annexes à cela comme ESPHome, Mosquitto ou encore Node-Red.