Schlagwort-Archive: Linux

BitBastelei #171 – ZFS on Linux

BitBastelei #171 - ZFS on Linux

(41 MB) 00:23:38

2015-10-25 11:00 🛈

ZFS ist ein Speichersystem, welches den Aufbau professioneller Speichersysteme ermöglicht.

02:55 – Inodes
03:43 – Blockgrößen
04:31 – Copy on Write
06:25 – Snapshots
07:25 Transaktionssicherheit bei Backups
18:10 – BTRFS https://www.youtube.com/watch?v=y-yYc4sP9zM

SSH Root-Login auf Debian Jessie aktivieren

„Mal schnell“ einen Server mit Debian aufsetzen – kann ja nicht so schwer sein. Dachte ich. Eine Kleinigkeit ist jedoch zu beachten: Mit der tasksel-Auswahl „SSH-Server“ wird dieser zwar installiert und passend gestartet, standardmäßig ist der Login jedoch nur mit dem zusätzlich erstellten User möglich, nicht jedoch als root.

Da ich für den Server Remote-Scripte laufen habe, welche bisher nicht auf ein User->sudo-System ausgelegt sind, ist für mich ein SSH root-Login unumgänglich. Um diesen auf dem Debian-System zu aktivieren öffnet man die Datei /etc/ssh/sshd_config und entfernt bzw. kommentiert (# davor) die folgende Zeile:

PermitRootLogin without-password

Notizzettel: Wenn mal wieder sinnlose Fehler auftreten…

Wenn man plötzlich mit recht nichtssagenden Meldungen wie

Version: 2.1.1, Linux Version: 2.1.1, Package Iteration: 
go get -v github.com/tools/godep
github.com/tools/godep
go build github.com/tools/godep: /usr/lib/go/pkg/tool/linux_amd64/link: signal: killed
exit status 1
exit status 1

oder auch

remote: Counting objects: 56476, done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 56476 (delta 0), reused 0 (delta 0), pack-reused 56464
Receiving objects: 100% (56476/56476), 94.21 MiB | 6.98 MiB/s, done.
error: index-pack died of signal 92)   
fatal: index-pack failed

beworfen wird, so kann die Ursache auch recht banal und im Log schnell auffindbar sein:

Out of memory: Kill process 2308 (git)

Eyeup, die Kiste hat recht wenig RAM und keinen SWAP eingerichtet – könnte krachen, vor allem wenn Speicherfresser wie node.js mitreden möchten. Auch kann es in diesem Fall helfen /tmp nicht als Ramdisk (tmpfs) laufen zu lassen.

ZFS: Dateien trotz vollem Datenträger löschen

Narf – da war der Bug schneller als der Admin hinter dem Monitoring: 0k freier Speicher vermeldet ein ZFS-Storage. Na kein Problem, kaputtes Programm gestoppt und schnell mal den Schrott gelöscht. Oder auch nicht:

rm: cannot remove file: Disk quota exceeded

Really?!

Ursache wäre wohl „COW“ – Copy on write. Bei Änderungen werden die neuen Daten erst mal auf die Festplatte geschrieben – erst wenn dort kein Fehler auftritt werden die entsprechenden Zeiger im Dateisystem aktualisiert und die vorherigen Daten ungültig.

Die Lösung, welche z.B. bei der Uni Freiburg zu finden ist, ist effektiv, aber mir nicht wirklich verständlich: Anstatt die Datei zu löschen wird sie erst mit /dev/null überschrieben – dies schlägt trotz COW offenbar nicht fehl. Der so freigewordene Speicherplatz, welche zuvor durch den Inhalt der Datei belegt wurde, sollte nun ausreichen um den Löschbefehl umzusetzen:

rm test
#rm: cannot remove file `test': Disk quota exceeded
cp /dev/null test
rm test
stat test
stat: der Aufruf von stat fuer "test" ist nicht moeglich: Datei oder Verzeichnis nicht gefunden

Squid als Proxy-Server

„Mein Internet ist kaputt“ – ich denke jeder 1st-Leveler kennt diese Aussagen. Bauchschmerzen bereiten sie spätestens dann, wenn auch man selbst nicht mehr ins Netz kommt. Proxy weg. In solchen Situationen muss schnelle Hilfe her. Mein erster Blick: Da steht noch ne Testkiste – zwar ist Arch Linux nicht unbedingt die erste Wahl für Produktivserver, welche möglichst wartungsarm sein sollen, aber besser als nichts. Bauen wir mal einen Proxy.

1. Squid installieren

Die Platzhirsch unter den Proxys dürfte ohne Frage Squid sein. Die GPL-Software kann sowohl als Caching als auch Reverse Proxy eingesetzt werden. Ich nutze nur die erste Funktion – Zugriffe der Benutzer sollen zwischengespeichert werden. Die Installation ist unter nahezu allen Distributionen mit wenigen Schritten über den Paketmanager möglich. In meinem Fall reicht ein „pacman -S squid“.

2. Zugriffs- und Speicherkonfiguration

Neben der Software wird auch eine Standardkonfiguration installiert, welche unter /etc/squid/squid.conf zu finden ist. Standardmäßig wird den privaten IPv4-Bereichen erlaubt auf die üblichen Ports für HTTP, FTP, Gopher, Wais und HTTPs zu verbinden. Sofern man keine restriktive Webzugriffslinie besitzt können diese Beispiele also übernommen werden. Einige Änderungen und Ergänzungen können allerdings Hilfreich sein:

# Keine Verbindung zu localhost - schuetzt ggf. falsch eingerichtete Webanwendungen auf dem Server
http_access deny to_localhost

#E-Mail-Adresse des Admins - so kommen die Beschwerden der Nutzer an die richtige Stelle
cache_mgr info@ad....fo

#Beim Stoppen des Dienstes 10 Sekunden darauf warten laufende Uebertragungen abzuschliessen
shutdown_lifetime 10 seconds

#Im RAM werden bis zu 4 GB als Cache genutzt
cache_mem 4096 MB

#Objekte mit mehr als 50MB werden nicht gecached
maximum_object_size 50 MB

# Bis 95% Fuellstand des Caches werden keine Objekte ersetzt
cache_swap_low 95

# Je naeher wir an 98% kommen desto aggressiver werden alte Objekte ersetzt
cache_swap_high 98

#Alles ueber 512kb wird nicht im RAM sondern nur auf HDD gespeichert
maximum_object_size_in_memory 512 KB

# HDD-Cache Typ aufs (async), Ordnerangabe, 32GB, Ordner erste Ebene, Ordner zweite Ebene
cache_dir aufs /var/cache/squid 32768 32 256

#Eyecandy
visible_hostname proxy.lan.adlerweb.info

#Boese Seiten
acl bad_url dstdomain "/etc/squid/bad-sites.acl"
http_access deny bad_url

#Interne IP des Clients nicht nach draussen senden
forwarded_for off

In meinem Fall musste auch der Standardport dran glauben, stattdessen wird nun 8080 verwendet, welches dem Altsystem entspricht und lästiges Umkonfigurieren erspart:

http_port 8080

3. Diktator-Modus

In der Konfiguration schimmert es schon etwas durch: I aim to misbehave. Da es sich um mein Netz handelt greifen auch meine Zensurrichtlinien. Unter /etc/squid/bad-sites.acl liegt eine Liste mit Domains, welche vom Proxy gesperrt werden. Dies kann z.B. sinnvoll sein um Werbung oder die Ziele quasselfreudiger Programme auszusperren. Dabei solltet ihr natürlich das alte Credo beherzigen: With great power comes great responsibility.

.facebook.com
.facebook.de
.google-analytics.com
.googleadservices.com
[...]

4 Minuten Später
…ist der Proxy installiert und das Internet läuft wieder. Job erledigt, wenden wir uns wieder den Katzenvideos zu.

Und sonst?
Wer es etwas weiter treiben möchte: SquidGuard oder Dansguardian können Webseiten nach Themenbereichen sperren. SquidClamav kann die aufgerufenen Webseiten auf Viren prüfen. Sarg verwandelt das Log in einen praktischen HTML-Report mit Top-Usern und den Beliebtesten Webseiten. Ansonsten hat auch sicher die Suchmaschine der Wahl noch genügend Ideen zur Freizeitvernichtung.

Linux: Partitionen innerhalb einer Image-Datei/LV mounten

Bisher speicherte ein Windows-System seine Datensicherung per CIFS (aka Samba) auf einer Linux-basierten NAS. Das Konzept ist dabei schon etwas älter – die Windows-Software unterstützte bei der Einrichtung weder Kompression noch Deduplizierung, sodass hier das ZFS-Dateisystem der Linux-Kiste einiges an Platz einsparen konnte. Inzwischen ist die Windows-Software gewachsen: Kompression und Deduplizierung werden bereits vorab durchgeführt, dafür machten die vielen neuen Funktionen immer häufiger Probleme mit CIFS. Kaputte Locks, schlechte Performance, Verbindungsabbrüche – alles lässt sich recht genau auf die Kombination aus dem Server und CIFS zurückführen. Während eine „normale“ Kopie unter Linux mit etwa 100MB/s von statten geht schafft der Server nur 4MB/s. Andere Protokolle sind schneller, andere Windows-Server haben ebenfalls keine Probleme. Inzwischen sind ohnehin neue Platten fällig – Zeit hier gegenzusteuern.

Die Speicherung soll weiterhin auf der Linux-Kiste erfolgen – dort ist die Sicherung und Verwaltung deutlich zuverlässiger und flexibler. Andererseits habe ich keine Lust auf CIFS-Fehlersuche, also lassen wir es einfach weg – die Lösung: iSCSI. Der Windows-Server greift direkt auf den rohen Datenträger des Linux-Systems zu. Da wie erwähnt keine Linux-seitige Kompression stattfinden muss wird diese einfach per LVM verwaltet und ist über den Kernel-iSCSI-Server exportiert. Das Anlegen verläuft ohne Probleme, müssen nur noch die Daten rüben. Mit 4MB/s. Bei fast 4TB. Mit 5 Tagen Restzeit. Nope.

Also, fassen wir nochmal zusammen: Sowohl der alte als auch der neue Datenbestand liegen auf dem selben Linux-System. Warum nicht einfach da kopieren? NTFS-Schreiben unter Linux ist zwar nicht schnell, aber die 4MB/s-Marke sollte zu schaffen sein. Problem: Auf dem LVM-LV hat Windows automatisch eine GPT-Partitionstabelle angelegt, sie lässt sich also nicht direkt unter Linux mounten.

Um trotzdem an das NTFS-System zu kommen müssen wir erst mal wissen wo die passende Partiton beginnt. Hier kommt parted zum Einsatz, welcher auch GPT-Partitionstabellen unterstützt. Da wir die Angaben in Byte, nicht den üblichen Sektoren, benötigen muss die Anzeige erst ungeschaltet werden.

[root@nas ~]# parted /dev/speicher2/windows9
GNU Parted 3.2
/dev/dm-1 wird verwendet
Willkommen zu GNU Parted! Rufen Sie "help" auf, um eine Liste der verfügbaren Befehle zu erhalten.
(parted) unit B
(parted) print
Modell: Linux device-mapper (linear) (dm)
Festplatte  /dev/dm-1:  4178147540992B
Sektorgröße (logisch/physisch): 512B/512B
Partitionstabelle: gpt
Disk-Flags:

Nummer  Anfang      Ende            Größe           Dateisystem  Name                          Flags
 1      17408B      134235135B      134217728B                   Microsoft reserved partition  msftres
 2      135266304B  4178146492415B  4178011226112B  ntfs         Basic data partition          msftdata
(parted) quit

Wie wir sehen wurden auf dem LVM-LV durch Windows zwei Partitionen angelegt: Die Erste enthält Managementdaten, die Zweite ist unsere eigentliche NTFS-Datenpartition. Letztere beginnt bei 135266304 Byte – genau diesen Bereich müssen wir auf dem Datenträger also überspringen um auf das NTFS-Dateisystem zugreifen zu können. Also legen wir uns ein passendes Loop-Device an. Da ich bereits ein anderes Device aktiv habe nutze ich loop2 – generell ist die Zahl wählbar.

[root@nas ~]# losetup -o 135266304 /dev/loop2 /dev/speicher2/windows9
[root@nas ~]# mount -t ntfs-3g /dev/loop2 /mnt/test/
[root@nas ~]# mount | grep test
/dev/loop2 on /mnt/test type fuseblk (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other,blksize=4096)
[root@nas ~]# df -h test/
Dateisystem    Größe Benutzt Verf. Verw% Eingehängt auf
/dev/loop2      3,8T    604G  3,3T   16% /mnt/test

Passt doch, schon haben wir unter Linux nativen Zugriff auf das Device. Das Kopieren läuft nun mit 90MB/s – nicht ganz die bestmögliche Geschwindigkeit, für NTFS über fuse aber kein Schlechter wert – und etwas schneller als die 4MB/s der Windows-Kiste.

BTRFS-Recovery

Narf… Das war zu viel. Durch einen Umbau hatte sich offenbar ein Kabel im Lüfter meines Chipsatzes verheddert – keine gute Voraussetzung, wenn man mal eben Wine neu kompiliert. Es kommt, was kommen musste: Kernel panic.

Nunja, Fehler gefunden, weiter gehts. Nicht. Zwar startete das System, meine Home-Partition blieb aber verschwunden. Kurzer Blick auf den Aufbau: Mein Home liegt auf einer separaten Partition, ist mit LUKS verschlüsselt und nutzt – da ich die gigabyteweise IRC-Logs vorratsdatenspeichere und transparente Komprimierung wollte – BTRFS. Das Log verrät: LUKS selbst läuft, mount hingegen scheint sich aufzuhängen. In dmesg sieht alles OK aus, nur die normalen BTRFS-Meldungen, keine Fehler.

Strange, aber Reboot fixed ja fast alles, also schnell die magischen Zeichen eingetippt und zur Sicherheit im Rescue-Mode gestartet. Dort per Hand cryptsetup aufgerufen und erst mal btrfsck losgelassen. Kein Fehler. Mount? Nope.

OK, nun bin ich genervt, vor allem da die Kiste nicht unbedingt schnell bootet. Qemu to the rescue, also schnell ein Debian geklont und die Partition vorgesetzt. Schlechte Idee. Die bei Debian genutzten BTRFS-Libs/Module sind eine Nummer zu alt und können mit der Partition gar nichts anfangen. Ein Arch-Download später kann es weiter gehen.

Erst einmal ein normaler mount in der VM – vielleicht ist ja nur der Host kaputt, außerdem ist auf der CD ein älterer Kernel. Leider ohne erfolg, also VM-Reboot und den Hammer ausgepackt. Mit „mount -o recovery,nospace_cache“ lassen sich viele Fehler schon beheben, aber auch hier scheint der mount nichts zu vollziehen. Keine Reaktion, keine IO-Last, keine Fehlermeldung.

Die Lösung: btrfs_zero_log. Hiermit werden die offenen Transaktionen gelöscht. Die kann zwar zu Datenverlust von Änderungen, die kurz vor Absturz geschrieben wurden, führen, aber besser als gar keine Partition. Der mount in der VM war schlussendlich erfolgreich und auch der Host verfügte kurze Zeit später wieder über alle Dateien. Warum btrfsck das offenbar defekte Log nicht ankreidete ist mir allerdings ein Rätsel – sollte das nicht die Aufgabe des Tools sein?

FTP-Uploads per Shell-Script

Ab und an komme auch ich nicht drumrum mit Zielen zu arbeiten, welche keine SSH/SFTP-Verbindung zulassen, sondern nur per FTP(S) erreichbar sind. Grade beim Automatisieren über Shell-Scripte ist das reichlich unschön. Ein praktischer Client ist in diesem Fall das Urgestein ncftp. Mit dessen Tools lässt sich z.B. schnell ein ein entferntes Verzeichnis löschen und durch die lokale Kopie ersetzen:

echo 'rm foo/bar/*
rm foo/baz/*
rmdir foo/bar
rmdir foo/baz
' | ncftp -u $USER -p $PASS $HOST

ncftpput -R -u $USER -p $PASS $HOST /foo/* ~/dev/foo/*

Windows Shutdown per Linux

Ab und an möchte man entfernte Rechner mal runterfahren. Mit Linux-Zielen ist das per ssh üblicherweise kein Problem, möchte man jedoch von einem Linux-PC den Shutdown-Befehl an einen Windows-Rechner geben muss man schon einmal suchen. Abhilfe schafft wie üblich Samba, welches den „net“-Befehl mitbringt. Ein Shutdown sieht dann wie folgt aus:

net rpc SHUTDOWN -C "Grund für den Shutdown" -f -I 127.0.0.1 -U username%password

CUPS/foomatic/gutenprint: „Unable to get list of printer drivers: Success“

Eigenlich bin ich ja Verfechter papierloser Abläufe, leider sind viele Behörden damit nicht einverstanden oder schreiben sinnloserweise selbstgestrickte Vorgaben statt offener Standards vor. Zum Glück stehen hier noch ein paar Drucker aus den 80ern und 90ern rum, die nicht nach 10 Seiten das Zeitliche segnen. Also: Drucker raus, Papier rein. Error. Bei der Installation des Druckers auf meinen PCs – genauer der Suche nach möglichen Treibern – meldete CUPS teilweise folgende, sehr aussagekräftige, Fehlermeldung:

Unable to get list of printer drivers: Success

Auffällig dabei: Ein Perl-Script bezüglich Foomatic belagert zuvor einen CPU-Kern. Auch konnte ich bei einem System beobachten, dass der Fehler erst nach Installation zusätzlicher Treiber (foomatic-db & Co) auftrat, mit „leerer“ Treiber-Liste jedoch nicht. Der Fehler ist konstant, also sowohl in der Desktop-GUI als auch im CUPS-Webinterface reproduzierbar.

tl;dr: Don’t do gutenprint…

Schauen wir mal genauer auf den 100%-Prozess: Dieser wird vom Nutzer „daemon“ gestartet und hat kein nice-Level. Der genaue Aufruf lautet

/usr/bin/perl /usr/lib/cups/driver/foomatic list

Das Script selbst lässt sich auch auf der Konsole manuell starten. „list“ gibt hierbei nicht wirklich etwas – auch nach mehreren Minuten keine Ausgabe. „help“ am Ende zeigt die möglichen Optionen:

foomatic -A
foomatic -P
foomatic -p [-d ] [-w]
foomatic list
foomatic cat [-w]
foomatic -h

-A : show all Printer ID’s and compatible drivers
-P : show all Printer ID’s whose names and model
matched by the RE. For example:
-P HP will match all names with HP in them
-p : Printer ID
-d : Driver name
If the driver is not specified then the default driver
for the is used.
list : List all possible PPDs in the format needed by the
cups-driverd
cat : Generate PPD file appropriate to the .
Available CUPS PPD URIs are listed by
„foomatic list“.
-w : Generate PPD which is compatible with the CUPS PostScript
driver for Windows (GUI strings are limited to 39
characters).
-h : show help information

Leider scheint es – jedenfalls laut Hilfe – keinen verbose- oder debug-Modus zu geben. Strace to the rescue. Zu sehen nicht viel – die Treiber-Dateien werden nacheinander geladen, die letzten Zeilen lauten:

stat(„/usr/share/foomatic/db/source/driver/xes.xml“, {st_mode=S_IFREG|0644, st_size=522, …}) = 0
stat(„/usr/share/foomatic/db/source/driver/xes.xml“, {st_mode=S_IFREG|0644, st_size=522, …}) = 0
stat(„/usr/share/foomatic/db/source/driver/xes.xml“, {st_mode=S_IFREG|0644, st_size=522, …}) = 0
open(„/usr/share/foomatic/db/source/driver/xes.xml“, O_RDONLY) = 3
lseek(3, 0, SEEK_CUR) = 0
read(3, „\n

Dummerweise ist „xes.xml“ auch die alphabetisch letzte Datei, also eher kein Fehler darin zu vermuten. Narf. Nunja – räumen wir mal auf. Unter /usr/share/foomatic/db/source müssen die Dateien unter PPD, driver, opt und printer weichen. Success. Kind of. Der Foomatic-Prozess endet ohne Fehler, also muss einer der Treiber der Übeltäter sein. Als erstes wandert opt wieder zurück, hier ist nicht viel drin. Noch alles OK. Auch das zurückkopieren von PPD zeigt keine Änderung. Printer klingt interessanter, daher spiele ich hier jede Datei einzel zurück:

for i in * ;do mv $i ../printer && echo $i && (/usr/bin/perl /usr/lib/cups/driver/foomatic list || exit) ; done

Dauert zu lange – ich entscheide mich nur die XML-Dateien der für mich interessanten Hersteller zu nutzen. Läuft noch. Es folgt Drivers. Weniger dateien, trotzdem manuell. Erster Kandidat: necp6 – ein Treiber für meinen Nadeldrucker. Passt – foomatic list liefert nun eine Liste aller NEC-Nadeldrucker. Fehlt noch mein Laser. Da Gutenprint schnell sein soll kopiere ich deren XMLs – nichts geht mehr. Hört sich nach Verursacher an – kopieren wir alles außer Gutenprint: Passt. Auch in CUPS lässt sich nun der Drucker anlegen. Fehler Gefunden würde ich sagen…