Debian aufräumen - rc-Pakete mühelos mit meinem Python-Skript entfernen

Wenn Ihr Debian als Euer Betriebssystem verwendet, habt Ihr bestimmt schon einmal mit dem Befehl dpkg gearbeitet, um Pakete zu verwalten. Bei Debian, Ubuntu, etc. kommt es oft vor, dass Pakete mit dem Status „rc“ (removed and configuration files) auf Eurem System verbleiben und Platz beanspruchen. Das manuelle Entfernen dieser Pakete kann jedoch zeitaufwändig sein. In diesem Blog-Artikel stelle ich Euch ein von mir entwickeltes Python-Skript vor, das diesen Prozess automatisiert und vereinfacht.

Hintergrund

Wenn Ihr in Debian oder Ubuntu Pakete deinstalliert, bleiben in der Regel noch Paketbestandteile und Konfigurationsdateien zurück. Dass Reste vorhanden sind erkennt man am Paketstatus „rc“. Um solche Pakete zu identifizieren und zu entfernen, wird normalerweise der Befehl

dpkg -l | grep ^rc | awk {'print $2'} | xargs dpkg -P 

verwendet. Dieser Befehl filtert alle Pakete mit dem Status „rc“ aus der Liste der installierten Pakete und entfernt sie dann vollständig.

Das Python Skript

Mein Python-Skript vereinfacht diesen Vorgang und bietet einige zusätzliche Funktionen. Hier sind die Kernfunktionen des Skripts:

  1. Liste Pakete mit dem Status „rc“ auf
    Durch den Aufruf des Skripts ohne Argumente oder mit dem Argument -l könnt Ihr eine Liste der Pakete mit dem Status „rc“ anzeigen lassen:
    ./purgerc -l
    Ihr seht nun alle relevanten Pakete, die das Skript bereinigen kann.
  2. Entferne Pakete mit dem Status „rc“
    Durch den Aufruf des Skripts mit dem Argument -f werden alle Pakete mit dem Status „rc“ entfernt:
    ./purgerc -f
    Das Skript führt automatisch den Befehl
    dpkg -l | grep ^rc | awk {'print $2'} | xargs dpkg -P
    aus und entfernt die entsprechenden Pakete.
  3. Übersicht über entfernte Pakete
    Nach dem Entfernen gibt das Skript eine Übersicht über die entfernten Pakete aus:
    Packages removed successfully:
    package1
    package2
    ...
  4. Hilfemeldungen
    Durch den Aufruf des Skripts mit dem Argument -h oder -? erhaltet Ihr eine Hilfemeldung:
    ./purgerc -h

Verwendung und Sicherheit

Die Verwendung des Skripts erfolgt selbstverständlich auf eigene Gefahr!

Das Skript wurde unter Debian 12 entwickelt und setzt Python 3.7 voraus.

Um das Skript auszuführen, müsst Ihr sicherstellen, dass Ihr die erforderlichen Berechtigungen habt, Pakete zu entfernen. Dies wird normalerweise durch die Verwendung von sudo erreicht. Damit es von jedem beliebigen Verzeichnis aus aufgerufen werden kann, sollte es eventuell im Verzeichnis /usr/local/bin abgelegt werden.

Bitte beachtet, dass die Verwendung von shell=True bestimmte Sicherheitsrisiken mit sich bringen kann. In diesem Fall, da die Eingabe vom Benutzer nicht direkt in den Befehl eingefügt wird, sollte es jedoch in Ordnung sein. Wenn Ihr Euch dennoch Sorgen macht, könnt Ihr alternative Methoden wie die Verwendung von subprocess.Popen oder die Aufteilung des Befehls in separate Aufrufe in Betracht ziehen.

Mit diesem Python-Skript wird die Bereinigung von Debian-Paketen mit dem Status „rc“ einfacher und benutzerfreundlicher. Es bietet Euch eine klar strukturierte Möglichkeit, Pakete anzuzeigen, zu entfernen und eine Zusammenfassung der durchgeführten Aktionen zu erhalten. Verabschiedet Euch von komplexen Befehlen und automatisiert diesen Vorgang mit diesem nützlichen Skript

Das Skript „purgerc“

#!/usr/bin/env python3
import subprocess
import sys

def list_rc_packages():
    try:
        # Run dpkg command to list packages with status "rc"
        result = subprocess.run(['dpkg', '-l'], capture_output=True, text=True, check=True)
        lines = result.stdout.split('\n')
        rc_packages = [line.split()[1] for line in lines if line.startswith('rc')]
        
        if rc_packages:
            print("These packages can be purged:")
            print('\n'.join(rc_packages))
        else:
            print("No packages available to be purged.")
    except subprocess.CalledProcessError as e:
        print(f"Error: {e}")
        sys.exit(1)

def remove_rc_packages():
    try:
        # Run dpkg command to list packages with status "rc" and remove them
        result = subprocess.run('dpkg -l | grep "^rc" | awk \'{print $2}\' | xargs dpkg -P', capture_output=True, text=True, shell=True, check=False)
        if result.returncode == 0:
            removed_packages = result.stdout.strip().split('\n')
            print("Packages removed successfully:")
            print('\n'.join(removed_packages))
        else:
            print("No packages available to be purged.")
    except subprocess.CalledProcessError as e:
        print(f"Error: {e}")
        sys.exit(1)

def print_usage():
    print("Usage:")
    print("  purgerc             : List packages with status 'rc'")
    print("  purgerc -l          : List packages with status 'rc'")
    print("  purgerc -f          : Purge packages with status 'rc'")
    print("  purgerc -h or -?    : Show this usage message")

def main():
    if len(sys.argv) == 1:
        list_rc_packages()
    elif len(sys.argv) == 2:
        if sys.argv[1] == '-l':
            list_rc_packages()
        elif sys.argv[1] == '-f':
            remove_rc_packages()
        elif sys.argv[1] in ['-h', '-?']:
            print_usage()
        else:
            print("Invalid argument. Use -h or -? for usage.")
            sys.exit(1)
    else:
        print("Invalid number of arguments. Use -h or -? for usage.")
        sys.exit(1)

if __name__ == "__main__":
    main()

Emotet Erkennung mit Icinga / Nagios und EmoCheck

Neulich wurde bei Heise (https://heise.de/-4652554) über ein interessantes Tool berichtet, mit dem geprüft werden kann, ob ein PC bereits mit der Schadsoftware „Emotet“ infiziert ist. Dies erledigt das Tool „EmoCheck“ (https://github.com/JPCERTCC/EmoCheck/releases) indem es den Rechner auf Prozesse untersucht, die typisch für eine Emotet-Infektion sind. In dem Artikel wird darauf hingewiesen, dass sich ein mit Emotet infizierter Rechner nicht zwangsläufig sofort auffällig verhält. In dem genannten Artikel heißt es: „[…] typischerweise vergehen zwischen der ersten Emotet-Infektion in einem Firmennetz und dem Verteilen des Erpressungs-Trojaners Ryuk ein bis zwei Wochen.“

Es gibt einige Diskussionen über die Funktionsweise dieses Tools. So regt sich einiges an Kritik am Umstand, dass EmoCheck nach statischen Prozessnamen sucht. Ich teile diese Bedenken dahingehend, dass Emotet seinen Prozessen jederzeit anderslautende Namen geben könnte. Allerdings bin ich der Meinung, dass dieses Werkzeug einen installierten Virenschutz sicherlich sinnvoll ergänzen kann und es in Anbetracht des doch erheblichen Schadenpotentials von Emotet sicherlich nicht schlecht ist, sich nur auf einen Prüfmechanismus zu verlassen.

In diesem Artikel beschreibe ich, wie man das Monitoringsystem Icinga bzw. Nagios in Verbindung mit EmoCheck nutzen kann um in einem Unternehmensnetz Emotet-Infektionen frühzeitig erkennen zu können und sich gegebenenfalls aktiv warnen zu lassen.

./libexec/check_emotet
#!/usr/bin/perl
use strict;
use warnings;
use File::Copy;

binmode STDOUT, ":utf8";
use utf8;
use JSON;

use experimental qw( switch );
use feature qw(switch say);

# Declare infection pointer
my $infected = 0;
my $infected_host = "";
my $dir = '/opt/emocheck';

foreach my $fp (glob("$dir/*.json")){
        my $json;
        {
                local $/; # This enables 'slurp' mode
                open my $fh, "<", $fp;
                $json = <$fh>;
                close $fh;
        }
        my $data = decode_json($json);
        if ($data->{'is_infected'} eq 'yes'){
                # Infection found! Set $infected to 1 and set/concatenate affected hostnames delimited by '|'
                $infected = 1;
                if ($infected_host eq ""){
                        $infected_host = $data->{'hostname'};
                }else{
                        $infected_host .= "/" . $data->{'hostname'};
                }
        }
        move($fp, $dir. "/processed");
}

given ($infected) {
    chomp($infected);
    when ($infected lt '1') { print "OK - No infection found."; exit(0);      }
    when ($infected eq '1') { print "CRITICAL - One or more infections suspected. ($infected_host)"; exit(2); }
    default { print "UNKNOWN - $infected of disk space used."; exit(3); }
}

@echo off
.\emocheck_x64 /quiet /json /output \\icinga\emocheck

checkcommands.cfg
define command {
                command_name                          check_emotet
                command_line                          $USER1$/check_emotet
}

advanced_services.cfg
define service {
                service_description                   Check Emotet Infection
                max_check_attempts                    1
                first_notification_delay              0
                notification_interval                 0
                notification_options                  c,r
                notifications_enabled                 1
                event_handler_enabled                 1
                check_command                         check_emotet!
                check_period                          24x7
                notification_period                   24x7
                host_name                             icinga.mein.netz
                contact_groups                        +admins,ProductionAdmins
                use                                   generic-service
}

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run]
"emocheck"="C:\\Program Files\\Emocheck\\emocheck_x64.exe /quiet /json /output \\\\icinga\\emocheck"

Suchgeschwindigkeit in Roundcube erhöhen

Mal so nebenbei eine schnelle Lösung für ein nerviges Problem mit Roundcube.

Ich persönlich nutze hauptsächlich den Roundcube Webmailer. Er ist sehr flexibel, überall nutzbar und „eigentlich“ auch recht schnell. Mein Postfach habe ich mittels Ordnern strukturiert, die Datenmenge ist mit ca. 5 GB beachtlich.

Warum aber „eigentlich“ schnell? Sofern man Mails liest, schreibt und versendet ist der Webmailer wahrlich schnell. Benutzt man jedoch die Suchfunktion von Roundcube ist es mit der Geschwindigkeit schnell vorbei. Dies ging bei meinen System soweit, dass der Apache Webserver gelegentlich einen Fehler 500 zurückgab. Die Ursache war, dass der entsprechende PHP-Prozess in ein Timeout gelaufen war.

Wenn ich etwas such, dann erledigte ich dies bislang zumeist über den Mozilla Thunderbird Mailclient. Da dieser einen lokalen Suchindex aufbaut, bekommt man hier extrem schnell die gewünschten Suchergebnisse präsentiert. Was zuhause gut funktioniert, war mit Roundcube eben bisher ein wirkliches Problem.

Eine logische Erklärung brachte mir ein Beitrag im Plesk-Forum. Sobald man in Dovecot die Volltextsuche aktiviert, läuft die Suche mit bisher ungeahnter Geschwindigkeit. Hier die Lösung:

Auf dem Mailserver die Datei /etc/dovecot/conf.d/99-fts.conf anlegen und mit folgendem Inhalt befüllen:

protocol imap {
mail_plugins = "quota imap_quota fts fts_squat"
}
plugin {
fts = squat
fts_squat = partial=4 full=10
fts_autoindex = yes
}

Danach den Dovecot-Prozess neu starten, das Mail-Log sicherheitshalber auf Fehler untersuchen und die nun deutlich verbesserte Suchgeschwindigkeit genießen.

Der Beitrag, dem ich diese Information entnommen habe, ist unter der URL https://support.plesk.com/hc/en-us/articles/115000532574-The-search-speed-is-slow-in-Roundcube zu finden.

Raspberry Pi – Kernel Upgraden/Downgraden

Wie in meinem Artikel Tvheadend – Aussetzer beim Streaming erwähnt, kann es unter bestimmten Umständen notwendig sein, den Raspberry Pi mit einem anderen, als dem in der jeweiligen Raspbian-Version enthaltenen Kernel zu betreiben. Bekanntschaft habe ich mit diesem Problem bereits im Zusammenhang mit Tvheadend und Node-Red gemacht.

Ich werde nun beschreiben, wie der Kernel up- oder downgegraded werden kann. Hierfür setze ich voraus, dass der Raspberry Pi unter Raspbian läuft. Zunächst sollte man (sofern noch nicht geschehen) herausfinden, welcher Kernel aktuell läuft. Mit dem Befehl

uname -r

wird die momentan laufende Kernel-Version angezeigt. In meinem Fall war dies die 4.9.70-v7+.

Möchte man nun ein Downgrade auf die Version 4.4.50-v7+ durchführen, muss man sich den git-Hash des entsprechenden Commits heraussuchen. Dies erledigt man im Git-Repository von Hexxeh unter der Adresse https://github.com/Hexxeh/rpi-firmware . Mit einem Klick auf den Knopf „<soundsoviele> Commits“ bekommt man eine Übersicht über alle vorhandenen Kernel-Versionen angezeigt.

Nun wird bis zur gewünschten Version herunter gescrollt. Relevant sind hier die Einträge „kernel: bump to x.x.xx“. Im rechten Bereich der Ansicht können wir den entsprechenden Hash in die Zwischenablage nehmen.

Um nun die eigentliche Installation der gewünschten Version vorzunehmen gehen wir wieder in die Console und geben nun (beispielsweise für die 4.4.50) folgenden Befehl ein:

rpi-update 52241088c1da59a359110d39c1875cda56496764

Nun läuft die Installation an, die den Kernel, die Kernelmodule und die Firmware-Files installiert.

Im Anschluß muss der Raspberry Pi neu gebootet werden.

 

 

Tvheadend – Aussetzer beim Streaming

Wie man Probleme mit Aussetzern bei Tvheadend bei der Nutzung auf dem Raspberry Pi löst, erkläre ich in diesem Beitrag. Ich werde hier keine Anleitung zur Einrichtung von LibreELEC, Kodi, Tvheadend, etc. bereitstellen, da das Internet voll solcher Anleitungen ist.

Vor einem guten Jahr habe ich meinen konventionellen SAT-Receiver, eine „Volksbox“, in Rente geschickt. Sie lief mir nicht stabil genug und war mir im Handling etwas, naja, unbequem. Ich bin verwöhnt von einer DreamBox 7025, die ich jahrelang genutzt habe.LibreELEC

Länger schon wollte ich mich mit Kodi beschäftigen – einem Mediacenter für Fernsehen und so ziemlich alle anderen medialen Anforderungen, die man sich vorstellen kann. Mit LibreELEC (https://libreelec.tv/) habe ich eine Lösung gefunden, die man nur auf die SD-Karte packen muss, diese Karte in den Raspberry Pi stecken, booten und los geht’s…

Einen geeigneten Raspberry Pi hatte ich zur gleichen Zeit zu einem guten Preis als Bundle (Raspberry + Gehäuse + Netzteil + SD-Karte) irgendwo im Netz gefunden und bestellt.

Möchte man nur Filme, die man auf einem NAS liegen hat, ansehen oder Online-Mediatheken diverser Fernsehsender nutzen, dann muss man nur noch die entsprechenden „Apps“ im LibreELEC-Image installieren und kann dann sofort diese Dienste nutzen. Möchte man zusätzlich Satelliten-TV nutzen, wird es etwas komplizierter, da man nun einen SAT-Receiver dazu bringen muss, den jeweiligen per Kodi gewählten Sender ins Netzwerk zu streamen.

Aufbau

Bei mir kommt folgende Hardware zum Einsatz:

  1. LG 42″ Fernseher mit u.A. HDMI-Anschluss
  2. Ein Raspberry Pi 3 mit 16 GB SD-Karte (libreELEC installiert), angeschlossen am Fernseher
  3. Ein Raspberry Pi 2 als zentraler Server für interne NextCloud, DHCP, DNS, Node-RED-Host, etc.
  4. Ein an den zentralen Raspberry Pi 2 angeschlossener USB-Satreceiver (TechnoTrend TT-connect S2-4600), Tvheadend

Tvheadend steuert den Satreceiver, stellt also den vom sog. PVR-Client auf der LibreELEC-Maschine angeforderten Transponder ein und streamt somit das entsprechende Programm über’s LAN zu Kodi schickt. Nach einem Problem mit der SD-Karte am zentralen Raspberry Pi 2 habe ich diese Maschine neu installiert. Fortan hatte ich Probleme – das Fernsehbild zeigte oft Klötzchen, blieb hängen, schien puffern zu müssen und hatte Ton-Ausfälle. Im Syslog fand ich plötzlich folgende Meldungen:

[codeblocks name=’codeblock_0′]

Diese „Continuity Counter Errors“ bereiteten mir wirklich Kopfzerbrechen. Die Last auf dem zentralen RPI hatte sich durch die Neuinstallation nicht vergrößert. Da ich die Schüssel nur mit einem sehr rudimentären Messgerät ausgerichtet hatte, bestellte ich sogar einen Fachbetrieb für SAT-Installationen um nachzumessen. Es sei alles perfekt eingestellt, bestätigte der Techniker, an der Ausrichtung der Schüssel konnte es also nicht liegen. Heute konnte ich nun das Problem eingrenzen und schließlich erfolgreich lösen.

Nach der Neuinstallation lief mein zentraler RPI mit dem Kernel v4.9.35. Unter der URL https://forum.libreelec.tv/thread/4235-dvb-issue-since-le-switched-to-kernel-4-9-x/?pageNo=2 erhielt ich den finalen Hinweis. Es handelt sich um ein bekanntes Fehlerbild, dass Tvheadend unter dem v4.9-Kernel dieses Verhalten zeigt. Ich habe nun den Kernel, wie in der genannten URL beschrieben, auf die v4.4 zurückgedreht, wodurch es nun wieder wunderbar funktioniert.

Node-RED – Installation unter Ubuntu

Was ist Node-RED?

Node-RED LogoNode-RED ist ein grafisches Entwicklungswerkzeug, dass vor allem von Leuten benutzt wird, die sich mit IoT (Internet of Things – Internet der Dinge) auseinandersetzen. In erster Linie kann Node-RED dafür genutzt werden, Geräte (sowohl netzwerkfähiges Equipment als auch Geräte, die seriell, per Bluetooth, 1-wire, i²c, etc. angebunden sind) miteinander zu vernetzen, Daten per Sensor oder aus Cloud-Diensten zu empfangen, auszuwerten und weiter zu verarbeiten. Node-RED bietet hierfür eine hervorragende grafische Oberfläche an um dies visuell zu erledigen. Hochinteressant ist die Möglichkeit, auf Ereignisse, die von bzw. durch ein angeschlossenes Gerät (oder einen eingebundenen Dienst) erzeugt werden, eine weitere Aktion auslösen zu können.

Weiterlesen

Eine eigene SSL Zertifizierungsstelle (Root CA) für die Nutzung im LAN erstellen - Teil II

Interne Zertifikate erzeugen

Im ersten Teil haben wir ein Root-Zertifikat für unsere eigene SSL Zertifizierungsstelle erzeugt. Wir sind nun in der Lage, nach Belieben SSL-Zertifikate zu erzeugen, denen unser Browser vertrauen wird (nachdem wir unsere Zertifizierungsstelle innerhalb unseres Netzwerks bekannt gemacht haben).
Wir werden uns nun Schritt für Schritt an die Erzeugung eines Zertifikates für einen Apache Webserver machen und uns ansehen, wie der Virtual Host konfiguriert werden muss.

Weiterlesen

Eine eigene SSL Zertifizierungsstelle (Root CA) für die Nutzung im LAN erstellen – Teil I

Vertrauenssache – Interne SSL-Zertifikate

Im LAN werden oftmals SSL-Zertifikate zur Nutzung verschiedener  Dienste benötigt. Oft bleibt hier nichts anderes übrig, als selbstsignierte Zertifikate zu verwenden. Diese Zertifikate erfüllen zwar aus technischer Sicht ihren Zweck, den Anwender bzw. Administrator stellen sie aber immer wieder vor lästige Probleme.

Weiterlesen