WordPress: wichtige Sicherheitsmaßnahmen

Wer WordPress nutzt, wird sich schon Gedanken darüber gemacht haben, wie man die Sicherheit des Systems erhöhen kann. WordPress hat ein eigenes Security Team, welches die Software stetig auf Schwachstellen hin überprüft, daher gilt der Core auch als recht sicher. Allerdings gibt es auch hier ständig neue potentielle Sicherheitslücken, wie beispielsweise die neue Rest-API. Größter Angriffsvektor für Hacker bleiben jedoch nach wie vor schlampig programmierte WordPress-Plugins. Wer die Full Disclosure-Mailingliste abonniert hat, wird wissen, was ich meine: Dort tauchen ziemlich regelmäßig Schwachstellen in WordPress-Plugins auf. Wie kann man sich nun aber effektiv schützen, auch wenn man auf bestimmte Plugins angewiesen ist? Dieser Post soll eine lose Sammlung effizienter Maßnahmen sein, die die Sicherheit des Systems verbessern.

Keine Ausführungsrechte für das DocumentRoot

Letztens hat mir jemand eine WordPress-Instanz über ein anfälliges WordPress-Plugin gehackt, eine PHP-Shell hingelegt und darüber NodeJS heruntergeladen. Anschließend wurden verschiedene Hacks auf weitere Seiten aufgeführt. Wie kann man das verhindern? Unter Linux gibt es die Möglichkeit, beim Mounten von Filesystemen die Option noexec zu setzen. Diese gewirkt, dass grundsätzlich ausführbare Dateien (wie Binaries oder Skripte) nicht ausgeführt werden können. Die Option kann man einfach in der /etc/fstab mitgeben. Voraussetzung ist natürlich, dass das DocumentRoot auf einem eigenen Filesystem liegt, beispielsweise auf einem LVM-Volume. Ist das nicht so, kann man sich mit einem kleinen Trick behelfen. Im Beispiel ist /var/www/html das DocumentRoot:

$ mount -o bind /var/www/html /var/www/html
$ mount -o remount,noexec /var/www/html

Der erste Befehl mountet das Verzeichnis auf sich selbst als sogenannten Bind-Mount. Der zweite Befehl setzt für den Mount die Option noexec und verhindert damit das Ausführen von Dateien. Folgendermaßen kann das getestet werden:

$ cat <<EOF > /var/www/html/test.sh
> #!/bin/bash
> echo "Hello World"
> EOF
$ chmod 755 /var/www/html/test.sh
$ /var/www/html/test.sh
bash: /var/www/html/test.sh: Keine Berechtigung

weiterlesen

Shell: Abläufe mit xargs parallelisieren

Viele Unix-Tools, die es schon seit Urzeiten des Computers gibt, sind heutigen Softwareentwicklern und Sysadmins oft gar nicht mehr so geläufig. Daher möchte ich heute hier xargs beleuchten.

Grundlegende Benutzung

xargs ist laut Beschreibung ein Tool mit welchem man Befehlszeilen bauen und ausführen kann. Hier ein kleines Beispiel:

echo -e "1\n2\n3\n4" | xargs sleep

Der Echo-Befehl gibt die Zahlen 1 bis 4 in einer separaten Zeile aus. xargs nimmt den Inhalt aller Zeilen und hängt ihn an den Befehl sleep an. Schlussendlich wird also folgendes Ausgeführt:

sleep 1 2 3 4

Dieser Befehl wartet insgesamt 10 Sekunden und kehrt dann zurück. Will man nun aber für jeden übergebenen Parameter einen eigenen Sleep-Befehl ausführen, kann man die Anzahl der übergebenen Argumente pro Befehl beschränken:

echo -e "1\n2\n3\n4" | xargs -n 1 sleep

Jetzt werden vier sleep Prozesse gestartet, die sequentiell ablaufen. Das kann man auch gut sehen, wenn man misst, wie lange alles insgesamt dauert:

time echo -e "1\n2\n3\n4" | xargs -n 1 sleep
real 0m10.006s
user 0m0.000s
sys 0m0.004s

Parallelisierung

Und jetzt parallelisieren wir die Befehlsaufrufe. Das geht mit der Option -P. Damit können wir bestimmen, wie viele Prozesse gleichzeitig gestartet werden. Um das Beispiel einleuchtend zu machen, legen wir fest, dass 4 Prozesse gleichzeitig gestartet werden. Nach Adam Ries sollte die ganze Anweisung also nur insgesamt 4 Sekunden dauern:

time echo -e "1\n2\n3\n4" | xargs -n 1 -P 4 sleep
real 0m4.003s
user 0m0.000s
sys 0m0.000s

weiterlesen

WordPress: Automatischen Anker (ID-Attribut) für Überschriften einfügen

Auf Webseiten mit viel Inhalt, wie beispielsweise Wiki-Seiten oder Dokumentationen, gibt es die Möglichkeit Anker an bestimmten Stellen zu setzen, die man mit Links referenzieren kann. Das ist einerseits mit benamten Link-Tags möglich, andererseits mit IDs.

weiterlesen

mutt: gesamte Email in Datei speichern

Will man bestimmte Teile einer Mail in eine Datei speichern, kann man mittels v alle Parts anzeigen lassen und dann mit speichern. Dabei werden aber keine Header gespeichert.

Will man die komplette Mail inklusive Header und Anhängen als Datei speichern kann man nutzen (Pipe bzw. senkrechter Strich). Dieser bewirkt, dass die Mail über STDIN an einen Befehl geschickt wird – daher öffnet sich eine Kommandozeile. Dort gibt man dann einfach folgendes ein:

weiterlesen

Apache 2.4 mit PHP5 FPM via Sockets

Vorwort

Die meisten Anleitungen für einen Apache2 mit PHP lassen den User PHP als Apache-Modul installieren. Das hat der Vorteil, dass es extrem einfach zu installieren ist und keinen weiteren Konfigurationsaufwand braucht. Für Webserver, auf denen nur eine Site läuft, ist das oft auch ausreichend. Sobald aber mehr als eine Site betrieben wird, muss man sich darüber Gedanken machen, dass PHP immer unter dem Webserver-Nutzer (per default www-data) läuft. Eine Implikation daraus ist, dass wenn eine Site erfolgreich gehackt wird, der Angreifer auch Zugriff auf die andere Site hat, und auch auf alle Inhalte, die der Nutzer www-data lesen darf. Das ist sicherheitstechnisch bedenklich. Nun gibt es verschiedene Möglichkeiten dieses Problem zu lösen. Eines wäre PHP via SuExec und FastCGI anzusprechen. Das ist hier im Hetzner-Wiki erklärt. Eine andere Lösung ist PHP FPM (FastCGI Process Manager) zu nutzen. Das soll hier erklärt werden.

Installation

Ein funktionierender Apache wird vorausgesetzt. Fall noch nicht installiert braucht man noch das FastCGI-Modul. Außerdem brauchen wir auch PHP-FPM.

$ apt-get install libapache2-mod-fcgid php5-fpm
$ a2enmod proxy_fcgid
$ apache2ctl configtest && apache2ctl graceful

Damit ist das FastCGI-Proxy-Modul installiert und aktiviert. PHP-FPM sollte fehlende Abhängigkeiten ebenfalls mit installiert haben.

Konfiguration

PHP-FPM Konfiguration

Die grundsätzliche Konfiguration von PHP-FPM wird in /etc/php5/fpm/php-fpm.ini gemacht. Dort kann man reinschauen, muss aber meist nichts ändern. Wichtig sind die sogenannten Pool-Konfigurationen. Diese liegen unter /etc/php5/fpm/pool.d. Eine Default-Konfiguration liegt schon dort (www.conf), allerdings sollte diese nur zu Referenzzwecken verwendet werden. Um diesen Pool zu deaktivieren kann man ihn einfach umbenennen:

mv /etc/php5/fpm/pool.d/www.conf /etc/php5/fpm/pool.d/www.conf_inactive

Eine neue Pool-Konfiguration hingegen könnte beispielsweise so aussehen:

[cloud]
user = www-user-cloud
group = www-user-cloud
listen = /var/run/php5-fpm-cloud.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 256
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
;pm.status_path = /status
;ping.path = /ping
access.log = "/var/www/sites/cloud.misterunknown.de/logs/php-$pool.access.log"
access.log = "/var/www/sites/cloud.misterunknown.de/logs/php-$pool.access.log"
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
slowlog = "/var/www/sites/cloud.misterunknown.de/logs/php-$pool.slow.log"
security.limit_extensions = .php .php3 .php4 .php5

php_flag[display_errors] = off

php_admin_flag[log_errors] = on

php_admin_value[max_execution_time] = 600
php_admin_value[error_reporting] = E_ALL
php_admin_value[open_basedir] = "/var/www/sites/cloud.misterunknown.de:/var/www/sites/cloud.misterunknown.de/tmp:/data/owncloud:/dev/urandom"

weiterlesen

getssl: Let’s Encrypt ohne Python-Client

Vorwort

Nachdem Mozilla starke Kritik an Wosign und Startcom geübt hat, entfernte nun Apple als erstes die Zertifizierungsstelle aus seinen Trust-Stores. Für den Otto-Normal-Verbraucher heißt das nun, dass die Zertifikate von StartCom und Wosign faktisch wertlos sind; es ist ungewiss, ob sich die CA davon wieder erholt, auch wenn die Maßnahme vorerst auf ein Jahr begrenzt ist, und sich WoSign dann erneut einer unabhängigen Überprüfung unterziehen lassen kann.

Damit bleibt Let’s Encrypt die letzte mir bekannte Möglichkeit, kostenlos SSL-Zertifikate zu nutzen. Und bei aller berechtigten Kritik an dem Vorgehen, Zertifikte nur für 90 Tage auszustellen und diese mit einem Client automatisiert erneuern zu lassen, ist das Verfahren zumindest transparent und quelloffen.

Wem der native Python-Client nicht zusagt, der kann aus einer Vielfalt von alternativen Clients wählen. Ich habe mich für getssl entschieden, und möchte hier kurz eine Einführung geben.

Installation

Getssl ist ein simples Bash-Skript – daher kann auch ein unerfahrener Entwickler in den Code schauen und nachvollziehen, was dort eigentlich passiert. Installiert wird das Skript folgendermaßen:

curl --silent https://raw.githubusercontent.com/srvrco/getssl/master/getssl &gt; /usr/local/sbin/getssl
chmod 700 /usr/local/sbin/getssl

Anschließend kann man das Skript mit -h aufrufen, um sich verfügbare Parameter ausgeben zu lassen:

$ getssl -h
getssl ver. 1.61
Obtain SSL certificates from the letsencrypt.org ACME server

Usage: getssl [-h|--help] [-d|--debug] [-c|--create] [-f|--force] [-a|--all] [-q|--quiet] [-Q|--mute] [-u|--upgrade] [-U|--nocheck] [-w working_dir] domain

Options:
  -h, --help      Display this help message and exit
  -d, --debug     Outputs debug information
  -c, --create    Create default config files
  -f, --force     Force renewal of cert (overrides expiry checks)
  -a, --all       Check all certificates
  -q, --quiet     Quiet mode (only outputs on error, success of new cert, or getssl was upgraded)
  -Q, --mute      Like -q, but mutes notification about successful upgrade
  -u, --upgrade   Upgrade getssl if a more recent version is available
  -U, --nocheck   Do not check if a more recent version is available
  -w working_dir  Working directory

weiterlesen

Firefox: Alte iLO-Versionen aufrufen

Bei älteren iLO-Versionen kann es vorkommen, dass der Firefox  beim Herstellen der HTTPS-Verbindung den SSL-Fehler SSL_ERROR_BAD_MAC_ALERT bringt. Hintergrund ist, dass TLS-Versionen älter als 1.2 von Firefox blockiert werden.

Das kann man umgehen, indem man die entsprechenden Hosts in die Ausnahmenliste einträgt:

weiterlesen

Continuous Integration: flashplayerdebugger auf Linux-Server

Wer Continuous-Integration-Systeme für Flash- bzw. ActionScript-Projekte verwendet, wie beispielsweise Bitbucket und Bamboo aus dem Atlassian-Universum, möchte auch Unit-Tests (FlexUnit) etc. auf dem Server ausführen lassen. Das ist nicht ganz einfach, da der flashplayerdebugger ein X-Display braucht und nur als 32bit-Variante vorliegt. Ich beschreibe hier die Minimal-Variante mit der wir es unter Debian Wheezy zum Laufen gebracht haben.

Display zur Verfügung stellen

Grundsätzlich gibt es 2 Möglichkeiten FlexUnit „headless“ zu betreiben. Erstens kann man den FlexUnit ANT-Task mittels eines VNC-Servers ein entsprechendes Display bereitstellen und damit arbeiten. Zweitens kann man auch ein Framebuffer-Device per Xvfb bereitstellen, auf dem gearbeitet wird. Nach Beleuchtung beider Mechanismen wurde Xvfb als brauchbarer erachtet:

apt-get install xvfb

Das Paket bietet einerseits das Xvfb-Binary, welches dauerhaft ein Display bereitstellt und das Wrapper-Skript „xvfb-run“, mit dem man Programme in einem separaten Display starten kann (beispielsweise xvfb-run xterm ). Für CI-Umgebungen verwenden wir Xvfb als permanentes Display, da das am ressourcenschonendsten ist. Zu beachten ist, dass Xvfb am besten als der User gestartet wird, unter dem später auch die Tests laufen. Ein entsprechendes Init-Skript erledigt das:

#! /bin/bash
#
### BEGIN INIT INFO
# Provides:             Xvfb framebuffer device
# Required-Start:       $local_fs
# Required-Stop:        $local_fs
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    Xvfb framebuffer device
### END INIT INFO

USER="ciuser"
XVFB=/usr/bin/Xvfb
XVFBARGS=":0 +extension RANDR"
PIDFILE=/var/run/Xvfb/xvfb.pid

do_start () {
        echo -n "Starting virtual X frame buffer: Xvfb ..."
        su - ${USER} -c "/sbin/start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS"
        echo "."
}

do_stop () {
        echo -n "Stopping virtual X frame buffer: Xvfb ..."
        su - ${USER} -c "/sbin/start-stop-daemon --stop --quiet --pidfile $PIDFILE"
        echo "."
}

case "$1" in
                start)
                                do_start
                                ;;
                stop)
                                do_stop
                                ;;
                restart)
                                do_stop
                                do_start
                                ;;
                *)
                                echo "Usage: $0 {start|stop|restart}"
                                exit 3
                                ;;
esac

weiterlesen

Owncloud zu Nextcloud migrieren

Nach Unstimmigkeiten des Owncloud-Gründers mit der dahinter stehenden Firma hat er einen eigenen Fork namens Nextcloud erstellt. Im Nachgang musste die amerikanische Firma Owncloud Inc. schließen, nachdem ihnen die Kreditlinie gestrichen wurde. Die Owncloud GmbH in Deutschland ist davon zwar nicht unmittelbar betroffen, es bleibt aber wohl eine Frage der Zeit.

weiterlesen

Roundcube: Ausgehende IP festlegen

Wer mittels Roundcube Mails direkt an einen entfernten (nicht lokalen) Mailserver sendet, möchte unter Umständen die ausgehende IP festlegen, um beispielsweise sicherzustellen, dass der Reverse-DNS-Eintrag korrekt ist. Direkt in Roundcube gibt es dafür keine Einstellung, aber über die Stream-Kontext-Optionen von PHP kann man das festlegen.

weiterlesen