blog.alexanderkoch.net Nerdy news from /home/alex

17Nov 110

Testing TRIM with LUKS on LVM

One can find many guides on the net on how to test TRIM using dd and hdparm, which all describe the same procedure:

  • create a random-filled file, sync it to disk
  • determine the LBAs the file resides in using hdparm --fibmap [file]
  • pick one sector, raw-read it with hdparm --read-sector [sector] [device]
  • delete the random file, sync again
  • verify TRIM was issued by reading the same block again, should return only zeroes

The problem with all these guides is that they don't say anything about the influence partitioning and other layers like LVM can have on the right LBA to use with hdparm --read-sector.
You must add any offsets resulting from either other partitions or payload-offsets from LVM, LUKS and thelike to the address you got from hdparm --fibmap!

I'll explain the concrete steps using my setup:

[alex@thor ~]$ fdisk -l /dev/sdd
 
Disk /dev/sdd: 128.0 GB, 128035676160 bytes
255 heads, 63 sectors/track, 15566 cylinders, total 250069680 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xddfc7af4
 
   Device Boot      Start         End      Blocks   Id  System
/dev/sdd1   *        2048     1050623      524288   83  Linux
/dev/sdd2         1050624   250069679   124509528   8e  Linux LVM

The PV our target LV resides on starts at sector 1050624, which is our first offset.

[alex@thor ~]$ dmsetup table
root-plain: 0 56619008 crypt aes-xts-plain [keyslot] 0 254:0 4096 1 allow_discards
m4vg0-root: 0 55050240 linear 8:50 2048
(...)

Here we can see that LVM has a payload offset of 2084 bytes and LUKS (dm-crypt) one of 4096 bytes (fits well for an SSD).

[alex@thor usr]$ hdparm --fibmap testfile
 
testfile:
 filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0     272600     272607          8

So finally we calculate the "real" address of our chosen sector (the first one) by 272600 + 1050624 + 2048 + 4096 = 1329368.

Happy TRIM-testing, and keep in mind the implications for crypto-recurity!

15Jul 110

DBus durchsuchen

Wer den DBus durchsuchen möchte, um schnell herauszufinden, welche Calls eine bestimmte Anwendung anbietet, dem könnte DBusExplorer sehr nützliche Dienste tun.

Mir hat das gerade eine Brücke zwischen xbindkeys und Exaile geliefert, um per Multimediatasten den Player zu steuern:

# ~/.xbindkeysrc
 
"dbus-send --type=method_call --dest=org.exaile.Exaile /org/exaile/Exaile org.exaile.Exaile.PlayPause"
  XF86AudioPlay
 
"dbus-send --type=method_call --dest=org.exaile.Exaile /org/exaile/Exaile org.exaile.Exaile.Next"
  XF86AudioNext
 
"dbus-send --type=method_call --dest=org.exaile.Exaile /org/exaile/Exaile org.exaile.Exaile.Prev"
  XF86AudioPrev
3Sep 100

Audigy 2 – Eine Ode an die Vergangenheit

... oder Früher war alles besser! Der letzte Jammerpost beschreibt den Ärger, den man heute immer noch mit dem Thema "Sound unter Linux" haben kann - zumindest bei neuer (und minderwertiger) Hardware. Völlig schmerzfrei und absolut out-of-the-box kann es dagegen bei älterer (bzw. hochwertigerer) Hardware laufen:

Beim Verfassen des vergangenen Posts habe ich mich immer wieder versucht, zu erinnern, wie das früher so mit ALSA & Co. lief; dabei viel mir meine gute, alte Creative Soundblaster Audigy 2 Platinum ein, die irgendwo im Keller in der Hardwarekiste vor sich hin gammelte. "Moment, die war doch hardwaremixing-fähig..." - kurz Google befragt und bestätigt.

Problem bei der Audigy (und Grund für das Triste Dasein in der Kiste) war, dass das zugehörige Output-Rack für die Front bei Einbau in einen 5,25"-Schacht aufgrund der herausstehenden Regler das Schließen meiner Gehäusetür verhindern würde. Ohne Rack hätte es jedoch keinen Kopfhörer- und Mikro-Ausgang vorne am Gehäuse gegeben. Zumindest nicht so ohne Weiteres, was ich damals noch nicht wusste...

Nach ein par Google-Orgien fand ich diverse HowTos (z.B. hier oder hier), wie man an einen internen, 10-poligen Anschluss auf der Karte ein AC'97- bzw. HD-Audio Frontpanel anschließen kann. Nun ist dieser Anschluss leider bei der Audigy 2 (ohne "ZS") leider nicht bestückt - also Arbeit für den Lötkolben. Mit ein paar Zentimetern altem Telefonkabel konnte ich die benötigten Pins (1, 2, 4, 6, 8) schließlich emulieren und mithilfe einer kurzerhand umfunktionierten USB-Buchse an mein Frontpanel anschließen. Hierbei noch ein Tip: Wer Pin 1 (HP-Masse) nicht festgelötet bekommt, kann sich die Masse auch einfach vom Slotblech holen, verursacht keine Störgeräusche.

Also dann im BIOS die onboard-Karte deaktiviert, System gebootet und noch flux das emu10k1-Modul gebacken - fertig. Sound läuft direkt über ALSA mit parallelem Zugriff, 5.1 mit 48000Hz, out-of-the-box. Kein Soundserver, keine /etc/asound.conf, keine ~/.asoundrc - so einfach und elegant kann Sound unter Linux auch sein, die richtige Karte vorausgesetzt. Leider haben selbst die etwas besseren (=teureren) aktuellen Karten kaum noch Hardwaremixer.

Upmixing für Stereo-Signale erreiche ich mit den folgenden paar Zeilen:

# /etc/asound.conf
 
pcm.ch51dup {
    type plug
    slave.pcm "surround51"
    slave.channels 6
    route_policy duplicate
}

Früher waren also zumindest die Soundkarten besser ;)

28Mrz 100

Dynamic DNS-Caching with PDNSd and DHCP

(I write this in English because I was asked to do so by some people on the Arch forums. Anyway, I think this should be no problem as if you hack on configs you normally understand enough to get this done as well.)

I've been using pdnsd for DNS caching for quite a while now and I can feel the speed up while browsing the web (at least I can go on believing so ;) ) or checking for updates in the AUR.
The problem with pdnsd in conjunction with mobile devices (like the netbook I'm typing this on) is that in the basic setup, it only uses static DNS servers, described in /etc/pdnsd.conf. So if you happen to get behind some firewall that doesn't permit DNS queries to other nameservers than the ones advertised by DHCP, you have to change your setup manually - and switch back when you're out.
It would be great if pdnsd took the DNS your machine got from DHCP and use it as primary source for cache-misses. This also uses the eventually existing DNS infrastructure and local caches, instead of bypassing them. Here's how I implemented that, using pdnsd and dhcpcd:

  1. Setup pdnsd as described in the Arch Wiki article, but do not create a /etc/resolv.conf.head. Create a primary DNS source entry, mine looks like this:
    server {
    	label="maindns";
    	ip=8.8.8.8, 8.8.8.4;  # I use Google dns as fallback
    	proxy_only=on;        # Do not query any other name servers
    	timeout=4;            # Server timeout
    	uptest=none;          # No uptest
    	purge_cache=off;      # Keep stale cache entries in case the ISP's
    			      # DNS servers go offline.
    }
  2. In /etc/resolv.conf, the only nameserver should be your local machine:
    # /etc/resolv.conf
    nameserver 127.0.0.1
  3. In /etc/dhcpcd.conf, disable the resolv.conf-hook to prevent dhcpcd from changing the resolving scheme:
    [...]
    nohook resolv.conf
  4. In /usr/lib/dhcpcd/dhcpcd-hooks, we create a hook script (e.g. 21-pdnsd.conf) that uses pdnsd-ctl to override the nameserver IPs defined in /etc/pdnsd.conf with the ones received by DHCP:
    # Set the IP of "maindns" entry for pdnsd
     
    case "$reason" in
    	BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT|STATIC)
    		SRVS=""
    		for X in $new_domain_name_servers; do
    			if [ -z "$SRVS" ]; then
    				SRVS="$X"
    			else
    				SRVS="${SRVS},$X"
    			fi
    		done
    		pdnsd-ctl server 0 up $SRVS
    		;;
    	PREINIT|EXPIRE|FAIL|IPV4LL|NAK|NOCARRIER|RELEASE|STOP)
    		# reset to values in /etc/pdnsd.conf
    		pdnsd-ctl config
    		;;
    esac

That's it, no big deal ;)
If you find any problems or disadvantages with this setup, feel free to post them in the comments!

15Feb 100

Automatische Vhosts mit Lighttpd

Mein bereits erwähntes lighttpd-vhost-script hat ein Update erfahren und unterstützt jetzt Subdomains und Vhost- sowie Subdomain-spezifische configs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/bin/bash
 
VHOST_ROOT="/var/www"
VHOST_DEF="default"
VHOST_CONF="vhost.conf"
SBD_ROOT="subdomains"
DOC_ROOT="htdocs"
 
for VHOST in $(find $VHOST_ROOT -mindepth 1 -maxdepth 1 -type d -exec basename {} \;); do
 
	# skip default vhost
	if [ "$VHOST_DEF" == "$VHOST" ]; then
        continue
    fi
 
	echo "\$HTTP[\"host\"] =~ \"^(www\.|)$VHOST\" {"
	echo "  server.document-root = \"$VHOST_ROOT/$VHOST/$DOC_ROOT\"" 
	echo "  accesslog.filename = \"/var/log/lighttpd/$VHOST.access.log\""
	if [ -e "$VHOST_ROOT/$VHOST/$VHOST_CONF" ]; then
		# include vhost config
		cat "$VHOST_ROOT/$VHOST/$VHOST_CONF"
	fi
	echo "}"
	echo ""
 
	# subdomains
	if [ -d "$VHOST_ROOT/$VHOST/$SBD_ROOT" ]; then
		for SBD in $(find $VHOST_ROOT/$VHOST/$SBD_ROOT -mindepth 1 -maxdepth 1 -type d -exec basename {} \;); do
			echo "\$HTTP[\"host\"] =~ \"^$SBD.$VHOST\" {"
			echo "  server.document-root = \"$VHOST_ROOT/$VHOST/$SBD_ROOT/$SBD/$DOC_ROOT\""
			echo "  accesslog.filename = \"/var/log/lighttpd/$VHOST.access.log\""
			if [ -e "$VHOST_ROOT/$VHOST/$SBD_ROOT/$SBD/$VHOST_CONF" ]; then
				# include subdomain's custom config
				cat "$VHOST_ROOT/$VHOST/$SBD_ROOT/$SBD/$VHOST_CONF"
			fi
			echo "}"
		done
		echo ""
	fi
done
15Feb 100

Server setup – Teil 3: Mailserver

Jeder, der einfach nur einen kleinen Mailserver mit Greylisting und IMAP-Daemon aufsetzen will, und sich damit an Exim4/Courier wagt, wird verstehen, warum man zum Thema Mailserver so gut wie kein aktuelles Material im Netz findet: hat man die configs endlich so, wie man sie haben will, will man um Gottes Willen nicht nochmal damit in Kontakt kommen ;)

Als endgültige MTA/MDA Lösung bin ich nun bei Postfix/Dovecot geblieben (danke nochmal für den Tipp, Mario :) ). Warum? Weil es so verdammt viel einfacher zu konfigurieren ist, und meine vergleichsweise primitiven Anforderungen an einen MTA trotzdem voll erfüllt. Will man einen skalierbaren Mailserver mit Loadbalancing und diversen Features für größere Setups, ist man sicher mit Exim4 besser beraten.

Da das Setup stark von der Umgebung abhängt, möchte ich hier einfach auf die beiden Quellen verweisen, die ich besonders hilfreich fand:

Interessant fand ich auch den Hinweis, auf den ich bei meiner Recherche zur Exim4-Einrichtung gestoßen bin, betreffend SPOP3 und SIMAP, die SSL-Varianten der beiden Dienste: gemäß RFC 2595 soll die Verwendung separater Ports für die SSL-gesicherten Varianten von POP3 und IMAP nur eine Übergangslösung gewesen sein, weil damals das Kommando STARTTLS noch von kaum einem Client unterstützt wurde. Leider hatte ich noch keine Zeit, das Dokument zu lesen.

2Feb 100

Server Setup – Teil 2: Webserver

Disclaimer: Okay, das könnte jetzt evtl. Richtung Jammerpost gehen, aber auf der anderen Seite könnte es jemandem die vier Stunden rumconfen und Wikis abgrasen ersparen, die jetzt hinter mir liegen.

lighttpdDiesmal war der Webserver an der Reihe. Für meine paar kleinen Seiten war ich auf der Suche nach einem leichtgewichtigen Webserver ohne viel Schnickschnack (load-balancing, usw.) und lighttpd schien mir da ideal.

Aufgesetzt ist das Ding schnell, das Wiki gibt einem mit dem 10-Minutes-Setup eine wunderbare Starthilfe und bietet zu jedem Modul eine eigene Wiki-Seite.
Einzig bei der Konfiguration von etwaigen virtuellen Hosts muss Hand angelegt werden. Es gibt zwar mit mod_simple_vhost ein Modul für eine automatische Konfiguration anhand der Verzeichnishierarchie, hat aber einen kleinen Schönheitsfehler: www.domain.tld und domain.tld sind zwei verschiedene Hosts und würden in verschiedene Vhosts abgebildet werden.

Nun ist dieses Problem alles andere als neu und es existieren diverse Lösungen, beispielsweise:

  • Symlinks erstellen - bläht den Vhost-Root auf, unschön
  • URL-Redirection - sauberer, zwingt aber jeden Aufruf in ein fixes Format

Nachdem ich mal einen Blick in die Sourcen riskiert habe, ist mir aufgefallen, dass die simple_vhost-Methode auch nicht performanter umgesetzt wird als einfache Conditionals, daher erstelle ich einfach für jeden Vhost einen Block der Form:

$HTTP["host"] =~ "^(www\.|)test.tld" {
    server.document-root = "/var/www/test.tld/htdocs"
    server.errorlog = "/var/log/lighttpd/test.tld.error.log"
    accesslog.filename = "/var/log/lighttpd/test.tld.access.log"
}

Der Regex matcht sowohl auf "test.tld" als auch "www.test.tld". Diese Methode hätte jetzt allerdings den Nachteil, alle Vhosts manuell eintragen zu müssen, also simuliere ich die Automatik von mod_simple_vhost mit einem kleinen Bashscript, welches ich in einer sonst leeren config mit include_shell "/etc/lighttpd/vhost-autoconf.sh" einfach direkt einbinde:

#!/bin/bash
 
VHOST_ROOT="/var/www"
VHOST_DEF="default"
DOC_ROOT="htdocs"
 
# we exclude the default vhost
 
for VHOST in $(find $VHOST_ROOT -mindepth 1 -maxdepth 1 -type d -exec basename {} \;); do
    if [ "$VHOST_DEF" != "$VHOST" ]; then
        echo "\$HTTP[\"host\"] =~ \"^(www\.|)$VHOST\" {"
	echo "  server.document-root = \"$VHOST_ROOT/$VHOST/$DOC_ROOT\""
        echo "  server.errorlog = \"/var/log/lighttpd/$VHOST.error.log\""
        echo "  accesslog.filename = \"/var/log/lighttpd/$VHOST.access.log\""
        if [ -e "$VHOST_ROOT/$VHOST/server.conf" ]; then
            cat "$VHOST_ROOT/$VHOST/server.conf"
        fi
        echo "}"
    fi
done

Das if-statement bindet existierende server.conf für jeden Vhost ein, sodass hier noch separate Einstellungen getätigt und automatisch eingefügt werden können.

19Feb 094

Qmail-SMTP über xinetd mit SSL

Kürzlich verweigerte der Qmail-SMTPd auf dem von mir betreuten Mailserver den Dienst, was ich als Anlass nahm, gleich von inetd auf xinetd umzusteigen. Das ermöglichte dann den Einsatz von Spamdyke als ultimatives Bollwerk gegen unerwünsche Mails.

Extrem hilfreich dabei waren dieses HowTo und die Stunnel-Homepage. TLS lief out-of-the-box; die SSL-Realisierung war etwas tricky, daher hier meine funktionierende config für xinetd mit stunnel für SSL und eingebundenem Spamdyke:

service smtps
{
	socket_type	= stream
	protocol	= tcp
	wait		= no
	disable		= no
	user		= root
	instances	= 100
	env		= SMTPAUTH=1 END=1
	server          = /usr/bin/stunnel
	server_args     = -D 3 -o /var/log/stunnel.log -T -p /var/qmail/control/servercert.pem -l /var/qmail/bin/tcp-env -- smtps -Rt0 /var/qmail/bin/relaylock /usr/local/bin/spamdyke -f /etc/spamdyke.conf /var/qmail/bin/qmail-smtpd /var/qmail/bin/smtp_auth /var/qmail/bin/true /var/qmail/bin/cmd5checkpw /var/qmail/bin/true
}