Lighttpd, PHP-FPM, Let's Encrypt mit Multidomains
Im folgenden Artikel möchte ich erklären, wie man eine Webserver Umgebung mit PHP-FPM und Let's Encrypt Zertifikaten mit dem Webserver Lighttpd (lighty) umsetzen kann. Die folgende Konfiguration führt dazu, dass ihr bei folgenden Tests, eine A(+) bekommt:
Hinweis: Ein natürlicher Menschenverstand wird vorausgesetzt, bitte nicht einfach blind kopieren!
Installation
Als erstes installieren wir die benötigt Software:
apt install lighttpd php-fpm certbot
Konfiguration
lighttpd - PHP-FPM
Im folgenden werden wir lighttpd konfigurieren. Als erstes sorgen wir dafür das lighttpd mit PHP-FPM umgehen kann, dazu gehen wir in den Ordner /etc/lighttpd/conf-available/.
Dort werden wir jetzt die Datei 15-fastcgi-php.conf bearbeiten, und folgenden Inhalt einfügen:
# -*- depends: fastcgi -*-
# /usr/share/doc/lighttpd/fastcgi.txt.gz
# http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs:ConfigurationOptions#mod_fastcgi-fastcgi
## Start an FastCGI server for php (needs the php5-cgi package)
fastcgi.server += ( ".php" =>
((
"socket" => "/var/run/php/php7.2-fpm.sock",
"broken-scriptfilename" => "enable"
))
)
Umbedingt den Socket Pfad kontrollieren! Jetzt sagen wir lighttpd er soll das Modul laden:
lighttpd-enable-mod fastcgi
lighttpd-enable-mod fastcgi-php
service lighttpd force-reload
Jetzt kann lighttpd mit PHP Dateien umgehen.
lighttpd
Im folgenden werden wir lighttpd konfigurieren. Dazu bearbeiten wir die Datei /etc/lighttpd/lighttpd.conf und fügen folgenden Inhalt hinzu:
server.modules = (
"mod_access",
"mod_alias",
"mod_compress",
"mod_redirect",
)
#default webseite
server.document-root = "/var/www/html/kiefer-networks.de/"
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
server.errorlog = "/var/log/lighttpd/error.log"
server.pid-file = "/var/run/lighttpd.pid"
server.username = "www-data"
server.groupname = "www-data"
server.port = 80
#Server Tag ist der Name der angezeigt wird beim Abtasten des Servers (Nginx v.234)
server.tag = "Mein Server"
index-file.names = ( "index.php", "index.html", "index.lighttpd.html" )
#Zugriff auf folgende Dateien untersagen
url.access-deny = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = ( "application/javascript", "text/css", "text/html", "text/plain" )
# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
#Wir erlauben nur das die HTTP Requests Methoden GET & POST erlaubt sind
$HTTP["request-method"] !~ "^(GET|POST)" {
url.access-deny = ("")
}
#Setzten der entsprechenden HTTP Headers, Achtung CSP anpassen
server.modules += ( "mod_setenv" )
$HTTP["scheme"] == "https" {
setenv.add-response-header = (
"Content-Security-Policy" => "default-src 'self'; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self'; media-src 'self'; frame-src https://*.openstreetmap.org https://*.google.com; font-src https://fonts.googleapis.com; connect-src 'none'",
"Strict-Transport-Security" => "max-age=15768000; includeSubDomains; preload",
"X-Content-Type-Options" => "nosniff",
"X-Frame-Options" => "DENY",
"X-XSS-Protection" => "1; mode=block"
)
}
#Umleiten von HTTP zu HTTPS
$HTTP["scheme"] == "http" {
$HTTP["host"] =~ ".*" {
url.redirect = (".*" => "https://%0$0")
}
}
#Multi Webseiten Konfiguration
$HTTP["host"] =~ "(^|\.)example\.de$" {
server_name = "example.de"
server.document-root = "/var/www/html/example.de"
server.errorlog = "/var/log/lighttpd/ex_de_error.log"
}
$HTTP["host"] =~ "(^|\.)example\.com$" {
server_name = "example.com"
server.document-root = "/var/www/html/example.com"
server.errorlog = "/var/log/lighttpd/ex_com_error.log"
}
lighttpd SSL Konfiguration
Jetzt werden wir noch die SSL Konfiguration anpassen. Dazu bearbeiten wir die Datei /etc/lighttpd/conf-available/10-ssl.conf. Wir passen den Inhalt wir folgt an:
$SERVER["socket"] == ":443" {
protocol = "https://"
ssl.engine = "enable"
ssl.disable-client-renegotiation = "enable"
ssl.pemfile = "/etc/lighttpd/ssl/example.de.pem"
ssl.ca-file = "/etc/lighttpd/ssl/fullchain.pem"
ssl.ec-curve = "secp384r1"
setenv.add-environment = (
"HTTPS" => "on"
)
ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"
ssl.honor-cipher-order = "enable"
ssl.cipher-list = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
$HTTP["host"] =~ "(^|\.)example\.de$" {
ssl.pemfile = "/etc/lighttpd/ssl/example.de.pem"
ssl.ca-file = "/etc/lighttpd/ssl/fullchain.pem"
}
$HTTP["host"] =~ "(^|\.)example\.com$" {
ssl.pemfile = "/etc/lighttpd/ssl/example.com.pem"
ssl.ca-file = "/etc/lighttpd/ssl/fullchain.pem"
}
}
Dazu erstellen wir noch den folgenden Ordner
mkdir /etc/lighttpd/ssl/
Jetzt noch das SSL Modul aktivieren
lighttpd-enable-mod ssl
service lighttpd restart
Let's Encrypt
Bei lighttpd gibt es eine Besonderheit bei den Zertifikaten, so muss der Private Schlüssel und das Zertifikate in einer Datei sein und das CA immer als Referenz mit angebenen sein. Damit wir das nicht für jede Datei einzeln machen müssen, werden wird ein fertiges Script nehmen, was sich auch darum kümmert, die Zertifikate aktuell zu halten.
Dazu wechseln wir nach /opt. Dann klonen wir folgenden Repo:
git clone https://github.com/galeone/letsencrypt-lighttpd.git
Wechselt in den neuen Ordner letsencrypt-lighttpd. Als erstes bearbeiten wir die Datei letsencrypt-lighttpd.service und passen den ExecStart an nach /opt/letsencrypt-lighttpd/renew.sh.
ExecStart=/opt/letsencrypt-lighttpd/renew.sh
Dann kopieren die Service Dateien und starten den Dienst:
cp letsencrypt-lighttpd.* /etc/systemd/system/
systemctl enable letsencrypt-lighttpd.timer
Jetzt der "schwierige" Teil, wir passen noch renew.sh an:
#!/usr/bin/env bash
set -eu
#Domain sudomain part (mail.example.de => mail)
domain_subdomains=( \
#domain sub sub sub
"example.de w ww www" \
"example.com w ww www" \
)
email=mail@example.de
w_root=/var/www/html/ #Speicherort der Webseiten
user=root
group=root
# end configuration
if [ "$EUID" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
for domain_set_string in "${domain_subdomains[@]}"; do
domain_set=(${domain_set_string// / })
domain=${domain_set[0]}
unset domain_set[0]
all_subdomains="-d $domain"
if [ ${#domain_set[@]} -gt 0 ]; then
for sub_domain in "${domain_set[@]}"; do
all_subdomains="$all_subdomains -d $sub_domain.$domain"
done
fi
/usr/bin/certbot certonly --agree-tos --renew-by-default \
--rsa-key-size 4096 --email $email --webroot -w $w_root$domain \
$all_subdomains
cat /etc/letsencrypt/live/$domain/privkey.pem \
/etc/letsencrypt/live/$domain/cert.pem \
> /etc/lighttpd/ssl/$domain.pem
cp /etc/letsencrypt/live/$domain/fullchain.pem \
/etc/lighttpd/ssl/
chown -R $user:$group /etc/lighttpd/
chmod 600 /etc/lighttpd/*.pem
done
Hinweis: Die Webseiten müssen im Ordner /var/www/html/ gespeichert werden, im Format der angegebenen Domain: /var/www/html/example.de
Jetzt starten wir die Dienste neu:
service php7.2-fpm restart
service lighttpd restart
Dann lassen wir uns noch die Zertifikate austellen
bash /opt/letsencrypt-lighttpd/renew.sh
Fazit
Der Lighttpd ist ein leistungsstarker Server, der wunderbar ein Ersatz für nginx und Apache sein kann.