Home.

Technik-Blog

Willkommen auf meinem
Notiz - Blog
Blog

Kmoser's Tech-Blog

Freitag
18
November 2016
Klaus Moser
Klaus Moser

Power Manager IoT

Mit diesem Beitrag möchte ich euch mein erstes, richtiges Arduino-Projekt vorstellen. Der Powermanager tut jetzt schon fast ein Jahr zuverlässig seine Arbeit und es gab bislang noch keinen Ausfall oder sonstige Probleme mit dem Gerät. Bisher habe ich mich nicht getraut das Projekt vorzustellen, da ich ja ein absolut blutiger Neuling auf dem Gebiet bin und dementsprechend natürlich gewisse Selbstzweifel habe. Der Powermanager macht hier aber so einen guten Job dass es egoistisch wäre ihn für mich zu behalten. Ich hoffe dass ich damit der Community wieder ein bisschen etwas zurück geben kann.

Der verwendete Code ist auf GitHub zu finden.

WARNUNG

Arbeiten am 230V Stromnetz ist Laien nicht erlaubt und sollten generell von einem Fachmann durchgeführt werden. Zwar drohen keinem Handwerker Strafen aber man muss damit rechnen dass im Falle eines Schadens die Versicherung die Schadensregulierung verweigert. Ich übernehme keinerlei Haftung für Schäden jeglicher Art die durch den Nachbau dieses Projektes entstehen. Dieses Projekt ist als reines Lern-Projekt für mich gedacht gewesen und sollte von einem Laien nicht nachgebaut werden. Bei unsachgemäßen Umgang besteht LEBENSGEFAHR!!

Warum das Ganze

Nachdem ich vor Weihnachten 2015 das Glück hatte den IoT Adventskalender von Conrad zu erstehen hat mich das Arduino Fieber erwischt. Nach ersten Experimenten mit LEDs und Steuerung der selben über das LAN habe ich mir ein Set aus allen möglichen Modulen für den Arduino sowie ein paar Arduino Nanos bestellt. Bei den Modulen war unter anderem auch ein Relais-Modul mit einem schaltbaren Strom von 10A und ein Ethernet Modul dabei. Die Idee einen 230V Verbraucher über LAN und damit ggf. auch über Internet zu steuern fand ich irgendwie reizvoll.

Erste Versuche mit dem Relais und dem Ethernet-Modul waren erfolgreich. Habe dann ein 8-fach Relais Modul entdeckt und die Erweiterung von einem auf acht Relais war dann nur noch eine Kleinigkeit.

Was mich an vielen Funksteckdosen massiv stört ist, dass sie keinen Knopf haben um sie manuell zu schalten. Diesen Fehler wollte ich natürlich nicht machen und damit mussten noch 8 Buttons her. Eine Led, die den jeweiligen Schaltzustand anzeigt wäre natürlich auch noch nett und schon lag die Menge der IO-Pins, die ich für mein Bastelprojekt benötigen würde mit mindestens 30 IO-Pins (6 braucht das ENC28J60 LAN-Modul) weit über dem was der Arduino Nano an IO-Pins bereitstellt.

Habe einiges mit I2C Expandern wie dem PCF8574 und dem SparkFun SX1509 herum experimentiert, was auch ziemlich gut funktioniert hat. Irgendwann habe ich dann den Arduino Mega entdeckt, der für die Anwendung von Hause aus genügend IO-Pins zur Verfügung stellt. Durch die Masse an IO-Pins wurden noch zusätzliche Dinge möglich wie z.B. das Auslesen von Sensoren, in diesem Fall eines Temperatursensors für die Überwachung der Innentemperatur des Gehäuses.

Versuchsaufbau

Der Aufbau sieht wie folgt aus:

Die Widerstände an den LEDs werden nur für den Versuchsaufbau benötigt. Die beleuchteten Taster die später zum Einsatz kommen werden benötigen diese nicht. Auch die 3.3V Versorgung habe ich später über ein fertiges AMS1117 Modul realisiert (habe nur kein Fritzing-Part für das Modul gefunden).

So sah einer der ersten Versuchsaufbauten für das 8-fach Relaismodul dann aus. War ein ziemlicher Kabelsalat.

In diesem Staduim sollte man noch keine Experiemente mit dem öffentlichen Stromnetz machen, es sei denn man weiß wirklich genau was man tut. Hier liegen die Kontakte auf der Unterseite des Relais-Modules frei und eine Berührung kann böse Folgen haben.

Fhem

Parallel zu diesem Versuchsaufbau habe ich mich mit der Home Automation Software FHEM beschäftigt und festgestellt, dass es möglich ist Aktoren, welche über das LAN erreichbar sind, per Web-Command zu steuern. Also eigentlich genau das was ich da zum rumprobieren zusammengesteckt habe. Wirklich schwer war das nicht, insbesondere dank der guten Doku die es zu FHEM gibt. Für jedes Relais habe ich einen Dummy erstellt und jeweils einen Notify erstellt der das Relais per GET-Request schaltet.

define PM01_Sw_01 dummy
attr PM01_Sw_01 devStateIcon on:black_Steckdose.on off:black_Steckdose.off
attr PM01_Sw_01 group Schalter
attr PM01_Sw_01 room Arduino
attr PM01_Sw_01 setList on off
attr PM01_Sw_01 webCmd on:off
define PM01_Sw_01_notify_on notify PM01_Sw_01:on { GetHttpFile("192.168.0.201","/?on=0")}
attr PM01_Sw_01_notify_on room Arduino
define PM01_Sw_01_notify_off notify PM01_Sw_01:off { GetHttpFile("192.168.0.201","/?off=0")}
attr PM01_Sw_01_notify_off room Arduino

Das geht bestimmt noch besser, vor allem da nicht geprüft wird ob das Relais wirklich geschalten wurde oder nicht obwohl der Powermanager ja einen Status über den aktuellen Schaltzustand zurück gibt. Mein Fhem/Perl Kenntnisse reichen im Moment allerdings noch nicht für mehr. Im Moment reicht es aber, da bisher noch kein Schalt-Event nicht ausgefürt wurde.

Drückt man einen Taster am Powermanager, so sendet dieser einen GET Request an den Fhem  Server welcher dann den Status des zugehörigen Dummies setzt.

http://myserver/fhem/?cmd=setstate PM01_Sw_01 on

Die Library EtherCard bietet die Möglichkeit Request-Header zu setzen womit man den Basic Auth für Fhem hinbekommt.

Die ganze Konstruktion lag dann eine ganze Weile im Keller rum da andere Pflichten gerufen haben. Ich hatte zum Testen ein paar Verbraucher wie z.B. meinen Baustellenstrahler und ein Ladegerät angeschlossen die ich über die Fhem App schalten konnte. Nach einiger Zeit der Nutzung war ich echt überrascht wie zuverlässig das funktioniert. Diese Experimentier-Konstruktion hatte was von einer Funksteckdose nur mit dem Unterschied dass ich 8 Steckdosen auf einmal schalten konnte.

Das Projekt

Nachdem das Ganze so gut funktioniert hat habe ich beschlossen dem Ganzen ein Gehäuse zu spendieren und weiter damit zu experimentieren.

Bei meiner Suche nach einem potenziellen Gehäuse für die Konstruktion bin ich auf den PowerManager von Conrad Elektronik gestoßen. Bietet genüg Platz, das Metallgehäuse lässt sich schön erden und die Schalter lassen sich dank Standard-Maß leicht gegen Taster austauschen. Einziges Manko, nur 7 Steckdosen. Ein Relais ist also tot.

Ein paar passende beleuchtete Edelstahl Drucktaster habe ich in der Bucht gefunden. Diese haben einen Einbaudurchmesser von 19 mm und sind außerdem noch beleuchtet. Damit ist der Schaltzustand einer Steckdose direkt am Taster erkennbar. Bei der Spannung der LEDs hatte ich etwas Sorge, da diese 12 V beträgt. Hatte mir extra einen ULN2803 besorgt um mit den 5V von Arduino die 12 V schalten zu können. Es hat sich aber herausgestellt dass die LEDs mit 12 V viel zu hell sind und mit den 5 V eine optimale Helligkeit haben.

Hab das Darlington Array trotzdem drin gelassen, damit die IO-Pins des Arduino nur schalten und die Taster nicht mit Strom versorgen müssen. Für die Relais braucht man keinen da man hier nur die Optokoppler schalten muss.

Die Gesamtkosten des Projekts liegen etwa bei 130-150 Euro.

Materialliste

Typ Menge Notizen Link Einzelpreis Gesamtpreis
Power Manager 1 Power Manager BOOS RC7 <a href="https://www.conrad.de/de/power-manager-boos-rc7-steckdosenanzahl-7-998662.html">Link</a> 44,99 &euro; 44,99 &euro;
Arduino Mega 1 MEGA 2560 R3 Board <a href="https://de.aliexpress.com/wholesale?SearchText=arduino+mega">Link</a> 5,38 &euro; 5,38 &euro;
Arduino Prototype Shield 1 Prototype Shield ProtoShield V3 <a href="https://de.aliexpress.com/wholesale?SearchText=arduino+MEGA+Proto+Schild">Link</a> 1,90 &euro; 1,90 &euro;
Relais Modul 1 8 Kanal Relay 5V <a href="https://de.aliexpress.com/wholesale?SearchText=8+channel+relay">Link</a> 5,63 &euro; 7,95 &euro;
Netzwerkmodul 1 ENC28J60 Netzwerkmodul <a href="https://de.aliexpress.com/wholesale?SearchText=ENC28J60">Link</a> 2,04 &euro; 4,95 &euro;
Drahtbrücke 2 polig 14 (2 Pkg) 10x 2-polig Buchse Buchse Drahtbrücke 70cm Dupont-Kabel <a href="https://de.aliexpress.com/wholesale?SearchText=dupont+2+pin+70+cm">Link</a> 2,20 &euro; 4,40 &euro;
Drucktaster 7 Drucktaster Edelstahl IP67 19 mm <a href="http://www.ebay.de/sch/i.html?_from=R40&_trksid=p2050601.m570.l1313.TR0.TRC0.H0.XDrucktaster+Edelstahl+IP67+19+mm+LED+Ring+Gr%C3%BCn.TRS0&_nkw=Drucktaster+Edelstahl+IP67+19+mm+LED+Ring+Gr%C3%BCn&_sacat=0">Link</a> 6,69 &euro; 46,83 &euro;
Steckernetzteil Micro USB 1 Dünnes Netzteil bevorzugen <a href="https://de.aliexpress.com/wholesale?SearchText=Steckernetzteil+Micro+USB">Link</a> 2,57 &euro; 2,57 &euro;
Spannungswandler 3,3V 1 Spannungsregler AMS1117 3,3 V <a href="https://de.aliexpress.com/wholesale?SearchText=AMS1117+DC-DC+3.3V">Link</a> 0,30 &euro; 0,30 &euro;
8 fach Darlington Array 1 ULN 2803A <a href="https://de.aliexpress.com/wholesale?SearchText=ULN2803A">Link</a> 1,26 &euro; / 10 Stück 0,13 &euro;
USB-Schalttafeleinbaukabel 1 Ungewinkelt billiger <a href="https://de.aliexpress.com/item/30cm-Blcak-Right-Angle-USB-2-0-B-Female-to-USB-B-Male-Printer-90-Degree/32287213362.html">Link</a> 4,85 &euro; 4,85 &euro;
LM35 1 Temperaturfühler (optional) <a href="https://de.aliexpress.com/wholesale?SearchText=lm35">Link</a> 0,70 &euro; 0,70 &euro;
M3x6 Schraube schwarz 2x        
M3 Mutter 2x        

Überspannungsschutz

Man kann auch (wie ich) den Powermanager mit integriertem Überspannungsschutz nehmen, allerdings benötigt man dann ein weiteres Teil aus dem 3D Drucker um sich einen neuen Halter für die Überspannungsschutz-Komponente zu drucken, da das Bauteil an einer sehr ungünstigen Position sitzt. Einen passenden Halter habe ich konstruiert und kann hier heruntergeladen werden.

Zerlegen

Der Inhalt des Powermanagers ist recht überschaubar. Die Schalter im Frontpanel kommen raus da diese später durch Taster ersetzt werden. Am besten entfernt man erst mal alles aus dem Metallgehäuse, da noch Löcher für LAN und USB am Gehäuse gemacht werden müssen und sämtliche montierten Teile dabei nur stören. Die Komponente für den Überspannungsschutz muss auch erst mal weg, da dieser Platz später benötigt wird. Diesen erst mal zur Seite legen, der kommt später wieder rein.

Die Niete für die Masse-Leitungen muss aufgebohrt werden und wird später durch eine Schraube ersetzt.

Die Flachsteckhülsen von den Kabeln zu den Steckdosen schneidet man ab und crimpt stattdessen Adernendhülsen drauf, die wir später in die Relais schrauben können.

Position der Elektronik

Das Relaismodul wird im Gehäuse vorne links Platz finden, der Arduino Mega rechts davon. Die beiden Module sind von der Länge her so, dass sie ganz gut Platz im Powermanager haben wenn sie längs eingebaut werden. Die beiden Platinen bekommen noch je eine Trägerplatte aus dem 3D Drucker auf denen die beiden Module dann am Boden fixiert werden können.

Die 3D-Dateien für die Trägerplatten gibt es hier zum Download. Hat man einen Drucker der groß genug ist könnte man die beiden Module sogar auf einen Träger montieren.

LAN-Anschluss

Den LAN-Anschluß habe ich gewählt weil das Gehäuse aus Metall ist und damit bei Funkverbindungen die Gefahr besteht, dass die Verbindung nicht zuverlässig funktioniert.

Da auf der Rückseite recht wenig Platz ist, habe ich die LAN-Buchse recht weit hinten, seitlich am Gehäuse platziert. Für die Befestigung des Halters am Gehäuse habe ich ein kleinen Halter konstruiert den es hier zum Download gibt. Das geht mit Sicherheit noch besser, habe aber auch mit dem Thema 3D Druck gerade erst angefangen.

Die Größe und Position des Lochs habe ich mir auf einen kleinen Zettel aufgezeichnet, das Loch ausgeschnitten und mit ein paar Streifen Tesa auf der Seitenwand des Gehäuses fixiert. Dann mir der Bohrmaschine und einen kleinen Bohrer das Loch grob ausgebohrt und anschließend mit einem Dremel nachbearbeitet. Die Feinarbeit bis der RJ45 Port dann durch das Loch gepasst hat habe ich mit einer Eisenfeile gemacht.

Reset Button

Dieser ist eigentlich nicht nötig und ich habe ihn auch noch nie gebraucht, aber ich fand ihn irgendwie sexy :-) Unterhalb der Durchführung des Stromkabels aus dem Powermanager ein Loch bohren, so dass der Taster durch passt. Das Kabel so lang machen dass es bis zum Arduino Mega reicht. Lieber ein bisschen zu lang als zu kurz ;-).

Frontpanel

Aus dem Frontpanel müssen alle Schalter entfernt werden und gegen die neuen Edelstahl-Taster ersetzt werden. Die Pinbelegung meiner Taster ist auf dem Bild vermerkt und kann ggf. von anderen Taster abweichen. Wenn der Taster, wie meiner aus der Abbildung, sowohl einen Öffner- als auch einen Schließerkontakt hat muss man aufpassen dass man nicht versehentlich den falschen erwischt. Das könnte sonst zu unerwarteten Ergebnissen führen :-)

An die Taster werden die langen 2poligen Dupont Kabel angelötet. Dazu die Kabel in der Mitte halbieren und die Hälften jeweils an den Schaltkontakt (Schließer) und an die LED löten.

Wenn man es etwas schöner haben möchte dann halbiert man die Kabel nicht, sondern passt sie später beim Einbau der Länge nach so an dass sie nachher genau auf den Arduino passen.

Damit man die beiden Leitungen auseinanderhalten kann, habe ich um einen der beiden Leitungen ein Stück farbigen Schrupfschlauch gelegt. Die äußeren Kabel sind etwas länger die inneren, die näher am Arduino sind, sind etwas kürzer.

Temperatursensor

Ich habe vier Temperatursensoren ausprobiert. Den DHT11 und den DHT22, den Dallas DS18B20 und den LM35DZ. Sehr interessant war dass alle Sensoren eine ziemliche Abweichung bei Messen der Temperatur hatten. Alle Sensoren meldeten andere Temperaturen obwohl sie direkt nebeneinander lagen. Da ich aber hauptsächlich wissen wollte wie warm es im Inneren des Gehäuses wird und es im Betrieb zu einer Überhitzung kommt war dieser Umstand nicht so tragisch. Alles über 50°C ist einfach mal suspekt...

Da die Sensoren DHTxx und der DS18B20 serielle Kommunikationsprotokolle zur Datenübertragung verwenden, entsteht bei jeder Abfrage eine kleine Verzögerung in der der Powermanager auf Antwort des Sensors wartet und sich damit nicht um den Webserver kümmern kann.

Da ich befürchtet habe dass sich das evtl. negativ auf die Reaktionsgeschwindigkeit des Powermanagers auswirkt habe ich mich für den LM35DZ entschieden. Dieser liefert eine analoge Spannung zwischen 0 und 1 V mit einer Temperaturempfindlichkeit von 10mV/K. Der Arduino arbeitet standardmäßig mit 5V am analogen Eingang. Da der LM35DZ aber nur Spannungen bis maximal 1V ausgibt, würde man so etwa 80% an Genauigkeit verlieren. Um die Werte zu verbessern setzt man die AREF Spannung für die analogen Ports auf 1.1V. Teilt man 1.1V durch 1024 ergibt sich 0.001075V = 1.0742 mV pro Messschritt. Da laut Datenblatt 1 Grad 10 mV entsprechen ändert sich die Grad-Anzeige alle 10 mV / 1.0742 mV = 9.31 Messschritte um 1 Grad.

Prototyping Board

Es folgt das Herzstück des Powermanagers, der Arduino Mega mit Prototyping Board. Leider habe ich kein Fritzing Part für das Proto Board gefunden, sonst gäbe es an der Stelle noch eine Zeichnung. So gibt es nur zwei Bilder von der Festig bestückten Platine und einem Versuch die einzelnen Module zu kennzeichnen. Ich werde mal versuchen das Prototype Board in Fritzing selbst zu erstellen, allerdings kann das noch ein bisschen dauern...

Funktionsgruppe Beschreibung
1 Anschlusspins LAN-Port
2 Anschlusspins Relais Module
3 LM35 Temperatur Sensor
4 3.3V Spannungsregler für LAN-Modul. Das Spannungsregler-Modul ist einfach kopfüber in zwei 2pin Buchsenleisten gesteckt. Den Elko hätte ich mir vermutlich sparen können, da auf der Modulplatine schon Kondensatoren sind.
5 Anschlusspins für Taster je 1x GND und 1x IO
6 Darlington-Array und Anschlusspins für Tasterbeleuchtung. Der einzeln stehende PIN ist für die Stromversorgung der LEDs gedacht und kann je nach gewünschter Helligkeit und Tastern variieren. Ich habe sie bei mir mit einem Dupont-Kabel auf 5V gelegt.
7 Anschlusspins für Reset und LAN-Connected LEDs
8 Anschlußpin für Reset-Taster
9 Stromanschluss 5V

Zusammenbau

Nachdem man jetzt alles mal provisorisch zusammengesteckt hat und die Funktion überprüft hat kann man alles in das Gehäuse einbauen.

Der Arduino mit dem Proto Schield sowie das Relais-Modul kommen auf ihre jeweiligen Träger und werden an das Bodenblech geschraubt.

Für die Stromversorgung des Arduinos und des Relais habe ich ein normales Steckernetzteil verwendet, welches über eine Eurokupplung mit der Netzteilung hinter dem Hauptschalter und den Überspannungsschutz verbunden wird.

Das Netzteil sollte mindestens 1,5 A, besser 2 A liefern können. Die 8 Relais ziehen in angezogenem Zustand jeweils etwa 70 mA, der Arduino maximal 500 mA, das LAN-Modul max. 250 mA und die LEDs der Taster nochmal jeweils 10 mA. Damit sind wir bei 1380 mA plus noch etwas Reserve sollten mindestens 1,5 A schon sein. Da der Preisunterschied zwischen 1,5 A und 2 A sehr gering ist kann man auch gleich ein 2 A Netzteil nehmen dann ist man auch bissle weiter vom Limit entfernt. Der Powermanager IoT soll ja schließlich ne Weile halten ;-)

Die 230V habe ich über Wago-Klemmen an die Relais verteilt. Da die Relais maximal 10A vertragen habe ich flexible Adern mit 1,5mm2 Querschnitt genommen auf deren Enden ich Adernendhülsen aufgecrimpt habe. Laut Belastbarkeitstabelle bin ich bei 40 °C Umgebungstemperatur (sollte für Deutschland reichen...) noch bei einer Belastbarbeit von 14 A und damit (hoffentlich) auf der sicheren Seite. Die Wago Klemmen vertragen einen Strom von 32 A und sind damit auch mehr als ausreichend.

Theoretisch müsste die Ader vom Netz zum Wago-Verteiler einen größeren Querschnitt haben, aber ich habe einfach die Ader genommen die sowieso schon werksseitig verbaut war. Die 14 A gelten ja eh nur bei einer Umgebungstemperatur von über 40 °C und die Verbraucher die ich anschließen werde werden diese Last niemals ziehen. Außerdem fliegt bei 16 A sowieso der LSS und von daher sollte das so passen.

Nicht vergessen die Erdung wieder am Gehäuse zu befestigen, die kann im Zweifelsfall Leben retten. Habe die Erdung mit einer kleinen M3 Schraube, einer Mutter und einer Zahnscheibe, welche ein selbstständiges Lösen verhindern soll, wieder angebracht.

Fertig

Ist alles eingebaut, dann sieht der Powermanager IoT etwa so aus:

Im Nachhinein betrachtet hätte ich anstatt dem ENC28J60 Netzwerkmodul lieber ein W5100 Ethernet Modul verwenden sollen, das muss wohl etwas einfacher zu verwenden sein. Leider war mir das damals noch nicht bekannt.

Im Moment experimentiere ich auch gerade ein bisschen mit dem MQTT Protokoll was für diesen Zweck auch ziemlich gut geeignet sein dürfte. Der nächste Powermanager bekommt auf jeden Fall eine Anbindung an MQTT.

Montag
31
Oktober 2016
Klaus Moser
Klaus Moser

PPA hinzufügen / entfernen

PPA installieren

sudo add-apt-repository ppa:some-fancy-ppa/coolstuff
sudo apt-get update
sudo apt-get install coolstuff

PPA entfernen

sudo apt-get install ppa-purge
sudo ppa-purge ppa:some-fancy-ppa/coolstuff
Sonntag
31
Januar 2016
Klaus Moser
Klaus Moser

Ubuntu 14.04 - fail2ban

Das Paket fail2ban ist ein in der Sparche Python geschriebes Intrusion Prevention Framework mit dem man Dienste wie z.B. SSH, FTP, Apache, etc. vor Brute-Force oder DDOS Angriffen schützen kann indem es temporäre Firewall Regeln anlegt, die potenzielle Angreifer den Zugang zum Server verweigert. Es scannt permanent Logfiles und führt definierte Aktionen aus sobald ein oder mehrere, per regular Expression definierbare Ereignisse, innerhalb eines bestimmten Zeitraumes, eintreten.

Installation

Installiert wird fail2ban mit

sudo apt-get install fail2ban

Konfiguration

Die Standardkonfiguration befindet sich in der Datei /etc/fail2ban/jail.conf. Diese Datei scheint allerdings bei Updates des Paketes überschrieben werden zu können. Deshalb muss man sich eine lokale Kopie der Datei anlegen, in der man nun seine Änderungen eintragen kann.

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

In Ubuntu 16.04 gibt es den Unterordner /etc/fail2ban/jail.d/ in dem man Änderungen an der Standardkonfiguration vornehmen kann.

Als erstes legen wir mittels ignoreip die IPs fest, die fail2ban niemals sperren soll. Diese Einstellung befindet sich in der Sektion [DEFAULT]. Es können dabei IP-Adressen, DNS Hostnamen oder CIDR Bereiche sein.

ignoreip = 127.0.0.1/8 123.123.123.123/32 me.mydomain.de

Des weiteren kann man mittels bantime einstellen wie lange ein potenzieller Angreifer geblockt bleiben soll. Die Zeitspanne wird in Sekunden angegeben. Ein Wert von 600 entspricht also 10 Minuten.

bantime = 600

Ein Client wird als Angreifer eingestuft, wenn er innerhalb der in findtime definierten Zeitspanne maxretry Fehlversuche verursacht.

Die nächste Einstellung die wir tätigen müssen ist die E-Mail Adresse, an die die Warnungen gesendet werden sollen

destemail = me@mydomain.de

sowie den Absendernamen um den entsprechenden Server leichter identifizieren zu können

sendername = WWW01 Fail2Ban

Der Wert für mta kann entweder sendmail oder mail sein. Hat man postfix installiert setzt man den Wert auf sendmail.

mta = sendmail

Mit dem Parameter action kann man jetzt noch festlegen, was passieren soll wenn ein Client geblockt wurde. Es gibt in der Standardkonfiguration drei mögliche Werte, die oberhalb des action Parameter definiert sind.

Wert Erklärung
action_ Sperrt die IP
action_mw Sperrt die IP und schickt eine E-Mail mit einem Whois-Report an destemail
action_mwl Sperrt die IP und schickt eine E-Mail mit einem Whois-Report und den betreffenden Log-Zeilen an destemail.

Jails

Der Rest der Konfigurationsdatei ist in Sektionen eingeteilt, welche die Jails definieren. Fail2ban kommt von Hause aus mit einigen vordefinierten Jails, die man bei Bedarf einfach nur aktivieren muss. Eine Jail Definition sieht z.B. so aus:

[apache]

enabled = true
port = http,https
filter = apache-auth
logpath = /var/www/vhosts/*/log/access.log*
maxretry = 3
findtime = 300
bantime  = 1800

Der Name der Jail Definition steht in eckigen Klammern und alle folgenden Optionen gehören zu dieser Jail Definition, solange bis wieder ein Name in eckigen Klammern kommt und eine neue Jail Definition einleitet oder das Dateiende erreicht ist.

Option Erklärung
enabled Der Wert true aktiviert und der Wert false deaktiviert ein Jail
port Hier wird der zu überwachende Service definiert
filter Hier wird eine Datei referenziert, die unter /etc/fail2ban/filter.d liegt.
logpath Pfad zu der Log Datei. Es kann der * als Wirdcard für Zeichen und Unterverzeichnisse verwendet werden.
findtime Überschreiben des Wertes findtime aus der [GLOBAL] Sektion
maxretry Überschreiben des Wertes maxretry aus der [GLOBAL] Sektion
bantime Überschreiben des Wertes bantime aus der [GLOBAL] Sektion

Betreibt man einen Webserver kann man z.B. folgende Jails aktivieren:

ssh, apache, apache-noscript, apache-overflows, php-url-fopen

Betreibt man zusätzlich einen Mailserver wie ich ihn hier auch schon beschrieben habe, kann man auch noch folgende Jails aktivieren:

postfix, sasl, dovecot

Weitere Jails kann man definieren indem man eigene Filter schreibt.

Den Status eines Jails, in diesem Beispiel des ssh Jails, kann man abfragen mit:

Bash
fail2ban-client status ssh

[SSH] Jail Erweiterung

Für den SSH Jail habe ich, wie bei fail2ban.org beschrieben eine weitere failregex Zeile hinzugefügt um auch diese Zeilen zu erwischen:

Feb 9 06:53:05 www sshd[16660]: reverse mapping checking getaddrinfo for sd-41861.webserver.eu.com [195.154.65.98] failed - POSSIBLE BREAK-IN ATTEMPT!

Dazu bearbeitet man die Datei /etc/fail2ban/filter.d/sshd.conf

sudo nano /etc/fail2ban/filter.d/sshd.conf

und fügt die folgende Zeile bei den anderen Zeilen der failregex Variablen ein

^%(__prefix_line)sreverse mapping checking getaddrinfo .* \[<host>\] failed - POSSIBLE BREAK-IN ATTEMPT!\s*$</host>

Analyse

Die Log-Datei befindet sich unter /var/log/fail2ban.log. Hier findet man Informationen über das Sperren und Entsperren von IP-Adressen und dessen Jail Name. Ausserdem finden sich hier Informationen ob sich Jail Einstellungen geändert haben bzw. ob ein neuer Jail gestartet wurde.

Mitfolgendem Befehl kann man sich eine Liste vn IP-Adressen ausgeben lassen, welche gesperrt wurden sowie dessen Häufigkeit.

awk '($(NF-1) = /Ban/){print $NF}' /var/log/fail2ban.log | sort | uniq -c | sort -nr

Die Ausgabe sieht etwa so aus:

22 115.231.222.176
18 88.80.187.139
 6 61.174.49.106
 2 41.231.53.25
 1 217.64.98.42

Um diese Auswertung über über alle Logdateien zu machen führt man folgenden Bfehl aus:

zgrep -h "Ban " /var/log/fail2ban.log* | awk '{print $NF}' | sort | uniq -c

Möchte man die Liste auch noch nach Angriffspunkt sortieren geht das so

zgrep -h "Ban " /var/log/fail2ban.log* | awk -F[\ \:] '{print $10,$8}' | sort | uniq -c | sort -nr

Das ergibt eine Liste wie die folgende:

22 115.231.222.176 [ssh]
18 88.80.187.139 [ssh]
 6 61.174.49.106 [ssh]
 1 41.231.53.25 [ssh]

Da Angriffe meißtens nicht nur von einem Rechner kommen, sondern mehrere Rechner zum Einsatz kommen, kann man sich die Adressen auch nach einem Teilnetzbereich ausgeben lassen

zgrep -h "Ban " /var/log/fail2ban.log* | awk '{print $NF}' | awk -F\. '{print $1"."$2"."}' | sort | uniq -c | sort -rn

Das ergibt folgende Ausgabe:

26 115.239.
22 115.231.
18 88.80.
 6 61.174.
 1 41.231.

Wenn man nun genauer wissen möchte was eine IP bzw. Netzbereich so angestellt hat, kann man sich so die Zeilen des Logs anzeigen lassen:

zgrep 115.239. /var/log/fail2ban.log

Das ergibt dann z.B. folgende Ausgabe

2015-02-11 22:55:42,757 fail2ban.actions: WARNING [ssh] Ban 115.239.228.15
2015-02-11 23:23:47,000 fail2ban.actions: WARNING [ssh] Ban 115.239.228.34
2015-02-11 23:25:43,269 fail2ban.actions: WARNING [ssh] Unban 115.239.228.15
2015-02-11 23:53:47,388 fail2ban.actions: WARNING [ssh] Unban 115.239.228.34
2015-02-12 00:19:19,141 fail2ban.actions: WARNING [ssh] Ban 115.239.228.4
2015-02-12 00:47:09,186 fail2ban.actions: WARNING [ssh] Ban 115.239.228.11
2015-02-12 00:49:19,493 fail2ban.actions: WARNING [ssh] Unban 115.239.228.4
2015-02-12 01:17:09,405 fail2ban.actions: WARNING [ssh] Unban 115.239.228.11

Eigene Jails

Zusätzlich zu den mitgelieferten Jails kann man auch eigene Jails definieren.

Fail2ban Jail

Da bei mir sehr viele Angriffe auf den SSH Port gehen und die Angreifer durch die kurze Sperrdauer auch immer wieder kommen, habe ich mir einen eigenen Filter eingerichtet, der das fail2ban Logfile im Auge behält. Wird eine IP-Adresse häufig gesperrt, bekommt diese zur Belohnung eine längere Sperrdauer.

Dazu fügt man in der Datei /etc/fail2ban/jail.local eine neue Jail-Definition ein:

[fail2ban-ssh]
enabled  = true
port     = ssh
filter   = fail2ban-ssh
logpath  = /var/log/fail2ban.log
maxretry = 3
findtime = 21600
bantime  = 86400

Entsprechend dem was man unter filter eingetragen hat, muss man jetzt noch einen Filter unter /etc/fail2ban/filter.d/ anlegen, in diesem Fall heißt die Datei fail2ban-ssh.conf.

sudo nano /etc/fail2ban/filter.d/fail2ban-ssh.conf

In die Datei kommt folgender Inhalt:

# Fail2Ban filter for fail2ban log
#
failregex = \[ssh\] Ban <HOST>
ignoreregex =

Zum Abschluss muss der Filter noch aktiviert werden mit:

fail2ban-client add fail2ban-ssh
fail2ban-client start fail2ban-ssh

Damit ist der Filter erstellt und aktiv.

Typo3 Login Jail

Um Brute Force Attacken auf das Backend-Login von Typo3 zu verhinden kann man ebenfalls ein Jail anlegen:

Apache Scanners Jail

Wenn man die Access Logs des Apaches betrachtet findet man immer wieder Versuche Login-Seiten von CMS-System oder Administrationswerkzeugen wie phpmyadmin oder plesk zu finden. Diese Scanner können wir ebenfalls von unserer Seite ausschlißen in dem wir ein neues Jail anlegen.

Dazu fügt man in der Datei /etc/fail2ban/jail.local eine neue Jail-Definition ein:

[apache-noscanners]
enabled  = true
port     = http,https
filter   = apache-noscanners
logpath  = /var/log/apache*/*access.log
maxretry = 1

Jetzt legt man den entsprechenden Filter in /etc/fail2ban/filter.d/apache-noscanners.conf mit folgendem Inhalt an:

# Fail2Ban configuration file

[Definition]
failregex = ^<HOST> .*"GET .*w00tw00t
# try to access to admin directory
            ^<HOST> .*"GET .*admin.* 403
            ^<HOST> .*"GET .*admin.* 404
# try to access to install directory
            ^<HOST> .*"GET .*install.* 404
# try to access to phpmyadmin
            ^<HOST> .*"GET .*dbadmin.* 404
            ^<HOST> .*"GET .*myadmin.* 404
            ^<HOST> .*"GET .*MyAdmin.* 404
            ^<HOST> .*"GET .*mysql.* 404
            ^<HOST> .*"GET .*websql.* 404
            ^<HOST> .*"GET \/pma\/.* 404
# try to access to wordpress (we use another CMS)
            ^<HOST> .*"GET .*wp-content.* 404
            ^<HOST> .*"GET .*wp-login.* 404
# try to access to typo3 (we use another CMS)
            ^<HOST> .*"GET .*typo3.* 404
# try to access to tomcat (we do not use it)
            ^<HOST> .*"HEAD .*manager.* 404
# try to access various strange scripts and malwares
            ^<HOST> .*"HEAD .*blackcat.* 404
            ^<HOST> .*"HEAD .*sprawdza.php.* 404
            ^<HOST> .*"HEAD .*mocfilemanager.* 404
ignoreregex =

Um den Filter zu aktivieren folgende Befehle ausführen.

fail2ban-client add apache-noscanners
fail2ban-client start apache-noscanners

Solche Scanner Tools die nach Sicherheitslücken suchen gibt es z.B. bei sectools.org.

Apache SQL Injection Jail

Um SQL Injections zu unterbinden kann man ebenfall ein Jail einrichten. Ein schönes Beispiel gibt es auf GitHub (Forks beachten!!).

Um den Filter einzurichten eine Datei /etc/fail2ban/filter.d/apache-sqlinject.conf mit dem entsprechenden Inhalt aus dem GitHub Repository anlegen, dann in der Datei /etc/fail2ban/jail.d/020-apache2.conf folgende Passage hinzufügen:

020-apache2.conf
[apache-sqlinject]

enabled  = true
port     = http,https
filter   = apache-sqlinject
logpath  = /var/www/vhosts/*/log/access.log
#bantime  = 172800
maxretry = 2

Für den Fall das der Code mal nicht mehr vorhanden sein soll, hier eine gekürtze Fassung.

apache-sqlinject.conf
[Definition]

sqlfragments_generic = select.*from|delete.*from|update.*set|insert.*into|replace.*(value|set)
sqlfragments_havij = and(\+|%%20)ascii%%28substring|and(\+|%%20)Length|union(\+|%%20)all(\+|%%20)select|and(\+|%%20)1%%3C1|and(\+|%%20)1%%3D1|and(\+|%%20)1%%3E1|and(\+|%%20)%%27.%%27%%3D%%27|%%2F\*%%21[0-9]+((\+|%%20)[0-9]*)?\*%%2F

failregex = ^<HOST> -[^"]*"[A-Z]+\s+/[^"]*\?[^"]*(?i)(?:%(sqlfragments_generic)s|%(sqlfragments_havij)s)[^"]*HTTP[^"]*"

ignoreregex =

Fail2ban jail

Existiert das Fil2ban Logfile nicht, dann startet fail2ban nicht. Es muss also vorher angelegt werden. Dazu legt man ein neues Initscript /etc/init.d/fail2ban-tmpfs an das folgenden Inhalt hat:

#!/bin/bash
#
### BEGIN INIT INFO
# Provides:          fail2ban-tmpfs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Required-Start:
# Required-Stop:
# Short-Description: Create /var/log/fail2ban.log on tmpfs at startup
# Description:       Create /var/log/fail2ban.log needed by Apache.
### END INIT INFO
#
# main()
#
case "${1:-''}" in
  'start')
   # create the /var/log/fail2ban.log needed by fail2ban jail
   touch /var/log/fail2ban.log
   chmod 777 /var/log/fail2ban.log
   ;;
  'stop')
   ;;
  'restart')
   ;;
  'reload'|'force-reload')
   ;;
  'status')
   ;;
  *)
   echo "Usage: $SELF start"
   exit 1
   ;;
esac

Das Script ausführbar machen

sudo chmod a+x /etc/init.d/fail2ban-tmpfs

Dann das Script vor fail2ban starten

update-rc.d fail2ban-tmpfs defaults 90 10

Damit wird jetzt das Log-File vor dem Start von fail2ban angelegt und der Dienst kann wieder korrekt starten.

Probleme

Es kann sein, dass im Syslog sich wiederholende Meldungen wie folgt abgekürzt werden:

Feb 9 07:52:57 www sshd[19672]: message repeated 2 times: [ Failed password for root from 115.230.126.151 port 43913 ssh2]

wenn das passiert, stimmen der Zähler von fail2ban nicht mehr. Um diesen Wiederholungszähler zu deaktivieren muss man die Datei /etc/rsyslog.conf editieren und den Wert von RepeatedMsgReduction von on auf off stellen und danach rsyslog neu starten.

sudo service rsyslog restart

Jetzt kann fail2ban wieder die richtigen Werte ermtteln.

Blog

Kmoser's Tech-Blog