ioBroker: Ergänzung zu Open Source Hausautomatisierung im Vergleich

Im Artikel zu Open Source Hausautomatisierungslösungen wurden bereits einige Lösungen verglichen. Auf der diesjährigen 17. Gulaschprogrammiernacht  hat Bluefox ein weiteres System vorgestellt: ioBroker

ioBroker soll nun an den gleichen Kriterien wie die anderen 7 Systeme gemessen werden:

  1. Die Software muss quell-offen und frei sein (OpenSource)
  2. Dokumentation auf Englisch bzw. Deutsch und in ausreichenden Qualität und Detailtiefe vorhanden (Dokumentation)
  3. Größe der Community
  4. Support für Komponenten von eQ-3 für Homematic und Homematic IP (Hardware-Unterstützung), da diese bereits vorhanden ist.
  5. Apps für iOS bzw. Android (Apps)
  6. Verwendete Programmiersprachen & Technologien (Technologie)
  7. Die Software muss Graphen zur historischen Analyse von Messwerten bieten (Graphen)
  8. Die Software muss über Regeln erweiterbar sein, z.B. Verknüpfung von Schalter, Reaktion aufs Verlassen der Wohnung (Regeln)

ioBroker ist ein bei Github gehostetes OpenSource-Projekt unter MIT-Lizenz und basiert auf Node.js, einer Server-seitigen Implementierung von JavaScript.

Anleitungen zur Installation sind auf Deutsch, Englisch und Russisch vorhanden. Allerdings sollten die Autoren hier noch etwas Zeit investieren und Fehler ausbessern, da diese den Lesefluss beeinflussen.

Laut dem Vortrag von Bluefox (Videomitschnitt exisitiert) wächst die Community von ioBroker rasant an. Dazu trägt sicher auch bei, dass bereits eine Integration für Amazon Alexa existiert, was das Gesamtsystem deutlich smarter erscheinen lässt.

Homematic und Homematic-IP werden laut Forum unterstützt. Auch scheint Anwesenheitserkennung über Fritz!Box und das Steuern von Samsung TV Geräten unterstützt zu werden.

Wichtig sind natürlich auch Apps für:

Da ioBroker auf Node.js basiert kann beim Entwickeln sowohl Front- als auch Backend  in einer Sprache entwickelt werden. Daten werden sowohl in relationalen Datenbanken (MySQL, PostgreSQL oder SQLite) als auch in InfluxDB für zeitbasierte Daten abgelegt. Die transparenten Verbindungen über TCP erlauben es hierbei, Teile der Software modular auf mehreren Hosts zu betreiben.

Zur Visualisierung bietet ioBroker einen Editor, der komplett im Browser läuft. Hierbei werden unterschiedliche Darstellungen für Zielgeräte angeboten.  Diese Funktionalität wird über den VIS-Adapter bereit gestellt. Graphen stellt das System hierbei über den Flot-Adapter dar.

Zur Eigentlichen Automatisierung bietet ioBroker das Definieren von Szenen über den Szenen-Adapter aber auch das Erstellen komplexer über Adapter für Blockly und node-red.

Zusätzlich zu den, für den Vergleich wichtigen, Punkten bietet eine Integration in Apples Homekit. Diese ist ebenso ein Pluspunkt wie auch der optionalen Clound-Zusatz, der einen Zugriff aus der Ferne auch ohne eigenes VPN ermöglicht.

Alles in Allem ist ioBroker eine weitere Software mit guten Ansätzen, die ich aber aus Zeitgründen und da ich weder mit Node.js noch Javascript besonders viel Erfahrung besitze, nicht weiter betrachten werde.

Dynamische IP – Reagieren auf Änderungen

Als DSL Nutzer kommt man hierzulande meist nicht in den Genuss einer statischen IPv4 Adresse sondern bekommt regelmäßig eine andere IPv4 von seinem Provider zugewiesen. Als Nebeneffekt wird dadurch das Anbieten von Serverdiensten an Heimanschlüssen oder auch der Betrieb eines IPv6 Tunnels erschwert.

Die FRITZ!Box bietet Unterstützung für einige DDNS-Provider, manchmal möchte man aber auch einfach ein Skript ausführen. Den möglichen Anwendungen sind kaum Grenzen gesetzt.

Über Dienste wie https://icanhazip.com/ kann man sich seine öffentliche IP-Adresse, die zum Abrufen der Seite verwendet wurde, einfach anzeigen lassen und auch in Skripten verwenden. Möchte man die Aktualisierungen wirklich nur dann ausführen, wenn sich die IP geändert hat, so kann das Skript react_to_ip_change.sh helfen. Zu finden ist es im GIT.

Im wesentlichen Skript vergleicht das Skript eine gespeicherte IP mit der aktuell von https://icanhazip.com/ zurück gelieferten. Unterscheiden die beiden sich, so werden alle Skripte in /usr/local/etc/ipchange.d/ ausgeführt.

Kombiniert man das mit Cron, so aktualisiert man die eigene IP zeitnah in allen relevanten Systemen:

# m h dom mon dow command
* * * * * /usr/local/bin/react_to_ip_change.sh

Noch mal der Link zum GIT: https://code.nerd2nerd.org/n0ob/react_to_ip_changes

Icinga2 mit Docker

Aus diversen Gründen hatte ich Bedarf nach einen Icinga2 Setup inklusive icingaweb2.

Einleitung

Wichtige Anforderungskriterien waren:

  • Alarmierung über Mails ist möglich
  • Neuste Versionen zum Testen
  • Docker-typische “Separation of Concerns” und nicht “alles in einen Container”

Images wie icinga/icinga2 oder jordan/icinga2 konnten entweder nicht alle Features oder waren Monolithisch angelegt. Muss man einen monolithischen Container, der seine Datenbank enthält, durch eine neue Version ersetzen, sind die Daten (ohne zusätzlichen Aufwand) verloren.

Also doch ein eigenes Image, oder besser gleich 2:

docker_icinga2_core

Das docker_icinga2_core-Image bietet folgende Features:

  • Ausführen des icinga2 Daemons und der Plugins aus monitoring-plugins-standard
  • Volume zum Ablegen der Icinga2-Konfiguration außerhalb des Containers
  • Versand von Alarm-Benachrichtigungen über einen Smarthost (z.B. gmail, siehe hierzu GmailAndExim4)
  • Speicherung der aktuellen Konfiguration und Statusinformationen in einer MySQL (IDO)
  • Integrierte Kommandozeilenoption zum einmaligen Einrichten der IDO-Datenbank mit passendem Schema
  • (Optionale) Anbindung von Graphite zur Speicherung der Messdaten und Aufbereitung als Graphen
  • (Optionale) Bereitstellung der Icinga2-API für andere Container auf Port 5665

docker_icinga2_web

Das docker_icinga2_web-Image bietet folgende Features:

  • Zugriff auf icingaweb2 über Container-Port 80 (eventuell empfiehlt sich der Einsatz von docker_nginx_auto_proxy)
  • Steuerung des icinga2_core über die Icinga2-API
  • Die aktuellen Statusinformationen werden der IDO Datenbank entnommen
  • Festlegung der berechtigten Nutzer finden über eine Auth Datenbank statt

Deployment

Darstellung der Zusammenhänge der einzelnen Komponenten

Weitere Informationen zum Starten der einzelnen Container finden sich in den Git-Repositories zu docker_icinga2_core und docker_icinga2_web.

Fazit

Das Container-Duo läuft nun seit einigen Tagen auf meinem NAS und überwacht diverse interne Geräte sowie einige externe Dienste und meldet mir deren Ausfall zeitnah per Mail. Graphite und/oder Grafana ist noch nicht aktiv angebunden ist aber während der Testphase verprobt worden.

Update 29. November 2017

Auf Wunsch eines meines Lesers Patrick finden sich die Quellen für die beiden Container unter:

Warnung: ist nicht explizit erneut geprüft und kann Fehler enthalten. Benutzen auf eigenes Risiko ;)

Debian Pakete bauen im Docker-Container

Leider gibt es wohl für Debian 8 Jessie kein (aktuelles) Netatalk gibt, hier eine kleine Beschreibung wie man sich mit Docker und checkinstall ein entsprechendes Paket selber erstellen kann, ohne seinen Host mit den zur Paketerstellung notwendigen Abhängigkeiten zu belasten. Als Einstieg diente mir das Wiki von Netatalk und das Blog von Daniel Lange.

Zunächst das Dockerfile:

# Wir wollen das Paket später auf Debian 8 einsetzen. Andere 
# Distributionen sind analog möglich
FROM debian:8

# Update der Paketbasis und Installation der benötigten Abhängigkeiten
RUN apt-get update -y; \
    apt-get install -y build-essential \
        devscripts debhelper cdbs autotools-dev dh-buildinfo \
        libdb-dev libwrap0-dev libpam0g-dev libcups2-dev libkrb5-dev \
        libltdl3-dev libgcrypt11-dev libcrack2-dev \
        libavahi-client-dev libldap2-dev libacl1-dev \
        libevent-dev d-shlibs dh-systemd wget libtdb-dev checkinstall

# Quellcode beziehen und extrahieren
RUN wget http://prdownloads.sourceforge.net/netatalk/netatalk-3.1.10.tar.bz2; \
    tar xvf netatalk-3.1.10.tar.bz2

Anschließend bauen wir das Docker-Image:

docker build --tag=docker_build_netatalk .

Auführen mit:

docker run -v /tmp:/target --rm -ti docker_build_netatalk

Im Container dann folgendes durchführen:

$ cd netatalk-3.1.10
$ ./configure \
    --with-init-style=debian-systemd \
    --without-libevent \
    --without-tdb \
    --with-cracklib \
    --enable-krbV-uam \
    --with-pam-confdir=/etc/pam.d \
    --with-dbus-daemon=/usr/bin/dbus-daemon \
    --with-dbus-sysconf-dir=/etc/dbus-1/system.d \
    --with-tracker-pkgconfig-version=1.0
$ make
# Legt einige Verzeichnisse an, wird ja eh weggeworfen
$ make install 
$ checkinstall \
    --default \
    --install=no \
    --requires="libtdb1,libcrack2"
# Benutze cp oder scp, um das erzeugte Paket zu sichern
$ cp /netatalk-3.1.10/netatalk_3.1.10-1_amd64.deb /target
$ exit

Nach dem Ende löscht sich der Container dank –rm selbst und wir haben mit netatalk_3.1.10-1_amd64.deb ein schönes Debian-Paket, welches auch sauber wieder entfernt werden kann.

Programme mit tmux beim Systemstart automatisch starten

Da ich für das neuste Projekt (ClimateRecording) für den Linux-Client auf der Arietta Hardware erstmal noch kein Init-Script wollte, musste eine alternative Lösung gefunden werden.

Nachdem der Client bisher manuell in tmux gestartet wurde, bot sich als Lösung die Skriptbarkeit von tmux an:

tmux new-session -d -s client_tmux
tmux select-pane -t client_tmux
tmux send-keys "cd /$PATH/ClimateRecording/linuxClient" C-m
tmux send-keys "/$PATH/ClimateRecording/linuxClient/client.py" C-m

Trägt man diese Zeilen in der Datei /etc/rc.local ein, so wird bei jedem Systemstart eine Session für tmux gestartet und darin der Linux-Client ausgeführt.

Mit

tmux a -t client_tmux

kann man dann nach Login auf der Arietta die tmux-Session aktivieren.

 

Docker.io in der Praxis – OpenVPN Server

Nach dem ersten Artikel zu Docker nun ein weiterer Post zum Thema.

Diesmal direkt mit dem Erstellen eines eigenen Images. Es geht um OpenVPN, ein open-source VPN, welches eine Vielzahl von Plattformen (Windows, OS X, Linux, Android und iOS) unterstützt.

Veröffentlicht habe ich das ganze unter github.Die zentrale Datei ist die Datei Dockerfile, welche den Build des Images steuert.

FROM debian

MAINTAINER Joachim Lusiardi

RUN apt-get update; \
    apt-get -y install openvpn ;

ADD start.sh /start.sh

RUN chmod +x /start.sh

VOLUME ["/etc/openvpn"]
VOLUME ["/var/log/openvpn"]

EXPOSE 1194/udp
EXPOSE 1194/tcp

ENTRYPOINT /start.sh

FROM legt ein Basis-Image fest, hier die neuste Version von Debian.
MAINTAINER gibt den Betreuer des Images an.
RUN führt Befehle innerhalb des Images aus. Hier das Updaten der Packet-Quellen, Installieren von OpenVPN und dem Ausführbarmachen des start-Skripts.
ADD fügt eine Datei dem Image hinzu.
VOLUME gibt an, das ein Verzeichnis des Images beim Ausführen auf ein Verzeichnis des Hosts gelegt werden kann.
EXPOSE definiert welche Ports von ausserhalb des Images erreichbar sein sollen. Diese sind nicht automatisch beim Starten des Images auf eine öffentliche IP gebunden.
ENTRYPOINT gibt an, welches Kommando ausgeführt werden soll.

Weitere Detail auf github und auch unter https://registry.hub.docker.com/u/shing19m/docker-openvpn-server/.

Docker.io in der Praxis – Installation

Nachdem Docker immer mehr gehyped wird (LinuxMagazin 09/14, c’t 17/2014), soll das ganze hier mal für einen Root-Server inklusive folgender Dienste getestet:

  • WordPress (inklusive MySQL Datenbank)
  • OpenVPN Server
  • getrennter SSH Server für IRC mit irssi in screen oder tmux

Zusätzlich soll als Option das schnelle und einfache Bereitstellen von weiteren Diensten auf Basis von Technologien wie Node.js und NoSQL Datenbanken möglich sein.

Installation von Docker auf dem Root-Servers

Zunächst muss Docker installiert werden. Das soll nun hier besprochen werden.

Basisinstallation

Der Hoster bietet hier Debian-76-wheezy-64-minimal an.

Nach der Installation muss die Liste der Paket-Quellen angepasst werden (Debian Testing wird benötigt). Dabei hilft der Debian Sources List Generator:

deb http://ftp.debian.org/debian testing main contrib 
deb-src http://ftp.debian.org/debian testing main contrib 

deb http://ftp.debian.org/debian/ jessie-updates main contrib 
deb-src http://ftp.debian.org/debian/ jessie-updates main contrib 

deb http://security.debian.org/ jessie/updates main contrib 
deb-src http://security.debian.org/ jessie/updates main contrib

Anschließend mit apt-get update und apt-get dist-upgrade auf die Debian-Version jessie (bzw. testing) updaten.

Nun für den richtigen Kernel sorgen:

echo "deb http://ftp.us.debian.org/debian wheezy-backports main" > \
    /etc/apt/sources.list.d/wheezy-backports.list
apt-get update
apt-get -t wheezy-backports install linux-image-amd64

Docker installieren

Für Docker gibt es ein Ubuntu Repository, welches auch für Debian verwendet werden kann:

apt-key adv --keyserver keyserver.ubuntu.com \
    --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
echo "deb http://get.docker.io/ubuntu docker main" > \
    /etc/apt/sources.list.d/docker.list
apt-get update
apt-get install lxc-docker

Die beiden letzen Schritte nach dieser Anleitung: http://doduck.com/docker-install-on-debian-7/

IPv6 für die Container

IPv6 ermöglicht es, für jeden Container eine eigene IP zu reservieren.

Leider wird IPv6 von Docker zum aktuellen Stand (23. August 2014, Docker Version  1.2.0) noch nicht unterstützt, kann aber über lxc direkt an den Container durchgereicht werden. Wenn IPv6 nicht verwendet werden soll, so kann dieser Abschnitt übersprungen werden.

Für IPv6 muss in der Datei /etc/sysctl.conf folgende Zeile eingefügt oder wieder eingkommentiert werden:

net.ipv6.conf.all.forwarding=1

Und der Docker-Daemon muss auf den lxc Treiber umgestellt werden. Dazu unter Debian in der Datei /etc/default/docker folgendes eintragen:

DOCKER_OPTS="--exec-driver=lxc"

Zusätzlich muss das lxc Paket installiert werden:

apt-get install lxc

Nun muss der von Docker angelegten Bridge noch eine  IPv6 IP hinzufügen:

ip -6 addr add aaaa:bbbb:cccc:dddd::1:1/112 dev docker0

Dabei muss natürlich aaaa:bbbb:cccc:dddd durch einen entsprechenden Teil des eigenen IPv6 Subnetzes ersetzt werden.

Um das Ganze zu Vereinfachen, bietet es sich an, Container dann mit folgendem Script zu starten:

#!/bin/bash

NW_IP=$1
shift
NW_GW=aaaa:bbbb:cccc:dddd::1:1
#shift
REST=$@

docker run \
    --lxc-conf="lxc.network.flags=up" \
    --lxc-conf="lxc.network.ipv6=$NW_IP" \
    --lxc-conf="lxc.network.ipv6.gateway=$NW_GW" \
    $REST

Beim Aufrufen muss die IPv6 Adresse inklusive Subnetzmaske angegeben werden, also aaaa:bbbb:cccc:dddd::1:2/112.

Résumé

Nun ist es möglich mit Docker Container zu verwenden und sogar IPv6 direkt in die Container zu leiten.

Arietta G25 und das WPA-WLAN

Das Arietta G25 ist ein Embedded Linux Board mit:

  • 400Mhz ARM-9 CPU Atmel AT91SAM9G25
  • 128 oder 256 MByte DDR2 RAM
  • MicroSD Karten Slot für bis zu 64 GB
  • Debug-Port für optionales Debug-Modul
  • 3 USB Ports (1 Port für optionales WLAN reserviert)
  • 20×2 Pin Header im 2,54 mm für
    • I2C
    • USB
    • UART
    • PWM

Die komplette Liste der Ausstattung findet man auf der Herstellerseite.Das WLAN Modul WIFI-2-IA mit RaLink RT5370N kann fest auf die Basisplatine gelötet werden und belegt dann einen der 3 USB-Ports.

Anschließend kann man sich auf der Arietta einloggen (entweder per ssh über USB-LAN oder über serielle Konsole und den Debug-Port). In beiden Fällen ist das voreingestellte Passwort für den root-Nutzer “acmesystems”.

Mit wpa_passphrase SSID PASSWORT kann man sich den notwendigen Wert für die Konfiguration in /etc/network/interfaces berechnen lassen. Als Ergebnis erhält man:

network={
        ssid="SSID-WERT"
        psk=PSK-WERT
}

Daraus ergibt sich für WLAN0 folgendes:

auto wlan0
iface wlan0 inet dhcp 
        wpa-ssid "SSID-WERT"
        wpa-psk PSK-WERT

Dabei sind die Anführungszeichen zu beachten. Mit ifup wlan0 kann die Schnittstelle aktiviert werden und sollte sich dann per DHCP eine IP-Adresse und Default-Route erhalten.

 

nmon: Einschränken auf ausgewählte Festplatten bzw. Partitionen

nmon is bei der Anzeige von Festplattendaten nicht wählerisch und zeigt (zumindest unter Linux, AIX war grade nicht zur Hand ;) ) jeweils Daten zur Gesamtplatte (z.B.  /dev/sda) als auch zu einzelnen Partitionen (z.B. /dev/sda1 und /dev/sda3) an. Soweit ist das kein Problem, nur summiert nmon die einzelnen Werte auf, was zu unsinnig hohen Werten führt, wenn in der Summe sowohl die Festplatte als auch einzelne Partitionen summiert werden.

Nun gilt es also nmon auf ausgewählte Festplatten oder einzelne Partitionen zu beschränken. Das Handbuch (nmon -h) ergibt:

-g <filename> User Defined Disk Groups [hit g to show them]
 - file = on each line: group_name <disks list> space separated
 - like: database sdb sdc sdd sde
 - upto 64 disk groups, 512 disks per line
 - disks can appear more than once and in many groups

Also sieht eine entsprechende Datei für meinen Fall (3 Festplatten, jeweils eine relevante Partition) so aus:

Data1 sda3
Data2 sdb1
Data3 sdc1

Wie in der Hilfe beschrieben, wird nmon nun mit der Datei als Parameter gestartet:

nmon -g disks.dat

Anschließend zeigt nmon nach Druck auf ‘g‘ die entsprechenden Statistiken an.