Scripte zum Erstellen und Erneuern von Letsencrypt Zertifikaten

Vor längerer Zeit (2016) habe ich nach Scripten oder OpenSource Software zum Erstellen und Erneuern von Letsencrypt Zertikaten gesucht, da ich nach dem Ende von StartSSL auf die Letsencrypt Zertikate umgestiegen war und diese nicht nur für Webseiten, sondern auch für Postfix, Dovecot und Vsftpd nutze.
Leider habe ich nichts gefunden, was meine Anforderungen entsprach und habe daher die Scripte selber geschrieben. Ausgangspunkt war der FreeBSD Port von acme-tiny. Zunächst entstand das Basisscript zum Erstellen der Zertifikate, auch wenn noch kein einziges vorhanden war, indem ich zunächst eine sub.domain.tld.cnf mit den openssl Basisdaten erstelle.

Wobei, noch davor muß als erstes ein eigener account.key erzeugt werden, wie es auch auf der acme-tiny Seite erklärt ist:

openssl genrsa 4096 > account.key

Dann kann man ein Zertikat mit folgendem Script erstellen:

#!/usr/local/bin/bash
#
# Dirk Dettmering
#
# Version 0.13 
# 23.01.2019
#

USAGE="Syntax: $0 domain.tld altdomain.tld subdomain.domain.tld
       Erster Parameter ist die primaer geschuetzte Domain und
       dann kommen die alternativen Domainnamen"

if [ "$#" == "0" ]; then
    echo "$USAGE"
    exit 1
fi

# Variablen für Einstellunge:
KEYDIR="/usr/local/etc/letsencrypt"
#KEYDIR="/usr/local/etc/letstest"
ACMETINY="/usr/local/bin/acme_tiny"
# Verzeichnis für die ACME-Challenge (Port 80!!!, nicht 443!!!)
ACMEDIR="/usr/local/www/challenges/"
# ACMEDIR="/usr/local/www/challenges/.well-known/acme-challenge/"
# Standard-Unterverzeichnis für die ACME-Challenge (Port 80!!!, nicht 443!!!)
# ACMESUBDIR=".well-known/acme-challenge/"

# Benutzer Variablen für Einstellungen
ACCOUNTKEY=$KEYDIR/account.key
DOMAIN="$1"
shift
for num
    do
	ALTDOMAINS=$ALTDOMAINS" "$num
done

BACKUPDIR=$KEYDIR/backup/$DOMAIN/`date +%Y-%m-%d`
LOG=$KEYDIR/logs/$DOMAIN.log
LOGtmp=$KEYDIR/logs/$DOMAIN_tmp.log

# SSL-Konfiguration:
SSLCNF=$KEYDIR/$DOMAIN/$DOMAIN.cnf
COUNTRY="DE"
STATEORPROVINCENAME="Hessen"
CITY="Musterstadt"
ORGANIZATIONNAME="Musterfirma"
ORGANIZATIONALUNITNAME="IT-Abteilung"
EMAIL="cert-admin@domain.tld"
#
# Servicerestarts:
HTTPRESTART="/usr/local/sbin/apachectl graceful"
IMAPRESTART="service dovecot restart"
SMTPRESTART="service postfix restart"
CHOWN="root:wheel"
# Weitere Vaiablen (Diese müssen im Normallfall nicht geändert werden)
CHMOD="644"
# Wird auf false gesetzt, wenn was schief läuft
CRTOK=true
# Ende der Benutzer-Variablen.

# Ab hier beginnt das Script.

# Es wird geprüft, ob acme-tiny vorhanden ist
if [ ! -f $ACMETINY ]; then
    echo "ACME_TINY nicht gefunden"
    exit 2
fi

# Datum und Variablen werden ins LOG geschrieben
echo "--- Start ---" >$LOG
date >>$LOG
echo "Domain: $DOMAIN" >>$LOG
echo "Accountkey: $ACCOUNTKEY" >>$LOG
echo "------------------------" >>$LOG

# Ordner fü die Domain erstellen, falls nocht nicht vorhande:
if [ ! -d $KEYDIR/$DOMAIN ]; then
    mkdir -p $KEYDIR/$DOMAIN
fi

# Backup-Ordner fuer aktuelle Zertifikate wird erstellt
if [ -s $KEYDIR/$DOMAIN/$DOMAIN.pem ] && [ ! -d $BACKUPDIR ]; then
    mkdir -p $BACKUPDIR
    mv -f $KEYDIR/$DOMAIN/lets-encrypt-x3-cross-signed-intermediate.pem $BACKUPDIR > /dev/null 2>&1
    mv -f $KEYDIR/$DOMAIN/$DOMAIN.crt $BACKUPDIR > /dev/null 2>&1
    mv -f $KEYDIR/$DOMAIN/$DOMAIN.csr $BACKUPDIR > /dev/null 2>&1
    mv -f $KEYDIR/$DOMAIN/$DOMAIN.pem $BACKUPDIR > /dev/null 2>&1
    mv -f $KEYDIR/$DOMAIN/$DOMAIN-chain.pem $BACKUPDIR > /dev/null 2>&1
fi

# Es wird geprüft, ob der ACCOUNT-Key existiert.
if [ ! -f $ACCONTKEY ]; then
    echo "Account Key $ACCOUNTKEY nicht vorhanden" >> $LOG 2>&1
    echo "Key kann mit dem folgenden Befehl erstellt werden:" >> $LOG 2>&1
    echo "openssl genrsa 4096 > $ACCOUNTKEY" >> $LOG 2>&1
    exit 3
fi

# prüfen, ob die Domain erreichbar ist:
if /usr/bin/nc -z $DOMAIN 80 > /dev/null 2>&1; then
    echo "Domain erreichbar" >>$LOG 2>&1
else
    echo "Domain nicht erreichbar" >>$LOG 2>&1
    exit 4
fi

# Private Key der Domain erstellen, wenn noch nicht vorhanden:
if [ ! -f $KEYDIR/$DOMAIN/$DOMAIN.key ]; then
    openssl genrsa 4096 > $KEYDIR/$DOMAIN/$DOMAIN.key 2>>$LOG 2>&1
fi

# Config-Datei für CSR erstelen, wenn noch nicht vorhanden:
if [ ! -f $SSLCNF ]; then
    echo "[ req ]
    distinguished_name = req_distinguished_name
    string_mask = nombstr
    # The extensions to add to a certificate request
    req_extensions = v3_req
    # GWDG default options for certificate request
    [ req_distinguished_name ]
    countryName = Country Name (2 letter code)" > $SSLCNF
    echo -n "countryName_default = " >> $SSLCNF
    echo $COUNTRY >> $SSLCNF
    echo "countryName_min = 2" >> $SSLCNF
    echo "countryName_max = 2" >> $SSLCNF
    echo "stateOrProvinceName = State or Province Name (full name)" >> $SSLCNF
    echo -n "stateOrProvinceName_default = " >> $SSLCNF
    echo $STATEORPROVINCENAME >> $SSLCNF
    echo "localityName = Your City" >> $SSLCNF
    echo -n "localityName_default = " >> $SSLCNF
    echo $CITY >> $SSLCNF
    echo "0.organizationName = Organization Name (eg, company)
    0.organizationName_default = "$ORGANIZATIONNAME >> $SSLCNF
    echo "organizationalUnitName = Organizational Unit Name (eg, section)
    organizationalUnitName_default = "$ORGANIZATIONALUNITNAME >> $SSLCNF
    echo "commonName = Common Name (e.g. server FQDN or YOUR name)" >> $SSLCNF
    echo "commonName_max = 64" >> $SSLCNF
    echo -n "commonName_default = " >> $SSLCNF
    echo $DOMAIN >> $SSLCNF
    echo "emailAddress = Email Address" >> $SSLCNF
    echo "emailAddress_max = 64" >> $SSLCNF
    echo -n "emailAddress_default = " >> $SSLCNF
    echo $EMAIL >> $SSLCNF 
    echo "[ v3_req ]" >> $SSLCNF
    echo -n "subjectAltName = DNS:" >> $SSLCNF
    echo -n $DOMAIN >> $SSLCNF
fi

for SUB in $ALTDOMAINS; do
    echo -n ", DNS:" >> $SSLCNF
    echo -n $SUB >> $SSLCNF
done

# CSR wird erstellt
# openssl req -new -sha256 -key /etc/ssl/letsencrypt/domain.key -subj "/C=US/O=Acme/CN=example.com" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:www.example.com,DNS:static.example.com")) -out /etc/ssl/letsencrypt/example.com/domain.csr
openssl req -new -sha256 -key $KEYDIR/$DOMAIN/$DOMAIN.key -batch -config $KEYDIR/$DOMAIN/$DOMAIN.cnf -out $KEYDIR/$DOMAIN/$DOMAIN.csr >> $LOG 2>&1

# CSR von Lets-Encrypt signieren lassen
/usr/local/bin/python2.7 $ACMETINY --account-key $ACCOUNTKEY --csr $KEYDIR/$DOMAIN/$DOMAIN.csr --acme-dir $ACMEDIR > $KEYDIR/$DOMAIN/$DOMAIN.crt
RESULT=$?
if [ ! $RESULT == 0 ];then
    echo "Signierung nicht erfolgreich!" >>$LOG
    echo "Signierung nicht erfolgreich!"
    exit $RESULT
else
    echo "Signierung erfolgreich!" >>$LOG
fi

# Append the Let's Encrypt intermediate cert to your cert
/usr/local/bin/wget -q -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > $KEYDIR/$DOMAIN/lets-encrypt-x3-cross-signed-intermediate.pem 2>>$LOG 2>&1
cat $KEYDIR/$DOMAIN/$DOMAIN.crt $KEYDIR/$DOMAIN/lets-encrypt-x3-cross-signed-intermediate.pem >> $KEYDIR/$DOMAIN/$DOMAIN-chain.pem

# Rechte
/usr/sbin/chown -R $CHOWN $KEYDIR/$DOMAIN 
/bin/chmod -R $CHMOD $KEYDIR/$DOMAIN/*

# Jetzt kommen die Prüfungen, ob das CRT OK ist.
if [ `grep -c CERTIFICATE $KEYDIR/$DOMAIN/$DOMAIN-chain.pem` = 6 ]; then
    echo "Zertifikat ist OK" >>$LOG
    # PEM-Datei wird erstellt (PEM = KEY + CRT)
    cat $KEYDIR/$DOMAIN/$DOMAIN.key >$KEYDIR/$DOMAIN/$DOMAIN.pem
    cat $KEYDIR/$DOMAIN/$DOMAIN-chain.pem >>$KEYDIR/$DOMAIN/$DOMAIN.pem
else
    CRTOK=false
    echo "Zertifikat ist Fehlerhaft" >>$LOG
    exit 7
fi

# Hier wird anhand des Prüfungsergebnisses weiter entschieden
if $CRTOK; then
    # CRT ist OK

    # Webserver neu Starten!
    # $HTTPRESTARTCMD 2>/dev/null >/dev/null
    $HTTPRESTARTCMD  > /dev/null 2>&1
    # Mailserver neu Starten!
    $IMAPRESTART > /dev/null 2>&1
    #$SMTPRESTART > /dev/null 2>&1
else
    # Fehler beim CRT
    mkdir -p $KEYDIR/failed/$DOMAIN-`date +%Y-%m-%d-%H-%M`
    mv $KEYDIR/$DOMAIN/* $KEYDIR/failed/$DOMAIN_`date +%Y-%m-%d_%H-%M`
    exit 5
fi

Das Script ruft man dann wie folgt auf:

~/bin/cert-create.sh www.domain.tld domain.tld subdomain.domain.tld

Im vHost des Apache habe ich die Letsencrypt Challenge mit einem Include vorbereitet:

Die Datei /usr/local/etc/apache24/Includes/acme.conf hat folgenden Inhalt:

# Let's Encrypt acme-client:
Alias /.well-known/acme-challenge /usr/local/www/challenges
#Alias /.well-known/ /usr/local/www/challenges
<Directory /usr/local/www/challenges>
   Options None
   AllowOverride None
   Order deny,allow
   #Allow from all
   Require all granted
   Header add Content-Type text/plain
</Directory>

Und wird in der vHost Konfiguration eingebunden:

<VirtualHost *:80>
ServerName www.domain.tld
ServerAlias domain.tld
ServerAdmin webmaster@leseratte-linz.de
DocumentRoot /srv/domain.tld/www
ErrorLog /srv/domain.tld/logs/error.log
CustomLog /srv/domain.tld/logs/access.log combined
Alias /.wwwstats_ "/srv/webalizer/domain.tld"
<Directory />
   AllowOverride All
   Options -Indexes
   Require all granted
</Directory>

Include /usr/local/etc/apache24/Includes/acme.conf
# Auf SSL umschreiben:
RewriteEngine On
RewriteCond % 80
RewriteRule ^(.*)$ https://www.domain.tld/$1 [R,L]
</VirtualHost>

Für die SSL Konfiguration gibt es eine weitere Include Datei:

Die SSL vHost Konfiguration:

<VirtualHost *:443>
ServerName www.domain.tld
ServerAlias domain.tld
ServerAdmin webmaster@domain.tld
DocumentRoot /srv/domain.tld/www
ErrorLog /srv/domain.tld/logs/ssl-error.log
CustomLog /srv/domain.tld/logs/ssl-access.log combined
Alias /.wwwstats_ "/srv/webalizer/domain.tld/"
Include /usr/local/etc/apache24/Includes/acme.conf
<Directory />
   AllowOverride All
   Options -Indexes
   Require all granted
</Directory>

Include /usr/local/etc/apache24/Includes/ssl.conf
SSLCertificateFile /usr/local/etc/letsencrypt/www.domain.tld/www.domain.tld.crt
SSLCertificateKeyFile /usr/local/etc/letsencrypt/www.domain.tld/www.domain.tld.key
SSLCertificateChainFile /usr/local/etc/letsencrypt/www.domain.tld/www.domain.tld-chain.pem
</VirtualHost>

Die Datei /usr/local/etc/apache24/Includes/ssl.conf:

# generated 2019-09-10, https://ssl-config.mozilla.org/#server=apache&server-version=2.4.39&config=intermediate
# https://ssl-config.mozilla.org/
# requires mod_ssl, mod_socache_shmcb, mod_rewrite, and mod_headers
# enable HTTP/2, if available
Protocols h2 http/1.1

# HTTP Strict Transport Security (mod_headers is required) (63072000 seconds)
Header always set Strict-Transport-Security "max-age=63072000"
<IfModule mod_ssl.c>
  SSLEngine on
  SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
  SSLCipherSuite "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECD
  SSLHonorCipherOrder on
  SSLHonorCipherOrder     off
  SSLSessionTickets       off
  SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
  <IfModule mod_headers.c>
    Header always set Strict-Transport-Security: "max-age=15768000"
  </IfModule>
</IfModule>

Die Konfigurstionsdateien für postfix, dovecot undvsftpd mit SSL spare ich mir hier. Dazu gibt es genug Quellen im Netz.

Mit dem Scrpit acme-update.sh erneuere ich wöchentlich die Letsencrypt Zertifikate:

#!/usr/local/bin/bash
#
# Dirk Dettmering
#
# 0.8 02.12.2016
#

# Servicerestarts:
HTTPRESTART="/usr/local/sbin/apachectl graceful"
FTPRESTART="service vsftpd restart"
IMAPRESTART="service dovecot restart"
SMTPRESTART="service postfix restart"

DATUM=`date +%d-%m-%Y`
STEMPEL=`date +%d-%m-%Y' '%H:%M`
DOMAINLIST="/usr/local/etc/letsencrypt/domains.txt"
TLOG="/tmp/acme-update.log"
LOG="/usr/local/etc/letsencrypt/logs/update.log"
STATUS=0

echo "#############################################################" >> $LOG
echo "" >> $LOG
echo $DATUM": Update der Zertifikate aller Domänen" >> $LOG

while read line; do
    IFS=" "
    set -- $line
    /usr/local/bin/bash /root/bin/cert-create.sh $1 $2 $3 $4 $5 $6; >> $LOG 2>&1
    RCODE=$?
    echo -e "$line\c" >> $LOG
    if [ $RCODE -ge 1 ]; then
	STATUS=$(($STATUS + $RCODE))
	echo "Status: "$STATUS
	#STATUS="Error"
	echo "Beim Erstellen des Zertifikats ist ein Fehler aufgetreten. Returncode: "$RCODE >> $LOG
    else
	echo ": OK" >> $LOG
    fi
done < /usr/local/etc/letsencrypt/domains.txt

echo "" >> $LOG

if [ $STATUS -eq 0 ]; then
    # Webserver neu Starten!
    $HTTPRESTARTCMD  > /dev/null 2>&1
    RCODE=$?
    if [ $RCODE -ge 1 ]; then
	STATUS="Error"
	echo "Beim Neustart des Apache ist ein Fehler aufgetreten: "$RCODE >> $LOG
    else
	echo "Apache erfolgreich neu gestartet" >> $LOG
    fi
    # FTP Server neu Starten!
    $FTPRESTARTCMD  > /dev/null 2>&1
    RCODE=$?
    if [ $RCODE -ge 1 ]; then
	STATUS="Error"
	echo "Beim Neustart des FTP Servers ist ein Fehler aufgetreten: "$RCODE >> $LOG
    else
	echo "VsFTPD erfolgreich neu gestartet" >> $LOG
    fi
    # Mailserver neu Starten!
    $IMAPRESTART > /dev/null 2>&1
    if [ $RCODE -ge 1 ]; then
	STATUS="Error"
	echo "Beim Neustart von Dovecot ist ein Fehler aufgetreten: "$RCODE >> $LOG
    else
	echo "Dovecot erfolgreich neu gestartet" >> $LOG
    fi
    $SMTPRESTART > /dev/null 2>&1
    if [ $RCODE -ge 1 ]; then
	STATUS="Error"
	echo "Beim Neustart von Postfix ist ein Fehler aufgetreten: "$RCODE >> $LOG
    else
	echo "Postfix erfolgreich neu gestartet" >> $LOG
    fi
else
    echo "Kein Neustart, weil ein Returncode groesser Null war!"
fi
echo "" >> $LOG

Und hier beide Dateien zum Download: letsencrypt-scripte.tar.bz2

Der Postillon schafft auch noch wirklich jedem ernsten Thema Humor abzugewinnen!

Und hier gleich noch eine Postillon Perle:

Statt Händeschütteln: AfD empfiehlt wegen Coronavirus neuen kontaktlosen Gruß mit erhobenem rechten Arm

Weiterer Humor des Postillion

Oder muß es „Weiterer Humor aus dem Der Postillion“ lauten?

Da ich als Schüler selber fast immer in der letzten Reihe Platz genommen habe, mußte ich über den Artikel „Ständiger Unruheherd“: Bildungsministerium schafft letzte Reihe im Klassenzimmer ab schon sehr schmunzeln!

Der Postillion Humor

Der Humor vom Postillion ist immer wieder saugenial (mit Ausnahme des Jahresabreißkalenders, der ist ziemlich maximal unlustig). daher werde ich ab und zu hier ein paar Perlen erwähnen.

Z.B. Sensation! Autobahn-Fahrer entdeckt weitere Fahrbahn rechts neben der Mittelspur

Ich wollte gerade ein Photos des Artikels hier einfügen, aber es ist offensichtlich selber kein Photo vom Postillion, daher füge ich es lieber nicht ein.

Ist wohl ein alter Artikel von 2015, wurde aber gerade wieder neu veröffentlicht.

Nachladen von Kernelmodulen verhindern

In der aktuellen c’t 01/2020 steht im Artikel „FAQ: Basics zum Linux-Kernel, Teil 5“ folgender Hinweis, wie man das Nachladen von Kernelmodulen im laufenden Betrieb verhindern kann:

Sie können die angesprochene Angriffsfläche schon ein gutes Stück reduzieren, indem Sie dem Kernel Ihrer Distribution das Nachladen von Modulen verbieten:

echo 1 > /proc/sys/kernel/modules_disabled Diese Blockade können Sie im Betrieb nicht widerrufen, daher müssen Sie neu starten, um wieder Module laden zu können. Sie sollten den Befehl daher erst ausführen, wenn das System wirklich alle im Betrieb erforderlichen Kernel-Module geladen hat. Bei einer selbst gebauten Firewall und simplen Servern ist das oft schon am Ende des Boot-Prozesses der Fall, daher kann es dort ausreichen, den Befehl über die /etc/rc.d/rc.local auszuführen.

Möglicherweise sollte man vor dem Aktivieren der Modulladeblockade bei einigen Systemen im laufenden Betrieb, wenn alle Funktionalitäten schon mal genutzt wurden, mit einem lsmod nachsehen, ob beim Start möglicherweise noch nicht alle für den Betrieb des Systems erforderlichen Kernelmodule geladen wurden und diese dann mit einem modprobe vor dem echo Befehl laden.

Problem mit RedirectPermanent und automatischen Updates von Let’s Encrypt

Meine Scripte zum Erstellen und Erneuern der Let’s Encrypt funktionierte nach einem Serverumzug und ein paar Konfigurationsänderungen nicht mehr. Folgende Fehlermeldung wurde ausgeworfen:

Verifying www.domain.tld...
Traceback (most recent call last):
File "/usr/local/bin/acme_tiny", line 141, in get_crt
assert (disable_check or _do_request(wellknown_url)[0] == keyauthorization)
File "/usr/local/bin/acme_tiny", line 46, in _do_request
raise ValueError("{0}:\nUrl: {1}\nData: {2}\nResponse Code: {3}\nResponse: {4}".format(err_msg, url, data, code, resp_data))
ValueError: Error:
Url: http://www.domain.tld/.well-known/acme-challenge/xr8lBzb_kujRUBCVMwXI7dVLy1m6wrfEkhw-Jr_Mapw
Data: None
Response Code: None
Response: <urlopen error [Errno 8] Name does not resolve>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/bin/acme_tiny", line 198, in <module>
main(sys.argv[1:])
File "/usr/local/bin/acme_tiny", line 194, in main
signed_crt = get_crt(args.account_key, args.csr, args.acme_dir, log=LOGGER, CA=args.ca, disable_check=args.disable_check, directory_url=args.directory_url, contact=args.contact)
File "/usr/local/bin/acme_tiny", line 143, in get_crt
raise ValueError("Wrote file to {0}, but couldn't download {1}: {2}".format(wellknown_path, wellknown_url, e))
ValueError: Wrote file to /usr/local/www/challenges/xr8lBzb_kujRUBCVMwXI7dVLy1m6wrfEkhw-Jr_Mapw, but couldn't download http://www.domain.tld/.well-known/acme-challenge/xr8lBzb_kujRUBCVMwXI7dVLy1m6wrfEkhw-Jr_Mapw: Error:
Url: http://www.domain.tld/.well-known/acme-challenge/xr8lBzb_kujRUBCVMwXI7dVLy1m6wrfEkhw-Jr_Mapw
Data: None
Response Code: None
Response: <urlopen error [Errno 8] Name does not resolve>
Signierung nicht erfolgreich!

Wie ich dann herausgefunden habe, mag Let’s Encrypt nicht mit der Konfiguration Redirect permanent spielen:

<VirtualHost *:80> ServerName domain.tld ServerAlias www.domain.tld ServerAdmin contact@domain.tld DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined Redirect permanent / https://domain.tld/ <Directory /var/www/html>    Options FollowSymLinks AllowOverride all Require all granted </Directory> </VirtualHost>

Nachdem ich statt mit

Redirect permanent / https://domain.tld/

das Umschreiben zu HTTPS mittels folgendem Block 

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^/.well-known/.*$
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]

umgesetzt habe, konnte ich wieder Zertifikate anfordern und erneuern.

Geschützt: Berichte über den Angriff auf Marburg Genossen in Chemnitz

Dieser Inhalt ist passwortgeschützt. Um ihn anschauen zu können, bitte das Passwort eingeben:

Störche im Ebsdorfergrund

Gestern beim Joggen habe ich zunächst 4 Störche hinter einem pflügenden Trecker gesehen und bedauert, daß ich mein Handy nicht dabei hatte. Auf dem Rückweg habe ich aus der Ferne an einer Staubwolke gesehen, daß der Bauer immer noch am Pflügen war. Da bin ich schnell nach Hause und mit der Kamera hingefahren:

(Durch Anklicken der Bilder manuell zum nächsten Bild wechseln, ansonsten wechseln sie automatisch alle 10 Sekunden.)

Einzeln können sie dann durch Anklicken auch als Lightbox größer dargestellt werden.

Und hier kann man nochmal sehen, daß es wirklich 15 Störche waren:

Unvollständige / komische Auswertung religiöser Fragen bei Civey?!

Heute ist mir zum zweiten mal aufgefallen, daß bei Civey bei einer Frage mit religiösem Inhalt eine mögliche Antwort „Ich bin konfessionslos“ war:

die ich als Atheist dann auch gewählt habe. Aber in der Auswertung fehlt diese Antwort dann:

Das als Ausversehen abzutun, fällt mir ehrlich gesagt schwer. Ich habe Civey angemailt. Mal schauen, was sie dazu antworten.

 

Event Organiser anpassen

Um die Farben des WP Plugins Event Organiser Posterboard anzupassen, muß nicht die CSS Datei sondern event-organiser-posterboard/event-organiser-posterboard.php in Zeile 246 angepaßt werden:

$colour     = ( eo_get_event_color() ? eo_get_event_color() : '#B61C3E' );

Für ein SPD Rot ist hier #E3000F und für das SPD Dunkelrot #B61C3E einzutragen (siehe SPD Corporate Design manual).
Allerdings ist das noch nicht das richtige rot. Es sieht zu kräftig aus:
Termine des OV Ebsdorf