Skip to content

NGINX - Webserver, Load Balancer und Proxy

NGINX ist neben Apache einer der bekanntesten Webserver. Allerdings kann das Tool mehr als nur ein schlichter Webserver sein. Reverse Proxy, Load Balancer, Mail Proxy oder HTTP cache Server sind ein paar wenige Funktionen die Nginx beherrscht.

Ich möchte euch heute ein paar Beispiele zu einzelnen Funktionen zeigen. Den Anfang macht logischerweise die Installation. Als System verwende ich einen Ubuntu 20.04 LTS Server.

 

Nginx

 

Installation Nginx unter Ubuntu/Debian

Die Installation der frei verfügbaren Version (Die kommerzielle Variante nennt sich Nginx Plus) erfolgt über das Nginx Repository.

sudo wget https://nginx.org/keys/nginx_signing.key

sudo apt-key add nginx_signing.key

sudo nano /etc/apt/sources.list.d/nginx.list

  deb https://nginx.org/packages/mainline/ubuntu/ focal nginx
  deb-src https://nginx.org/packages/mainline/ubuntu/ focal nginx
              
sudo apt install nginx

sudo systemctl is-enabled nginx.service

sudo systemctl enable nginx

Nach der Installation erfolgt eine schnelle Kontrolle.

ss -ltn
ubuntu:~$ curl -I http://127.0.0.2

HTTP/1.1 200 OK
Server: nginx/1.19.6
Date: Thu, 17 Dec 2020 22:20:49 GMT
Content-Type: text/html
Content-Length: 612

Nginx selbst kompilieren

Es besteht auch die Möglichkeit, das Nginx Paket selbst zu kompilieren. Dies wird dann nötig, wenn Pakete benötigt werden, die in der Standardvariante nicht enthalten sind. Die war zum Beispiel bei der Verwendung von GeoIP oder LibreSSL mal bzw. ist noch so.

Mit dem folgenden Befehl können die installierten Module eingesehen werden.

Nginx –V

In der Standardinstallation sollte hier das Modul --add-dynamic-module=/build/nginx-5J5hor/nginx-1.18.0/debian/modules/http-geoip2 angezeigt werden. D.h. das eingangs erwähnte Geo IP Modul wird hier bereits geladen.

Einen eigenen Nginx Server unter Debian/Ubuntu einrichten

Nach einer erfolgreichen Installation zeigt Nginx eine Standardseite an. Diese kann gelöscht oder zusätzlich eine eigene virtuelle Seite angelegt werden. Auf einer IP können so mehrere Webseiten gehostet werden.

Folgende Struktur bietet sich unter Ubuntu an:

Konfiguration der einzelnen virtuellen Server.

/etc/nginx/sites-available/xyz

Momentan aktive Server wobei es sich hier um einen Symlink handelt.

/etc/nginx/sites-enabled/xyz

Schritt für Schritt heißt dies für einen Server welche auf Port 80 lauscht:

#config anlegen
touch /etc/nginx/sites-available/itrig

#config schreiben
nano /etc/nginx/sites-available/itrig

server {

        listen 80 default_server;    

        # Make site accessible from http://localhost/

        server_name localhost;
        location / {
            root /usr/share/nginx/html;
            index index.html index.htm;
        }
}

#aktiv setzen
ln -s /etc/nginx/sites-available/itrig /etc/nginx/sites-enabled/itrig

Konfiguration überprüfen

nginx –t

Neustart der Konfiguration mit

#lädt nur die neue Konfiguration
nginx –s reload

oder

sudo systemctl reload nginx


Nginx als Loadbalancer verwenden

Neben der reinen Webserverfunktion bietet NGINX die Möglichkeit den Server, als Loadbalancer zu betreiben. Da heißt der Server sorgt für Ausfallsicherheit bzw. Leistung von Webanwendungen, in dem er die Last verteilt. Vorstellen kann man sich dies wie einen Haupthändler, welcher Daten unter verteilt.

LoadbalancerNginx bietet mehrere Varianten an, wie diese Verteilung geschehen kann.

Round Robin

Das bekannteste dürfte das Round Robin Verfahren sein. Es wird eine Liste von Servern durchgearbeitet und die Last nach und nach verteilt. Ist die Liste zu Ende, fängt der Server wieder am Anfang an.

Im unteren Beispiel werden 3 Server in der Gruppe "itrigloadbalancer" zusammengefasst und der Webserver geht diese Liste nach und nach durch. Unterstützt werden die Protokolle HTTP, HTTPS, FastCGI, uwsgi, SCGI, memcached, und gRPC.

http {
    upstream itrigloadbalancer {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://itrig.de;
        }
    }
}

Least Connected

Eine weitere Lastverteilung ist das Least-Connected-Verfahren. Hier wird auf die aktiven Verbindungen der einzelnen Server geschaut. Der Server, welcher die geringste Anzahl an aktiven Verbindungen hat, bekommt die Anfrage zugeschanzt.

upstream intrigleastload {
        least_conn;
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

Session-Persistenz - IP Hash

Die dritte Möglichkeit Last zu verteilen, stellt das IP-Hash-Verfahren dar. Hier werden von den zugreifenden Client IPs Hash Werte erstellt. Anhand dieser Werte wird einem Client immer ein bestimmter Server zugewiesen. Damit erhält der Nutzer eine Session Persistenz, da Anfragen immer vom gleichen Server beantwortet werden.

Beim Round-Robin- oder Least-Connected-Load-Balancing kann jede nachfolgende Anfrage eines Clients potenziell auf einem anderen Servern ankommen.

upstream itrighash {
    ip_hash;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
}

Weighted load balancing

Alle Varianten lassen sich zusätzlich gewichten. So kann es vorkommen, dass ein Server eine bessere Hardware verbaut hat, als ein anderer. Mit Weighted load balancing lässt sich einzelnen Geräten mehr Last zuschieben.

upstream itrigmitgewicht {
        server srv1.example.com;
        server srv2.example.com weight=3;
        server srv3.example.com;
    }
upstream itrig {
    ip_hash;
    server srv1.example.com weight=2;
    server srv2.example.com;
    server srv3.example.com;
}

Mehr zu der Thematik unter load_balancing.


Nginx als Reverse Proxy verwenden

Den aufmerksamen Lesern dürfte aufgefallen sein, dass in einem Code Beispiel weiter oben eine Zeile mit "proxy_pass" vorhanden ist. Diese Zeile deutet darauf hin, dass NGINX als Reverse Proxy eingesetzt wird und ein Aufruf nicht direkt auf dem Server landet, sondern weitergeleitet wird.

location /webshop {
proxy_pass http://opencart.itrig.local;
}

location /landkarte {
proxy_pass http://192.168.100.99;
}

Es gibt verschiedene "Vorteile" für so eine Weiterleitung.

So kann der Nginx als HTTPS Endpunkt dienen und die Struktur dahinter kann unverschlüsselt agieren. Auch bietet NGINX die Möglichkeit als Reverse Proxy und als Load Balancer gleichzeitig zu arbeiten, die Details sind weiter oben zu lesen.

Weiter erlaubt der vorgeschaltete Server eine Caching Funktion, was zum schnelleren Ausliefern von Webseiten beitragen kann.

Hier ein Beispiel mit gesplittetem Cache aus der offiziellen NGINX Cache Dokumentation.

proxy_cache_path /path/to/hdd1 levels=1:2 keys_zone=my_cache_hdd1:10m
                 max_size=10g inactive=60m use_temp_path=off;
proxy_cache_path /path/to/hdd2 levels=1:2 keys_zone=my_cache_hdd2:10m
                 max_size=10g inactive=60m use_temp_path=off;

split_clients $request_uri $my_cache {
              50%          “my_cache_hdd1”;
              50%          “my_cache_hdd2”;
}

server {
    # ...
    location / {
        proxy_cache $my_cache;
        proxy_pass http://my_upstream;
    }
}

Das Thema Sicherheit spielt ebenso eine Rolle, da durch den vorgeschalteten Server, die Angriffsfläche kleiner gehalten wird.


NGINX mit Regex

Richtig interessant wird es, sobald die aufgerufene URL verschiedene Eigenschaften besitzt bzw. ein besonderes Verhalten zeigen sollte.

Diese Eigenschaften werden mit regulären Ausdrücken umgesetzt.

Hier sind ein paar Beispiele von regulären Ausdrücken für NGINX :

# Die URL ist durch * case insensitive
 location ~* /itrig/ {
    #...
    #...
    }

# Die URL ist case sensitive das ^ sorgt dafür das nur z.B. /itrig/logo.jpg gültig ist und nach dem ersten Match gestoppt wird.
 location ^~ /itrig/ {
    #...
    #...
    }

# Bilder anhand der Endung umleiten
 location ~ \.(gif|jpg|png)$ {
    root /data/images;
    }

# Unnötige Endungen aussperren (case insensitive)
 location ~* "\.(old|orig|original|php#|php~|php_bak|save|swo|aspx?|tpl|sh|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rdf)$" {
    deny all;
    }

# Einen Alias setzen
 location /_/static {
        alias /path/to/glory;
    }

# Rewrite einer URL,  "pfad" wird entfernt
    location /pfad {
        rewrite ^/pfad(.*)$ $1 break;
        proxy_pass http://splunk-api:8080;
    }

Es bietet sich immer an, eigene Befehle zu testen, bevor sie produktiv eingesetzt werden, denn neben Einschränkungen auf URLs kann ebenso Haus und Hof geöffnet werden.

Ein Regex Test sollte daher immer gemacht werden. Hier findet sich so ein Tool online regex.datahoarder.dev.

Das Tool kann jederzeit auf der eigenen Umgebung gehostet werden und ist auf Github zu finden.

Nginx_Regular_Expression_Tester

 

LVM Anleitung - Volume Group umbenennen (Ubuntu/Mint)

Nachdem ich vor ein paar Tagen auf LVM und einen Update Fehler eingegangen bin, möchte ich heute kurz zeigen, wie eine Volume Group umbenannt werden kann.

Unter Ubuntu/Mint ist das an sich nur ein Befehl, allerdings sollten noch weitere Dateien angepasst werden, da es sonst zu Problemen kommt.

fstab

LVM - Volume Group umbenennen

Informationen zur vorhandenen Volume Group anzeigen

sudo vgdisplay

 

Volume Group umbenennen

sudo vgrename Ubuntu16 ubuntu

  Volume group "Ubuntu16" successfully renamed to "ubuntu"

 

File system table editieren und Name anpassen

sudo  nano /etc/fstab

# <file system> <mount point>   <type>  <options>       <dump>  <pass>

/dev/mapper/ubuntu-root /               ext4    errors=remount-ro 0   1

/dev/mapper/ubuntu-tmp  /tmp            ext4    errors=remount-ro 0   1

/dev/mapper/ubuntu-var  /var            ext4    errors=remount-ro 0   1

 

Initramfs anpassen, ebenfalls hier den neuen Namen einfügen

sudo nano /etc/initramfs-tools/conf.d/resume

 

Danach muss noch der Grand Unified Bootloader GRUB angepasst werden

sudo nano /boot/grub/grub.cfg

 

Ab Ubuntu 18.04 gilt es einen weitereren Eintrag zu editieren

sudo nano /boot/grub/menu.lst

 

Nun muss noch das initial ram filesystem neu gebaut werden

sudo  update-initramfs -u -k all

 

Mögliche Fehlermeldung

update-initramfs: Generating /boot/initrd.img-5.4.0-52-generic

cryptsetup: ERROR: Couldn't resolve device

Solltet ihr cryptsetup nicht verwenden, dann könnt ihr diesen Fehler ignorieren oder auch gleich deinstallieren

sudo apt-get remove cryptsetup

Alles auf einmal

Hier nochmal alle Schritte zusammengestellt. Der Einfachheit halber, können Änderungen mit sed gemacht werden

#!/bin/bash

altevolumegroup="ubuntu16"
neuevolumegroup="ubuntu"

vgrename ${altevolumegroup} ${neuevolumegroup}
sed -i "s/${altevolumegroup}/${neuevolumegroup}/g" /etc/fstab
sed -i "s/${altevolumegroup}/${neuevolumegroup}/g" /boot/grub/grub.cfg
sed -i "s/${altevolumegroup}/${neuevolumegroup}/g" /boot/grub/menu.lst
sed -i "s/${altevolumegroup}/${neuevolumegroup}/g" /etc/initramfs-tools/conf.d/resume
update-initramfs -c -k all

Anstatt des Namens kann übrigens auch die UUID genommen werden. Allerdings solltet ihr das Script dann so nicht verwenden.

vgrename Zvlifi-Ep3t-e0Ng-U44h-o0ye-KHu1-nl7Ns4 ubuntu

 

LVM Fehler nach Ubuntu 20.04 Update - VG is using an old PV header, modify the VG to update

Neulich ist mir ein Fehler beim Update von Ubuntu 16.04 auf Ubuntu 20.04 im LVM aufgefallen. Und zwar wurde eine Meldung angezeigt, die auf alte PV (Physical Volume) Header in einer VG (Volume Group) anspielt.

Ich hatte zum Thema LVM vor langer Zeit mal einen Artikel verfasst, falls es jemanden interessiert.

Der Fehler lässt sich mit dem Befehl vchck, welcher die Konsistenz von VGs prüft, nachstellen:

sudo vgck
  WARNING: PV /dev/sda2 in VG derVolumeGroupName is using an old PV header, modify the VG to update.
  WARNING: PV /dev/sda5 in VG derVolumeGroupName is using an old PV header, modify the VG to update.


Mit dem gleichen Tool lässt sich der Fehler beheben und zwar mit der Option updatemetadata, laut man pages kann er folgendes:

Update VG metadata to correct problems.  If VG metadata was updated while a PV was missing, and the PV reappears with an old version of metadata, then this option (or any other command that writes metadata) will update the metadata on the previously missing PV.

 Der LVM Fehler sollte nach dem Ausführen von vgck zusammen mit updatemetadata nicht mehr auftauchen.

 sudo vgck --updatemetadata derVolumeGroupName

 

PostgreSQL 12 Cluster auf PostgreSQL 13 aktualisieren

Die neue Version der Datenbanksoftware ist bereits einige Tage verfügbar.

Wer sich mit den Neuerungen beschäftigen möchte, der kann gerne in die Release Notes schauen oder sich diese Video zu Gemüte führen.

 

Hier soll es heute um das Update auf die neueste Version unter Ubuntu, Mint und Co gehen.

An dieser Prozedur hat sich seit den letzten Releases nicht wirklich etwas geändert, dennoch kann es nicht schaden, den Vorgang noch einmal durchzuspielen.

postgres_logo

Installation und Update auf PostgreSQL 13 unter Ubuntu

# Create the file repository configuration:
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

# Import the repository signing key:
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

# Update the package lists:
sudo apt-get update

# Install the latest version of PostgreSQL.
sudo apt-get -y install postgresql-13

# Sicherung erstellen
sudo su postgres
pg_dumpall > Sicherung
exit

#Vorhandene Cluster anzeigen
pg_lsclusters

#Neues Cluster anhalten
sudo pg_dropcluster --stop 13 main

#Vorhandenes Cluster aktualisieren
sudo pg_upgradecluster 12 main

postgresql13

Nun kanns die neue Version getestet werden, sollte alles korrekt sein, kann das alte Cluster entfernt werden

sudo pg_dropcluster 11 main
sudo pg_dropcluster 12 main

 

Läuft nicht ganz rund – WSL2 mit Windows 10 2004 und VirtualBox

In der Vergangenheit hatte ich bereits über WSL2 berichtet und die neuen Funktionen, die damit einhergehen. Leider kommt es nach der Aktivierung von WSL2 unter Windows 10 2004 zu Problemen mit VirtualBox.

Microsoft sind Probleme bekannt und listet dies auch auf der betreffenden FAQ Seite auf.

Ich hatte beispielsweise in der Vergangenheit mit aktivem WSL2 Probleme meine vorhandene Linux Server Systeme zu starten, bereits beim Bootvorgang kam es zu Kernel Fehlern, welche das System ausbremsten.

Da waren Fehler wie VERR_NEM_VM_CREATE_FAILED oder VERR_NEM_MISSING_KERNEL_API_2

WSL1 kannte diese Probleme noch nicht, da es Hyper-V (Windows Hypervisor Plattform) nicht verwendete, WSL2 tut aber genau dies, was wiederum zu dubiosen Fehlermeldungen in Verbindung mit VirtualBox führt.

Schlimmer wurde es mit Ubuntu Desktop 20.04 unter VirtualBox, hier war es nicht mehr möglich ein apt update auszuführen, ohne Hash Fehler (Hash sum mismatch) zu erhalten.

Hash_sum_mismatch

WSL2 und VirtualBox entweder oder - Die Lösung

Zunächst solltet ihr für eine aktuelle Umgebung sorgen

  • Aktualisiert VirtualBox, die neueste September Version 6.1.14 hat eines der hier beschriebenen Probleme gelöst. Changelog-6.1#v14
  • Deaktiviert das  Feature Windows Feature "Plattform für virtuelle Computer", damit greift VirtualBox auf seine eigene Engine zurück

PlattformfuervirtuelleComputer

Nach einem Neustart sollten alle Probleme in VirtualBox in Verbindung mit Linux Installation und Fehlern wie "Hash sum mismatch" oder "failed to fetch store" der Vergangenheit angehören. Negativer Effekt, WSL2 funktioniert nun nicht mehr.

Zum besseren Verständnis eine Übersicht der einzelnen Funktionen

  • Hyper-V ist der Hypervisor von Microsoft.
  • Plattform für virtuelle Computer - Ermöglicht Unterstützung für virtuelle Maschinen und ist für WSL2 erforderlich.
  • Windows-Hypervisor-Plattform - Ermöglicht die Ausführung von Virtualisierungssoftware auf dem Windows-Hypervisor. Die Hypervisor-Plattform ist eine API, die Drittanbieter-Entwickler für die Verwendung von Hyper-V verwenden können, beispielsweise Oracle VirtualBox oder Docker.

 

WSL und VirtualBox zusammen verwenden

Wie bereits oben erwähnt ist momentan ein Zusammenspiel von VirtualBox und WSL2 nicht ohne Probleme möglich.

Wer dennoch beide System verwenden möchte, der hat momentan nur die möglich auf WSL1 downzugraden.

WSL-Ubuntu_18.04_LTS_downgrade

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

wsl --list –verbose

wsl --set-version kali-linux 1

dism.exe /online /disable-feature /featurename:VirtualMachinePlatform /norestart

 

WSL selbst sollte natürlich weiterhin in den Windows Einstellungen aktiv sein.

WindowsSubsystemfuerLinux