Bis jetzt habe ich für die meisten meiner Webseiten Lighttpd als Webserver benutzt. Eigentlich war ich damit auch immer sehr zufrieden, allerdings hat er das Problem das er zumindest in Version 1.4 kein HTTP/2 unterstützt. Also habe ich mich in den letzten Tagen mal nach einer Alternative umgesehen. Wichtig war mir das der Webserver schön schlank ist und sich einfach konfigurieren lässt. Außerdem muss er natürlich HTTP/2, PHP und SSL unterstützen.
Bei der suche nach einem schlanken Webserver bin ich dann auf Caddy gestoßen. Das schöne an dem Webserver ist das er nicht nur HTTP/2 unterstützt sondern direkt per Let's Encrypt Zertifikate erstellt. Leider gibt es Caddy (noch?) nicht in den Debian Paketquellen, man muss ihn also von Hand installieren was aber denkbar einfach ist.
PHP 7 mit FastCGI Process Manager (FPM) installieren
Dieser Schritt ist nur unter Debian Jessie oder älter nötig!
Als erstes benötigt man das Paket php7.0-fpm das sich noch nicht seit Stretch in den Debian Paketquellen befindet.
Man muss also erst mal das Repository von packages.dotdeb.org hinzufügen. Dazu führt man einfach die folgenden Befehle aus:
echo "deb http://packages.dotdeb.org jessie all" > /etc/apt/sources.list.d/dotdeb.list echo "deb-src http://packages.dotdeb.org jessie all" >> /etc/apt/sources.list.d/dotdeb.list wget https://www.dotdeb.org/dotdeb.gpg apt-key add dotdeb.gpg
Jetzt noch kurz die Quellen aktualisieren und das Paket installieren.
apt-get update apt-get install php7.0-fpm
Caddy Webserver installieren
Benötigte Pakete installieren.
apt-get install libcap2-bin
Als erstes legen wir ein temporäres Verzeichnis an und laden den Webserver dort hin runter, hier muss man evtl. die Adresse des Download Links anpassen um die aktuelle Version zu erhalten. Alternativ kann man auch unter https://caddyserver.com/download sich sein eigenes Paket zusammenstellen und das verwenden.
mkdir /tmp/caddy && cd /tmp/caddy wget https://github.com/mholt/caddy/releases/download/v0.9.1/caddy_linux_amd64.tar.gz
Danach wird das Paket entpackt und nach /usr/bin/caddy verschoben.
tar zxvf caddy_linux_amd64.tar.gz mv caddy_linux_amd64 /usr/bin/caddy
Jetzt muss man noch ein paar Rechte anpassen so das Caddy später mit www-data laufen darf.
mkdir /var/www chown www-data /var/www setcap cap_net_bind_service=+ep /usr/bin/caddy
Außerdem musste ich dafür sorgen das Caddy PHP-FPM benutzen darf, dazu habe ich in der /etc/php/7.0/fpm/pool.d/www.conf
einfach das ; vor listen.mode = 0660
entfernt.
Wenn das alles erledigt ist kann man eine Service anlegen, dazu macht man einfach nano /etc/systemd/system/caddy.service
und trägt
in die Datei folgenden ein:
[Unit] Description=Caddy webserver Documentation=https://caddyserver.com/ After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/etc/caddy/ LimitNOFILE=4096 PIDFile=/var/run/caddy/caddy.pid ExecStart=/usr/bin/caddy -agree -email mail@example.com -pidfile=/var/run/caddy/caddy.pid -conf="/etc/caddy/Caddyfile" Restart=on-failure StartLimitInterval=10 [Install] WantedBy=multi-user.target
Hier sollte man die E-Mail Adresse durch seine eigene austauschen damit die später für Let's Encrypt genutzt wird. Alle anderen Angaben kann man
eigentlich so lassen. In dem Beispiel läuft der Webserver mit dem Benutzer www-data was eigentlich OK ist. Wenn man einen anderen Benutzer
nutzen möchte kann man den Eintrag dazu ändern, wichtig ist nur das man ihn nicht als Root laufen lässt. Im Startbefehl kann mit dem Parameter
-conf=
angegeben werden wo die Konfigurationsdatei liegen soll, da /etc/caddy/
ein ganz guter Ort ist und die default
Datei Caddyfile
heißt muss man hier eigentlich auch nichts ändern.
Zum Schluss muss man den Service noch bekannt geben.
systemctl enable caddy systemctl daemon-reload
Die Konfiguration
Zum Schluss fehlt noch die Konfiguration für die einzelnen Webseiten. Dazu legt man in /etc/caddy/ eine Datei mit dem Namen Caddyfile an. Wenn man im Startbefehl einen anderen Pfad angegeben hat muss man die Datei im entsprechenden Pfad anlegen.
nano /etc/caddy/Caddyfile
Der minimale Inhalt der für eine PHP Seite benötigt wird sieht folgendermaßen aus:
example.com { root /pfad/zum/docroot fastcgi / /run/php/php7.0-fpm.sock php }
Eine ausführliche Beschreibung aller möglichen Optionen findet man hier.
Der Webserver legt dann für jede Domain ein eigenes SSL Zertifikat an so dass man sich darum nicht weiter kümmern muss.
Mehrere Webseiten können einfach in die selbe Datei eingetragen werden, das wird zwar bei vielen Seiten etwas unübersichtlich,
wenn man auf dem Server aber wie ich eh nur wenige Seiten betreibt ist das kein Problem. Man kann auch einfach für jede Domain eine Datei
anlegen und dann in /etc/caddy/Caddyfile mit import example.com
die Datei einbinden.
Optimierte Konfiguration
Die minimale Konfiguration reicht zwar aus um eine Webseite auszuliefern, daran lässt sich aber noch einiges verbessern. Z.B. sollte man immer
gzip
eintragen um die Seiten komprimiert auszuliefern.
Auch der HTTP Header lässt sich über die Konfiguration optimieren.
header / -Server header / -X-Powered-By header / X-Content-Type-Options "nosniff" header / X-Xss-Protection "1; mode=block" header / X-Frame-Options "SAMEORIGIN" header / Referrer-Policy "no-referrer" header / Strict-Transport-Security "max-age=31536000" header / Expect-CT "enforce; max-age=30;"
In der ersten Zeiler wird der Server Tag aus dem Header entfernt, der ist nicht nur überflüssig sondern kann einem Angreifer auch erzählen
welcher Webserver genutzt wird.
Dann werden verschiedene Header die der Sicherheit dienen gesetzt, dadurch werden MIME type sniffing oder Cross Site Scripting Attacken erschwert. Außerdem
wird SSL erzwungen und der Public Key von Let's Encrypt gepinnt.
Jetzt kann man noch bestimmte TLS Protokolle zulassen, so werden alte unsichere Protokolle nicht akzeptiert.
tls mail@example.com { protocols tls1.0 tls1.2 }
Die Mail Adresse die hier angegeben wird benutzt Caddy um Zertifikate zu beantragen.
Caddy starten
Wenn die Konfiguration angelegt ist kann man den Server mit service caddy start
starten. Mit service caddy status
lässt sich überprüfen ob er läuft. Sollte dort ein Fehler angezeigt werden lohnt sich ein Blick in /var/log/daemon.log.
Kommentare
Anforderungen Caddy Webserver braucht? Z.b Wie viel Ram und Cpu? Abgesehen davon dass ich auf manchen Webseiten täglich zwischen 50-100k Besucher habe, natürlich hängt davon auch ab wie gut man alles konfiguriert hat, trotzdem würde es mich interessieren wie viel ungefähr Ram/Cpu benötigt wird nur um Caddy am laufen zu lassen. Was ich auch persönlich feier sind die "Proxy" Directives "reverse proxy und robust load balancer".. Muss mich mal die tage damit auseinandersetzen.
Danke Tas für solch einen informativen Beitrag.
Wie viel CPU/RAM er braucht ist schwer zu sagen, hier auf dem Server dümpelt er gerade mit 0% CPU und ca. 3% RAM/512 rum. Da brauchen die PHP Prozesse deutlich mehr.
Ich habe vor einiger Zeit mal Apache, Nginx und Lighttpd verglichen, da hat der Lighttpd deutlich gewonnen. Gefühlt ist aber der Caddy nochmal schneller, ich werde dazu aber bei Gelegenheit nochmal einen ausführlichen Test machen.
Für mich war der Hauptgrund auf Caddy umzusteigen die HTTP/2 Unterstützung (die es für Lighttpd nicht gibt) und das automatische anlegen von Zertifikaten, das ist da wirklich super einfach da man nur einen V-Host konfiguriert und sich Caddy um alles weitere kümmert.