HTTP-BASIC-AUTH nach Umleitung auf HTTPS

Eine HTTP-BASIC-AUTH-Authentifizierung sollte man nicht unverschlüsselt durchs Netz jagen. Doof ist es, wenn die Umleitung per .htaccess erst nach der Authentifizierung greift, da die erste Anfrage über HTTP läuft, von der Authentifizierung abgefangen wird und erst danach umgeleitet wird.
Eine Möglichkeit dies zu umgehen sieht so aus:

SetEnvIf %{SERVER_PORT} ^80$ IS_NON_SSL

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

AuthUserFile /pfad/zur/.htpasswd
AuthName "HTTP-BASIC-AUTH über TLS"
AuthType Basic
require valid-user
Allow from env=IS_NON_SSL

via http://stackoverflow.com/questions/10267102/apache-htaccess-redirect-to-https-before-asking-for-user-authentication

Note to self: selbstsignierte Zertifikate mit OpenSSL

Selbstsignierte Zertifikate mit eigener CA über OpenSSL:

Erstellen des CA-Keys:
openssl genrsa -out ca.key 4096 
openssl req -new -x509 -days 1825 -key ca.key -out ca.crt 

Erstellen und signieren eines CSR:
openssl genrsa -out server.key 4096 
openssl req -new -key server.key -out server.csr 
openssl x509 -req -days 1824 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

Let’s encrypt!

Seit einiger Zeit bietet “Let’s encrypt” seine SSL-Zertifikate in einer geschlossenen Beta-Phase an.
Die CA möchte schnell und einfach Zertifikate für jeden anbieten. Dies geschieht über ein Tool, welches über die Shell ausgeführt wird. Es kümmert sich um die Erstellung des Private-Keys, des CSR, die Validierung der Domain und die Erzeugung des Zertifikates.
“Let’s encrypt” wird direkt aus den GIT-Repos heruntergeladen und ausgeführt. Dabei werden z.T. noch benötigte Pakete nachinstalliert.
Zertifikate werden anschließend über
systemctl stop httpd
cd letsencrypt
./letsencrypt-auto --agree-dev-preview --rsa-key-size 4096 --server https://acme-v01.api.letsencrypt
.org/directory certonly
systemctl start httpd

angefragt. Dabei wird über Port 80 des Servers kommuniziert, was ich etwas unschön finde, da man vorher einen laufenden Webserver beenden muss.
Die Zertifikate sind nur 90 Tage lang gültig, danach müssen sie erneuert werden. Dies kann automatisch über einen Cronjob geschehen, ein weiteres Eingreifen durch den Benutzer ist nicht mehr nötig.
./letsencrypt-auto --agree-dev-preview --renew-by-default --server https://acme-
v01.api.letsencrypt.org/directory -d johnassel.de -d www.johnassel.de certonly
erneuert schon vorhandene Zertifikate. Auch hier muss ein laufender Webserver für den Vorgang beendet werden.
Leider kann man “Let’s encrypt” nicht schon vorhandene CSRs signieren lassen. Diese Schritte übernimmt die Software. Mir wäre es lieber, wenn ich Key und CSR selbst generieren könnte, einen Einfluss kann man aktuell auf die Länge des Schlüssels wohl noch nicht haben.
Auch bietet “Let’s encrypt” die Möglichkeit, direkt die Konfiguration von Apache etc für die generierten Schlüssel und Zertifikate anzupassen. Irgendwie habe ich dabei Bauchschmerzen, wenn eine Software versucht meine Konfiguration anzupassen.
Mit entsprechenden Scripten sollte es aber kein Problem sein, den Vorgang der Zertifikaterstellung so zu scripten, dass “Let’s encrypt” nicht noch in der Konfiguration rumwurschteln muss.

Mit Netz und doppeltem Boden – Backup für den vServer

Wer einen eigenen Server betreibt sollte auf jeden Fall eine Backup-Strategie fahren, um im Falle eines Crashes/Angriffes keine wichtigen Daten zu verlieren. Bis jetzt bestand meine Lösung aus einem NFS-Share, welches mein Hoster zur Verfügung stellte, und einem Scrip, welches den kompletten vServer in ein TAR-Archiv schob, komprimierte und verschlüsselte:


#!/bin/sh
mount $ADRESSEDESNFSSHARES /storage/ -t nfs
systemctl stop mariadb
key=`openssl rand 128 -hex`
echo $key > key
path=/storage/`date +"%d-%m-%y"`
mkdir $path
openssl rsautl -encrypt -inkey public.key -pubin -in key -out $path/key.`date +"%d-%m-%y"`.enc
rm key
tar -cO --exclude='/proc' --exclude='/sys' --exclude='/backup' --exclude='/storage' --exclude='buildroot.img' /* | pbzip2 -c | ccrypt -K $key > $path/backup.`date +"%d-%m-%y"`.tar.bz2.cpt
systemctl start mariadb
umount /storage

Was tut dieses Script? Es generiert einen 128 Bit langen Verschlüsselungsschlüssel, welcher mit einem öffentlichen Schlüssel verschlüsselt wird. Der Verschlüsselungsschlüssel wird zur (symmetrischen) Verschlüsselung des komprimierten TAR-Archives genutzt. Beides wird anschließend auf dem NFS-Share gespeichert. Damit das TAR-Archiv nicht zwischengespeichert werden muss, werden alle Vorgänge (Packen, Komprimieren und Verschlüsseln) durch Pipes miteinander verbunden. Der große Nachteil dieser Lösung ist, dass es sehr zeitaufwändig ist, eine einzelne Datei wiederherzustellen. Zuerst muss das Archiv entschlüsselt, dekomprimiert und entpackt werden, was entsprechend dauern kann.
Auf der Suche nach einer besseren Lösung bin ich über duplicity gestolpert. Das Tool bietet die Möglichkeit, verschlüsselte, inkrementelle und einfach wieder herzustellende Sicherungen zu erstellen.


#!/bin/sh
mount $ADRESSEDESNFSSHARES /storage/ -t nfs
#systemctl stop mariadb
PASSPHRASE='GPGSCHLÜSSELHIERREIN'
SIGN_PASSPHRASE='GPGSCHLÜSSELHIERREIN'
export PASSPHRASE
export SIGN_PASSPHRASE
duplicity --exclude /var/tmp --exclude /tmp --exclude /proc --exclude /sys --encrypt-key 987AAD58 --sign-key 987AAD58 -v 8 / file:///storage > /var/log/backup/backup.log
duplicity remove-older-than 3W file:///storage > /var/log/backup/backup_cleanup.log
#systemctl start mariadbi
unset PASSPHRASE
unset SIGN_PASSPHRASE
umount /storage

Die Handhabung ist relativ einfach. Zunächst erstellt man einen GPG-Schlüssel. Anschließend läuft bei mir obiges Script, gesteuert per Cronjob, alle zwei Stunden durch. Über duplicity remove-older-than 3W werden alle Sicherungen, welche älter als 3Wochen sind, gelöscht. Die Wiederherstellung von Dateien erfolgt über duplicity –file-to-restore. Im Moment macht die Lösung einen ganz soliden Eindruck. Hoffentlich tut sie das im richtigen Ernstfall weiterhin.
Ach ja:
Auf jeden Fall die GPG-Schlüssel und den zugehörigen Key extra sichern! Ohne ist das Backup nicht mehr zu entschlüsseln!

Androids Vollverschlüsselung und ein anderes Passwort

Wer unter Android die Vollverschlüsselung aktiviert, muss ein Passwort oder eine PIN festlegen, mit welchem das Gerät wieder entschlüsselt werden kann. Dummerweise wird dieser Schlüssel auch für die Sperrung des Gerätes verwendet, wodurch fast nur schwache Passwörter zum Einsatz kommen. Wer hat schon Lust jedes mal beim Einschalten ein komplexes Kennwort einzugeben? Je kürzer und weniger komplex das Kennwort ist, desto schneller und einfacher lässt sich die Vollverschlüsselung angreifen. Daher liegt es nahe, für beide Szenarien, Verschlüsselung und Displaysperre, verschiedene Kennwörter mit unterschiedlicher Komplexität festzulegen. Leider bietet dies Android nicht von Haus aus an. Wer sein Telefon gerootet hat, kann dies über Umwege trotzdem erreichen. Über die Konsole kann das Passwort der Verschlüsselung mit

geändert werden. Man muss nur höllisch aufpassen, dass man das neue Passwort korrekt eingibt - eine zweite Abfrage, welche Tippfehler abfängt, gibt es nicht!

Ich grabe einen Tunnel

Befindet man sich in unsicheren Netzwerken (öffentliche Netzwerke, z.B. an einer Uni, öffentliche WLANs…) so muss man ziemlich aufpassen, da man nie wirklich weiß, ob sich nicht doch jemand mit bösen Absichten im Netz befindet. So ein Man-in-the-middle Angriff mit ARP-Spoofing ist mit den richtigen Tools schnell und unbemerkt durchgeführt. So kann man den Traffic von allen Rechnern im Netz scannen und interessantes wie Passwörter herausfiltern. Selbst SSL-Verbindungen sind angreifbar. Zwar gibt es deutliche Anzeichen für Angriffe, wie z.B. gemeldete, fehlerhafte Zertifikate durch den Browser o.ä., allerdings werden diese von den meisten Nutzern blind abgenickt. Ein schwerer Fehler, denn dann ist auch die eigentlich sichere SSL-Verbindung gekapert und kann mitgelesen werden. Oder die SSL-Verbindung wird auf dem Weg zum Zielrechner einfach komplett entfernt, die Warnung wegen eines falschen Zertifikats entfällt. Nur wer aufmerksam ist wird vielleicht merken, dass er die eigentlich per SSL geschützte Seite über eine normale HTTP-Verbindung aufruft.
Ein relativ wirksames Mittel gegen solche Manipulationen ist die Tunnelung des Traffics zu einem vertrauenswürdigen Netz. Dies kann beispielsweise ein Server im Internet oder gar das eigene Heimnetzwerk sein. Doch wie bekommt man seine Daten sicher aus dem unsicheren Netz heraus? Dafür bietet sich ein VPN-Tunnel an, welcher Datenverbindungen verschlüsseln und auch umleiten kann. Im Prinzip kann man sich ein VPN wie ein eigenes, kleines sicheres Netzwerk vorstellen, welches über andere, unsichere, Netzwerke aufgespannt ist. Gut, die Konstellation heißt vielleicht nicht umsonst Virtual Private Network ;-) Mitglieder in diesem virtuellen Netzwerk können sich untereinander sehen, als würden sie sich in einem physikalischen Netzwerk befinden.
Um ein VPN als sicheren Tunnel gegen dubiose Netzwerke zu nutzen, muss zunächst ein Endpunkt (also da, über welche Internetverbindung man schließlich ins Internet gehen will, z.B. im Heimnetzwerk) mit VPN-Server verfügbar sein. Hierfür bietet sich OpenVPN an, da es relativ einfach zu konfigurieren ist (als beispielsweise IPSec) und eine hohe Sicherheit bietet (von einem PPTP-VPN sieht man besser ab).
Ist OpenVPN installiert geht es an die Konfiguration. Dazu stellt man im Ordner /etc/openvpn/ (Unter Linux, unter Windows sind die Pfade anders) eine Konfigurationsdatei server.conf o.ä..
Diese sieht wie folgt aus:

mode server #Starte OpenVPN als Server
tls-server
script-security 2
server 192.168.23.0 255.255.255.0 #Definiert VPN-Adressbereich
persist-key
persist-tun
user openvpn
group openvpn
push "route 192.168.23.0 255.255.255.0" #Setzt Route zum angegeben Netz am Client
route 192.168.23.0 255.255.255.0
push "redirect gateway def1" #Leitet Traffic zum Server
client-to-client #Clients im VPN-Netzwerk können sich untereinander sehen
float
dev tun
proto udp
port 1194
keepalive 10 300
dh /etc/openvpn/easy-rsa/keys/dh1024.pem 
ca /etc/openvpn/easy-rsa/keys/ca.crt #Pfade zu den TLS-Zertifikaten
cert /etc/openvpn/easy-rsa/keys/server.crt
key /etc/openvpn/easy-rsa/keys/server.key
verb 4

Als nächstes müssen Zertifikate erzeugt werden – wie das geht steht hier: http://wiki.openvpn.eu/index.php/Erzeugen_einer_PKI_mit_EasyRSA

Damit der Server den ankommenden Traffic auch weiterleiten kann, muss noch ein bisschen am System geschraubt werden. Zunächst muss über eine iptables-Regel die Weiterleitung aus dem VPN-Netz an das Standardinterface erlaubt werden:
iptables -t nat -A POSTROUTING -s 192.168.23.0/24 -o eth0 -j MASQUERADE
Als nächstes wird die Weiterleitung von Datenpaketen mit echo "1" > /proc/sys/net/ipv4/ip_forward aktiviert. Diese Einstellunen sind allerdings nicht persistent, bei einem Neustart werden die Einträge wieder zurückgesetzt. Damit ein Reboot überlebt wird, muss net.ipv4.ip_forward=1 in der Datei /etc/sysctl.conf gesetzt sein. Alternativ können die Befehle auch in bei Systemstart z.b. über rc.local aktiviert werden (das ist aber irgendwie nicht so schön ;-)).
Wann nach oben verlinkter Anleitung alle Zertifikate generiert wurden, können diese an den Clients eingerichtet werden. Unter Linux geht dies bequem über den Netzwerkmanager, wie es unter Windows aussieht, keine Ahnung – das habe ich noch nicht probiert ;-)
Unter Android kann die Verbindung auch genutzt werden.
Dazu ist eine Konfigurationsdatei erforderlich, bei mir sieht sie wie folgt aus:

remote $Adresse-zum-VPN-Server 1194
client 
dev tun
proto udp
resolv-retry infinite 
nobind 
persist-key 
persist-tun 
float 
tls-client
ca $Zertifikat-der-CA
cert $Zertifikat
key $Key
Screenshot_2013-07-14-10-22-17
OpenVPN für Android, Routing

Diese wird in “OpenVPN für Android” importiert. Unter “Routing” muss dann noch das Häkchen zur Weiterleitung des Traffics über die VPN-Verbindung gesetzt werden (siehe Screenshot links).
Ob der Tunnel funktioniert kann über Webseiten wie http://browserspy.dk/ip.php überprüft werden. Dazu besucht man die Webseite einmal mit aktivierten und einmal mit deaktiviertem VPN. Sind beide IPs unterschiedlich, so funktioniert der Tunnel und der Traffic wird darüber weitergeleitet. Angriffe von den darunter liegenden Netzwerken sind somit nicht mehr möglich. Als nettes Nebenfeature ist dort auch nur noch die VPN-Verbindung sichtbar, alles andere ist unsichtbar.