Linux als Router

Bezugnehmend auf meine Anleitung zur Installation eines Samba4 AD Servers soll dieser neben seiner Aufgabe als AD-Domain Controller, DHCP und DNS Server noch zusätzlich als Gateway für die Clients dienen. Hierzu benötigt dieser zwei Netzwerkkarten. Bei mir ist die erste Karte (eth0) für das interne, private Netzwerk gedacht. Die zweite (eth1) hat die gewünschte Verbindung zum Internet.

Somit sieht die interfaces Datei bei mir wie folgt aus:

Falls ihr auf eurem Server bislang weder DHCP noch DNS betreibt, muss als erstes DNSmasq installiert werden. Falls ihr vom vorherigen Tutorial zur Installation eines Samba4 Servers kommt, ist dies bereits erledigt und könnt euch Schritt 1. sparen. Der Vollständigkeit halber aber hier in kompakter Form:

  1. DNSmasq installieren:

    Konfigurations Datei öffnen:

  2. Ab hier gehts dann für alle weiter und das IP Forwarding im Linux Kernel muss zunächst aktiviert werden:

    Dort die folgende Zeile auskommentieren:

    Damit die Änderungen sofort greifen folgenden Befehl ausführen (oder rebooten):
  3. Zuletzt IPTables installieren und eine Minimalkonfiguration eingeben:
    IPTables installieren

    Konfigurationsdatei öffnen und folgenden Inhalt einfügen:


    Zuletzt die neue Konfiguration aktivieren:

Ab nun sollten alle Clients, die nur im internen Netzwerk hängen ins Internet geroutet werden.

SEH myUTN-50a USB Device Server auf Debian 9 installieren

Zur Installation des oben angegeben USB Device Servers auf einem Debian 9 sind folgende Schritte notwendig.

Aktuelle Software bei SEH herunterladen:

Da die Software leider nur mit einer veralteten SSL Version klarkommt, muss diese bei Debian zunächst nachinstalliert werden, also auch erstmal herunterladen:

Nun die Version von libSSL installieren:

Die von SEH heruntergeladene Software entpacken:

Dann den Treiber, den Daemon und das Kommandozeilentool installieren:

Abschließend den Daemon starten:

Bei mir hat der USB Server vom DHCP-Server die IP 10.101.42.213 bekommen, daher verwende ich für die ersten einfachen Tests diese IP. Am USB-Server selbst ist ein USB Modem angeschlossen, welches nun für den Linux-Server aktiviert werden kann:

Das Modem ist also am zweiten USB Port angeschlossen. Dann kann es auch lokal an die Linux Maschine „gestöpselt“ werden:

Das USB Modem kann nun so verwendet werden, als wäre es direkt mit dem Linux Server verbunden. Sehr praktisch zum Beispiel, wenn der Linux Server virtuell betrieben wird 😉

PHP7 auf Debian 8 (Jessie) installieren

PHP 7 bringt im Vergleich zu seinen Vorgängern viele Verbesserungen. Insbesondere signifikante Performance Verbesserungen, was für mich alleine schon Grund genug ist, um es zu nutzen, wo es technisch machbar ist. Leider ist php7 in den Repositorys des noch aktuellen Debian Releases 8 nicht enthalten, wohl aber Version 9 (Stretch)

Möchte man php7 aber auf dem noch aktuellen Release Debian8 einsetzen, so muss dies über einen kleinen Umweg installiert werden. Außerdem ist zuletzt noch die MySQLi Erweiterung in der php.ini zu aktivieren.

Zunächst also php 7 mit folgenden Befehlen installieren:

In der Datei /etc/php/7.0/apache2/php.ini muss nun noch die Zeile  extension=php_mysqli.dll auskommentiert werden.

Abschließend den Webserver neustarten:

Viel Spaß mit php7!

 

Samba 4.4.2 auf Debian 8.4 installieren (Jessie)

samba_logo_4cIn dieser Anleitung soll auf einem frisch installierten Debian System ein Samba 4.4.2 AD DC installiert werden. Da in den Debian Repositorys von Samba „nur“ die Version 4.1.x vorhanden ist, heißt dies also, dass die Quelltexte von Samba.org geladen, entpackt, kompiliert, installiert und konfiguriert werden. Zu guter Letzt wird eine neue Domäne bereitgestellt und ein Windows Client darf der Domäne beitreten. Ausserdem wird der Samba-Server mit dem RSAT Tools verwaltet.  Basis der Installation ist ein frisch aufgesetztes Debian 8.4 (Jessie) ohne Desktop. Außer den Systemwerkzeugen wurde lediglich der ssh Server installiert. Außerdem sind alle Updates mit

bereits installiert worden. Zu Beginn darf der Rechner auch gerne noch als DHCP Client konfiguriert sein damit er am Internet hängt.

Da die allermeisten der folgenden Befehle root Rechte benötigen, gehe ich davon aus das der root angemeldet ist und spare mir daher das sudo .

Als erstes sollten die für die Samba Installation benötigten Abhängigkeiten installiert werden:

(Der isc-dhcp-server  ist nicht zwingend notwendig. In diesem Tutorial werde ich ihn aber später noch brauchen. Ggf könnt ihr den also weglassen.)

Während der Installation sind drei Fragen zu beantworten. Die erste Frage nach dem voreingestellten Realm für Kerberos Version 5 lege ich auf MY.OWN.DOM  fest. Zu beachten ist, dass ihr als Toplevel keinen öffentlichen Domainnamen nehmen solltet. Also statt des von mir gewählten .DOM solltet ihr nicht so etwas wie  .COM, .DE, .ORG oder zb. .NET nehmen, da diese Domains öffentlich sind. Ihr solltet lieber etwas wählen, das es nicht im Internet gibt, damit es beim DNS zu keinen Konflikten kommt.

Die beiden nächsten Fragen müssen mit dem während der Installation des Debian Servers vergebenen HostNamen beantwortet werden. Welcher Name das ist, lässt sich auch mit dem Befehl hostname  erfragen. Bei mir heisst die Maschine smbdc01:

Dann können auch schon die Samba 4.4 Quelltexte geladen werden:

Nach dem Download entpacken:

Nun in das gerade entpackte Verzeichnis wechseln:

Und mit den beiden folgenden Befehlen kompilieren:

Beide Befehle nehmen je nach Rechenleistung einige Minuten in Anspruch.

Last but not least: Installieren:

Damit samba bequem aufgerufen werden kann, ist es ratsam die $PATH Variable um die neuen samba Pfade zu ergänzen.

Damit das greift, müßt ihr euch aber einmal ausloggen $ exit  und dann wieder einloggen. Wenn alles geklappt hat sollte samba grundsätzlich laufen, was wir mit folgendem Befehl prüfen:

jep, läuft 😀

Falls das Netzwerk des Servers per DHCP konfiguriert wurde, ist es somit nun an der Zeit dies zu ändern. Ein Domänencontroller sollte immer auch die Rolle des DHCP und DNS Servers haben. Letzterer wird in Kürze mit dem Bereitstellen der neuen Domäne aktiviert. Der DHCP Server kommt später dazu, sodass wir jetzt erstmal mit festen IPs zum weiteren Testen arbeiten. Da der DC auch immer eine feste IP haben sollte, ist dies also sowieso erstmal gar nicht so verkehrt. Ich spiele hier mit meinen Installationen in einem HyperV Sandkasten. Daher habe ich es leicht und ändere die Netzwerkverbindung des Servers auf einen Netzwerkswitch des HyperV, der als privates Netz konfiguriert ist. Falls ihr mit einer echten physikalischen Maschine arbeitet, solltet ihr einen Switch (KEINEN Router) zur Hand nehmen und den Samba Server nun mit diesem verkabeln. Abgesehen vom Netzteil, ist der Switch selbst erstmal mit keinen weiteren Geräten verbunden. Vor allem nicht mit eurem Router!

Falls ihr bis gerade so wie ich per ssh gearbeitet habt, wars das natürlich nun erstmal. Also meldet euch artig an der Konsole an und vergebt dem Server eine feste IP indem ihr die interfaces Datei editiert:

Damit der Server die feste IP 10.101.42.1 hat, sieht meine Datei wie folgt aus:

Um die Änderungen zu übernehmen muss das Netzwerk einmal neugestartet werden:

 mit ping könnt ihr zB prüfen ob dies funktioniert hat:

Wenn eine Antwort kommt, dann läuft das Netz. Wenn nicht, dann checkt nochmal eure interfaces  Datei.

So langsam kommen wir dann auch zum spannenden Teil. Die neue Domäne wird bereitgestellt. Meine Domäne wird wie oben bereits erwähnt my.own.dom heißen und ich stelle diese mit denen vom samba Team geratenen Voreinstellungen bereit. Wer sich für die weiteren Schalter interessiert, sollte sich den entsprechenden Abschnitt auf samba.org durchlesen.

Die Installation läuft recht simpel mit nur einem Befehl und ein paar Fragen ab:

Nach Abschluß des Assistenten startet man den Server mit dem Befehl samba .

Bevor wir einen Dienst einrichten um den Sambaserver nach einem reboot automatisch zu starten, testen wir mit den beiden folgenden Befehlen  erstmal, ob das bereitstellen der Domäne auch funktioniert hat.

Wenn es bei euch zu Fehlern kommt, solltet ihr euch den Bereich Trobleshooting auf samba.org durchlesen.  Hier läuft es, also installieren wir nun den Dienst, damit Samba demnächst nach einen Neustart des Server automatisch startet. Dafür muss nur eine Datei mit folgendem Inhalt angelegt werden:

Nun muss der Dienst noch aktiviert werden: systemctl enable samba.service

Nun kann Samba mit den üblichen Befehlen gestartet und gestoppt werden:

Zuletzt wird der DHCP Server eingerichtet:

Die Installation dessen habe ich euch bereits bei der Installation der Abhängigkeiten untergeschoben gehabt, daher muss er nun nur noch konfiguriert werden. Dies geschieht in der Datei dhcpd.conf, welche also zB mit nano zu öffnen ist:

folgende Zeilen sind nun anzupassen:

Die Datei mit STRG+O  und STRG + X  speichern und schließen. Nun nur noch den Dienst des DHCP-Servers starten:

Es ist soweit, der erste Windowsclient kann / darf der Domäne beitreten. Ich werde hierfür einen Windows 10 Pro x64 Client nehmen. Um die Domäne auch zu verwalten, habe ich auf diesem bereits die RSATs installiert. (Hier steht wie das geht). Der Windows Client muss natürlich im selben physikalischen Netz hängen wie der Sambaserver! Da letzterer nun aber bereits als DHCP Server arbeitet, sind an dem Windows Client keinen Einstellungen im Netzwerk mehr notwendig.

Um der Domäne beizutreten könnte man wie üblich den Weg über die Systemsteuerung gehen, Aber wir nehmen mal den neuen Weg über die Einstellungen -> System -> Info (links unten) -> Systeminfo (rechts unten) und landen: „In der Systemsteuerung!!“ Dort also wieder wie gewohnt auf „Einstellungen ändern“ klicken, und nochmal auf ändern um der neuen Samba Domäne beizutreten:MY1Klickt nun noch auf OK und sobald ihr nach einem Nutzerkonto gefragt werdet, gebt das Konto des Domänenadmins an (Das Kennwort habt ihr bei der Installation des Sambasevers vergeben):

MY2

Et voila, euch geht’s wie den Leuten früher aus der Werbung eines ISP: „Bin ich da etwa schon drin?“:MY3Den Linux Rechner mussten wir bisher nicht einmal neustarten. Kaum begeben wir uns aber an ein Windows und „Schwubs“, schon wird der erste Neustart verlangt. Tut dies also…

Nach dem Neustart steht die erste Anmeldung in der Domäne an. Da bisher kein Nutzerkonto außer dem des Administrators besteht, meldet sich also zunächst der Administrator an:

MY4

Nach dem Login könnt ihr direkt das AD und / oder die Gruppenrichtlinienverwaltung aufrufen und euch dort austoben, als wäre es eine MS Domäne:
MY5
Als Sahnehäubchen könnte man dem Linuxserver auch noch eine zweite Netzwerkschnittstelle verpassen. Über diese könnte der Linuxserver dann die Windows Clients ins Internet routen. Aber dies ist Teil eines separaten Tutorials.

Windows 10 Upgrade dauerhaft verhindern

Ich persönlich finde Windows 10 wirklich sehr gelungen und bin bereits komplett darauf umgestiegen. Dennoch kann es gute Gründe dafür geben, dass man nicht auf Windows 10 umsteigen möchte. Den persönlichen Geschmack lasse ich an dieser Stelle auch mal gelten. Der Trick das Update KB3035583 über die Systemsteuerung zu deinstallieren hilft leider nicht wirklich. Auch wenn man das Update nach der Deinstallation deaktiviert, erscheint es irgendwann wieder, sobald Microsoft eine „aktualisierte“ Version des Updates bereitstellt. Damit landet es wieder in der Liste der zu installierenden Updates. Auf Dauer ist das also sehr lästig. Der bislang sicherste Weg das Upgrade dauerhaft abzuwürgen führt über die Registry. Folgende zwei Schlüssel verhindern die Hinweise, dass man doch endlich auf Windows 10 umsteigen möge:

(Nach einem Neustart des Rechners ist dann der Spuk mit dem Upgrade vorbei.)

Gwx OSUpgrade

MS Security Essentials auf Windows 2012 R2 installieren

Mit einem kleinen Trick kann man Security Essentials von MS auch auf einem Windows Server 2012 R2 installieren:

  1. Version für Windows 7 hier herunterladen.
  2. in den Kompatibilitätseinstellungen auf Windows 7 setzen:msse
  3. Jetzt das Setup nicht per Doppelklick starten, sondern eine Konsole öffnen, zu der Datei navigieren und mit folgendem Befehl das Setup starten:   mseinstall.exe /disableoslimit

So installiert lässt es sich leider nicht mehr über die Systemsteuerung deinstallieren. Hierzu bedarf es dann wieder der Kommandozeile und dem Befehl: mseinstall.exe /disableoslimit /u

Ggf kann es dann erforderlich sein, dass man dieselbe mseinstall.exe verwendet, mit der es seinerzeit auch installiert wurde. Also schadet es nicht, die Datei an guter Stelle zu sichern.

Kennwortrichtlinien anpassen

Die Kennwortrichtlinien die man in einer Windows Domäne unter Computerkonfiguration -> Richtlinien -> Windows-Einstellungen -> Sicherheitseinstellungen -> Kennwortrichtlinie einstellen kann, lassen sich in einem Samba4 AD so leider nicht verwalten. Stattdessen müssen diese mit ein paar Befehlen auf der Konsole des Samba Servers erstellt werden:

 

RSAT auf Windows 10 installieren

EDIT (30.12.2015): Diese Anleitung ist mittlerweile überflüssig, da es die RSAT mittlerweile auch auf Deutsch zum herunterladen von Microsoft gibt (Link).

Zum aktuellen Zeitpunkt gibt es die Remote Server Administration Tools (RSAT) für Windows 10 nur in der englischen Version. Das alleine sollte einen nicht abschrecken diese zu nutzen. Allerdings ist deren Installation durch die fehlende deutsche Sprachunterstüzung auf einem deutschen Windows 10 unerwartet aufwendig. Daher dieses Tutorial:

Vor dem Download der RSAT von der Microsoft Seite muss erstmal die englische Sprachunterstützung für Windows 10 nachinstalliert werden: Hierzu auf Start -> Einstellungen -> Zeit und Sprache und zuletzt im linken Menü auf Region und Sprache klicken. Anschließend auf den Knopf Sprache hinzufügen.

Aus der Liste der verfügbaren Sprachen nun English und dann English (Unites States) wählen. Daraufhin gelangt Ihr zurück auf die Seite Region und Sprache. Klickt auf den Eintrag und  dort steht nun „English (United States) Sprachpaket verfügbar“.W10English2

Doch das täuscht. Klickt auf Optionen und man sieht warum:W10English3

Für die RSAT muß das Sprachpaket noch heruntergeladen werden. Verfügbar bedeutete in dem Fall nur, dass es zum Download verfügbar ist. Die Übersetzung ist hier meiner Meinung nach unglücklich. Klickt also bei Sprachpaket auf Herunterladen. (Handschrift und Spracherkennung sind für die RSAT unnötig.) Macht euch ggf. einen Kaffee. Der Download und die Installation kann durchaus ein paar Minuten beanspruchen:W10English4

 Falls ihr ein Kennwort zum anmelden habt, beachtet bitte, dass die Tastatureinstellungen ebenfalls auf Englisch umgestellt wird. Gfg solltet ihr daher im Bereich Tastaturen noch das deutsche Tastaturlayout aktivieren, damit ihr euch wieder anmelden könnt.

Nachdem das Sprachpaket heruntergeladen ist, geht wieder zurück auf die Einstellungen Region und Sprache und klickt bei English auf „Als Standard“.W10English5

Meldet euch ab und wieder an. Nun könnt ihr die RSAT Tools herunterladen und installieren. Zum Abschluss verlangt der Installationsassistent einen Neustart. Nach diesem sind die RSAT Tools installiert. und verfügbar. Ihr könnt nun das englische Sprachpaket über den gleichen Weg wie es drauf gekommen ist auch gefahrlos wieder deinstallieren. Die Tools sind anschließend immernoch verfügbar:

W10RSAT

Sie präsentieren sich nach dem öffnen allerdings in einem gepflegten denglischen Sprachmix.

root Zugriff per SSH aktivieren

Der root Zugriff per SSH ist seit Debian 8 standardmäßig nicht mehr erlaubt. Für meine Testumgebungen ist dies äußerst lästig. Aktivieren kann man den root Zugang wieder, indem man folgende Datei zB mit Nano öffnet:

Dort die folgende Zeile von

nach

ändern.

Nun noch den SSH Server neustarten und dem root Login steht nichts mehr im Wege:

 

Udev & Systemd

Das Ziel ist simpel: Wenn eine bestimmte USB Festplatte angesteckt wird, so soll Linux automatisch damit beginnen bestimmte Verzeichnisse auf die USB Festplatte zu kopieren, bzw besser die vorhandene Verzeichnisstruktur der Quelle mit dem Backuplaufwerk abgleichen, sodass nur die Dateien erneut auf das Backup kopiert werden, die seit dem letzten Backup verändert wurden.

Die Umsetzung war dann zumindest für mich deutlich anspruchsvoller als am Anfang geplant. Denn um Aktionen auszuführen, wenn sich etwas am USB Bus tut ist udev zwar das Mittel der Wahl, aber die Skripte die udev startet dürfen laut Manpage „nicht lange laufen“ bzw. werden nach meiner Erfahrung gekillt, wenn sie dennoch lange brauchen. Die Lösung liegt darin, statt eines Scriptes einen Dienst von udev starten zu lassen, welches dann widerum ein Script startet. Aber einen Schritt nach dem anderen:

Gegeben sind 7 USB-Festplatten unterschiedlicher Hersteller. Festplatte1 wurde mit „Montag“ gelabelt, Festplatte 2 mit „Dienstag“, Festplatte 3 mit „Mittwoch“ usw… An jedem Kalendertag wird die zum Wochentag passende Festplatte gesteckt. Mittels udev wird das stecken einer Festplatte erkannt und ein Script ein Dienst gestartet, welcher wiederum ein Shellscript startet, welches das Label der Festplatte mit dem Wochentag abgleicht und bei Übereinstimmung die gewünschte Sicherung anstößt.

Mein Praxisfall bezog sich zwar auf ein NAS mit dem Debian basierten OpenMediaVault, aber das ganze läßt sich 1:1 auf den RaspberryPi übertragen.

Zunächst einmal müssen wir herausfinden, wo sich die noch nicht gemountete Festplatte am Pi versteckt. Alle vom Kernel erkannten Laufwerke (und nicht nur die) sind zunächst einmal in dem Verzeichnis /dev/ aufgelistet. Festplatten werden dabei als „sd*“ eingebunden. Für jede angeschlossene Festplatte existiert ein Eintrag. Für die erste wäre dies „sda“, für die zweite „sdb“ usw. Die Partitionen der Platten werden dann durchgezählt. Sollten also auf der ersten Festplatte drei Partitionen sein, so exitieren 4(!) Einträge:

sda steht dabei für die Festplatte an sich, nicht für eine Partition der Festplatte. Die Einträge sda1, sda2 und sda3 geben dann die Partionen der Festplatte an. Für mein Szenario ist jede Festplatte nur mit einer Partition versehen, sodass ich die Einträge in dem Listing oben gerade „dabei geschummelt“ habe.

Da sda1 über USB angeschlossen wurde, läßt sich über udev eine Regel erstellen was passieren soll, wenn dieses USB Device angeschlossen wird.

Moment mal, was zur Hölle ist udev?!?!

Wer das noch nie gehört hat liest sich am besten den Eintrag dazu auf Wikipedia durch. Hier nur das wichtigste von dort zitiert: „udev überwacht und wertet hotplug-Ereignisse aus. Finden sich dort Informationen über ein neu angeschlossenes Gerät, werden zu diesem Gerät vorhandene zusätzliche Informationen dem sysfs-Dateisystem entnommen und eine neue Gerätedatei im /dev-Verzeichnis erzeugt. Dabei ist der für die spezielle Datei verwendete Name und die Zugriffsberechtigung frei durch Regeln konfigurierbar.“ (Quelle: Wikipedia)

Das schöne an udev sind die Regeln die sich damit erstellen lassen. Es bietet die Möglichkeit Geräte nach bestimmten Kriterien zu filtern und Aktionsreglen für diese Filter zu erstellen. Dh. wenn ein Filter auf ein neu angeschlossenes Gerät zutrifft, dann kann zB. Ein Shellscript gestartet werden, dass sich um weitere Arbeiten für dieses Gerät kümmert. Oder z.B. die gewünschte Sicherung anstößt.

Um diese Filter zu erstellen, müssen wir zunächst einmal herausfinden wo sich die Festplatte unter /dev/ eingenistet hat. Also Platte zunächst nochmal abstöpseln und den Befehl von oben erneut ausführen:

Na gut, an meinem RaspberryPi hängt nur die eine echte Festplatte, daher ist das bei mir nicht schwierig, aber bei euch könnten da jetzt noch diverse sda’s, sdb’s bis sde’s oder so vorhanden sein.

Anschließend die Platte wieder anstecken und den Befehl erneut ausführen:

Wie gesagt, in meiner Testumgebung gibts gerade nur die eine Festplatte… Daher ist das hier leicht und meine Festplatte befindet sich momentan unter /dev/sda1. (Sie ist dort aber nicht gemounted!)

Nachdem ich nun weiß wo sich die Platte befindet, kann ich über udev eine Fülle an Informationen auslesen lassen (Die Ausgabe erfolgt in Blöcken. Aus Gründen der Lesbarkeit habe ich in dem folgenden Listing einige Blöcke entfernt):

😀 Yummy!!

udev gestattet es in seinen Regeln die Kritierien der einzelnen Blöcke zu kombinieren. D.h. alles was im ersten Block ausgegeben wurde kann ich für eine Regel verwenden oder alles was in Block zwei steht. Es ist jedoch nicht möglich Attribute aus Block zwei mit Block eins zu kombinieren. Also möglich ist es schon, bloß wird es nicht funktionieren 😉

In den meisten Anleitungen, die man im Netz findet, werden die Regeln immer auf die Werte der Attribute „Model“, „idVendor“ und / oder „Vendor“ bezogen. Das ist in den meisten Fällen auch gut und richtig. Da ich aber mit Festplatten unterschiedlicher Hersteller arbeite, muss ich etwas allgemeiner bleiben.

Das Anlegen der Regeln erfolgt durch das Anlegen einer Regeldatei in dem Verzeichnis /etc/udev/rules.d/. Und natürlich gibts dort bereits auch einige Regeldateien:

Die Nummerierung ist nicht willkürlich, sondern in dieser Reihenfolge werden die Regeln von udev abgearbeitet. Um nix „durcheinander zu bringen“, sollte eure Regeldatei also nicht gerade mit 10 beginnen. Wie im echten Leben ist es besser sich „Hinten“ anzustellen, und daher ist meine Regeldatei hier die 99-usb-backup-disk.rules geworden.

Die Datei selbst enthält nur eine einzige Zeile mit den Filterkritierien und diversen Aktionen. Ich kann und will hier nicht alle Möglichkeiten wiedergeben die udev bietet. Wer sich tiefer einarbeiten will, sollte google mit dem Begriff „writing udev rules“ füttern und sich von den im Netz gebotenen Anleitungen überwältigen lassen.

Meine Regel soll immer greifen, wenn ein USB Laufwerk angeschlossen wird. Also bezieht sich mein Filter auf Block 3 der obigen Ausgabe (Ob es tatsächlich das gewünschte Sicherungslaufwerk ist soll das Backupscript über das Label der Partition hinterher herausfinden):

Subsystem und Driver sind die Werte die aus udev kommen. Das doppelte „=“ ist in dem Fall wichtig, da sonst keine Prüfung, sondern eine unnütze Zuweisung erfolgen würde! Der Parameter KERNEL bewirkt, dass der Filter nur greift, wenn durch das Hotplug -Event ein neues /dev/sdX1 Device angelegt wurde. Den Parameter „Action“ habe ich nicht aus obiger Ausgabe, aber er ist wichtig damit die Regel nur dann greift, wenn das Gerät frisch gestöpselt wurde.

Soweit so gut die Regel. Nun soll ein Script (/home/pi/roboBackup.sh) gestartet werden. Zu Testzwecken halten wir es erstmal extrem simpel:

Das Script tut nicht viel. Es ewartet einen Parameter (nämlich die Device-Datei sdX1) und schreibt diesen in eine Log Datei. Damit das Script aufgerufen wird muss dies nun noch in die udev Regel eingefügt werden und die komplette Datei sieht demnach so aus:

%k ist der gewünschte Parameter welcher das Blockdevice wiedergibt. (siehe zb „man udev“)

Abschließend muss udev noch mit dem Befehl $ sudo /etc/init.d/udev restart neusgestartet werden.

Wenn alles klappt kann nun die Platte erneut gestöpselt werden und es sollte im Heimatverzeichnis die laut roboBackup.sh zu erstellende log.txt vorhanden sein (keine Sorge, es kann durchaus 4 bis 5 Sekunden dauern bis die Datei log.txt erscheint):

Soweit also alles nach Plan… Doch nun kommt der Pferdefuss und das Problem: Dieses Demoscript ist klein, niedlich und funktioniert auch wunderbar. Aber das noch zu erstellende Backup Script wird einige 100 GB an Daten zu sichern haben. Und das jeden Tag. Das Script wird also nicht innerhalb weniger Sekunden abgearbeitet sein, sondern mehrere Stunden laufen. Vor allem wenn man über USB 2.0 sichern muss. Und dazu ist laut manpage der Schalter RUN von udev nicht gedacht:

RUN:
Add a program to the list of programs to be executed for a specific device. This can only be used for very short running tasks. Running an event process for a long period of time may block all further events for this or a dependent device. Long running tasks need to be immediately detached from the event process itself.

Leider liest man im Netz viel zu häufig „schlechte“ Lösungen zu diesem Problem indem z.B. das von udev aufgerufene Shellscript nur das lang laufende Shellscript als Hintergrundprozess aufruft. Das ist aber unsauber und auch nicht die für Linux angedachte Lösung. Der Artikel von Jason Ryan beschreibt schön wie man es denn richtig tun sollte, indem man einen systemd Dienst von udev startet. Dieser Beschreibung fehlt mir nur leider, wie man einen Parameter an dem zu startenden Dienst übergibt.

Hierzu bin ich aber über stackoverflow auf diese Lösong gekommen: „Proper(-ish) way to start long-running systemd service on udev event (device hotplug)

Die Lösung beschreibt allerdings ein komplexeres Problem und daher will ich es im folgenden mit Jason’s Artikel zusammenführen und auf mein kleineres Problem herunterbrechen:

Damit es nicht langweilig wird gilt zunächst einmal festzustellen ob überhaupt systemd von der Distribution verwendet wird. Bei Debian basierten Systemen ist dies nämlich nicht der Fall. Am leichtesten lässt es ich testen indem man den Befehl:  $ sudo systemctl

Wenn systemd nicht installiert ist, kommt einfach nur eine Fehlermeldung und es ist noch das ältere sysv-init installiert. Um sysvinit durch systemd zu ersetzen ist folgender Befehl notwendig. Da die Änderung tiefgreifend ist, sollte man eine Sicherung des Systems haben. Auch die Bestätigung der Installation ist daher etwas ungewöhnlicher als sonst (siehe Zeile 20):

Nötig ist es nicht, aber ich empfehle einen Neustart nachdem systemd installiert wurde. Anschließend sieht die Ausgabe von systemctl wie folgt aus:

Als nächstes muss die Datei erstellt werden, welche für das starten des Dienstes per systemd verantwortlich ist:

Damit der Dienst einen Parameter entgegennehmen kann, ist das „@“ im Namen der Dienstdatei zwingend notwendig! Der Dienst heißt zwar roboBackup.service, wird von udev dann aber durch das @ zu dem jeweiligen Device zugeordnet. Somit läuft roboBackup dann zb. bei sda1 als roboBackup@sda1.service. Wenn eine zweite Festplatte angesteckt würde, während das erste Script noch läuft, so würde wieder roboBackup gesartet. Dann aber als roboBackup@sdb1.service. Beide Dienste würden unabhängig voneinander und eigentständig eine Sicherung auf ihre jeweils von udev zugeteilte Festplatte durchführen.

Der Inhalt von roboBack@.service ist erfreulich übersichtlich:

Der Parameter %I sorgt dafür das der Parameter des Dienstes (sdbX1) als Parameter an das auszuführende Shellscript übergeben wird.

Nun muss noch die udev Regeldatei angepasst werden, dass statt des direkten Shellscripts mittels RUN nun der Dienst aufgerufen wird. Also wird der Teil mit RUN ersetzt und die udev Regeldatei sieht nun wie folgt aus:

Nachdem nun alles vorbereitet ist, muss sowohl udev neu gestartet werden, als auch der Dienst roboBackup@.service gestartet werden:

Einem ersten Test steht nun nichts mehr im Wege. Zur Sicherheit lediglich die alte log.txt löschen: rm -f ~/log.txt

Also Platte abziehen, Platte einstöpseln, bis 5 zählen, et voilà:

Perfekt! Sowohl udev als auch systemd laufen und arbeiten Hand in Hand!! Bleibt nur noch das Script als solches. Das Gerüst des Backup Scriptes selbst könnte dann wie folgt aussehen: