Posts Tagged ‘Security’

verschlüsselte Volumes bequem mounten

Ich habe mein home verschlüsselt. Dieses wird automatisch, beim anmelden gemountet. Da ich in mein home noch ein paar andere verschlüsselte Dateisysteme einhänge funktionieren die Standard-Mittel, wie /etc/crypttab nicht. Dabei ergibt sich das folgende Problem: Die Volumes werden beim booten eingehangen und zu diesen Zeitpunkt existiert mein home noch nicht.

Da ich faul bin möchte ich auch möglichst wenig Passwörter eingeben, weiterhin soll meine Freundin auch den Rechner anmachen können und nicht an meinen Passwort scheitern. Deswegen wird nur mein home via Passwort entschlüsselt, für die anderen Dateisysteme kommen key-files zum Einsatz. Diese liegen in meinen verschlüsselten home.

Da ich mir selbst nicht vertraue, möchte ich den sudo-Mechanismus oder suid-Bits nicht benutzten. Deswegen habe ich mir die beiden Skripte cryptdisks_start und cryptdisks_stop genauer angesehen. In einen ersten Schritt habe ich mir eine /etc/user_crypttab erzeugt.

root@walhalla ~ # cat /etc/user_crypttab
# definition             volume                        key                                   options      mountpoint                mountoptions
data--group-video_crypt  /dev/mapper/data--group-video /home/rennecke/key-files/video-key    luks         /home/rennecke/Videos     noatime

Die ersten vier Parameter entsprechen denen, der crypttab, mountpoint und mountoptions sind entsprechen den gleichnamigen Optionen von mount.

Mein user_cryptdisks_start-Skript sieht wie folgt aus:

#!/bin/sh
 
# user_cryptdisks_start - wrapper around cryptsetup which parses
# /etc/user_crypttab, just like mount parses /etc/fstab.
 
# Initial code stolen from cryptdisks_start by Jon Dowland <jon@alcopop.org>
# Copyright (C) 2011 by Michael Rennecke <michael_rennecke@gmx.net>
# License: GNU General Public License, v2 or any later
# (http://www.gnu.org/copyleft/gpl.html)
 
CRYPTTAB="/etc/user_crypttab"
 
set -e
 
if [ $# -lt 1 ]; then
	echo "usage: $0 <name>" >&2
	echo >&2
	echo "reads $CRYPTTAB and starts the mapping corresponding to <name>" >&2
	exit 1
fi
 
. /lib/cryptsetup/cryptdisks.functions
 
INITSTATE="manual"
DEFAULT_LOUD="yes"
 
if [ -x "/usr/bin/id" ] && [ "$(/usr/bin/id -u)"  != "0" ]; then
	log_warning_msg "$0 needs root privileges"
	exit 1
fi
 
log_action_begin_msg "Starting crypto disk"
mount_fs
 
 
count=0
tablen="$(egrep -vc "^[[:space:]]*(#|$)" "$CRYPTTAB")"
egrep -v "^[[:space:]]*(#|$)" "$CRYPTTAB" | while read dst src key opts mnt mopts; do
	count=$(( $count + 1 ))
	echo ""
	if [ "$1" = "$dst" ]; then
		ret=0
		handle_crypttab_line_start "$dst" "$src" "$key" "$opts" <&3 || ret=$?
		echo ""
		fsck -pv /dev/mapper/$dst
		echo ""
		mount -o $mopts /dev/mapper/$dst $mnt
	elif [ $count -ge $tablen ]; then
		ret=1
		device_msg "$1" "failed, not found in user_crypttab"
	else
		continue
	fi
	umount_fs
	log_action_end_msg $ret
	exit $ret
done 3<&1

Zum Schluss noch mein user_cryptdisks_stop-Skript:

#!/bin/sh
 
# user_cryptdisks_stop - wrapper around cryptsetup which parses
# /etc/user_crypttab, just like mount parses /etc/fstab.
 
# Initial code stolen from cryptdisks_stop by Jonas Meurer <jonas@freesources.org>
# Copyright (C) 2011 by Michael Rennecke <michael_rennecke@gmx.net>
# License: GNU General Public License, v2 or any later
# (http://www.gnu.org/copyleft/gpl.html)
 
CRYPTTAB=/etc/user_crypttab
 
set -e
 
if [ $# -lt 1 ]; then
	echo "usage: $0 <name>" >&2
	echo >&2
	echo "reads $CRYPTTAB and stops the mapping corresponding to <name>" >&2
	exit 1
fi
 
. /lib/cryptsetup/cryptdisks.functions
 
INITSTATE="manual"
DEFAULT_LOUD="yes"
 
if [ -x "/usr/bin/id" ] && [ "$(/usr/bin/id -u)"  != "0" ]; then
	log_warning_msg "$0 needs root privileges"
	exit 1
fi
 
log_action_begin_msg "Stopping crypto disk"
echo ""
 
count=0
tablen="$(egrep -vc "^[[:space:]]*(#|$)" "$CRYPTTAB")"
egrep -v "^[[:space:]]*(#|$)" "$CRYPTTAB" | while read dst src key opts mnt mopts; do
	count=$(( $count + 1 ))
	if [ "$1" = "$dst" ]; then
		umount $mnt
 
		ret=0
		handle_crypttab_line_stop "$dst" "$src" "$key" "$opts" <&3 || ret=$?
	elif [ $count -ge $tablen ]; then
		ret=1
		device_msg "$1" "failed, not found in user_crypttab"
	else
		continue
	fi
	log_action_end_msg $ret
	exit $ret
done 3<&

Die beiden Skripte kann nun root ausführen, um Dateisysteme einzuhängen. Bei jeden einhängen wird geschaut, ob ein fsck nötig ist. Mein Dank gilt meet-unix, er hat stand mit mit Rat zu Seite, da ich noch etwas Solaris-geschädigt bin. Anmerkungen, bitte als Kommentar hinterlassen.

“Sichere” Captchas programmieren

Man möchte manchmal Teile seiner Seite mittels Captchas schützen. Es gibt zahlreiche fertige Varianten, auch für wordpress. Diese haben fast immer den Nachteil, dass sie JavaScript, Flash, oder Sessions benutzen. Persönlich habe ich eine Abneigung gegen JavaScript und Flash. Sessions lassen sich nicht immer nachträglich nutzen und man erzeugt serverseitig etwas Last. Fakt ist, dass ich keine Sessions mag! Das schlimmste an fertigen Captcha-Lösungen ist der zum Teil invalide html-Code. Ich möchte validen xhtml 1.0 strict-Code haben und das Captcha sollte in mein Design passen. Wenn man die ganzen Anforderungen erfüllt haben möchte, so muss man wohl oder übel sein Captcha selbst programmieren.

Wie komme ich zum sicheren Captcha

Wenn ich auf Sessions verzichten möchte, so muss ich die Lösung des Captcha mit auf die Seite schreiben. Das kann man in einen nicht sichtbaren Feld machen. Damit man dieses Feld nicht so einfach auslesen kann, schreibt man einen Hash hinein bzw. man verschlüsselt den Inhalt.

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
define(KEY, "Ich bin ein Key");
define(IV, "KlyV6gxG3MOPzlfuj8azF6sKKTnsdsiN58i0zjHA0EU=");
 
function Crypt($plaintext){
    $td = mcrypt_module_open('rijndael-256', '', 'ofb', '');
 
    $iv = base64_decode(IV);
    $ks = mcrypt_enc_get_key_size($td);
 
     /* Create key */
    $key = substr(md5(KEY), 0, $ks);
 
    /* Intialize encryption */
    mcrypt_generic_init($td, $key, $iv);
 
    /* Encrypt data */
    $encrypted = mcrypt_generic($td, $plaintext);
 
    /* Terminate decryption handle and close module */
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
 
    return base64_encode($encrypted);
}
 
function Decrypt($chiffre){
    $td = mcrypt_module_open('rijndael-256', '', 'ofb', '');
 
    $iv = base64_decode(IV);
    $ks = mcrypt_enc_get_key_size($td);
 
     /* Create key */
    $key = substr(md5(KEY), 0, $ks);
 
    $chiffre = base64_decode($chiffre);
    mcrypt_generic_init($td, $key, $iv);
    $plaintext = mdecrypt_generic($td, $chiffre);
 
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
 
    return $plaintext;
}
 
function draw_captcha_form(){
    .....
    $time = time() + 60*30;
    $captchaSolution = "Test"
    echo "\t\n\tBitte Captcha lösen<br/>\n";
    // erzeuge ein Captcha
    echo "\t\n";
    echo "\t" . '
<input name="captvalue" id="captvalue" value="" size="40" tabindex="4" type="text"/>' . "\n";
    echo "\t"    . '
<input name="captcha" value="'. Crypt($time . "~" . $captchaSolution . "~" . $REMOTE_ADDR) . '" type="hidden"/>' . "\n";
}
 
function check_post($) {
    ....
    $captcha = $_POST['captvalue'];
    list($timeOld, $secret, $addr) = explode('~',Decrypt($_POST['captcha']));
    ....
    if($timeOld <= time()){
            echo "Deine Zeit ist abgelaufen";
            return;
    }
    if($addr != $REMOTE_ADDR){
            echo "Falsche IP";
            return;
    }
    if($secret != $captcha){
            echo "Falsches Captcha";
            return;
    }
    .....
}

Mit diesen Ideen kann man sich nun sein eigenes Captcha zusammen bauen. Ich generiere z.B. Matheaufgaben.