Nginx Konfiguration optimieren und Geld sparen

Standardmäßig protokolliert Nginx erfolgreiche Zugriffe in seinen Access Logs. Mit wenig Aufwand kann man dies unterbinden und die Serverlast sehr deutlich reduzieren. Die Lastreduzierung geht so weit, dass man einen kleineren vServer braucht als ohne diese Optimierung. Zudem kann man dann Fail2Ban auf die Logs verwenden. Hier erfahren Sie wie das geht.

Nginx protokolliert standardmäßig erfolgreiche Anfragen

Standardmäßig protokolliert Nginx alle erfolgreiche Zugriffe in seinen Zugriffsprokolldateien (“Access Logs”). In meiner eigenen Konfiguration hatte ich mit der Anweisung “access_log off;” bei JS, CSS, Bildern, PDFs usw. die Protokollierung im Erfolgsfall schon seit Jahren unterbunden. Dennoch kommen bei gut-besuchten Websites eine Menge Protokollsätze zusammen. Bei Nextcloud / OwnCloud gibt es sehr sehr viele PROPFIND-Sätze wenn Clients die Platten von PCs mit dem Serverbestand an Dateien synchronisieren, und noch mehr wenn auch Kontakte und Kalender synchronisiert werden.

Die Anfragen und deren Beantwortung sind in meiner Erfahrung nicht das große Problem – erst recht nicht wenn man einen Baremetal-Server betreibt. Das Problem ist das Schreiben der Protokollsätze in den Logdateien durch Nginx – und zwar einzeln: Logdatei öffnen, einen Satz am Ende anfügen, wieder schließen, und das immer wieder. In aller Regel für nichts und wieder nichts. Früher gab es den Grund dafür, dass Programme wie AWstats und Webalizer diese Dateien ausgewertet haben um Statistiken über Besuche zu erstellen – aber wer nutzt noch diese Technologie? Heutzutage verwendet man Plugins wie WP Statistics, Matomo oder Google Analytics und relevante Daten werden gleich in einer DB gespeichert.

An einem mittelgroßen vServer mit Nextcloud und ca. 8 andere Websites hatte meine externe Zabbix-Überwachung immer wieder gemeldet, dass verschiedene Dienste an dem vServer langsam antworten würden – obwohl die CPU-Belastung selten über 4 bis 5 Prozent lag. Seit ich untenstehende Optimierung in Kraft gesetzt habe, hat es keine einzige solche Meldung mehr gegeben. An einem kleineren Server, mit 5 Websites und den Zabbix-Server, konnte ich sogar CPU- und RAM-Zuteilung halbieren, und damit über 8 Euro / Monat an Servermiete sparen.

Grundsätzliches Unterbinden von Protokollsätzen mit 2xx und 3xx HTTP-Codes bei Nginx

Hier zunächst das Gewusst Wie bei der Nginx-Dokumentation. In aller Kürze: Das Feature heißt “Conditional Logging”, wobei man erst eine Bedingung festhält, und dann “if=condition” bei der Angabe der Logdatei hinten anhängt.

Die Bedingung (muss in Nginx http context stehen):

map $status $loggable {
  ~^([23]|401) 0;
  default 1;
}

access_log /var/log/nginx/access.log combined buffer=16k flush=10s if=$loggable;

Der Regex fängt alle Codes ab, die mit 2 oder 3 anfangen (Erfolg und Weiterleitung). Ich habe zusätzlich Code 401 abgefangen – dass ist die Einleitung der HTTP-Authentifizierung, die ja planmäßig kommt und damit keinen echten Fehler darstellt. Zudem habe ich den Standard-Log (die bei Anfragen auf die IP-Adresse sowie bei nicht-vorhandenen vhost-Angaben benutzt wird) gleich spezifiziert:

  • “combined” ist das übliche Logformat.
  • “buffer=16k” gibt die Größe des Puffers für noch nicht ausgeschrieben Logsätze an. Fehlt diese Angabe, schreibt Nginx jeden neuen Logsatz extra, was sehr unvorteilhaft ist.
  • “flush=10s” sagt, dass egal ob der Puffer voll ist oder nicht, spätestens nach 10 Sekunden alle angefallenen Sätze schreiben.

Nginx Konfiguration für vhosts in Plesk

Da ich Server grundsätzlich mit Plesk verwalte, beschreibe ich hier wie man die Access Logs der vhosts konfiguriert – die Technik kann für andere Konstellationen adaptiert werden, die Lösung ist bei Plesk leider etwas unschmackhaft. Denn leider vererben sich nicht alle Angaben, wenn man “access_log” mehrfach angibt. Genauer gesagt: Wenn man im Nginx server context nach der von Plesk erzeugten Konfiguration eine zweite “access_log” Anweisung setzt, dann werden buffer und flush Anweisungen anscheinend beachtet, die if-Bedingung aber nicht. Man muss also, damit alles greift, die Anweisung von Plesk abändern.

Das geht mit Plesk Custom Templates, was ich gerne vermeiden würde, aber in diesem Fall (und auch bei manchen Anforderungen wegen der “.php” Block) sich nicht vermeiden lässt. Es geht um das Template /domain/nginxDomainVirtualHost.php. In der Custom-Fassung muss die Zeile mit “access_log” wie folgt angepasst werden:

access_log "<?php echo $VAR->domain->physicalHosting->logsDir . '/' . ($OPT['ssl'] ? 'proxy_access_ssl_log' : 'proxy_access_log') ?>" combined buffer=16k flush=10s if=$loggable;

Dann müssen alle Webserver-Konfigurationen neu erzeugt werden:
# /usr/local/psa/admin/bin/httpdmng –reconfigure-all

Schließlich Nginx neu starten:
# systemctl restart nginx.service

Danach ist Ruhe in den Logdateien 

Zur Kontrolle aller Logdateien (angenommen alle Sites benutzen SSL):
# ls -l /var/log/nginx/access.log /var/www/vhosts/system/*/logs/proxy_access_ssl_log

Letzter Tipp bzgl. Plesk: Obiger Code mit der Bedingung und globalem access_log kann man in einer Datei z.B. ‘maploggable.conf’ im Verzeichnis /etc/nginx/conf.d einbringen.

Diese Idee von selektivem und gepuffertem Schreiben der Access Logs habe ich als Kommentar zu einem bereits vorhandenen Benutzerwunsch im Plesk User Voice geschildert. Please vote up and comment!

Kurze Logdateien als Voraussetzung für Fail2Ban

Bevor ich obige Optimierung vornahm, hatte ich Fail2Ban-Jails für Nginx selbst entwickelt (da sie von Plesk nicht bereitgestellt werden). Als ich sie einschaltete, stand der Server. Es kam wohl zu einer chronischen Überlastung des IO-Systems, als Nginx laufend neue Logsätze schrieb, und Fail2Ban die gleichen Dateien laufend mit mehreren Regexen durchkämmte. Das war der Grund, warum ich obige Optimierung recherchiert habe. Nun sind meine Fail2Ban Jails für Nginx aktiv – und ich habe immer noch keine einzige Meldung von Zabbix über langsame Antwortzeiten. Und so habe ich einen wesentlich sichereren Server, und noch dazu Geld gespart.

1 Kommentar

zu Nginx Konfiguration optimieren und Geld sparen

  • schrieb am

    Lieber Tim Reeves,

    ich möchte einfach erst mal danke sagen für diese informative Webseite.

    Auf der Suche nach einer Lösung für mein Problem mit Uptime Kuma, Docker und Nginx unter Plesk bin ich auf Ihre/Deine wirklich tolle Seite, mit vielen für mich interessanten Einblicken in die Handhabung von Nginx unter Plesk, gestoßen.

    Nun werde ich hier mal stöbern, ob ich darunter nicht auch eine Lösung für mein Problem mit Websocket Fehler auf https://status.dceserver.de/dashboard finde.
    Falls Ihnen/Dir dazu eine mögliche Lösung bekannt ist, würde ich mich sehr über einen Tipp freuen.

    Mit freundlichem Gruß aus Unterfranken

    Ortwin

Schreibe einen Kommentar

Bitte alle Felder ausfüllen. Deine IP-Adresse wird anonymisiert gespeichert. Fantasienamen und E-Mail Adressen (wie "donald@duck.org") werden akzeptiert.