Full filesystem without content?

Since a few days I had a problem on my Ubuntu machine that I use at home: After logging in, the system showed a warning, that /tmp was nearly full. Checking it with df -h showed that over 95% of 10 gigabyte were used. But sudo du -hs /tmp/ showed that only 5 megabyte were used by files. /tmp has it’s own partition and uses the XFS filesystem. On askubuntu.com and serverfault.com I found some promising problem descriptions and possible solutions, but none of them fit for me. Finally xfs_repair solved the problem. For this you need to unmount /tmp, so I did this:

  • Edit /etc/fstab so that the tmp-partition will not be mounted on next boot (put „#“ at the beginning of the line that mounts /tmp)
  • Reboot, /tmp is now part of the root filesystem /.
  • Call sudo xfs_repair /dev/sdxY (replace sdxY by whatever your tmp-partition is).
  • Mount the partition somewhere temporarily (for example /mnt/tmp) and check with df -h if this solved the problem.
  • Edit /etc/fstab again to reactivate the tmp-partition. Then reboot and check again.

Funksteckdosen von REV Ritter über 433MHz schalten

Heute habe ich versucht eine paar Funksteckdosen von REV Ritter mit einem 433MHz Sendermodul (FS1000A) und einem Banana Pi zu schalten. Mit einem Raspberry Pi sollte es genauso funktionieren. Die Steckdosen mit der Artikelnummer 00834514 gibt es für ca. 15 Euro in Baumärkten oder bei Amazon (3 Steckdosen und eine Fernbedienung). Im Gegensatz zu meinen anderen Funksteckdosen von Mumbi (m-AFS102) kann man bei den REV-Steckdosen die Funk-Kennung nicht selbst einstellen. Man muss also zuerst mal ermitteln, welche Daten die Fernbedienung sendet. Dazu habe ich das Empfängermodul (XY-MK-5V) angeschlossen (VCC auf Pin 1, GND auf Pin 6, DATA auf Pin 12), die Software pilight nach dieser Anleitung installiert und den Service mit service pilight start gestartet. Dann einfach pilight-receive aufrufen, auf eine Taste der Fernbedienung drücken und die Ausgaben prüfen. Bei mir sah das ungefähr so aus:


{
"message": {
"id": 12345678,
"unit": 15,
"state": "on"
},
"origin": "receiver",
"protocol": "arctech_switch",
"uuid": "0000-01-23-45-1234ab",
"repeats": 2
}

Der gleiche Message-Block wurde mehrmals wiederholt, abwechselnd mit den Protokollen arctech_switch und arctech_contact. Zum Senden hab ich das Empfänger-Modul entfernt und das Sender-Modul angeschlossen (VCC auf Pin 1, GND auf Pin 6, DATA auf Pin 11). Jetzt musste ich nur noch das passende Protokoll finden, denn pilight-send hat kein offensichtlich passendes Protokoll angeboten. Funktioniert hat es dann mit dem Protokoll kaku_screen. Mit folgendem Befehl konnte ich dann die Steckdosen schalten:


# An
pilight-send -p kaku_screen -u 15 -i 12345678 -t
# Aus
pilight-send -p kaku_screen -u 15 -i 12345678 -f

Dateitransfer mit rsync: Eigentümer, Gruppen und Rechte behalten ohne root Login

Wenn man Verzeichnisse und Dateien von einem Linux Server auf einen anderen übertragen will, werden am Zielsystem Eigentümer und Gruppe der Dateien geändert und Zeitstempel neu gesetzt. Dadurch passen die Berechtigungen auf diese Dateien und Verzeichnisse eventuell nicht mehr. Außerdem verliert man die Information wann die Dateien zuletzt geändert wurden. In vielen Fällen will man diese Eigenschaften (Owner, Group, Permissions, Timestamps) aber unverändert behalten. Das Problem dabei ist, dass man am Zielsystem root-Rechte braucht, um sämtliche Dateieigenschaften bei den kopierten Dateien zu übernehmen. Ein direkter Login per SSH mit dem Benutzer root ist aber aus Sicherheitsgründen normalerweise nicht erlaubt ("PermitRootLogin no" in /etc/ssh/sshd_config) und das ist auch gut so. Das sollte man auch auf keinen Fall ändern! Braucht man auch nicht, denn dafür hat man folgende Alternativen:

Im einfachsten Fall will man die Daten nur einmal kopieren. Dann kann man die Dateien auf dem Quell-System per tar in eine Datei packen, per scp kopieren und am Zielsystem wieder auspacken. Die Eigenschaften der Dateien bleiben dabei erhalten.

Wenn man Dateien und Verzeichnisse mehrmals abgleichen will, ist der Umweg über tar sehr umständlich. Außerdem müssen dabei immer alle Daten übertragen werden. Das Kopieren per rsync hat den Vorteil, dass nur bei der ersten Übertragung alles kopiert wird. Ab dann werden nur noch geänderte oder neue Dateien übertragen. Bei Bedarf können am Zielsystem auch Dateien gelöscht werden, die seit der letzten Übertragung am Quellsystem gelöscht wurden (Parameter --delete). Damit man die Dateieigenschaften auf dem Zielsystem übernehmen kann verwendet man rsync zusammen mit sudo. So kann man das unter Debian und Ubuntu einrichten, bei anderen Linux-Derivaten wird es genauso (oder zumindest so ähnlich) funktionieren:

Zuerst erlaubt man dem Benutzer, der zum Kopieren verwendet wird (hier: myuser), die Benutzung von rsync ohne die Eingabe eines Passworts. Dazu wird am Zielserver die Datei /etc/sudoers bearbeitet (mit dem Befehl visudo, diese Datei immer mit visudo bearbeiten!) und folgende Zeile eintragen:

myuser ALL=NOPASSWD:/usr/bin/rsync

Mehr muss man nicht einrichten. Rsync startet man am Quellsystem dann zum Beispiel so (hier wird der Inhalt von /var/www in das selbe Verzeichnis am Zielserver example.com kopiert):

rsync -av -e ssh --rsync-path="sudo rsync" /var/www/ myuser@example.com:/var/www/

  • -a: Archiv-Modus, bei dem die Eigenschaften erhalten bleiben (Details siehe ManPage).
  • -v: Verbose, d.h. rsync gibt aus, was gemacht wird.
  • -e ssh: Verwende SSH zur verschlüsselten Übertragung.
  • --rsync-path="sudo rsync": Verwendet am Zielsystem rsync zusammen mit sudo.
  • --delete: Löscht am Zielsystem die Daten, die es am Quellsystem nicht mehr gibt (nicht im Beispiel oben, aber bei mehrmaligem Abgleich unter Umständen sinnvoll).

Sowohl beim Kopieren eines tar-Files als auch bei der eleganten rsync-Lösung gilt: Übernommen werden Benutzer-IDs und Gruppen-IDs, nicht deren Namen. Eine Grundvoraussetzung ist also, dass die Benutzer und Gruppen auf beiden Systemen die gleichen Benutzer-IDs bzw. Gruppen-IDs haben. Sonst hat man am Zielsystem nicht die Datei-Eigentümer und Gruppen, die man haben wollte.

Eigene externe IP-Adresse speichern (Bash-Skript)

Wegen einem Problem mit meiner DSL-Verbindung wollte ich ein Protokoll über die Häufigkeit der Verbindungsabbrüche haben. Die Idee war, jede Änderung der IP-Adresse zu speichern. Mein DSL-Problem ist mittlerweile behoben, aber vielleicht kann das Skript ja sonst noch jemand brauchen.

Das ganze besteht aus zwei Teilen: Einmal checkip.sh, das die aktuelle IP ermittelt und ausgibt. Und recordip.sh, das die aktuelle IP mit der letzten IP vergleicht und bei einer Änderung einen Eintrag in eine Protokolldatei macht (Datum, Uhrzeit, IP)  und einen Text ausgibt.

checkip.sh: Zur Ermittlung der externen IP-Adresse kann man wget (oder curl) und den Dienst http://checkip.dyndns.org/ benutzen. Das hat allerdings den Nachteil, dass bei jedem Check eine Abfrage an den DynDNS-Server geschickt wird. Eleganter geht es, wenn man eine Fritz!Box hat, bei der UPNP aktiviert ist. Die Idee dazu hatte ich von http://www.gimme-th.at. Irgendwann hat das aber nicht mehr funktioniert und ich musst mir selbst etwas basteln. War aber nicht besonders schwierig, die Grund-Idee war vorhanden und wie die Abfrage geht stand im Wiki von UbuntuUsers.de. Hier ist das Skript, das seit einigen Jahren bei meiner Firtz-Box 7270 funktioniert (umbenennen in checkip.sh und IP-Adresse der Fritz-Box anpassen):

Skript zum Download: checkip.txt

recordip.sh: Zum Ermitteln der IP wird ./checkip.sh aufgerufen, es sollte deshalb im selben Verzeichnis wie recordip.sh liegen. Die Protokoll-Datei und die Datei zum Zwischenspeichern der aktuellen IP können bei Bedarf am Anfang des Skripts geändert werden.


#!/bin/bash
# file to save the last recorded ip
LASTIPFILE=/tmp/lastip
# file to save an ip-history
LOGFILE=/home/username/ip.log

# if lastipfile does not exist, create it
if [ ! -e $LASTIPFILE ]; then
echo "NoIpSavedYet" > $LASTIPFILE
fi

# get the current ip with a script from www.gimme-th.at
IP=`./checkip.sh`
# Get the last ip
LASTIP=`cat $LASTIPFILE`

if [ $IP != $LASTIP ]; then
# output message
echo "IP geaendert, neue IP ist $IP";
# append ip to logfile
echo `/bin/date +%Y%m%d_%H%M%S` $IP >> $LOGFILE
# remember current ip until next check
echo $IP > $LASTIPFILE
fi

Skript zum Download: recordip.sh

Wenn man automatisch einmal pro Minute prüfen und bei Änderungen benachrichtigt werden will, kann man das sehr schön als Cron-Job einrichten. Ein Text wird nur bei einer Änderung ausgegeben, d.h. Mails bekommt man auch nur, wenn sich die IP tatsächlich geändert hat.

Getestet unter Ubuntu Linux mit einer Fritz!Box 7270. Bei Fragen oder Verbesserungsvorschlägen einfach einen Kommentar schreiben. Danke!

Dovecot-Authentifizierung mit SSL

Diese kurze Anleitung beschreibt, wie man einen Dovecot IMAP-/POP3-Server so einrichtet, dass eine Anmeldung mit Klartext-Passwort nur noch über eine verschlüsselte SSL-Verbindung funktioniert. Ausprobiert habe ich das ganze zuhause auf meinem Server, der unter Ubuntu 8.0.4.1 x86 läuft und auf dem Dovecot bereits seit einigen Tagen problemlos funktioniert (Update: Bei einer Neu-Installation von Ubuntu 9.10 hat es auch geklappt). Die meisten Infos zu dieser Anleitung stammen aus dem Ubuntu-Wiki und dem Dovecot-Wiki.

1. Das Passwort verschlüsselt ablegen
Für die Anmeldung am Mailserver will ich nicht das Systempasswort des Users (aus /etc/shadow) verwenden, sondern ein eigenes. Das soll aber nicht im Klartext irgendwo rumliegen, sondern nur als SHA-Hash. Dabei hilft das Programm dovecotpw, dem als Parameter das gewünschte Hash-Verfahren übergeben wird. Hier ein Beispiel, wie es mit Salted SHA aussieht, man könnte aber genauso gut salted MD5 oder etwas anderes verwenden.

dovecotpw -s ssha -u <username>

Das Ergebnis verwendet man, um einen Eintrag in der Datei /etc/passwd.dovecot zu erzeugen. Jede Zeile der Datei beginnt mit dem Benutzernamen, gefolgt von einem Doppelpunkt. Danach kommt die Ausgabe von dovecotpw, also das Passwort Schema und der Hashwert des Passworts. Ein Beispiel:
username:{SSHA}bhLzZ105Lh+hShJ8UK3jD+nQekwD0okG

Man muss Dovecot noch mitteilen, wo die Passwort-Datei abgelegt ist, da diese nicht /etc/passwd.dovecot sein muss, sondern auch anderswo liegen kann. Dazu folgenden Eintrag in /etc/dovecot/dovecot.conf machen:
passdb passwd-file {
args = /etc/passwd.dovecot
}

2. Unverschlüsselte Plaintext-Authentifizierung abschalten
Wenn bisher die Anmeldung mit Plaintext-Passwörtern über unverschlüsselte Verbindungen zulässig war, dann sollte man dies jetzt in der Datei /etc/dovecot/dovecot.conf abschalten.
disable_plaintext_auth = yes

3. SSL einrichten
Nach dieser Beschreibung im Dovecot-Wiki kann man sehr schnell die Verwendung einer SSL-Verbindung einrichten. In Ubuntu 8.0.4.1. funktioniert das ohne irgendeine Änderung bereits nach der Installation. Bei mir trat nur das Problem auf, dass das verwendete Snakeoil-Zertifikat bereits abgelaufen war. Mit folgendem Befehl kann man sich sehr einfach ein neues Zertifikat selbst erstellen:
sudo make-ssl-cert generate-default-snakeoil --force-overwrite
Leider lässt sich dabei keine Gültigkeit einstellen und das erzeugte Zertifikat müsste bereits nach einem Monat erneuert werden. (Update zu Ubuntu 9.10: Mittlerweile wurde die Default-Gültigkeit auf 10 Jahre geändert, man kann also direkt bei 4. weitermachen.) Ändern kann man das ganze, indem man make-ssl-cert anpasst. Dabei handelt es sich um ein einfaches Skript, das unter /usr/sbin liegt. Mit einem beliebigen Editor öffnen (z.B.sudo vim /usr/sbin/make-ssl-cert und nach openssl suchen. In die folgende Zeile (bei mir Zeile 124) fügt man den Parameter -days ein, der die Gültigkeitsdauer angibt:
openssl req -config $TMPFILE -new -x509 -nodes \
Nach der Änderung:
openssl req -config $TMPFILE -new -days 365 -x509 -nodes \

Für die „Nicht-Snakeoil-Variante“ findet man den zu änderenden Openssl-Aufruf einige Zeilen darüber.

4. Dovecot neu starten und testen
Zum Schluss muss man nur noch den Server neu starten (sudo /etc/init.d/dovecot restart) und die Einstellungen des Mail-Clients anpassen. Im Thunderbird wäre das bei den Konto-Einstellungen zu finden:
-> Server-Einstellungen -> Sicherheit & Authentifizierung -> Verschlüsselte Verbindung verwenden -> SSL
Das sollte es dann gewesen sein.