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

 

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

 

Ubuntu - immer Up2date mit unbeaufsichtigten Updates

Die Woche war lang und das Wochenende hat schon einen Fuß in der Tür. 
Dennoch ein kleiner Tipp zum Freitag.

Damit ein System auf einem aktuellen Stand bleibt und keine Sicherheitslücken aufweist, müssen regelmäßig Updates installiert werden.
Dies kann händisch via apt-get upgrade oder mit Orchestrierungs- Lösungen alà Landscape (siehe Artikel), Ansible und Co gelöst werden.


Ubuntu selbst bringt allerdings ebenfalls Funktionen mit, ein System mit den neuesten Updates zu versorgen.
Bei kleinen Netzwerken mit drei bis vier Ubuntu Systemen, bietet sich diese Möglichkeit durchaus an, denn Landscape und Co wären hier zuviel des Guten.

Unattended Updates unter Ubuntu nutzen

Das Paket "unattended-upgrades" ermöglicht die automatische Installation von Updatepaketen.
Aber nicht nur die Installation, sondern auch Neustarts und Prioritäten von Updatepaketen können darüber definiert werden.

unattended-updates-einrichtungBevor das Paktet konfiguriert werden kann, sollte es installiert werden.

sudo apt-get install unattended-upgrades apt-listchanges

Nach der Installation wird eine Config Datei benötigt. Diese kann händisch angelegt werden oder automatisch mit

sudo dpkg-reconfigure -plow unattended-upgrades

Creating config file /etc/apt/apt.conf.d/20auto-upgrades with new version

angelegt werden. Hier erscheint eine zusätzliche Abfrage auf dem Bildschirm (siehe Screenshot).

Bei einem Blick auf die nun generierte Datei finden sich ein paar Einträge.

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

 
Hier muss eigentlich Nichts weiter angepasst werden.
Nutzer die bereits apticron in Verwendung haben, könnten die erste Zeile theoretisch entfernen, da über dieses Paket bereits die Listen regelmäßig aktualisiert werden

Konfiguration von unbeaufsichtigten Updates

Jedoch wird eine weitere Datei angelegt, in der diverse Einstellungen gemacht werden sollten.

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades
  • In diesem Beispiel werden nur Sicherheitsupdates automatisch installiert.
  • Danach wird eine Mail an root versendet.
  • Im Fehlerfall wird ebenfalls eine Nachricht versendet (der Punkt // Unattended-Upgrade::MailOnlyOnError "true"; sollte auskommentiert bleiben).
  • Nicht mehr verwendete Abhängigkeiten werden mit diesen Einstellungen automatisch entfernt.
  • Um den automatischen Updatevorgang abzuschließen, wird das System um 3:30 Uhr neu gestartet.

Alle aktiven Punkte sind fett markiert.



// Automatically upgrade packages from these (origin:archive) pairs
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";

//      "${distro_id}:${distro_codename}-updates";
//      "${distro_id}:${distro_codename}-proposed";
//      "${distro_id}:${distro_codename}-backports";
};


// This option allows you to control if on a unclean dpkg exit
// unattended-upgrades will automatically run
//   dpkg --force-confold --configure -a
// The default is true, to ensure updates keep getting installed
//Unattended-Upgrade::AutoFixInterruptedDpkg "false";

// Split the upgrade into the smallest possible chunks so that
// they can be interrupted with SIGUSR1. This makes the upgrade
// a bit slower but it has the benefit that shutdown while a upgrade
// is running is possible (with a small delay)
//Unattended-Upgrade::MinimalSteps "true";

// Install all unattended-upgrades when the machine is shuting down
// instead of doing it in the background while the machine is running
// This will (obviously) make shutdown slower
//Unattended-Upgrade::InstallOnShutdown "true";

// Send email to this address for problems or packages upgrades
// If empty or unset then no email is sent, make sure that you
// have a working mail setup on your system. A package that provides
// 'mailx' must be installed. E.g. "user@example.com"
Unattended-Upgrade::Mail "root";

// Set this value to "true" to get emails only on errors. Default
// is to always send a mail if Unattended-Upgrade::Mail is set
// Unattended-Upgrade::MailOnlyOnError "true";

// Do automatic removal of new unused dependencies after the upgrade
// (equivalent to apt-get autoremove)
Unattended-Upgrade::Remove-Unused-Dependencies "true";

// Automatically reboot *WITHOUT CONFIRMATION*
//  if the file /var/run/reboot-required is found after the upgrade
//Unattended-Upgrade::Automatic-Reboot "false";

// If automatic reboot is enabled and needed, reboot at the specific
// time instead of immediately
//  Default: "now"
Unattended-Upgrade::Automatic-Reboot-Time "03:30";

// Use apt bandwidth limit feature, this example limits the download
// speed to 70kb/sec
//Acquire::http::Dl-Limit "70";

Viel mehr muss nicht konfiguriert werden. Sollte ein Update gelaufen sein, wird automatisch eine E-Mail versendet, welche über die gelaufenen Updates oder entstandene Fehler informiert.

unattended-updates-linux


 

Ubuntu - IPv6 auf einem Tomcat Server ausschalten

Heute ein Mini Tipp zum kleinen Freitag.

Ipv6 auf einen Tomcat Server abschalten

Um einem Tomcat Server beizubringen, dass er nur auf einer IPv4 Adresse lauscht, muss unter Ubuntu (14.04) nur ein Startparameter gesetzt werden. Danach kann mit "netstat -tlpn" geprüft werden, wo der Tomcat lauscht. Ich gehe in diesem Beispiel davon aus, dass der Server über apt-get installiert wurde.

nano /etc/default/tomcat7

oder

nano /etc/default/tomcat6

Nun die vorhanden Zeile

JAVA_OPTS="-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC"

um einen Zusatz ergänzen

JAVA_OPTS="-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC  -Djava.net.preferIPv4Stack=true"

tomcat

Das könnte dich auch interessieren

ZTE Open C - Update auf Firefox OS 2.x in 10 Minuten

Firefox OS 2.0  kommt in großen Schritten, für Geekphone Besitzer ist es bereits verfügbar. Leider gilt dies (noch) nicht für das ZTE Open C. Auf dem Smartphone läuft noch ein stabiles Firefox OS 1.3.

Für die Ungeduldigen habe ich darum eine Schritt für Schritt Anleitung zusammen gestellt, wie sich schon jetzt FFOS 2.x verwenden lässt.

Achtung: Alle nicht gesicherten Daten auf dem Smartphone gehen bei diesem Vorgang verloren.

Kontakte können beispielsweise mit Contacts2Xml oder PC Sync gesichert werden, siehe Artikel


ZTE Open C auf Firefox OS 2.x aktualisieren

Vorbereitung

Zunächst müssen ein paar Dinge erledigt werden.

zte-open-root-connect


Rooting eines ZTE Open C in 10 Schritten

  1. Starten des ZTE Upgrade Tools.
  2. Entfernen der SIM Karte aus dem Smartphone.
  3. Anschließen des Telefons an den PC und warten bis es erkannt wird.
  4. Einbinden des zuvor entpackten Image Verzeichnisses unter "Software Directory".
  5. Auswählen von "erase CEFS".
  6. Warten bis der Status auf "Ready" ist.
  7. Starten des Upgrades.
  8. Während des Vorganges werdet ihr gefragt ob die SD Karte formatiert werden soll, dies kann abgebrochen werden.
  9. Nach Abschluss des Vorganges "Upgrade complete" startet das Telefon wahrscheinlich neu.
  10. Smartphone ausschalten.

zte-open-root-connected

zte-open-rooting

zte-open-root


Upgrade des ZTE Open C via SD Karte

Die einfachste Methode das Telefon auf ein aktuelles System zu bringen, ist bestimmt der Weg über die SD Karte.
Bei meinem Versuch konnte die SD Karte nicht auf Anhieb gefunden werden, darum habe ich das System über Windows aktualisiert. Dennoch hier der Vorgang.

  1. Die heruntergeladene "update.zip" auf die SD Karte kopieren (Siehe Vorbereitung).
  2. Die SD Karte in das Smartphone einschieben.
  3. Das Telefon im Wiederherstellungsmodus starten (Power und Lautstärke oben gleichzeitig drücken).
  4. "apply update from sdcard" auswählen (Navigation mit den Lautstärketasten, Auswahl mit der Powertaste).
  5. Die "update.zip" auf der SD Karte auswählen und das Update mit der Powertaste starten.
  6. Fertig.

Upgrade des ZTE Open via Windows.

  1. Installation des Android SDK Standalone.
  2. Starten des SDK Managers und Installation der "Google USB Driver".
  3. Auf dem Smartphone in den Entwicklereinstellungen das "remote debugging" aktivieren.
  4. Über "Start/ausführen" eine Kommandozeile öffnen "cmd.exe".
  5. Zur Installation des Android SDK und deren Plattform Tools wechseln "D:\android-sdk\plattform-tools".
  6. Mit dem Befehl "adb reboot recovery" das Smartphon im Wiederherstellungsmodus starten.
  7. Nun "apply update from adb" auswählen (Navigation mit den Lautstärketasten, Auswahl mit der Powertaste)
  8. Jetzt wieder in die Kommandozeile wevchseln und mit dem Befehl "adb sideload D:\pfad\update.zip" das gewünschte Image aufspielen.
  9. Nachdem das Update abgeschlossen ist, über "reboot" das Telefon neu starten
  10. Fertig

FFOS-2.1

Upgrade des ZTE Open via Ubuntu

Der gleiche Vorgang ist natürlich auch unter Ubuntu möglich, hier müssen ähnlich wie im Windows erst Pakete installiert werden.

  1. Folgende Pakete werden benötigt "sudo apt-get install android-tools-adb android-tools-fastboot"
  2. Nach der Installation müsse noch ein paar Regeln hinzugefügt werden
  3. sudo nano /etc/udev/rules.d/91-permissions.rules --> SUBSYSTEM=="usb", MODE="0666", GROUP="plugdev"
  4. Neustart der Dienstes mit sudo service udev restart
  5. Auf dem Smartphone in den Entwicklereinstellungen das "remote debugging" aktivieren.
  6. Nun kann ein Terminal geöffnet werden
  7. Mit dem Befehl "adb reboot recovery" das Telefon im Wiederherstellungsmodus starten.
  8. Nun "apply update from adb" auswählen (Navigation mit den Lautstärketasten, Auswahl mit der Powertaste)
  9. Jetzt wieder in die Kommandozeile wevchseln und mit dem Befehl "adb sideload /pfad/update.zip" das gewünschte Image aufspielen.
  10. Nachdem das Update abgeschlossen ist, über "reboot" das Telefon neu starten
  11. Fertig



Troubleshooting

Ich habe testweise ein Image 2.0 und ein Image 2.1 aufgespielt. Bei der ersten Verwendung konnte ich keine eklatanten Fehler feststellen.

Es kann vorkommen, dass ein SIM Karten Fehler angezeigt wird ("unknown SIM state"). Hier genügt es den Flugzeugmodus zu aktivieren/deaktivieren, damit die Karte richtig erkannt wird.

Screenshots mit Firefox OS 2.1 erstellen

Eine Hürde, welche sofort genommen werden musste, war die Screenshot Funktion. Diese versteckt sich ab Version 2.1 hinter der Tastenkombination "Power/Lautstärke leiser".

FFOS2.1

Fazit

Dank der Hilfe unserer französischen Mozilla Kollegen, welche neben den fertigen Images ebenfalls eine ausführliche Anleitung bereitstellen,  ist es für jeden normalen FFOS Anwender mit einem ZTE Open C kein Problem mehr auf neuere Versionen zu wechseln.

Der erste Eindruck des neuen Systems 2.x ist gut. Aufgeräumt und flüssig wirkt es auf den ersten Blick. Der neue Aufbau des Homescreens muss ich noch bewähren, wobei ich jetzt schon sagen kann, die "search the web" Kopfzeile ist Gold wert. Genauso ist mir die neue Tastatur aufgefallen, diese lässt sich nun schnell auf eine andere Sprache umstellen.

Neue Funktion, wie beispielsweise"find my device" gilt es noch zu testen. Bis jetzt kann ich sagen, das Update lohnt sich.

[Update 11/2015]

Inzwischen ist ein Nightly Build von Firefox OS 2.5 für das ZTE Open C verfügbar. Testen konnte ich es noch nicht, somit kann ich momentan noch keine Aussage über Funktionen und Mängel treffen.