Kategorien
Linux

Die Bash und IFS – Zeilenschaltungen als Feldtrenner

Heute habe ich mal wieder etwas gelernt, wie eigentlich jeden Tag! 🙂

Mit der Variable IFS kann man in der Bash den Feldtrenner angeben, da ich als Feldtrenner die Zeilenschaltung erkennen wollte habe ich ihn auf „\n“ gesetzt.

Das klappt so lange im String kein „n“ enthalten ist!


Sobald aber im String ein „n“ enthalten ist wird dieses auch als Trenner erkannt und entsprechend passt das Ergebnis dann nicht mehr:

Die Lösung des Problems ist folgende:

IFS=$’\n‘

Damit klappt es dann wie gewünscht:

Kategorien
Linux Sicherheit

Nginx User Authentifizierung mit pam_script

Eigentlich wäre pam_script dazu gedacht nach erfolgreicher Anmeldung ein Script auszuführen welches irgendwelche Änderungen oder Anpassungen vornimmt. Zumindest lese ich das so aus der Man-Page… 🙂

Nachdem Nginx in Sachen Authentifizierung dem Apache doch an einigen Stellen hinterher hinkt, habe ich mich nach einer Lösung umgesehen um für eine Web-Applikation ein einfaches Anmeldesystem zu bauen welches in weiterer Folge dann auch die Möglichkeit bieten soll dass der User das Kennwort selbst verwaltet. Die Kennwörter sollen in einer MySQL Datenbank gespeichert werden bzw. nur deren Hashes.

Nach längerer erfolgloser Suche habe ich mir folgende Lösung selbst zusammen gezimmert, zuerst wird in der nginx-Config des betroffenen Webhost folgendes eingefügt:

location ^~ /test/ {
auth_pam „Please specify login and password“;
auth_pam_service_name „nginx-test“;
auth_pam_set_pam_env on;
}

Der „auth_pam_service_name“ muss mit dem Namen der Datei in /etc/pam.d/ überein stimmen – also nginx-test, dieses sieht wie folgt aus:

auth    required    pam_script.so expose_authtok dir=/usr/share/libpam-script/pam-script.d/test/
account required    pam_permit.so

Im entsprechenden Verzeichnis „/usr/share/libpam-script/pam-script.d/test/
“ findet sich dann das eigentliche Script welches sich um die Authentifizierung kümmert – pam_script_auth und dieses sieht wie folgt aus:

#!/bin/bash

SID=$(echo $PAM_SERVICE|awk -F ’nginx-‚ ‚{print $2}‘)
PASSWORD=$(cat)

MD5USER=$(echo „$PAM_USER“|md5sum|awk ‚{print $1}‘)
MD5PASS=$(echo „$PAM_AUTHTOK“|md5sum|awk ‚{print $1}‘)

AUTHOK=$(mysql -s -u root -pmysqlkennwort testdb01 -e „SELECT count(*) FROM test_users WHERE sid=\“$SID\“ AND md5uname=\“$MD5USER\“ AND md5p
asswd=\“$MD5PASS\““)

if [ „X$AUTHOK“ == „X1“ ]; then
       exit 0
else
       exit 1
fi

Vom Aufbau recht einfach gehalten, „SID“ ist quasi die Service ID – und diese hole ich mir vom „nginx-test“ indem ich „nginx-“ einfach wegschneide (dient der Erkennung von welchem Webhost die Anmeldung kam – es wird für jeden Webhost eine eigene verwendet!). User und Kennwort verarbeite ich als MD5SUM (man könnte hier auch sha256sum oder sha512sum verwenden), dadurch vermeide ich Probleme die es beim Select geben könnte!

Der Select wird dann auf eine Tabelle los gelassen deren Inhalt im einfachsten Fall einfach nur aus drei Feldern besteht – der „SID“, dem Benutzer-Namen als MD5 Hash und dem Kennwort als MD5 Hash. In den entsprechenden Feldern „sid“, „md5uname“ und „md5passwd“.

Wird ein User gefunden und somit 1 zurück gegeben, dann beendet sich das Script mit dem Rückgabewert „0“ welches ein Login zu lässt. In allen anderen Fällen gibt es ein „1“ zurück und somit ist der Login fehlgeschlagen.

Die Lösung habe ich in gut 30 Minuten zusammengezimmert und sie funktioniert soweit mal, mich würde jetzt interessieren ob ihr hier irgendwelche Sicherheitsbedenken habt!?

Kategorien
Linux Sicherheit

Rsync Backup Script mit ZFS/EXT4 Unterstützung und Infomail für Remote und lokale Systeme

Seit Jahren nutze ich eine Rsync Lösung zum Sichern von Servern die in der Cloud liegen oder keinen direkten Zugriff auf meine Sicherungsserver haben. Bis vor kurzem habe ich damit generell alle Linux Systeme gesichert, bei jenen die direkten Zugriff auf ein NFS oder SMB Share haben bin ich inzwischen auf den Veeam Backup Agent Free umgesteigen. Der leistet hier gute Dienste.

Meine Cloud Server sichere ich allerdings mit einem Rsync Script auf meinen zentralen Backup Server, ich habe gerne alle meine wichtigen Daten bei mir in guten Händen und kümmere mich um mein 3-2-1 Backup lieber selbst als dass ich alles einem Hoster anvertraue! 🙂

Jetzt war es mal wieder an der Zeit etwas am Backup Script zu verändern und bei der Gelegenheit habe ich es gleich komplett umgeschrieben. Was mir bei anderen Lösungen die ich gefunden habe gefehlt hat ist das Auswerten der Rückgabewerte vom rsync Befehl und darauf basierend eine entsprechende Info über den Erfolg oder Misserfolg der Sicherung.

Ebenso hat kaum ein Script eine Unterstützung für Medien die mit ZFS formatiert wurden eingebaut, da ich die Kompression von ZFS nutzen wollte habe ich das für mein Script implementiert.

Die Lösung besteht im Grunde aus folgenden Dateien:

Die Datei backup.config beinhaltet die allgemeine Konfiguration, wer soll das Infomail erhalten, Absenderadresse, Backupmedium, Dateisystemtyp,…
Welche Systeme gesichert werden sollen, wohin die Sicherung geht, wie lange die Sicherung vorgehalten wird, welche Dateien nicht gesichert werden und über welchen Port die SSH Verbindung zum System aufgebaut wird – das steht in der Datei backup-source.config.
Das Template File rsync_mail_template.html dient als Vorlage für das Infomail und das eigentliche Backup Script ist die Datei backup-rsync-remote.sh.

Mein exclude-File schaut wie folgt aus:

/proc
/dev
/media
/lost+found
/mnt
/sys
/var/cache
/var/games
/srv/backup
/var/lib/lxcfs/

Die brauche ich zum Rücksichern nicht wirklich und machen beim Sichern mehr Probleme als ein Backup der Dateien lösen kann. /srv/backup ist der Pfad in dem ich mein Sicherungsmedium einhänge, darum schließe ich das ebenfalls aus.

Ich kopiere die vier Dateien immer nach /usr/local/sbin/ und mache mit „chmod +x backup-rsync-remote.sh“ das Backup Script ausführbar. Nach ein paar Anpassungen des Backup Scripts kann es dann schon losgehen.

Wer z.B. einen Cloud Server einfach nur in ein lokales Verzeichnis auf seinem Backup Server sichern möchte (also kein externes Medium im Spiel), der fügt folgende Zeile in backup-source.config ein:

cloudserver1.example.domain|/srv/backup.cloud|30|/usr/local/sbin/excludeliste-rsync|22

Es wird also mit dem fqdn (full qualified domain namen) des Servers gestartet, anschließend folgt das Verzeichnis in dem die Sicherung abgelegt wird, die 30 sind die Anzahl an Sicherungen die vorgehalten werden, dann noch ein exclude-File mit Verzeichnissen die nicht gesichert werden sollen und am Schluss der SSH Port unter dem der Server ohne Passwort Abfrage erreichbar ist. 

Die Sicherung eines Cloud Server kann jetzt bereits gestartet werden, sofern die backup.config mit passenden Werten versehen wurde bekommt man nach der ersten erfolgreichen Sicherung ein entsprechendes Mail angeliefert.

Soll die Sicherung auf ein externes Medium erfolgen muss man noch ein paar Vorarbeiten leisten:

Will man mit ZFS arbeiten reicht es aus eine externe Festplatte ans System zu stecken, den Device Namen zu ermitteln (z.B. /dev/sdd) und anschließen die Platte mit dem Befehl „backup-rsync-remote.sh –init-zfs“ zu initialisieren. Anschließen kann direkt darauf gesichert werden. Vorausgesetzt wird dass das Paket „zfsutils-linux“ installiert ist!

Bei ext4 weise ich via Udev Regel meinen Sicherungsplatten einen eindeutigen Device Namen zu, damit ich im Backup Script nur /dev/backup_disk als Verweis zum Sicherungsmedium eingeben muss.

Eine solche Regel sieht wie folgt aus und steckt in der Datei „/etc/udev/rules/10-local.rules“:

KERNEL==“sd?1″,SUBSYSTEM==“block“,DRIVER==““,ATTR{partition}==“1″,ATTR{start}==“2048″,ATTR{size}==“7814035086″,

SYMLINK=“backup_disk“

Die passenden Werte für meine Sicherungsplatten bekomme ich vom Befehl:

udevadm info -a -p $(udevadm info -q path -n /dev/sdf1)

Wobei /dev/sdf1 entsprechend durch den Devicenamen eurer Sicherungsplatte zu ersetzen ist – am einfachsten findet man der heraus indem man die Sicherungsplatte ansteckt und sich mit „dmesg|tail“ die letzten Kernel Meldungen anzeigen lässt. 

Hat man die Udev Regel entsprechend erstellt/angepasst muss man den udev Dienst neu starten und triggern, das passiert mit folgender Befehlsabfolge:

systemctl restart udev
udevadm trigger

Anschließend sollte /dev/backup_disk existieren. Jetzt muss man die Platte nur noch für die Sicherung initialisieren:

backup-rsync-remote.sh –init-ext4

Zugegeben etwas mehr Aufwand als mit ZFS! 🙂
Jede Sicherungsplatte muss einmal initialisiert werden und bekommt dabei eine eindeutige ID zugewiesen (steht in der Datei HDID auf der Platte).

Die einzelnen Sicherungen landen dann jeweils im Verzeichnis „daily.X“ beginnend mit 0 für die aktuelle Sicherung, der Rest dürfte fast selbsterklärend sein. Wer mit „du -sch pfad-zum-sicherungsverzeichnis/*“ die Größen der Verzeichnisse prüft, der sieht wie viel sich nach jeder Sicherung verändert hat. Gesichert wird mit hard-links – in jedem daily.X Verzeichnis stecken also alle Daten vom Zeitpunkt der Sicherung drinnen.

Ich hoffe dem einen oder anderen hilft die Anleitung und mein Script dabei seine Daten zu sichern, ich würde mich über Feedback freuen und falls noch Fragen auftauchen ergänze ich den Blog-Beitrag sehr gerne und helfe weiter.

Das Script wird auch immer wieder erweitert und verbessert, wer also auf dem Laufenden bleiben möchte meldet sich am besten rechts oben mit seiner E-Mail Adresse unter „EMAIL SUBSCRIPTION“ an.

Kategorien
Allgemein

Veeam – Failed to get stat on Errno: 2. Unable to get device for path:

Nachdem entfernen eines Laufwerks kann Veeam die Sicherung eines Linux Systems nicht mehr durchführen und „failed“ mit der Fehlermeldung:

14:45:40 [error] Can’t get info for file [/srv/syslog.backup]
14:45:40 [error] Failed to retrieve mount point for [/srv/syslog.backup]

Soweit auch klar, das Verzeichnis gibt es nicht mehr! Allerdings scheitere ich auch daran die zu sichernden Dateien via Veeam Client entsprechend anzupassen.

Die Lösung ist wie immer pragmatisch, einfach mit sqlite3 CLI die Veeam Datenbank öffnen und entsprechend das Verzeichnis in der Datenbank suchen und entfernen.

sqlite3 /var/lib/veeam/veeam_db.sqlite

sqlite> select * from JobFilters;

{d6a30132-26d4-41ee-aa1c-dd7242d82e24}|{7487c858-4c06-421f-b284-aa90a1ce3608}|1|5|/var|
{df8a1212-ce58-4e28-a866-c5ccaa23ec6c}|{7487c858-4c06-421f-b284-aa90a1ce3608}|2|5|/srv/syslog.backup|

delete from JobFilters where id=“{df8a1212-ce58-4e28-a866-c5ccaa23ec6c}“;

Und schon funktioniert das Backup wieder wie gewohnt. Da ich auf den Support Seiten von Veeam keine passende Lösung gefunden habe wird’s hier veröffentlicht. Ein entsprechendes Ticket dazu wurde eröffnet.

Kategorien
Allgemein

Vergessenen Veeam Restore Point aushängen (Linux/cli)

Gelegentlich passiert es dass man nach dem Rücksichern von Dateien vergisst den Restore Point wieder auszuhängen. Ein klassischer „umount“ führt hier nicht zum Ziel weil veeam selbst noch auf dem Mount drauf hängt und diesen blockiert.

Es muss also via veeam der umount erfolgen – das klappt wie folgt:

#!/bin/bash

if [ -x „/usr/bin/veeamconfig“ ]; then
TIME=$(date „+%H%M“)
if [ $TIME -gt 1900 ]; then
VEEAMSESSION=$(/usr/bin/veeamconfig session list|grep „Mount“|grep „Running“|awk ‚{print $3}’|tr -d „{}“)
if [ „$VEEAMSESSION“ ]; then
/usr/bin/veeamconfig session stop –id $VEEAMSESSION
fi
fi
fi

Dieses kleine Script läuft bei mir stündlich ab, wird aber erst nach 19:00 Uhr aktiv und hängt verbliebene Mount-Sessions wieder aus.

Kategorien
Linux

OMD/Check-MK Installation auf Ubuntu 18.04 LTS Server

Meine bevorzugte Monitoring Lösung ist OMD (Open Monitoring Distritbution) mit check_mk, Nagios, WATO & Co an Bord.

Nachdem es auf der OMD Webseite noch keine passenden Pakete für Ubuntu 18.04 LTS gibt, habe ich jene von Debian „Buster“ verwendet.

Hier gibt es nur eine unerfüllte Abhängigkeit – „libicu57“. Diese lässt sich recht schnell lösen – einfach das libicu57 Paket von Ubuntu 17.10 herunterladen und mit

sudo dpkg -i libicu57_57.1-6ubuntu0.3_amd64.deb

installieren.

Anschließend klappt die Installation mit den „Buster“-Paketen wie’s in der Installationsanleitung von OMD angegeben ist ohne Probleme!

Kategorien
Linux

Windows 2016 im virsh/qemu virtuell unter Ubuntu 18.04 installieren/betreiben

Dies ist mal wieder so ein Blog Beitrag der in erster Linie mir selbst dient – damit ich beim nächsten Mal etwas weniger Zeit in das Zusammensuchen der einzelnen Teile benötige, side effect könnte sein dass sich der eine oder andere darüber freut dass ich mir hier die Arbeit gemacht habe! 😉

Für die eigentliche Installation benötigt mein Ubuntu folgende Pakete:

apt-get install virtinst libvirt-daemon libvirt-clients libvirt-bin qemu qemu-kvm qemu-user qemu-utils osinfo-db osinfo-db-tools libosinfo-bin bridge-utils

Und natürlich alle abhängigen Pakete die beim Aufruf des Befehls als Dreingabe noch dazu kommen…

Jetzt besorgt man sich noch die passende Windows DVD und das ISO mit den Virt-IO-Treibern – auf der Fedora Projektseite bekommt man folgendes Image zum Download virtio-win.iso

Meine ISOS habe ich im Verzeichnis /srv/samba/isos/ abgelegt und meine künftige virtuelle Maschine soll unter /srv/kvm/ liegen.

Der folgende Befehl startet die Erstellung der virtuellen Maschine, die Variablen $NAME, $MEMORY und $CPUS habe ich wie folgt belegt:

export NAME=win2016srv
export CPUS=6
export MEMORY=16348
virt-install –name $NAME –memory $MEMORY –vcpus $CPUS –cpu host –video cirrus –features hyperv_relaxed=on,hyperv_spinlocks=on,hyperv_vapic=on –clock hypervclock_present=yes –disk /srv/kvm/$NAME.qcow2,bus=virtio,size=200 –disk /srv/samba/isos/w2016.iso,device=cdrom,bus=ide –disk /srv/samba/isos/virtio-win-0.1.141.iso,device=cdrom,bus=ide –graphics vnc,listen=0.0.0.0 –noautoconsole –os-type=windows –os-variant=win2k12r2 –network bridge=br0,model=virtio

Anschließend ist die Virtuelle Maschine via VNC über die IP Adresse des Servers auf dem der Befehl ausgeführt wurde erreichbar.

Kleine Anmerkung am Rand, die Config des Interface br0 sieht wie folgt aus (/etc/network/interfaces):

auto eth0

auto br0
iface br0 inet static
bridge_ports eth0
address 192.168.1.123
netmask 255.255.255.0
gateway 192.168.1.1

 

Und schon zeigt sich im VNC die Windows Installation – bei der Auswahl der Festplatte muss man den passenden Treiber von der eingehängten CD auswählen, anschließend ist diese nutzbar.

Damit die virtuelle Maschine künftig automatisch startet fehlt noch dieser Aufruf:

virsh autostart win2016srv

 

Kategorien
Linux

Bounced Mails am IMAP Server finden und erneut versenden

Was tun wenn durch einen Fehler jede Menge Mails vom Mailserver gebounced wurden und man es nicht allen Leuten zumuten möchte dass sie die Mails erneut versenden müssen?

Alle an diesem Tag gesendeten Mails finden und via Script erneut in die Mail-Queue einordnen – was so einfach klingt ist im Grunde auch so einfach! (fast) 😉

Angenommen die gesendeten Mails liegen alle im Verzeichnis /srv/imap/{benutzer}/Maildir/.Sent/cur/ – dann könnte man anhand des Dateinamens schon mal ein wenig eingrenzen, alle Mails vom 19. und 20. Juli beginnen mit 1532… (Unix Timestamp).

Wir suchen also alle Mails die mit 1532 beginnen und prüfen dann mit „ls -al“ und grep ob sie an besagtem Tag versendet wurden – es interessieren uns nur die vom 20. Juli.

Alle Mails die gefunden werden injizieren wir dann unserem Postfix mit dem „sendmail“ Kommando.

#!/bin/bash

cd /srv/imap/

IFS=“

for I in $(ls);do

if [ -d „$I/Maildir/.Sent“ ]; then
for F in $(ls -al $I/Maildir/.Sent/cur/1532* 2>&1 |grep -v „No such file or directory“);do
TOSEND=$(echo $F|grep „Jul 20″|awk ‚{print $9}‘)
if [ $TOSEND ]; then
echo „$TOSEND“
cat „$TOSEND“||sendmail -t
fi
done
fi

done

Damit werden alle Mails erneut an den Mailserver übergeben und ausgeliefert.

Kann einem schon mal helfen, besser wär’s natürlich man kommt erst nicht in die Situation…!

Kategorien
Hardware

Linux und der Datalogic Gryphon GFS 4400 USB

Der Datalogic Gryphon GFS 4400 ist ein recht universeller Barcode Scanner der sich wunderbar in Produktionsanlagen verbauen lässt. Ich steuere ihn mit einem Linux Rechner und binde ihn nicht über die USB-Keyboard Schnittstelle an, sondern nutze die USV-COM Variante.

Per Default wird der Scanner laut Handbuch mit folgenden Einstellungen ausgeliefert:

RS-232: 9600,8,N,1,no handshaking,ACK/NAK disabled

Hier kommt die erste Hürde, das Datenblatt muss nach „stty“ übersetzt werden 🙂

Sobald der Scanner am System angeschlossen ist und auf USB-COM umgeschaltet wurde sieht man folgende Anzeige im Syslog:

Jul 18 15:25:33 e002110 kernel: [322458.030720] usb 1-9: new full-speed USB device number 37 using xhci_hcd
Jul 18 15:25:33 e002110 kernel: [322458.180222] usb 1-9: New USB device found, idVendor=05f9, idProduct=4204
Jul 18 15:25:33 e002110 kernel: [322458.180228] usb 1-9: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Jul 18 15:25:33 e002110 kernel: [322458.180232] usb 1-9: Product: Handheld Barcode Scanner
Jul 18 15:25:33 e002110 kernel: [322458.180236] usb 1-9: Manufacturer: Datalogic ADC, Inc.
Jul 18 15:25:33 e002110 kernel: [322458.180240] usb 1-9: SerialNumber: S/N G17AB1226
Jul 18 15:25:33 e002110 kernel: [322458.181927] cdc_acm 1-9:1.0: ttyACM0: USB ACM device

Der Scanner läuft also auf der Schnittstelle /dev/ttyACM0.

Mittels stty können jetzt die Kommunikationsparameter wie oben erwähnt eingestellt werden:

stty 9600 cs8 -cstopb -parenb ocrnl icrnl -F /dev/ttyACM0

Ein weiteres Problem das ich beim Einrichten hatte war dass der Scanner bei GS1-128 Barcodes den GS1 Code mit schickt – z.B. als Zeichen „+C1“ vor dem Barcode, das kann man abschalten indem man diese drei Barcodes scannt:

Wenn man jetzt via Bash Script die eingescannten Barcodes verarbeiten will, dann klappt das mit folgendem Befehl wunderbar:

head -n1 /dev/ttyACM0

In eine kleine „while“-Schleife verpackt und schon wird jeder eingelesene Barcode nach Wunsch verarbeitet.

Kategorien
Linux

$PAC Wallet mit Ubuntu 16.04 betreiben

Auf der Webseite von paccoin.net wird eine vorcompilierte Version ihrer Wallet für den $PAC Coin angeboten – wohl gemerkt für Ubuntu 16.04. Allerdings läuft das Ding nicht wirklich out of the box.

Folgende Schritte waren bei mir nötig um das Wallet zum Laufen zu bekommen:

sudo apt-get install libprotobuf9v5 libevent-pthreads-2.0-5 libevent-2.0-5
sudo add-apt-repository ppa:bitcoin/bitcoin
sudo apt-get update
sudo apt-get install libdb4.8 libdb4.8-dev libdb4.8++

Damit klappt dann der Aufruf von paccoin-qt ohne Fehlermeldung!