Influxdb und Grafana

Aus meinem beruflichen Umfeld ist mir Grafana als Lösung zur grafischen Aufbereitung gut bekannt. Daten beziehen wir klassisch aus Graphite.

Für ein Projekt habe ich nun die Daten über öffentliches Netz (also das Internet) in die Datensenke einliefern müssen. Zunächst auch hier an Graphite gedacht, jedoch ergab sich schnell die Überlegung, das der Graphite Port 2003 (hier lauscht der Carbon Daemon) jedwede Daten ohne Authentifizierung annimmt. In einem  öffentlichen Netz sicher kein akzeptabler Zustand, da hier jeder mit Kenntnis von Port und IP beliebige Stördaten einliefern kann. Also auf die Suche nach Alternativen.

InfluxDB bietet laut db-engines.com  als Berechtigungskonzept mit einer „einfache[n] Rechteverwaltung mit Benutzeraccounts“ mehr als Graphite. Auch verspricht die Implementierung in Go mehr Performance. Grund genug, sich InfluxDB näher anzusehen.

InfluxDB

Dank des offiziellen Docker Images ist InfluxDB schnell probeweise gestartet. Hinweise liefert die Seite des Docker-Hub. Zunächst wird die Standardkonfiguration extrahiert:

docker run --rm influxdb influxd config > influxdb.conf

In dieser Datei muss die Option auth-enabled nun aktiviert werden:

...
[http] 
...
auth-enabled = true
...

In Kombination mit meinen beiden Projekten docker_nginx_auto_proxy und docker_ssl_endpoint kann man nun einen Docker Container starten, der Daten über TLS abgesichert entgegen nimmt:

docker run --name=influxdb_1 -d \
 -e PROXY_DATA=server_names:$INFLUXDOMAIN,port:8086 \
 -v /data/influxdb/data:/var/lib/influxdb \
 -v /data/influxdb/conf:/etc/influxdb/influxdb.conf:ro \
 influxdb -config /etc/influxdb/influxdb.conf

Nun müssen wir mindestens einen Admin-Nutzer anlegen. Zunächst verbinden wir uns auf die InfluxDB-CLI:

docker run --rm --link=influxdb_1 -it influxdb influx -host influxdb_1

Anschließend legt folgendes Statement den Admin-Nutzer bofh an:

CREATE USER bofh WITH PASSWORD 'rrzs42' 
  WITH ALL PRIVILEGES

Anschließend die CLI beenden und beim Neuverbinden zusätzlich die Parameter username und password zur Authentifizierung verwenden. Weitere Informationen zur Nutzerverwaltung von InfluxDB findet man in der offiziellen Dokumentation.

Eine Datenbank sollte in der CLI ebenfalls erstellt werden:

CREATE DATABASE datensenke

Testweise können nun bereits Daten eingeliefert werden:

curl -X POST -u bofh:rrzs42 \
  --data-binary 'wert,key=value wert=42.23'\
  'https://$INFLUXDOMAIN/write?db=datensenke'

Die genaue Beschreibung über das Schreiben von Daten findet man in der offiziellen Dokumentation.

Grafana

Für Grafana gibt es ebenfalls ein offizielles Docker-Image. Der erste Schritt ist das Extrahieren der Konfiguration:

docker run --rm --name grafana grafana/grafana
docker cp grafana:/etc/grafana/grafana.ini .

Die wichtigste Anpassung der Konfiguration bezieht sich auf das Abschalten des selbständigen Anmeldens neuer Nutzer (allow_sign_up = false in der Kategorie users). Somit ist nur noch der Administrator (Login: admin) in der Lage, neue Nutzer anzulegen.

Gestartet wird der Grafana-Container mit folgendem Kommando:

docker run --name=grafana -d \
    -e PROXY_DATA=server_names:$GRAFANADOMAIN,port:3000 \
    -v /data/grafana/lib:/var/lib/grafana/ \
    -v /data/grafana/conf:/etc/grafana/grafana.ini \ 
    -e "GF_SERVER_ROOT_URL=https://$GRAFANADOMAIN" \
    -e "GF_SECURITY_ADMIN_PASSWORD=s3cr3t" \
    grafana/grafana

Nun kann die Grafana-Instanz unter  https://$GRAFANADOMAIN aufgerufen werden und der Login funktioniert mit den Credentials admin:s3cr3t.

Der nächste Schritt sollte das Ändern des Passworts des Administrators sein und das Anlegen neuer Nutzer sein. Dies geschieht unter Grafana-MenuAdminGlobal Users.

Um wie die Daten aus InfluxDB in Grafana nutzen zu können, legt man eine Datenquelle unter Grafana-MenuData Sources an. Die Einstellungen für InfluxDB sind in unserem Fall:

  • Type: InfluxDB
  • URL: https://$INFLUXDOMAIN
  • Access: Proxy
  • Http Auth: With Credentials
  • InfluxDB Details:
    • Database: datensenke
    • User: bofh
    • Password: rrzs42

Jetzt sind wir in der Lage, über Dashboards wie gewohnt Graphen an zu legen. Beispielsweise:Et voilà, flexible und ansehnliche graphische Aufbereitung von Zeitseriendaten.

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.

Gehäuse „selbst“ gemacht

Für eines meiner Projekte wahr mal wieder ein schickes Gehäuse gefragt. 160mm breit, 130mm hoch, 120mm tief, 2 Aussparungen: eine für ein Display, eine für eine Infrarotdiode. Aber selbst berechnen, aufzeichnen und selbst sägen? Heute mal nicht.

Berechnen und Zeichnen

Im großen Internet hat schon jemand ein Lösung für das Problem des Zeichnens bereitgestellt: Makercase.com ermöglicht über Eingabe von einigen Eckdaten (Höhe, Breite, Tiefe, Materialstärke, Innen- oder Außenmaß?) sowie optionaler Verzahnung das Anlegen des Korpus. Zusätzlich können noch Durchbrüche (Löcher) positioniert werden. Zum Abschluss kann das Modell als JSON gespeichert werden beziehungsweise als Schnittmuster für Laser-Cutter heruntergeladen werden.

Das ganze passiert in Javascript im Browser, entsprechend kann sich das auf älteren Maschinen etwas ziehen.

Ausdrucken des Schnittmusters auf Papier zum Testen der Position der Löcher und Verzahnungen wird empfohlen. Hier kam Inkscape zum Einsatz. Hier können (und müssen später) noch Anpassungen vorgenommen werden.

Ausschneiden (lassen)

Aussägen mit der Laubsäge von den Verzahnungen? Nein, dank FORMULOR* ist dies nicht mehr nötig. FORMULOR* kann die Schnittmuster von MakerCase nach einigen Anpassungen aus diversen Materialien ausschneiden.

Eine Anleitung für Inkscape findet sich in auch in Englisch. Wichtig ist es, die Vorlagen für Inkscape zu verwenden (der Link findet sich auf der Anleitungsseite neben dem Inhaltsverzeichnis), da hierdurch lt. FORMULOR* die Bearbeitung beschleunigt werden kann. In meinem Fall waren folgende Schritte notwendig:

  • Anordnen der einzelnen Teile auf einem 384x384mm großen Zeichenbereich (als Material 3mm Sperrholz)
  • Ändern der Schnittkanten auf Blau (RGB: 0,0,255)
  • Anpassen der Linienstärke auf 0.01mm (leider zeigt Inkscape diese dann nicht mehr an)

Lädt man eine Datei bei FORMULOR* hoch, wird diese zunächst auf Regelverstöße geprüft und entsprechend beanstandet.

Anschließend kann man den Bestellvorgang starten, in meinem Fall etwas über 30€ inkl. Versand.

Lieferung

Hat etwas gedauert, lag aber wohl daran, dass ich die Vorlage nicht verwendet habe (Errinnerung: Vorlagen für das jeweilige Programm befinden sich auf der entsprechenden Anleitungsseite neben dem Inhaltsverzeichnis). Qualitativ kann ich nicht meckern, hatte bisher aber auch keine Erfahrung mit Laser-Cut-Sperrholz. Riecht etwas verbrannt, aber das wird produktionsbedingt sein. Von daher: alles gut, wird sicher noch mal probiert.

Spielchen mit RSA-Schlüsseln

Als Einstiegshürde für ein CTF (Capture the Flag) dient gerne mal ein RSA Schlüsselpaar, von dem nur der öffentliche Teil bekannt ist. Also kein unrealistischer Ansatz, lediglich die Schlüssellängen sollten entsprechend klein sein.

Vorbereiten der Challenge

Diese Schritte werden vom Spielleitder durchgeführt. Wichtig ist eine geeignete, nicht zu lange Schlüssellänge zu wählen. Hier wählen wir 256 Bit als Schlüssellänge. Das sollte die Teilnehmer vor keine Probleme stellen.

Generieren des Schlüsselpaars

Der wesentliche Schritt bei der Erzeugung eines RSA-Schlüsselpaars ist die Wahl von 2 Primzahlen p und q, deren Produkt n (der RSA-Modulus) die gewünschte Schlüssellänge besitzt.

Dank OpenSSL ist es einfach ein RSA-Schlüsselpaar zu erzeugen:

openssl genrsa -des3 -out private.pem 256
openssl rsa -in private.pem -outform PEM -pubout -out public.pem

Daraus ergibt sich als Public Key beispielsweise:

-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhALRUOO0rvPEA282wqL4VF5GibnA1kcux
LHdIOcT807+DAgMBAAE=
-----END PUBLIC KEY-----

Den privaten Schlüssel private.pem können wir nun löschen, da wir diesen zum Einen nicht mehr benötigen und zum Anderen ja rekonstruieren wollen.

Verschlüsseln der Probedatei

Eine Probedatei lesbar.txt wird mit dem öffentlichen Schlüssel mit OpenSSL verschlüsselt:

openssl rsautl -encrypt -inkey public.pem -pubin -in lesbar.txt -out geheim.txt

Das Ergebnis der Verschlüsselung ist eine Datei, die nur unlesbare binäre Daten enthält. Sie kann hier heruntergeladen werden: geheim.txt. Diese Datei und der öffentliche Schlüssel gehen an die Teilnehmer.

Lösen der Challenge

Diese Schritte werden durch die Teilnehmer durchgeführt.

Knacken der Schlüssel

Zunächst müssen wir aus dem öffentlichen Schlüssel die beiden Parameter  n (Modulus) und e (Exponent) extrahieren:

from Crypto.PublicKey import RSA

public_key = RSA.importKey(open('public.pem', 'r').read())
print 'n =', public_key.n
print 'e =', public_key.e

Dazu verwenden wir die Bibliothek pycrypto (Debian: python-crypto). Ausgegeben werden die beiden oben genannten Werte, in unserem Beispiel also:

n = 815651207903382691105573612057017618852
    64115611526254943458542612275141001091
e = 65537

Nun muss der Modulus faktorisiert werden (n ist das Produkt der beiden Primzahlen p und q). Dazu kann das msieve von Jason Papadopoulos verwendet werden.

Für unsere Zahl n liefert msieve auf einem Core2Duo T7400 nach knapp 10 Minuten die beiden Primfaktoren:

p = 264446414907090989475638551039611206507
q = 308437234133027923039636551098640509513

Alternativ können wir auch factordb.com verwenden, wenn die Zahl dort bereits faktorisiert vorliegt.

Nun müssen wir aus p und q den privaten Exponenten d berechnen:

d = 1/e mod (p-1)*(q-1)

oder mit Python und dem Modul gmpy2:

import gmpy2

p = 264446414907090989475638551039611206507
q = 308437234133027923039636551098640509513
e = 65537
d = gmpy2.invert(e,(p-1)*(q-1))

Aus den Werten n,e und d wird nun der private Schlüssel erstellt und ausgegeben:

from Crypto.PublicKey import RSA
key = RSA.construct((n,e,d))
print key.exportKey()

In unserem Beispiel ergibt das:

-----BEGIN RSA PRIVATE KEY-----
MIGrAgEAAiEAtFQ47Su88QDbzbCovhUXkaJucDWRy7Esd0g5xPzTv4MCAwEAAQIh
ALFDhX4nG6FxbaChww6vnyzjasWei1L/rUg3aG/c6MaxAhEA6ArZu41/pzoKRlXH
MfYqSQIRAMbyhuPv26I/S0+zokene2sCEDxkfpDK3huHBp+RubtuJ0kCECAEWecG
6+7Rhto9y4kCkB8CEQCSSbMXMjOybMpz3gCOQYeS
-----END RSA PRIVATE KEY-----

Wir speichern den privaten Schlüssel wieder in der Datei private.pem ab.

Entschlüsseln der Probedatei

Wurde alles richtig durchgeführt, so kann man mit folgender OpenSSL Anweisung die Probedatei entschlüsseln:

openssl rsautl -decrypt -inkey private.pem -in geheim.txt -out lesbar.txt

Der genaue Inhalt von lesbar.txt wird hier jedoch nicht verraten.

Abschluss

Man erkennt hier am Zeitaufwand zur Faktorisierung eines 256 Bit Schlüssels bereits, dass die Sicherheit von RSA auf genau dieser Schwierigkeit basiert. In der Praxis verwendet man daher Schlüssellängen von mindestens 2000 Bit (siehe dazu die Technische Richtilinie des BSI: Kryptographische Verfahren: Empfehlungen und Schlüssellängen (Seite 39, Kapitel 3.5 – RSA).

UML mit PlantUML

PlantUML ist ein ein GPL Tool zur Erstellung von folgenden UMLDiagramm Typen aus reinen Text-Dateien:

  • Klassendiagramm (class diagram)
  • Sequenzdiagramm (sequence diagram)
  • Objektdiagramm (object diagram)
  • Anwendungsfalldiagramm (use case diagram)
  • Aktivitätsdiagramm (activity diagram)
  • Komponentendiagramm (component diagram)
  • Zustandsdiagramm (state diagram)
  • Deploymentdiagramm (deployment diagram) BETA (Stand 1. April 2017)
  • Zeitverlaufsdiagramm (timing diagram) BETA (Stand 1. April 2017)

Verwendbar ist PlantUML entweder online über einen Demo-Bereich oder lokal über eine JAR-Datei. Für ein lokales Ausführen braucht man Java und die Graphviz-Software.

Zusätzlich bietet das Plugin PlantUML integration von Eugene Steinberg (erhältlich für alle IntelliJ IDEA basierenden Produkte) eine Integration in meine Lieblings-IDE. Features sind unter anderem:

  • Syntax Highlighting
  • Autocompletion bereits definierter Elemente
  • Parallele Darstellung von Definition und Ergebnisgrafik

Kleines Beispiel aus meinem aktuellen Projekt:

@startuml

package modes {
    interface Mode {
     + handle_input(code): Mode
     + display(device)
     + handle_mpd(data)
     + activate()
    }

    class ModeProxy {
      current_mode
     + handle_input(code): Mode
     + display(device)
     + handle_mpd(data)
    }

    class MenuMode <<Singleton>> {

    }

    ModeProxy ..|> Mode

    MenuMode ..|> Mode
    MenuMode -->"*" Mode : "topics"
}
@enduml

und das zugehörige Bild:

Ergebnis der Demo Datei
Ergebnis der Demo Datei

Fazit: Ein gutes Tool mit einigen Vorteilen (z.B. einfache Versionierung der Eingabedateien) unter einer der richtigen Lizenzen, welches nicht nur in IntelliJ und Co verwendet werden kann sondern in einer Vielzahl weiterer Tools.

Literaturempfehlung: Daemon und weitere von Daniel Suarez

Aus gegebenen Anlass, live von der Dachterrasse, eine kleine Literaturempfehlung für Nerds und weitere technikinteressierte Kreise:

  • Daemon
  • Darknet
  • Kill Decision
  • Control

Und dazu noch ein Interview aus dem Mai 2011 geführt von Frank Rieger mit Daniel Suarez, dem Autor der Daemon-Reihe, und veröffentlicht in der faz.

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

Mounten von Partitionen aus Image-Dateien

Ist das Backup einer SD-Karte nur als Image-Datei vorhanden und keine Zeit erst wieder auf SD-Karte zu schreiben? Dateimanager kann Image-Dateien nicht direkt einbinden? Hier die Lösung:

  1. Auslesen der Partitionen und ihrer Startsektoren:
    fdisk -l ${QUELLDATEI}

    (Hier in der Spalte Start nach dem Anfang der Partition suchen, unter Units steht die Größe der Sektoren)

  2. Einbinden der gewählten Partition:
    mount ${QUELLDATEI} /mnt -o offset=$((${ANFANGSSEKTOR}*${SEKTORGRÖßE}
  3. Und fertig!

 

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.

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.