Kategorie: Linux

Themen rund um das freie System

  • Arch auf HyperV installieren

    In dieser Anleitung soll ein Arch Linux Grundsystem in einer virtuellen Maschine auf HyperV installiert werden.

    Das Erstellen der VM in HyperV setze ich voraus. Ich habe für diese Anleitung eine Maschine mit 127GB Festplatte, 4GB RAM, vier CPU Kernen und einem Netzwerkadapter konfiguriert.

    Zu beachten ist, dass ich mich für eine G2 Maschine entschieden habe, also eine UEFI VM.

    Damit Arch davon booten kann, muss der Sichere Start in den Einstellungen der VM deaktiviert werden.

    Der Vollständigkeit halber hier ein Screenshot meiner Einstellungen:

    Das ISO Image von Arch könnt ihr euch auf archlinux.org herunterladen.

    Nach dem „Einlegen“ der ISO und dem Starten der virtuellen Maschine seht ihr zunächst die Bootauswahl der ISO. Hier ist der erste Eintrag zu nehmen:

    Nach dem Bootvorgang des LiveImages, seit ihr im Livemodus von Arch:

    Nun kommt die eigentliche Arbeit.

    Das erste was hier sinnvoll ist, ist die Tastaturbelegung auf Deutsch umzustellen, sodass alle Tasten auch da sind, wo man sie erwartet. Dies geschieht mit dem Befehl:

    loadkeys de-latin1

    Wenn ihr wie oben erwähnt eine G2 VM (UEFI) erstellt habt, dann liefert euch der folgende Befehl diverse Ausgaben. Falls bei euch nichts ausgegeben wird, erstellt die VM als G2 neu.

    ls /sys/firmware/efi/efivars
    
    Boot0000-8be4df61-93ca-11d2-aa0d-00e098032b8c           dbx-d719b2cb-3d3a-4596-a3bc-dad00e67656f                    LoaderTimeInitUSec-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
    Boot0001-8be4df61-93ca-11d2-aa0d-00e098032b8c           ErrOutDev-8be4df61-93ca-11d2-aa0d-00e098032b8c              LoaderTimeMenuUSec-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
    Boot0002-8be4df61-93ca-11d2-aa0d-00e098032b8c           KEK-8be4df61-93ca-11d2-aa0d-00e098032b8c                    MemoryOverwriteRequestControl-e20939be-32d4-41be-a150-897f85d49829
    Boot0003-8be4df61-93ca-11d2-aa0d-00e098032b8c           Lang-8be4df61-93ca-11d2-aa0d-00e098032b8c                   MTC-eb704011-1402-11d3-8e77-00a0c969723b
    Boot0004-8be4df61-93ca-11d2-aa0d-00e098032b8c           LangCodes-8be4df61-93ca-11d2-aa0d-00e098032b8c              OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c
    BootCurrent-8be4df61-93ca-11d2-aa0d-00e098032b8c        LoaderDevicePartUUID-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f   OsIndicationsSupported-8be4df61-93ca-11d2-aa0d-00e098032b8c
    BootOptionSupport-8be4df61-93ca-11d2-aa0d-00e098032b8c  LoaderEntries-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f          PK-8be4df61-93ca-11d2-aa0d-00e098032b8c
    BootOrder-8be4df61-93ca-11d2-aa0d-00e098032b8c          LoaderEntrySelected-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f    PlatformLang-8be4df61-93ca-11d2-aa0d-00e098032b8c
    ConIn-8be4df61-93ca-11d2-aa0d-00e098032b8c              LoaderFeatures-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f         PlatformLangCodes-8be4df61-93ca-11d2-aa0d-00e098032b8c
    ConInDev-8be4df61-93ca-11d2-aa0d-00e098032b8c           LoaderFirmwareInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f     SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c
    ConOut-8be4df61-93ca-11d2-aa0d-00e098032b8c             LoaderFirmwareType-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f     SecureBootEnable-f0a30bc7-af08-4556-99c4-001009c93a44
    ConOutDev-8be4df61-93ca-11d2-aa0d-00e098032b8c          LoaderImageIdentifier-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f  SetupMode-8be4df61-93ca-11d2-aa0d-00e098032b8c
    CurrentPolicy-77fa9abd-0359-4d32-bd60-28f4e78f784b      LoaderInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f             Timeout-8be4df61-93ca-11d2-aa0d-00e098032b8c
    db-d719b2cb-3d3a-4596-a3bc-dad00e67656f                 LoaderTimeExecUSec-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f

    Als nächstes prüft ihr ob die VM mit dem Internet verbunden ist:

    ping -c4 archlinux.org

    Klappt die Verbindung, kann es mit dem partitionieren der Platte losgehen. Gewöhnlich sollte die Platte unter /dev/sda erreichbar sein. Prüft dies mit dem Befehl:

    fdisk -l

    Das Paritionieren der Platte startet ihr dann per cfdisk durch:

    cfdisk /dev/sda

    Im ersten Dialog wählt Ihr als Label gpt:

    Wählt anschließend Free Space und NEW aus dem unterem Menü. Navigieren kann man hier mit Tab oder den Pfeiltasten.

    Als erste Partition benötigen wir bei UEFI die EFI Partition. 300MB sollten hierfür genügen. Ihr könnt aber auch gerne die allgemein empfohlenen 512 MB verwenden:

    Wählt also New und gebt 300M ein:

    Geht anschließend auf Type und ändert den Partitionstyp auf EFI:

    Als nächstes wird die Swap Partition benötigt, welche immer mindestens so groß sein sollte, wie der zur Verfügung stehende Arbeitsspeicher des Rechners, bzw. der VM. In meinem Fall also 4GB.

    Selektiert also zunächst im Menü wieder Free Space und legt mittels New die Swap Partition an:

    Zuletzt wird noch die root ( / ) Partition benötigt. Auch hier markiert ihr zunächst wieder Free space und legt eine neue Parition mittels New an:

    Wählt hier den kompletten verbleibenden Platz aus. Hier könnt ihr also den Vorgegebenen Wert einfach übernehmen:

    Damit dies nun auch tatsächlich alles auf die Platte gelangt, müssen diese Einstellungen nun auf die Platte geschrieben werden. Hierzu wählt ihr Write aus dem unteren Menü:

    cfdisk hat nun seinen Job gemacht und kann über Quit beendet werden

    Als nächstes müssen auf den neu erstellten Partitionen Dateisysteme erstellt werden:

    Bootpartion (/dev/sda1):

    mkfs.fat -F32 /dev/sda1

    Swap Partition:

    mkswap /dev/sda2
    swapon /dev/sda2

    Root Partition:

    mkfs.ext4 /dev/sda3

    Als nächstes muss das Pacman Repository synchronisiert werden:

    pacman -Syy

    Root Partition mounten:

    mount /dev/sda3 /mnt

    Dateien installieren:

    pacstrap /mnt base linux linux-firmware sudo nano dhcpcd

    Sobald die Dateien heruntergeladen und kopiert wurden, geht es an die Konfiguration des Systems.

    Zunächst die fstab Datei erstellen:

    genfstab -U /mnt >> /mnt/etc/fstab

    Für die weiteren Eintellungen wird aus dem Livesystem in das installierte Arch gewechselt:

    arch-chroot /mnt

    Hier die Zeitzone auf Deutsch einstellen:

    ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime

    Als nächstes muss locale eingestellt werden. Hierzu mit nano die Datei /etc/locale.gen öffnen und editieren:

    nano /etc/locale.gen

    Hier die Einträge de_DE.UTF-8 UTF-8, en_US.UTF-8 UTF-8 und en_US ISO-8859-1 auskommentieren, indem das Zeichen # vor den Zeilen entfernt wird. Mit Strg+O und Strg+X die Änderungen speichern und Nano beenden.

    Abschließend die Einstellungen anwenden:

    locale-gen
    echo LANG=de_DE.UTF-8 > /etc/locale.conf

    Deutsche Tastatur:

    echo KEYMAP=de-latin1 > /etc/vconsole.conf

    Als nächstes wird der Hostname konfiguriert. Mein System bekommt hier den Namen „archsystem“:

    echo archsystem > /etc/hostname
    echo "127.0.0.1  localhost" >> /etc/hosts
    echo "::1        localhost" >> /etc/hosts
    echo "127.0.1.1  archsystem" >> /etc/hosts

    Nun wird das Kennwort für den root gesetzt:

    passwd

    Wo wir schon dabei sind, legen wir auch direkt einen normalen Useraccount (soehl) an. Durch das hinzufügen des Users zur Gruppe wheel erhält der User sudo Rechte:

    useradd -m -G wheel soehl

    Für den Account muss natürlich auch ein Kennwort vergeben werden:

    passwd soehl

    Nun noch sudo aktivieren:

    EDITOR=nano visudo

    Ziemlich am Ende der Datei steht die Zeile

    # %wheel ALL=(ALL) ALL

    Entfernt das Zeichen # am Anfang der Zeile und verlasst nano mit Strg+o und Strg+x.

    Last but not least muss nun noch Grub zum starten des Systems eingerichtet werden:

    Zunächst die nötigen Pakete installieren:

    pacman -S grub efibootmgr os-prober mtools

    Nun den Mountpoint für /dev/sda1 erstellen und mounten:

    mkdir /boot/efi
    mount /dev/sda1 /boot/efi

    Nun den Bootloader installieren:

    grub-install --target=x86_64-efi --bootloader-id=grub_uefi

    Ausgabe:

    Installing for x86_64-efi platform.
    Installation finished. No error reported.

    Abschließend die Datei /boot/grub/grub.cfg generieren:

    grub-mkconfig -o /boot/grub/grub.cfg

    Nun sollte alles erledigt sind, und es ist an der Zeit das System zum ersten mal zu booten:

    exit
    umount -R /mnt
    reboot

    Nach dem ersten reboot müssen die Netzwerkdienste noch aktiviert und gestartet werden:

    systemctl enable dhcpcd
    systemctl start dhcpcd
  • 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:

    $ nano /etc/network/interfaces
    # This file describes the network interfaces available on your system
    # and how to activate them. For more information, see interfaces(5).
    
    source /etc/network/interfaces.d/*
    
    # The loopback network interface
    auto lo
    iface lo inet loopback
    
    # Die Karte für das interne Netzwerk
    allow-hotplug eth0
    iface eth0 inet static
      address 10.101.42.1
      netmask 255.255.255.0
      broadcast 10.101.42.255
      network 10.101.42.0
      gateway 10.101.42.1
    dns-nameservers 10.101.42.1
    
    # Netzwerkschnittstelle zum Internet 
    # in diesem Fall per DHCP konfiguriert
    allow-hotplug eth1
    iface eth1 inet dhcp
    iface eth1 inet6 auto
    
    

    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:
      apt-get install dnsmasq

      Konfigurations Datei öffnen:

      $ nano -w /etc/dnsmasq.conf
      interface=eth0
      listen-address=127.0.0.1
      domain=my.own.dom
      dhcp-range=10.101.42.100,10.101.42.200,12h
    2. Ab hier gehts dann für alle weiter und das IP Forwarding im Linux Kernel muss zunächst aktiviert werden:
      $ nano /etc/sysctl.conf

      Dort die folgende Zeile auskommentieren:

      net.ipv4.ip_forward = 1

      Damit die Änderungen sofort greifen folgenden Befehl ausführen (oder rebooten):

      $ sysctl -p /etc/sysctl.conf
    3. Zuletzt IPTables installieren und eine Minimalkonfiguration eingeben:
      IPTables installieren

      $ apt-get install iptables-persistent

      Konfigurationsdatei öffnen und folgenden Inhalt einfügen:

      $ nano /etc/iptables/rules.v4
      *nat
      -A POSTROUTING -o eth1 -j MASQUERADE
      COMMIT
      
      *filter
      -A INPUT -i lo -j ACCEPT
      # ssh erlauben, damit wir uns nicht selbst aussperren
      -A INPUT -i eth1 -p tcp -m tcp --dport 22 -j ACCEPT
      # eingehende Pakete erlauben die zu den ausgehenden Verbindungen gehören
      # u.a. für Rechner aus dem Private-Netzwerk (eth0)
      -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
      # alles andere eingehend verbieten
      -A INPUT -i eth1 -j DROP
      COMMIT

      Zuletzt die neue Konfiguration aktivieren:

      iptables-restore < /etc/iptables/rules.v4

    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:

    $ wget https://www.seh-technology.com/fileadmin/user/downloads/deviceserver/tools/sehutnmanager-ubuntu_linux_64bit-3.0.31.zip

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

    $ wget http://ftp.de.debian.org/debian/pool/main/o/openssl/libssl1.0.0_1.0.1t-1+deb8u6_amd64.deb

    Nun die Version von libSSL installieren:

    $ dpkg -i libssl1.0.0_1.0.1t-1+deb8u6_amd64.deb

    Die von SEH heruntergeladene Software entpacken:

    $ unzip sehutnmanager-ubuntu_linux_64bit-3.0.31.zip

    Dann den Treiber, den Daemon und das Kommandozeilentool installieren:

    $ cd sehutnmanager-ubuntu_linux_64bit-3.0.31/
    $ dpkg -i seh-utn-driver_3.0.31-1dkms_all.deb
    $ apt-get -f install
    $ dpkg -i seh-utn-driver_3.0.31-1dkms_all.deb
    $ dpkg -i seh-utn-service_3.0.31-1_amd64.deb
    $ dpkg -i seh-utn-clitool_3.0.31-1_amd64.deb

    Abschließend den Daemon starten:

    $ /etc/init.d/seh-utn-srv start

    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:

    $ utnm -c "getlist 10.101.42.213"
    Port VID    PID    Manufacturer                  Product
    ---- ------ ------ ----------------------------- -----------------------------
    2    0x0baf 0x0303 U.S.Robotics                  USB Modem
    
    Port State           Owner                     Class Port name
    ---- --------------- ------------------------- ----- -------------------------
    2    Not activated                             0x02

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

    $  utnm -c "plugin 10.101.42.213 2"
    Port VID    PID    Manufacturer                  Product
    ---- ------ ------ ----------------------------- -----------------------------
    2    0x0baf 0x0303 U.S.Robotics                  USB Modem
    
    Port State           Owner                     Class Port name
    ---- --------------- ------------------------- ----- -------------------------
    2    Activated       root                      0x02

    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:

    $ sudo apt-get install curl
    $ curl https://www.dotdeb.org/dotdeb.gpg | sudo apt-key add -
    $ echo 'deb http://packages.dotdeb.org jessie all' >> etc/apt/sources.list
    $ echo 'deb-src http://packages.dotdeb.org jessie all' >> /etc/apt/sources.list
    $ sudo apt-get update
    $ sudo apt-get install php7.0

    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:

    $ sudo systemctl restart apache2.service

    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

    $ apt-get update
    $ apt-get upgrade

    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:

    $ apt-get install acl attr autoconf bison build-essential \
      debhelper dnsutils docbook-xml docbook-xsl flex gdb krb5-user \
      libacl1-dev libaio-dev libattr1-dev libblkid-dev libbsd-dev \
      libcap-dev libcups2-dev libgnutls28-dev libjson-perl \
      libldap2-dev libncurses5-dev libpam0g-dev libparse-yapp-perl \
      libpopt-dev libreadline-dev perl perl-modules pkg-config \
      python-all-dev python-dev python-dnspython python-crypto \
      xsltproc zlib1g-dev isc-dhcp-server

    (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:

    $ hostname
    smbdc01
    

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

    $ wget https://download.samba.org/pub/samba/stable/samba-4.4.2.tar.gz

    Nach dem Download entpacken:

    $ tar xfvz samba-4.4.2.tar.gz

    Nun in das gerade entpackte Verzeichnis wechseln:

    $ cd samba-4.4.2

    Und mit den beiden folgenden Befehlen kompilieren:

    $ ./configure --with-systemd
    $ make

    Beide Befehle nehmen je nach Rechenleistung einige Minuten in Anspruch.

    Last but not least: Installieren:

    $ make install

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

    $ echo export PATH=/usr/local/samba/bin/:/usr/local/samba/sbin/:$PATH >> /etc/profile

    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:

    $ samba -V
    Version 4.4.2

    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:

    $ nano /etc/network/interfaces

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

    # The loopback network interface
    auto lo eth0
    iface lo inet loopback
    
    # The primary network interface
    auto eth0
    iface eth0 inet static
        address 10.101.42.1
        netmask 255.255.255.0
        broadcast 10.101.42.255
        network 10.101.42.0
        gateway 10.101.42.1 
    dns-nameservers 10.101.42.1

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

    $ systemctl restart networking

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

    $ ping -c4 10.101.42.1

    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:

    $ samba-tool domain provision --use-rfc2307 --interactive
    Realm [MY.OWN.DOM]: MY.OWN.DOM
     Domain [MY]: MY
     Server Role (dc, member, standalone) [dc]: dc
     DNS backend (SAMBA_INTERNAL, BIND9_FLATFILE, BIND9_DLZ, NONE) [SAMBA_INTERNAL]: SAMBA_INTERNAL
     DNS forwarder IP address (write 'none' to disable forwarding) [10.101.1.42]: 8.8.8.8
    Administrator password: Passw0rd
    Retype password: Passw0rd
    Looking up IPv4 addresses
    Looking up IPv6 addresses
    No IPv6 address will be assigned
    Setting up share.ldb
    Setting up secrets.ldb
    Setting up the registry
    Setting up the privileges database
    Setting up idmap db
    Setting up SAM db
    Setting up sam.ldb partitions and settings
    Setting up sam.ldb rootDSE
    Pre-loading the Samba 4 and AD schema
    Adding DomainDN: DC=my,DC=own,DC=dom
    Adding configuration container
    Setting up sam.ldb schema
    Setting up sam.ldb configuration data
    Setting up display specifiers
    Modifying display specifiers
    Adding users container
    Modifying users Container
    Adding computers Container
    Modifying computers Container
    Setting up sam.ldb data
    Setting up well known security principals
    Setting up sam.ldb users and groups
    Setting up self join
    Adding DNS accounts
    Creating CN=MicrosoftDNS,CN=System,DC=my,DC=own,DC=dom
    Creating DomainDnsZones and ForestDnsZones partitions
    Populating DomainDnsZones and ForestDnsZones partitions
    Setting up sam.ldb rootDSE marking as synchronized        
    Fixing provision GUIDs
    A Kerberos configuration suitable for Samba 4 has been generated at /usr/local/samba/private/krb5.conf
    Setting up fake yp server settings
    Once the above files are installed, your Samba4 server will be ready to use
    Server Role:           active directory domain controller
    Hostname:              DC1
    NetBIOS Domain:        MY
    DNS Domain:            my.own.dom
    DOMAIN SID:            S-1-5-21-2614513918-2685075268-614796884

    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.

    $ smbclient -L localhost -U%
    Domain=[MY] OS=[UNIX] Server=[Samba 4.4.2]
    
            Sharename       Type      Comment
            ---------       ----      -------
            netlogon        Disk      
            sysvol          Disk      
            IPC$            IPC       IPC Service (Samba 4.4.2)
    Domain=[MY] OS=[UNIX] Server=[Samba 4.4.2]
    
            Server               Comment
            ---------            -------
    
            Workgroup            Master
            ---------            -------
    $ smbclient //localhost/netlogon -UAdministrator -c 'ls'
    Enter Administrator's password: Passw0rd
    Domain=[MY] OS=[Unix] Server=[Samba 4.4.2]
     .                                   D        0  Wed Sep 16 19:56:01 2015
     ..                                  D        0  Wed Sep 16 19:56:07 2015
    
                   49386 blocks of size 524288. 42093 blocks available
    

    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:

    $ nano /etc/systemd/system/samba.service
    [Unit]
    Description= Samba 4 Active Directory
    After=syslog.target
    After=network.target
    
    [Service]
    Type=forking
    PIDFile=/usr/local/samba/var/run/samba.pid
    ExecStart=/usr/local/samba/sbin/samba
    
    [Install]
    WantedBy=multi-user.target

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

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

    $ systemctl restart samba.service
    $ systemctl stop samba.service
    $ systemctl start samba.service
    

    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:

    $ nano /etc/dhcp/dhcpd.conf

    folgende Zeilen sind nun anzupassen:

    #
    # Sample configuration file for ISC dhcpd for Debian
    #
    #
    
    # The ddns-updates-style parameter controls whether or not the server will
    # attempt to do a DNS update when a lease is confirmed. We default to the
    # behavior of the version 2 packages ('none', since DHCP v2 didn't
    # have support for DDNS.)
    ddns-update-style none;
    
    # option definitions common to all supported networks...
    option domain-name "my.own.dom";
    option domain-name-servers 10.101.42.1, 8.8.8.8;
    
    default-lease-time 600;
    max-lease-time 7200;
    
    # If this DHCP server is the official DHCP server for the local
    # network, the authoritative directive should be uncommented.
    authoritative;
    
    # Use this to send dhcp log messages to a different log file (you also
    # have to hack syslog.conf to complete the redirection).
    log-facility local7;
    
    # No service will be given on this subnet, but declaring it helps the
    # DHCP server to understand the network topology.
    
    #subnet 10.152.187.0 netmask 255.255.255.0 {
    #}
    
    # This is a very basic subnet declaration.
    subnet 10.101.42.0 netmask 255.255.255.0 {
      Interface eth0;
      range 10.101.42.100 10.101.42.200;
      option routers 10.101.42.1;
    }
    
    # This declaration allows BOOTP clients to get dynamic addresses,
    # which we don't really recommend.
    
    #subnet 10.254.239.32 netmask 255.255.255.224 {
    #  range dynamic-bootp 10.254.239.40 10.254.239.60;
    #  option broadcast-address 10.254.239.31;
    #  option routers rtr-239-32-1.example.org;
    #}
    
    # A slightly different configuration for an internal subnet.
    #subnet 10.5.5.0 netmask 255.255.255.224 {
    #  range 10.5.5.26 10.5.5.30;
    #  option domain-name-servers ns1.internal.example.org;
    #  option domain-name "internal.example.org";
    #  option routers 10.5.5.1;
    #  option broadcast-address 10.5.5.31;
    #  default-lease-time 600;
    #  max-lease-time 7200;
    #}
    
    # Hosts which require special configuration options can be listed in
    # host statements.   If no address is specified, the address will be
    # allocated dynamically (if possible), but the host-specific information
    # will still come from the host declaration.
    
    #host passacaglia {
    #  hardware ethernet 0:0:c0:5d:bd:95;
    #  filename "vmunix.passacaglia";
    #  server-name "toccata.fugue.com";
    #}
    
    # Fixed IP addresses can also be specified for hosts.   These addresses
    # should not also be listed as being available for dynamic assignment.
    # Hosts for which fixed IP addresses have been specified can boot using
    # BOOTP or DHCP.   Hosts for which no fixed address is specified can only
    # be booted with DHCP, unless there is an address range on the subnet
    # to which a BOOTP client is connected which has the dynamic-bootp flag
    # set.
    #host fantasia {
    #  hardware ethernet 08:00:07:26:c0:a5;
    #  fixed-address fantasia.fugue.com;
    #}
    
    # You can declare a class of clients and then do address allocation
    # based on that.   The example below shows a case where all clients
    # in a certain class get addresses on the 10.17.224/24 subnet, and all
    # other clients get addresses on the 10.0.29/24 subnet.
    
    #class "foo" {
    #  match if substring (option vendor-class-identifier, 0, 4) = "SUNW";
    #}
    
    #shared-network 224-29 {
    #  subnet 10.17.224.0 netmask 255.255.255.0 {
    #    option routers rtr-224.example.org;
    #  }
    #  subnet 10.0.29.0 netmask 255.255.255.0 {
    #    option routers rtr-29.example.org;
    #  }
    #  pool {
    #    allow members of "foo";
    #    range 10.17.224.10 10.17.224.250;
    #  }
    #  pool {
    #    deny members of "foo";
    #    range 10.0.29.10 10.0.29.230;
    #  }
    #}
    
    

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

    $ systemctl start isc-dhcpd-server.service

    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.
  • 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:

    #Aktuelle Kennwortrichtlinie der Domäne anzeigen
    samba-tool domain passwordsettings show 
    
    #Kennwort des Administratorkontos läuft niemals ab:
    samba-tool user setexpiry Administrator --noexpiry 
    
    #Kennwortkomplexitätsregeln deaktivieren
    samba-tool domain passwordsettings set --complexity=off 
    
    #Kennwortchronik abschalten
    samba-tool domain passwordsettings set --history-length=0 
      
    #Minimales Kennwortalter deaktivieren
    samba-tool domain passwordsettings set --min-pwd-age=0 
    
    #Maximales Kennwortalter deaktivieren
    samba-tool domain passwordsettings set --max-pwd-age=0 
    
    #Minimale Kennwortlänge deaktivieren
    samba-tool domain passwordsettings set --min-pwd-length=0 
    

     

  • 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:

    $ nano /etc/ssh/sshd_config

    Dort die folgende Zeile von

    PermitRootLogin without-password

    nach

    PermitRootLogin yes

    ändern.

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

    $ systemctl restart ssh

     

  • 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:

    $ ls -lish /dev/sd*
    4513 0 brw-rw---T 1 root floppy 8, 0 Jan  1  1970 /dev/sda
    4514 0 brw-rw---T 1 root floppy 8, 1 Jan  1  1970 /dev/sda1
    4516 0 brw-rw---T 1 root floppy 8, 1 Jan  1  1970 /dev/sda2
    4519 0 brw-rw---T 1 root floppy 8, 1 Jan  1  1970 /dev/sda3

    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:

    $ ls -lish /dev/sd*
     ls: Zugriff auf /dev/sd* nicht möglich: Datei oder Verzeichnis nicht gefunden
    

    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:

    $ ls -lish /dev/sd*
    4513 0 brw-rw---T 1 root floppy 8, 0 Jan  1  1970 /dev/sda
    4514 0 brw-rw---T 1 root floppy 8, 1 Jan  1  1970 /dev/sda1

    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):

    $ udevadm info -a -p $(udevadm info -q path -n /dev/sda1)
     
    Udevadm info starts with the device specified by the devpath and then
    walks up the chain of parent devices. It prints for every device
    found, all possible attributes in the udev rules key format.
    A rule to match, can be composed by the attributes of the device
    and the attributes from one single parent device.
     
      looking at device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3:1.0/host1/target1:0:0/1:0:0:0/block/sda/sda1':
        KERNEL=="sda1"
        SUBSYSTEM=="block"
        DRIVER==""
        ATTR{ro}=="0"
        ATTR{size}=="3907024896"
        ATTR{stat}=="      83        0      664      150        0        0        0        0        0      150      150"
        ATTR{partition}=="1"
        ATTR{start}=="2048"
        ATTR{discard_alignment}=="0"
        ATTR{alignment_offset}=="0"
        ATTR{inflight}=="       0        0"
     
      looking at parent device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3:1.0/host1/target1:0:0/1:0:0:0':
        KERNELS=="1:0:0:0"
        SUBSYSTEMS=="scsi"
        DRIVERS=="sd"
        ATTRS{rev}=="0   "
        ATTRS{type}=="0"
        ATTRS{scsi_level}=="7"
        ATTRS{model}=="External USB 3.0"
        ATTRS{state}=="running"
        ATTRS{queue_type}=="none"
        ATTRS{iodone_cnt}=="0xcb"
        ATTRS{iorequest_cnt}=="0xcb"
        ATTRS{device_busy}=="0"
        ATTRS{evt_capacity_change_reported}=="0"
        ATTRS{timeout}=="30"
        ATTRS{evt_media_change}=="0"
        ATTRS{max_sectors}=="240"
        ATTRS{ioerr_cnt}=="0x2"
        ATTRS{queue_depth}=="1"
        ATTRS{vendor}=="TOSHIBA "
        ATTRS{evt_soft_threshold_reached}=="0"
        ATTRS{device_blocked}=="0"
        ATTRS{evt_mode_parameter_change_reported}=="0"
        ATTRS{evt_lun_change_reported}=="0"
        ATTRS{evt_inquiry_change_reported}=="0"
        ATTRS{iocounterbits}=="32"
        ATTRS{eh_timeout}=="10"
     
      looking at parent device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.4/1-1.4.3':
        KERNELS=="1-1.4.3"
        SUBSYSTEMS=="usb"
        DRIVERS=="usb"
        ATTRS{bDeviceSubClass}=="00"
        ATTRS{bDeviceProtocol}=="00"
        ATTRS{devpath}=="1.4.3"
        ATTRS{idVendor}=="0480"
        ATTRS{speed}=="480"
        ATTRS{bNumInterfaces}==" 1"
        ATTRS{bConfigurationValue}=="1"
        ATTRS{bMaxPacketSize0}=="64"
        ATTRS{busnum}=="1"
        ATTRS{devnum}=="8"
        ATTRS{configuration}==""
        ATTRS{bMaxPower}=="500mA"
        ATTRS{authorized}=="1"
        ATTRS{bmAttributes}=="80"
        ATTRS{bNumConfigurations}=="1"
        ATTRS{maxchild}=="0"
        ATTRS{bcdDevice}=="0000"
        ATTRS{avoid_reset_quirk}=="0"
        ATTRS{quirks}=="0x0"
        ATTRS{serial}=="20140824004767F"
        ATTRS{version}==" 2.10"
        ATTRS{urbnum}=="635"
        ATTRS{ltm_capable}=="no"
        ATTRS{manufacturer}=="TOSHIBA"
        ATTRS{removable}=="unknown"
        ATTRS{idProduct}=="a200"
        ATTRS{bDeviceClass}=="00"
        ATTRS{product}=="External USB 3.0"
     
      looking at parent device '/devices/platform':
        KERNELS=="platform"
        SUBSYSTEMS==""
        DRIVERS==""

    😀 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:

    $ ls -lish /etc/udev/rules.d/
    insgesamt 12K
    25727 4,0K -rw-r--r-- 1 root root 114 Feb 16 14:30 40-scratch.rules
    26570 4,0K -rw-r--r-- 1 root root  47 Feb 16 14:10 99-input.rules
     1373 4,0K -rw-r--r-- 1 root root 110 Feb 27 19:46 99-usb-backup-disk.rules

    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):

    SUBSYSTEMS=="usb", DRIVERS=="usb", KERNEL=="sd?1", ACTION=="add"

    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:

    #! /bin/bash
    # /home/pi/roboBackup.sh
    log=/home/pi/log.txt
     
    echo `date`       > $log
    echo Hello World >> $log
    echo $1          >> $log
     
    exit 0

    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:

    SUBSYSTEMS=="usb", DRIVERS=="usb", KERNEL=="sd?1", ACTION=="add", RUN+="/home/pi/roboBackup.sh %k"

    %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):

    $ cat /home/pi/log.txt
    Sat Feb 28 09:29:11 CET 2015
    Hello World
    sda1

    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):

    $ sudo apt-get install systemd-sysv
    Paketlisten werden gelesen... Fertig
    Abhängigkeitsbaum wird aufgebaut.
    Statusinformationen werden eingelesen.... Fertig
    Die folgenden zusätzlichen Pakete werden installiert:
      libcryptsetup4 libpam-systemd libsystemd-daemon0 libsystemd-id128-0 libsystemd-journal0 systemd
    Vorgeschlagene Pakete:
      systemd-gui python-cairo
    Die folgenden Pakete werden ENTFERNT:
      fake-hwclock init-system-helpers sysvinit
    Die folgenden NEUEN Pakete werden installiert:
      libcryptsetup4 libpam-systemd libsystemd-daemon0 libsystemd-id128-0 libsystemd-journal0 systemd systemd-sysv
    WARNUNG: Die folgenden essentiellen Pakete werden entfernt.
    Dies sollte NICHT geschehen, außer Sie wissen genau, was Sie tun!
      sysvinit
    0 aktualisiert, 7 neu installiert, 3 zu entfernen und 4 nicht aktualisiert.
    Es müssen 1.580 kB an Archiven heruntergeladen werden.
    Nach dieser Operation werden 3.557 kB Plattenplatz zusätzlich benutzt.
    Sie sind im Begriff, etwas potentiell Schädliches zu tun.
    Zum Fortfahren geben Sie bitte »Ja, tue was ich sage!« ein.

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

    $ sudo systemctl
    UNIT                                                              LOAD   ACTIVE SUB       JOB DESCRIPTION
    proc-sys-fs-binfmt_misc.automount                                 loaded active waiting       Arbitrary Executable File Formats File System Automount Point
    sys-devices-dev:f1-tty-ttyAMA0.device                             loaded active plugged       /sys/devices/dev:f1/tty/ttyAMA0
    sys-devices-platform-...2d1-1\x2d1.1-1\x2d1.1:1.0-net-eth0.device loaded active plugged       ec00
    sys-devices-platform-...-mmc0:0007-block-mmcblk0-mmcblk0p1.device loaded active plugged       /sys/devices/platform/mmc-bcm2835.0/mmc_host/mmc0/mmc0:0007/block/
    sys-devices-platform-...-mmc0:0007-block-mmcblk0-mmcblk0p2.device loaded active plugged       /sys/devices/platform/mmc-bcm2835.0/mmc_host/mmc0/mmc0:0007/block/
    sys-devices-platform-..._host-mmc0-mmc0:0007-block-mmcblk0.device loaded active plugged       /sys/devices/platform/mmc-bcm2835.0/mmc_host/mmc0/mmc0:0007/block/
     .
     .
     .
    sys-devices-virtual-sound-card0.device                            loaded active plugged       /sys/devices/virtual/sound/card0
    sys-devices-virtual-tty-tty0.device                               loaded active plugged       /sys/devices/virtual/tty/tty0
    sysinit.target                                                    loaded active active        System Initialization
    syslog.target                                                     loaded active active        Syslog
    systemd-tmpfiles-clean.timer                                      loaded active waiting       Daily Cleanup of Temporary Directories
     
    LOAD   = Reflects whether the unit definition was properly loaded.
    ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
    SUB    = The low-level unit activation state, values depend on unit type.
    JOB    = Pending job for the unit.
     
    90 units listed. Pass --all to see inactive units, too.

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

    $ sudo nano /etc/systemd/system/roboBackup@.service

    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:

    [Unit]
    Description=roboBackup ausfuehren
     
    [Service]
    ExecStart=/home/pi/roboBackup.sh %I
     
    [Install]
    WantedBy=system.device

    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:

    SUBSYSTEMS=="usb", DRIVERS=="usb", KERNEL=="sd?1", ACTION=="add", ENV{SYSTEMD_WANTS}+="roboBackup@%k.service"

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

    $ sudo /etc/init.d/udev restart
    $ sudo systemctl enable roboBackup@.service

    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à:

    $ cat ~/log.txt
    Sat Feb 28 11:09:33 CET 2015
    Hello World
    sda1

    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:

  • Temperaturfühler DS18B20 per Shell auslesen

    Kernemodule laden um den Temperatursensor anzusprechen:

    # sudo modprobe w1-gpio
    # sudo modprobe w1-therm

    Alternativ die Datei /etc/modules mit den Kernelmodulen ergänzen:

    # /etc/modules: kernel modules to load at boot time.
    #
    # This file contains the names of kernel modules that should be loaded
    # at boot time, one per line. Lines beginning with "#" are ignored.
    # Parameters can be specified after the module name.
     
    snd-bcm2835
    w1-gpio
    w1-therm

    Temperatur auslesen und in eine Datenbank pipen:

    #!/bin/bash
      
    #TempMessung.sh
    # Zwei parallel geschaltete Temperaturfühler abfragen und die Werte in eine MySQL Datenbank übertragen
     
    SENSOR1=28-00000609c38f
    SENSOR2=28-0000060a7b99
    TEMP1=$(echo $(cat /sys/bus/w1/devices/$SENSOR1/w1_slave | grep "t=") | cut -d "=" -f2)
    TEMP2=$(echo $(cat /sys/bus/w1/devices/$SENSOR2/w1_slave | grep "t=") | cut -d "=" -f2)
     
    echo "INSERT INTO schema.table (sensorID, temp) VALUES ('$SENSOR1', $TEMP1);" | mysql -uYourLogin -pYourPassword -h 127.0.0.1;
    echo "INSERT INTO schema.table (sensorID, temp) VALUES ('$SENSOR2', $TEMP2);" | mysql -uYourLogin -pYourPassword -h 127.0.0.1;
     
    exit 0

    Shell Skript über die Datei /etc/crontab automatisiert, minütlich starten:

    # /etc/crontab: system-wide crontab
    # Unlike any other crontab you don't have to run the `crontab'
    # command to install the new version when you edit this file
    # and files in /etc/cron.d. These files also have username fields,
    # that none of the other crontabs do.
     
    SHELL=/bin/sh
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
     
    # m h dom mon dow user  command
    17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
    25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
    47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
    52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
    * *     * * *   root    /home/pi/TempMessung.sh
    #

     

    ERGÄNZUNG von 09/2015:

    Seit dem Oktoberrelease 2014 von Debian Wheezy muss die Datei /boot/config.txt um folgende Zeile ergänzt werden damit der Pi den Sensor erkennt:

    dtoverlay=w1-gpio,gpiopin=4,pullup=on
  • raspi-config

    Nachdem ein frisches Image von Raspdian auf die Karte gebrannt ist und der Pi zum ersten mal gestartet ist, müssen noch einmalig ein paar Einstellungen vorgenommen werden.

    Hierfür bietet sich das enthaltene Tool Raspi-Config an, welches in der Shell mit folgendem Kommando zu starten ist:

    $ sudo raspi-config

    (Der erste Login auf dem Pi gelingt übrigens mit dem Nutzer „pi“ und dem Kennwort raspberry)

    • Als erstes sollte man den nicht genutzen Speicherplatz auf der Karte mit dem Punkt „Expand Filesystem“ verfügbar machen. Nachdem das Script seine Arbeit getan hat, ist ab dem nächsten Neustart der gesammte Platz der Karte verfügbar.
    • Mit Change User Password kann man das Kennwort für den Benutzer „pi“ ändern, und sollte dies auch tun.
    • Für die meisten Fälle kommt beim dem RasPi das Booten zur Konsole in Frage, da er als Desktop Arbeitsplatz zwar grundsätzlich fähig, aber nur bedingt tauglich ist. Hier sollte man also einstellen, dass der Pi nur zur Konsole bootet. Das lässt Resourcen für seinen Job als Webserver, Mailserver, oder oder oder.
    • Bei Internationalisations wird der Pi für den deutschen Sprachraum angepasst:
      •  Change Local auf de_DE.UTF-8 sollte in den meisten Fällen die beste Wahl sein. Unter Umständen kann aber auch de_DE@euro ISO-8856-15 relevant sein. Im Zusammenhang mit älteren Programmen, könnte es hier zwar Probleme geben, ist aber unwahrscheinlich.
      • Unter Change Timezone auf Europe – Berlin umstellen, damit der NTP-Dienst des Pi die korrekte Zeitzone und somit die korrekte Zeit einstellen kann.
      • Change Keyboard Layout: Meistens betreibt man einen Pi ja Headless, sodass man diese Punkt vernachlässigen kann. Aber falls sollte man hier ein deutsches Tastaturlayout auswählen.
    • Advanced Options:
      • Bei Hostname kann man dem Pi einen netteren Namen geben als den Standardnamen „Raspberry“. Nicht das Raspberry schlecht wäre, aber etwas persönlicher darf es ja auch werden 🙂
      • Memorysplit: Für einen Konsolenbetrieb des Pi, kann man hier den für die GPU reservierten Speicher auf ein Minimum von 16MB setzen. Sollte man auch, da man ansonsten den knappen RAM des Pi verschwendet.

    Die wichtigsten Einstellungen sollten damit erledigt sein. Aber wer möchte darf natürlich noch ein wenig in den weiteren Optionen des Tools herumstöbern.

    Zuletzt sollte man aber nun die neuesten Updates für den Pi herunterladen und installieren. Dies geschieht wieder in der konsole mit den Befehlen:

    $ sudo apt-get update
    $ sudo apt-get upgrade

    Für gewöhnlich ist der Pi damit erstmal ein Weilchen beschäftigt und man hat genügend Zeit für eine Tasse Kaffee, oder auch zwei.