Grünes Fragezeichen auf dunklem Hintergrund, umrahmt von weiteren Fragezeichen und Cyber Security Elementen

Was lernen wir aus bekannt gewordenen Cyberattacken?

Im Rahmen des World Economic Forum 2024 hat Emma Charlton in ihrem Artikel „2023 was a big year for cybercrime – here’s how we can make our systems safer“ auch fünf gravierende Cyberattacken kurz beleuchtet.

Ich möchte diesen Artikel zum Anlass nehmen die Einfallstore für die Cyberattacken zu untersuchen um daraus Lehren ziehen zu können. Ich habe dabei die Reihenfolge und Bezeichnungen der Attacken aus dem Artikel beibehalten.

1. Theft of US State Department records

Dass der Fokus bei dieser Attacke auf dem Aussenministerium der Vereinigten Staaten liegt dürfte der verwendeten Quelle bleepingcomputers.com geschuldet sein. Tatsächlich waren dutzende Organisationen von diesem Datenleck betroffen.

Vermutlich die chinesische Storm-0558-Gruppe ist in den Besitz eines Microsoft-Schlüssels gelangt. Dieser wird normalerweise in einem abgeschotteten Produktiv-System verwendet. Der genaue Hergang kann nicht sicher nachvollzogen werden, da die Protokollierung nicht so weit reicht, aber es wird folgender Ablauf vermutet (stark vereinfacht): Als Inhalt eines Crash-Dumps, der vermeintlich keine sensiblen Daten mehr enthalten sollte, gelang der Schlüssel in einen weniger geschützten Bereich. Dieser wurde dann über einen kompromittierten Zugang eines Microsoft-Ingenieurs ausgelesen. Über den Angriffsvektor auf den Microsoft-Ingenieur konnte ich keine genaueren Angaben finden.

Fazit

Eine Verkettung von Fehlern hat diesen Angriff ermöglicht. Den heikelsten Punkt sehe ich aber darin, dass Crash-Dumps aus abgeschotteten Produktiv-Systemen in einem weniger geschützten Bereich untersucht werden. In den Routinen, welche die sensiblen Daten entfernen sollten, können weiterhin Fehler auftreten, so dass ähnliche Probleme wieder auftauchen können.

Quellen

https://www.bleepingcomputer.com/news/security/microsoft-breach-led-to-theft-of-60-000-us-state-dept-emails/
https://www.bleepingcomputer.com/news/microsoft/hackers-stole-microsoft-signing-key-from-windows-crash-dump/
https://www.heise.de/news/Hackerangriff-aus-China-auf-Dutzende-Organisationen-und-auch-Staaten-9213658.html
https://www.heise.de/news/Neue-Erkenntnisse-Microsofts-Cloud-Luecken-viel-groesser-als-angenommen-9224640.html
https://www.heise.de/news/Gestohlener-Microsoft-Schluessel-stammte-aus-einem-Crash-Dump-9297240.html
https://www.microsoft.com/en-us/security/blog/2023/07/14/analysis-of-storm-0558-techniques-for-unauthorized-email-access/

2. DarkBeam’s data protection lapse

Beim Datenleck von DarkBeam waren mehr als 3,8 Milliarden Datensätze betroffen. Es handelte sich dabei um E-Mail-Adressen oder Benutzernamen und das zugehörige Passwort. Ob das Passwort dabei geschützt oder als Klartext abgelegt war war aus den von mir konsultierten Quellen nicht ersichtlich.

Ursache für das Datenleck war ein ungeschütztes Elasticsearch/Kibana-Interface. Laut Mutmassungen wurde nach Wartungsarbeiten vergessen das Passwort wieder zu setzen. Dies stellt aber bei mir die Frage warum der Passwortschutz für Wartungsarbeiten überhaupt entfernt werden muss. Dies fördert Fehler und entsprechende gravierenden Konsequenzen.

Fazit

Auf den ersten Blick ist hier klar menschliches Versagen die Ursache. Es sollten aber unbedingt die Prozesse überdacht werden um in Zukunft solche Fehler zu verhindern oder zumindest die Auswirkungen zu mindern. Insbesondere von einer Firma, die sich im Security-Bereich bewegt sollte dies erwartet werden dürfen.

Quellen

https://techreport.com/news/darkbeams-alarming-data-breach-exposes-3-8-billion-records/
https://cybernews.com/security/darkbeam-data-leak/
https://www.idstrong.com/sentinel/darkbeams-alarming-data-breach/

3. Royal Mail’s ransomware attack

Am Anfang des Jahres war Royal Mail, der nationale Postdienst im Vereinigten Königreich, Opfer einer Ransomware-Attacke. Die Hackergruppe LockBit verschlüsselten dabei wichtige Dateien und drohten damit Daten zu veröffentlichen. Sie verlangten 80 Millionen Dollar Lösegeld, was Royal Mail aber nicht gewillt oder nicht möglich war zu zahlen.

Über den Angriffsvektor wurde nicht informiert, es ist aber anzunehmen dass über Phishing Zugangsdaten erschlichen wurden oder per E-Mail die Schadsoftware ins System gelangte.

Fazit

Da hier vermutlich Phising der Angriffsvektor war wäre hier als Massnahme Schulung der Mitarbeiter und, falls nicht schon eingeführt, Zwei-Faktor-Authentisierung vorzusehen.

Quellen

https://www.theguardian.com/business/2023/jan/12/royal-mail-ransomware-attackers-threaten-to-publish-stolen-data
https://www.theguardian.com/business/2023/feb/21/royal-mail-international-deliveries-cyber-attack-ransom-strikes
https://www.bleepingcomputer.com/news/security/lockbit-ransomware-gang-claims-royal-mail-cyberattack/

4. MOVEit data theft

Die CL0P Ransomware Gruppe hat im Mai 2023 eine SQL injection zero-day-Lücke ausgenutzt um Software in der MOVEit Transfer Webanwendung zu installieren. Mit Hilfe dieser Webanwendung war es der Gruppe möglich Daten zu sammeln und zu stehlen. Dabei scheinen mehr als 2000 Organisationen von der Attacke betroffen zu sein. Die CL0P Gruppe versuchte unter Androhung der Veröffentlichung der Daten bei den Organisationen Geld zu erpressen. Um überhaupt initialen Zugriff auf die Systeme zu erlangen wurden Daten mittels Spear-Phising gesammelt.

Fazit

Als Betreiber einer Infrastruktur ist es unmöglich zero-day-Lücken zu verhindern, da man vom Hersteller der Software abhängig ist. Indem man sich über Sicherheitslücken in der eingesetzten Software informieren lässt, den Datenverkehr auf Unregelmässigkeiten überwacht und einen Notfallplan vorbereitet hat kann man schnell und besonnen reagieren und so die Auswirkungen einer Sicherheitslücke minimieren.

Quellen

https://www.ncsc.gov.uk/information/moveit-vulnerability
https://www.cisa.gov/news-events/cybersecurity-advisories/aa23-158a
https://www.inside-it.ch/erste-opfer-der-moveit-luecke-in-der-schweiz-20230616

5. Indonesia’s stolen passport records

Ein Hacker hat über 34 Millionen Passport-Daten gestohlen. Dabei handelt es sich um Namen, Geburtsdatum, Geschlecht des Besitzers sowie Nummer, Ausstell- und Ablaufdatum des Passes. Mit diesen Daten kann entsprechend Identitätsdiebstahl begangen werden.

Ob der Hacker über eine Sicherheitslücke, mittels Phishing erlangte Zugangsdaten oder eine Mischung von beidem zu den Daten gelangte konnte ich den Berichten nicht entnehmen. Vielleicht war es den zuständigen Behörden selber noch nicht klar über welchen Weg die Daten zum Hacker kamen.

Fazit

Als Kunde oder Bürger ist man den Organisationen, denen man seine persönlichen Daten anvertraut, ausgeliefert. Man kann nur möglichst Daten-sparsam unterwegs sein, das heisst sich nur registrieren wenn es anders nicht geht und nur die Daten angeben die zwingend nötig sind. In diesem Zusammenhang möchte ich auch darauf hinweisen, dass man für jeden Dienst ein eigenes Passwort verwenden sollte, so dass mit einem Datenleck nicht auch andere Konten gefährdet sind.

Aber wenn man einen Pass benötigt muss die Behörde natürlich die entsprechenden Daten verarbeiten um den Pass ausstellen zu können.

Quellen

https://www.cpomagazine.com/cyber-security/34-million-indonesian-passports-exposed-in-a-massive-immigration-directorate-data-breach/
https://asianews.network/hacker-breaches-data-of-34-million-indonesian-passports/

Gesamtfazit

So unterschiedlich diese fünf Cyberattacken sind, so unterschiedlich sind auch die Fazite aus ihnen. Die „Silver Bullet“, mit der man alle Probleme lösen kann, gibt es nicht. Nur indem man auf allen Stufen Vorkehrungen trifft kann man das Sicherheitsnetz so eng knüpfen dass die Risiken von Cyberattacken bezüglich Auftretenswahrscheinlichkeit und Auswirkung minimiert werden.

Wolkenhimmel

Nextcloud auf Shared Webhosting updaten

Das Betreiben einer Nextcloud-Instanz ist bei Hostpoint eigentlich nur geduldet und der Betrieb auf einem Shared Webhosting ist von Nextcloud auch nicht supported. Für den einfachen Datenaustausch betreibe ich aber trotzdem eine Instanz auf meinem Shared Webhosting und muss diese entsprechend auch immer mal wieder updaten. Dabei treten immer wieder dieselben Probleme auf, die ich hier mit den Workarounds dokumentieren will. Die Beschreibung ist auf dem Stand von Version 25, die Probleme traten aber identisch bei den Vorgängerversionen auf und ich vermute, dass sie auch bei den nachfolgenden Releases auftreten werden.

Ich verwende in dieser Beschreibung, da meine Nextcloud-Oberfläche auf Deutsch eingestellt ist, die deutschen Bezeichnungen.

0. Backup erstellen

Eigentlich sollte es jedem klar sein, dass bei einem Update immer etwas schief gehen kann. Aber nochmals zur Sicherheit: vor jedem Update Files und Datenbank sichern!

Um umfangreiche Verzeichnisse (wie z.B. eine Nextcloud-Installation) als einzelne Datei zu Sichern habe ich ein kleines php-Tool geschrieben, das auf Knopfdruck ein Backup startet und dann das .zip-File als Download zur Verfügung stellt.

Es empfiehlt sich zusätzlich die Datei core/shipped.json einzeln herunterzuladen, da wir diese im folgenden Ablauf noch ein paar Mal benötigen werden.

1. Update starten

Als Administrator das WebUI von Nextcloud starten. Falls in den Benachrichtigungen (Glocken-Symbol) auf das Update hingewiesen wird öffnet ein Klick auf den Hinweis die Verwaltungs-Seite, von welcher aus das Update gestartet werden kann. Ansonsten kann über das Benutzer-Menü oben rechts auf Administrationseinstellungen geklickt werden und es erscheint dieselbe Seite.

Unter „Version“ wird die aktuell verwendete Version angezeigt. Wenn eine neuere Version verfügbar ist wird diese unter „Aktualisieren“ aufgeführt. Dort befindet sich auch der Knopf „Updater öffnen“, mit dem die Update-Seite geöffnet wird.

Die Update-Seite ist auf Englisch, dementsprechend kommen hier die englischen Bezeichnungen zum Zug. Es wird nochmals die Ausgangs- und die Zielversion angezeigt.

Mit „Start update“ wird das Update ausgeführt.

Es werden die verschiedenen Schritte aufgeführt. Der aktuell laufende ist mir einem drehenden Kreis markiert während die erfolgreich durchgeführten Schritte mit einem grünen Haken markiert sind.

[Update, ab Version 29.0.0]
Schon während dieser Schritte kann ein Fehler auftreten, der in der Datei data/updater.log mit folgendem Fehler auftaucht:


Exception: Exception
Message: Not authenticated
Code:0

Dies kann z.B. schon auftreten wenn man zuerst das Changelog liest, das vom Updater aus erreichbar ist.
Um diesen Fehler zu beheben reicht es mit dem Browser eine Seite zurück zu gehen, den Updater erneut aufrufen und mit „Retry update“ das Update weiter ausführen.
[/Update]

2. Delete old files

Nach einiger Zeit schlägt der Schritt „Delete old files“ fehl und ist mit einem roten „X“ und hellroter Hintergrundfarbe markiert. Leider liefert die Update-Seite keine Informationen, was genau schief gelaufen ist. Genauere Informationen findet man in der Datei data/updater.log. Dabei sind 2 Fälle zu unterscheiden, wobei es irgendwann von Fall 1 zu Fall 2 wechselt:

  1. Message: Could not rmdir:
    Es ist ein Fehler beim Löschen des nach rmdir angegebenen Verzeichnisses aufgetreten.
    Man könnte nun das Verzeichnis von Hand löschen, dies ist aber gar nicht nötig. Auf der Update-Seite ist anstelle des Buttons „Start update“ nun der Button „Retry update“ vorhanden. Dieser führt das Update an derselben Stelle weiter und versucht entsprechend nochmals das Verzeichnis zu löschen, was dann meistens auch klappt.
    Man muss nicht nach jedem Fehler im Log nachschauen was passiert ist, man kann auch einfach mehrmals auf „Gut Glück“ auf „Retry update“ klicken.
  2. Message: core/shipped.json is not available
    Spätestens wenn der Klick auf „Retry update“ augenblicklich wieder einen Fehler meldet sollte wieder das Log konsultiert werden. Wenn die obenstehende Meldung erscheint benötigen wir das einzeln gesicherte File. Dieses wird vermutlich beim Löschen der alten Dateien ebenfalls gelöscht, wird aber für den Retry-Mechanismus wieder benötigt.
    Entsprechend kopieren wir die Datei wieder an ihre ursprüngliche Stelle und starten dann wieder mit „Retry update“. Solange nun beim Schritt „Delete old Files“ ein Fehler auftritt müssen wir immer zuerst wieder die Datei core/shipped.json hochladen und dann wieder auf „Retry update“ klicken.
    Irgendwann wird auch der Ordner core gelöscht, dann muss entsprechend auch der Ordner wieder erstellt oder kopiert werden.

3. Move new files in place

Wenn wir beim Schritt „Move new files in place“ angekommen sind gibt es wieder Fehler der Art „Message: Could not rmdir“ (diesmal aber ohne : nach rmdir). Nun kann wiederum direkt auf „Retry update“ geklickt werden bis auch diese Fehlergruppe durchgearbeitet ist und wir beim Schritt „Continue with web based updater“ landen. Dort kann nun ber Button „Disable maintaince mode and …“ angeklickt werden und man landet bei der Aktualisierung der Apps.

4. Aktualisierung der Apps

Es werden alle Apps aufgeführt, die aktualisiert werden. Zuunterst gibt es den Knopf „Aktualisierung starten“ welche den Prozess auslöst.

Dies kann ebenfalls fehlschlagen, was zur Folge hat dass der Maintenance-Mode aktiv bleibt. Dadurch kann aber der fehlgeschlagene Schritt nicht nochmals gestartet werden.

In der Datei config/config.php muss ‚maintenance‘ auf false gesetzt werden um den Maintenace-Mode auszuschalten und den Aktualisierungsprozess weiterzuführen.

5. Abschluss

Zum Schluss sollte wieder das Nextcloud-Dashboard angezeigt werden. Der Maintenance-Mode wird dabei automatisch wieder ausgeschaltet. Auf der Verwaltungs-Seite (Benutzer-Menü oben rechts, Administrationseinstellungen) sollte nun unter „Aktualisieren“ vermerkt sein dass die Version aktuell ist. Falls dies nicht der Fall ist war man vermutlich auf auf einer älteren Major-Version und man darf das ganze Spiel (inkl. Backup!) nochmals durchführen.

3dwire-frame hands typing on a blue keyboard

Dell Display Manager Ersatz unter Ubuntu 22.04

Ich habe mir einen neuen Monitor geleistet, den Dell P3421W mit eingebautem KVM-Switch. Diesen verwende ich mit DisplayPort-Anschluss an meinem Windows-Rechner und mit dem HDMI-Anschluss an meinem Ubuntu-System. Unter Windows kann mit dem Dell Display Manager eine Tastenkombination definiert werden, mit welcher auf den anderen Anschluss gewechselt werden kann. Für Linux bietet Dell diese Software aber nicht an.

Recherche

Sehr schnell bin ich bei askubuntu auf eine Frage mit Antworten gestossen, die genau diese Problematik widerspiegelte. Dabei hat sich gezeigt, dass es sich lohnt nicht nur die akzeptierte und bestbewertete Antwort zu lesen, sondern auch weniger gut bewertete, die aber möglicherweise neuer sind oder andere Aspekte beleuchten. In diesem Fall wurde als Alternative für ddccontrol ddcutil empfohlen.

Umsetzung

Als erstes habe ich ddcutil installiert:

sudo apt install ddcutil

Danach habe ich mit dem detect-Command den verwendeten I2C-bus bestimmt:

sudo ddcutil detect

Die Ausgabe in der Zeile I2C bus: /dev/i2c-4 gibt dabei die zu verwendende Bus-Nummer an, in meinem Fall 4.

Um nicht jedes Mal sudo-Rechte erlangen zu müssen habe ich meinen Benutzer der Gruppe i2c hinzugefügt und mittels einer udev-Regel die i2c-Busse der Gruppe i2c zugewiesen:

sudo usermod -G i2c -a <username>
sudo cp /usr/share/ddcutil/data/45-ddcutil-i2c.rules /etc/udev/rules.d/

Zum Schluss habe ich unter Settings->Keyboard->Keyboard Shortcuts->Custom Shortcut einen neuen Shortcut mit derselben Tastenkombination wie unter Windows und dem Command ddcutil -b 4 setvcp 0x60 0x0f erfasst.

Fazit

Mit den passenden Tools kann, mit ein wenig Aufwand, unter Linux das System mit individuellen Komfortfunktionen ergänzt werden.


Image courtesy of pixtawan at FreeDigitalPhotos.net

Zeitgeist 2020

Nachdem ich für das Jahr 2013 den letzten Zeitgeist-Artikel erstellt hatte möchte ich, auch angeregt durch das Browser-Titelthema in der c’t 02/21, für 2020 wieder die Statistiken meiner Seiten präsentieren.

Browser

Chrome ist auch auf meinen Seiten inzwischen der dominante Browser, wenn auch nicht mit 66% wie im oben verlinkten c’t-Artikel erwähnt.

Browser-Marktanteil Web 2020
Browser-Marktanteil Web 2020
Browser-Marktanteil Blog 2020
Browser-Marktanteil Blog 2020
BrowserWebseiteBlog
Chrome44.14%36.38%
Firefox30.81%27.40%
Microsoft Edge7.56%7.14%
Safari4.12%8.85%
Chrome Mobile3.19%6.14%
Mobile Safari3.06%5.80%
Andere7.11%8.41%
Marktanteile der Browser auf der Webseite und im Blog

Der Blog scheint öfters über Smartphones oder von Apple-Rechnern abgerufen zu werden als die Webseite. Chrome hat deshalb auf dem Blog einen kleineren Marktanteil, den er auch zusammen mit der mobilen Variante nicht wett machen kann. Safari legt sowohl in der Desktop als auch in der mobilen Variante zu und liegt deshalb mit der Desktop-Variante beim Blog auch vor dem Microsoft Edge.

Suchmaschinen

Bei den Suchmaschinen ist Google weiterhin dominant, nur Bing und DuckDuckGo können noch Prozentwerte grösser als eins erreichen.

SuchmaschineWebseiteBlog
Google95.4%96.6%
Bing2.5%1.5%
DuckDuckGo1.2%1.0%
Andere0.9%0.9%
Marktanteile der Suchmaschinen auf der Webseite und im Blog

Verweise

Hier noch die Liste der wichtigsten Domänen, die auf meine Webseiten verlinken:

RangWebseiteBlog
1blog.rolandbaer.chwww.rolandbaer.ch
2de.wikipedia.orgwww.startpage.com
3wordpress.orgbaidu.com
Die drei wichtigsten Verweisseiten auf die Webseite und den Blog

Die Verweise unter Webseite und Blog funktionieren, wie man an den top-platzierten Seiten sehen kann. Die von wikipedia kommenden Besucher lesen das NSIS-Tutorial und die Verweise von WordPress kommen von den Plugins. Blog-Besucher von Startpage kamen hauptsächlich aufgrund der Internet of Things (IoT) Artikel und die wenigen Besuche über Baidu kamen zur Startseite des Blogs.

Themen

Während die Zugriffszahlen in den letzten Jahren beim Blog klar tiefer waren als bei der Webseite hat der Blog im vergangenen Jahr massiv Besucher gewonnen und liegt nun etwa auf dem Level der Webseite.

Besucheszahlen des Blogs 2016 - 2020
Blog startet durch?

Die meisten Besuche des Blogs gehen dabei auf das Konto der Artikel im IoT-Bereich, sprich Arduino und Wemos D1 mini. Bei der Webseite lässt das Interesse am NSIS-Tutorial langsam aber stetig nach, mit dem neuen iperf-Tutorial konnten aber wieder neue Besucher auf die Webseite geholt werden.

Fazit

Gegenüber der letzten Statistik für das Jahr 2013 hat sich bei den Browsern einiges getan, wenn auch nicht so extrem wie in den Statistiken von den Marktforschungsunternehmen. Die Dominanz von Google bei den Suchmaschinen ist immer noch ungebrochen.

Gefreut haben mich die gestiegenen Besucherzahlen auf dem Blog, auch wenn sie (noch) nicht zu gestiegenen Interaktionen (sprich Kommentaren) mit den Besuchern geführt haben. Diese kommen hauptsächlich über das WordPress-Plugin List Last Changes auf der Webseite zustande.

HTTP-Header

Zusätzliche HTTP-Header definieren für statische Webseiten bei Webhoster

Verschiedene, teilweise sicherheitsrelevante Funktionalitäten können durch HTTP-Header aktiviert werden, so zum Beispiel die HTTP Strict Transport Security.

Wenn man eine dynamisch generierte Webseite (z.B. via php) hat kann man relativ einfach zusätzliche HTTP-Header definieren, die ausgeliefert werden sollen. Bei php kann dies z.B. mit der Funktion header() erreicht werden.

Bei statischen Webseiten gibt es diese Möglichkeit nicht. Oftmals hostet man solche Webseiten unter einem einfachen (shared) Hosting, für welches der Webhoster (in meinem Fall Hostpoint) oftmals in seiner Verwaltungsoberfläche keine Möglichkeit bietet die Header anzupassen.

Wenn die Webseiten mit dem Apache HTTP Server ausgeliefert werden und der Webhoster das Modul mod_headers aktiviert hat können über Einträge in der Datei .htaccess zusätzliche Header gesetzt werden.

Um zu überprüfen, ob der Mechanismus funktioniert kann ein Dummy-Header ausgegeben werden, der dann über die Entwicklerwerkzeuge des Browsers geprüft werden kann. Dies ist ungefährlich, da unbekannte Header vom Browser ignoriert werden. So kann z.B. folgende Zeile in der .htaccess-Datei im passenden Verzeichnis hinzugefügt werden:

Header add Test Debug

Dabei muss darauf geachtet werden, ob ein Bereich in der .htaccess-Datei für automatische Einträge durch die Verwaltungsoberfläche des Hosters reserviert ist. Falls die Datei noch nicht existiert kann sie mit der obigen Zeile als einzigem Inhalt neu erzeugt werden.

Wenn das Ganze erfolgreich war sollte im Antwort-Header eine Zeile mit folgendem Inhalt vorhanden sein:

Test: Debug

Wenn dies erfolgreich war kann der Test-Eintrag wieder gelöscht und der richtige Header definiert werden. Ansonsten sollte der Eintrag nochmals kontrolliert oder dann der Support des Hosters kontaktiert werden.

WeMos D1 mini als Temperatur- und Luftfeuchtigkeits-Webserver

Im nächsten Versuch mit dem WeMos D1 mini soll nun seine WiFi-Funktionalität zum Einsatz kommen. Der Plan ist dabei, mit dem bereits früher verwendeten Temperatur- und Luftfeuchtigkeitssensor DHT11 (Teil 1 und Teil 2) gemessene Daten über eine einfache Webseite darzustellen.

Als erstes der einfache Steckplatinen-Aufbau:

Steckplatinenaufbau mit Wemos D1 mini und DHT11
Aufbau des WeMos D1 mini mit dem Temperatur- und Luftfeuchtigkeitssensor DHT11

Der dazugehörige Code ist schon etwas komplizierter (basiert auf dem Beispiel von Bernhard Linz):

/*******************************************************************************************
 * Read data from DHT-11 sensor and present it with a web page                             *
 *                                                                                         *
 * Based on a Script by Bernhard Linz ( https://znil.net/ )                                *
 *******************************************************************************************/


// import used libraries
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "DHT.h"

// include WiFi credentials
#include "credentials.h"

// definitions
#define DHTPIN D5         // pin of the arduino where the sensor is connected to
#define DHTTYPE DHT11     // define the type of sensor (DHT11 or DHT22)

// create web server
ESP8266WebServer webServer(80);

// create instance of DHT                          
DHT dht(DHTPIN, DHTTYPE, 6);

// variables for measured values
float temperature;
float humidity;

// initialization
void setup() {
  Serial.begin(9600);
  Serial.println("DHT11 test web server");

  // initialize measuring
  pinMode(DHTPIN, INPUT);
  dht.begin();

  Serial.println("Connecting to ");
  Serial.println(ssid);

  // connecting to local wi-fi network
  WiFi.begin(ssid, password);

  // check wi-fi staus until connected
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("my IP: ");
  Serial.println(WiFi.localIP());
  uint8_t macAddr[6];
  WiFi.macAddress(macAddr);
  Serial.printf("mac address: %02x:%02x:%02x:%02x:%02x:%02x\n", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);

  webServer.on("/", handle_OnConnect);
  webServer.onNotFound(handle_NotFound);

  webServer.begin();
  Serial.println("HTTP server started");
}

void loop() {
  webServer.handleClient();
}

void handle_OnConnect() {
  temperature = dht.readTemperature();
  humidity = dht.readHumidity();
  webServer.send(200, "text/html", buildHtml(temperature,humidity));
}

void handle_NotFound(){
  webServer.send(404, "text/plain", "Not found");
}

String buildHtml(float _temperature,float _humidity){
  String page = "<!DOCTYPE html> <html>\n";
  page +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\"/>\n";
  page +="<meta charset=\"UTF-8\"/>";
  page +="<meta http-equiv=\"refresh\" content=\"5\"/>";
  page +="<title>WeMos D1 mini Temperature & Humidity Report</title>\n";
  page +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  page +="body{margin-top: 50px;} h1 {color: #444444;margin: 20px auto 30px;}\n";
  page +="h2 {color: #0d4c75;margin: 50px auto 20px;}\n";
  page +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
  page +="</style>\n";
  page +="</head>\n";
  page +="<body>\n";
  page +="<div id=\"webpage\">\n";
  page +="<h2>WeMos Lolin D1 mini</h2><h1>Temperature & Humidity Report</h1>\n";
 
  page +="<p>Temperature: ";
  page +=(int)_temperature;
  page +=" °C</p>";
  page +="<p>Humidity: ";
  page +=(int)_humidity;
  page +=" %</p>";
 
  page +="</div>\n";
  page +="</body>\n";
  page +="</html>\n";
  return page;
}

Mit dem Einbinden des ESP8266 Microcontrollers und dem vorherigen Verwenden des DHT11 sind schon alle nötigen Libraries vorhanden. Die WLAN Zugangsdaten habe ich in eine separate Datei ausgelagert um zu verhindern, dass diese versehentlich publiziert werden. Deshalb ist zusätzlich eine zweite Datei mit dem Namen „credentials.h“ mit folgendem Inhalt nötig:

#ifndef __CREDENTIALS_H__
#define __CREDENTIALS_H__

// WiFi credentials:
const char* ssid = "mySSID";
const char* password = "secret";

#endif

Nach dem Uploaden und Starten des Programmes sollte im Serial Monitor eine Ausgabe ähnlich der nachfolgenden erscheinen (SSID, IP- und MAC-Adresse anonymisiert):

DHT11 test web server
Connecting to
mySSID
....
WiFi connected
my IP: 192.168.xxx.xxx
mac address: 2c:f4:32:xx:xx:xx
HTTP server started

Falls nach der SSID längere Zeit nur Punkte erscheinen sind vermutlich die WLAN Zugangdaten falsch. Ansonsten kann mit einem Browser auf die angegebene IP-Adresse zugegriffen werden und es sollte eine Webseite mit den aktuellen Messwerten erscheinen. Die Webseite aktualisiert sich alle 5 Sekunden.

Webseite mit den aktuellen Messwerten Temperatur und Luftfeuchtigkeit, ausgeliefert vom WeMos D1 mini
Die Webseite mit den aktuellen Messwerten

Es empfiehlt sich im DHCP-Server für die MAC-Adresse des WeMos D1 mini immer dieselbe IP-Adresse vergeben zu lassen damit man nicht auf die Ausgabe des Serial Monitor angewiesen ist.

Bei Last Minute Engineers ist ein Tutorial zu finden, welches auch als Basis für das Script von Bernhard Linz diente. Dort wird die Webseite auch noch schöner gestaltet und zum Schluss wird auch noch auf das Aktualisieren mittels AJAX eingegangen.

Erste Schritte mit dem Wemos D1 Mini

Nach den ersten Schritten mit dem Arduino Nano (Teil 1 und Teil 2) soll nun ein anderer Mikrocontroller zum Zug kommen, der ESP-8266EX auf dem Wemos Lolin D1 mini board.

Um dieses Board in der Arduino IDE verwenden zu können muss es zuerst im Board Manger installiert werden. Es ist unter dem Namen „esp8266“ zu finden. Falls es nicht gefunden wird muss unter File->Preferences-> Additonal Boards Manager URLs die URL http://arduino.esp8266.com/stable/package_esp8266com_index.json hinzugefügt werden. Danach kann unter Tools->Boards->Board Manager der ESP8266 gesucht und installiert werden. Dadurch werden bei den Boards diverse ESP8266-Boards aufgelistet. Für diese Versuche wird WeMos D1 R2 & mini ausgewählt.

Als erstes war das Ziel, zwei LEDs mit zwei Tastern zum Leuchten bringen. Die hier eingesetzten LEDs haben eingebaute Vorwiderstände. Falls normale LEDs zum Einsatz kommen den Vorwiderstand nicht vergessen! Also zwei Pins als Input und zwei als Output definiert, Schaltung aufgebaut und los!

void setup() {
  pinMode(D2, INPUT);
  pinMode(D3, INPUT);

  pinMode(D6, OUTPUT);
  pinMode(D7, OUTPUT);
}

void loop() {
  int left = digitalRead(D2);
  int right = digitalRead(D3);

  digitalWrite(D6, left);
  digitalWrite(D7, right);
}
Erster fehlgeschlagener Versuch mit dem Wemos D1 mini (Steckplatinenansicht)
Erster fehlgeschlagener Versuch mit dem Wemos D1 mini

Die rote LED funktionierte auch wie geplant, die grüne leuchtete aber andauernd. Nachdem die normale Fehlersuche (Verbindungen und Code kontrollieren) keinen Erfolg brachte war der nächste Schritt die Recherche: gibt es Pins bei diesem Board, die speziell geschaltet sind? Schlussendlich hat mir diese Pinout Referenz des ESP8266 (Kapitel „Wemos D1 Mini Pinout“ und „Best Pins to Use“, leider nicht direkt verlinkbar) das Problem aufgezeigt: D3 (GPIO0) ist für Input als „pulled up“ angegeben und sollte nicht verwendet werden. Also das Ganze umgebaut und nochmals versucht:

void setup() {
  pinMode(D6, INPUT);
  pinMode(D7, INPUT);

  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
}

void loop() {
  int left = digitalRead(D6);
  int right = digitalRead(D7);

  digitalWrite(D1, left);
  digitalWrite(D2, right);
}
Zweiter, erfolgreicher Versuch (Steckplatinenansicht)
Zweiter, erfolgreicher Versuch

Mit diesem Umbau klappte dieser einfache Aufbau dann wie geplant.

Temperatur und Luftfeuchtigkeit messen und Anzeigen mit dem Arduino Nano

Im letzten Teil wurde der Temperatur-Sensor DHT-11 mit dem Arduino Nano ausgelesen. Nun sollen die gemessenen Werte auch ohne Computer anzeigen werden können.

Der Aufbau basiert auf der letzten Schaltung und erweitert diese um das Display, welches ebenfalls aus dem Arduino Adventskalender stammt. Damit alles Platz hat kommen zwei kleine Steckboards zum Einsatz.

Steckplatinen-Aufbau mit Arduino Nano, DHT-11 und Display
Steckplatinen-Aufbau mit Arduino Nano, DHT-11 und Display

Für die Ansteuerung des LCD wird zusätzlich die Bibliothek „LiquidCrystal“ von Arduino, Adafruit benötigt, welche in der Arduino IDE wiederum unter Tools->Manage Libraries… hinzugefügt werden kann. Bei der Erstellung des Programmes wurde die Version 1.0.7 verwendet. Dem grösseren Aufbau entsprechend ist auch der Code umfangreicher.

/*******************************************************************************************
 * Read data from DHT-11 sensor and show it on a two-line LCD with an arduino nano         *
 *                                                                                         *
 * based on a script by Philippe Keller (www.bastelgarage.ch)                              *
 *******************************************************************************************/


// import used libraries
#include "DHT.h"                
#include <LiquidCrystal.h>

// definitions
#define DHTPIN 2          // pin of the arduino where the sensor is connected to
#define DHTTYPE DHT11     // define the type of sensor (DHT11 or DHT22)
       
// create instance of DHT                          
DHT dht(DHTPIN, DHTTYPE, 6);

// create instance of LiquidCrystal
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() {
  Serial.begin(9600);
  Serial.println("DHT11 test program 2");
  dht.begin();
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("T:        C");
  lcd.setCursor(0,1);
  lcd.print("rF:       %");
}

void loop() {
  // Wait two seconds between measurements as the sensor will not measure faster
  delay(2000);
                                   
  float h = dht.readHumidity();
  float t = dht.readTemperature();
 
  // validate values
  if (isnan(h) || isnan(t)) {      
    Serial.println("Error while reading data!");
    return;
  }

  // send data via serial connection to pc
  Serial.print("Luftfeuchtigkeit: ");
  Serial.print(h);
  Serial.print("%\t");
  Serial.print("Temperatur: ");
  Serial.print(t);
  Serial.write("°");
  Serial.println("C");

  // write data to liquid crystal display
  lcd.setCursor(4,0);
  lcd.print(t);
  lcd.setCursor(4,1);
  lcd.print(h);
}

Für die Speisung der Schaltung habe ich eine USB-PowerBank verwendet. Im Einsatz sieht dann das Ganze so aus:

Arduino Nano, DHT-11 und Display im Einsatz
Arduino Nano, DHT-11 und Display im Einsatz

Temperatur und Luftfeuchtigkeit messen mit dem Arduino Nano

Für meine ersten Schritte im Mikrocontroller-Umfeld abseits der vorgetrampelten Pfade von Starter Kit oder Adventskalender wollte ich mich mit der Luftfeuchtigkeitsmessung beschäftigen. Dabei ist mir der Temperatur- und Luftfeuchtigkeits-Sensor DHT-11 über den Weg gelaufen.

Der DHT-11 ist ein einfacher und günstiger Sensor, der die Temperatur und die Luftfeuchtigkeit misst und über ein einfaches Protokoll ausgibt. Wenn eine höhere Genauigkeit gefordert ist kann der etwas grössere und teurere DHT-22 eingesetzt werden. Für die Ansteuerung der beiden Sensoren kann dabei die selbe Bibliothek verwendet werden, es muss bei der Instanzierung nur der passende Typ angegeben werden.

Der erste einfache Aufbau benötigt nur einen Arduino (in meinem Fall kam der Arduino Nano aus dem Adventskalender zum Einsatz) und den Sensor auf einem Modul. Dieses Modul beinhaltet den Pull-up-Widerstand bereits, beim Einsatz des „nackten“ Sensors muss dieser noch entsprechend hinzugefügt werden. Beim Modul muss noch beachtet werden dass es Versionen mit verschiedenen Pin-Belegungen gibt. Beim von mir eingesetzten Modul ist die Belegung VCC / Data / GND, es gibt aber auch Module mit Data / VCC / GND.

Steckplatinen-Aufbau mit Arduino Nano und DHT-11
Steckplatinen-Aufbau mit Arduino Nano und DHT-11

Das erste Programm soll dabei nur die Daten auslesen und über die Schnittstelle zum PC ausgeben. Dazu muss die Bibliothek „DHT sensor library“ von Adafruit in der Arduino IDE unter Tools->Manage Libraries… hinzugefügt werden. Beim Erstellen des Programmes war die Version 1.3.8 aktuell. Danach kann der untenstehende Code in die IDE übernommen werden:

/*******************************************************************************************
 * Read data from DHT-11 sensor via an arduino nano                                        *
 *                                                                                         *
 * based on a script by Philippe Keller (www.bastelgarage.ch)                              *
 *******************************************************************************************/


// import used library
#include "DHT.h"

// definitions
#define DHTPIN 2          // pin of the arduino where the sensor is connected to
#define DHTTYPE DHT11     // define the type of sensor (DHT11 or DHT22)
       
// create instance of DHT                          
DHT dht(DHTPIN, DHTTYPE, 6);

void setup()
{
  Serial.begin(9600);
  Serial.println("DHT11 test program");
  dht.begin();
}

void loop()
{
  // Wait two seconds between measurements as the sensor will not measure faster
  delay(2000);
                                   
  float h = dht.readHumidity();
  float t = dht.readTemperature();
 
  // validate values
  if (isnan(h) || isnan(t)) {      
    Serial.println("Error while reading data!");
    return;
  }

  // send data via serial connection to pc
  Serial.print("Luftfeuchtigkeit: ");
  Serial.print(h);
  Serial.print("%\t");
  Serial.print("Temperatur: ");
  Serial.print(t);
  Serial.println("°C");
}

Dieses Programm wird dann auf den Arduino übertragen. Dabei musste ich für meinen Arduino Nano den Prozessor auf „ATMega 328P (Old Bootlaoder)“ und den Programmer auf „AVRISP mkII“ einstellen. Nach dem Übertragen produziert das Programm dann im Serial Monitor eine Ausgabe wie folgende:

DHT11 test program
Luftfeuchtigkeit: 36.00%      Temperatur: 25.60°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.40°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.50°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.60°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.40°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.40°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.40°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.40°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.60°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.50°C
Luftfeuchtigkeit: 35.00%      Temperatur: 25.50°C
Luftfeuchtigkeit: 35.00%      Temperatur: 25.50°C
Luftfeuchtigkeit: 36.00%      Temperatur: 25.50°C

Natürlich möchte man nicht die ganze Zeit einen PC oder Laptop mitschleppen um die Teperatur und Luftfeuchtigkeit zu messen. In einem nächsten Ausbauschritt wird deshalb eine Anzeige hinzukommen.