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

 

LAMP Server mit SSL - Linux, Apache, MySQL, PHP unter Ubuntu 14.04 in 10min installieren

Im Prinzip hatte ich bereits ein fast komplette Anleitung für einen LAMP Server unter Ubuntu verfasst. Zu finden ist sie im Artikel "Wordpress Installation in 5 Minuten".

Dennoch möchte ich heute eine etwas ausführlichere Anleitung niederschreiben, die als Grundlage für weitere Installationen dienen kann.

1. Apache Server installieren

sudo apt-get update

sudo apt-get upgrade

sudo apt-get install apache2

Der Server startet direkt nach der Installation und ist unter http://localhost zu erreichen.

lamp-apache2-server

Weitere Konfigurationen wie bzw. das Härten sind in anderen Anleitungen zu finden. Siehe beispielsweise den Artikel "Hardening Apache".

Hier geht es nun mit dem MySQL Server weiter.

2. MySQL Server installieren

sudo apt-get install mysql-server

Das verlangte root Passwort vergeben und zwingend merken.

sudo apt-get install libapache2-mod-auth-mysql php5-mysql

lamp-mysql-server

Um die Installation abzurunden und eine erste Härtung vorzunehmen, sollte folgendes Skript ausgeführt werden.

sudo /usr/bin/mysql_secure_installation

Remove anonymous users? [Y/n] y ... Success!

Disallow root login remotely? [Y/n] y ... Success!

Remove test database and access to it? [Y/n] y

- Dropping test database...

- Removing privileges on test database... ... Success!

Reload privilege tables now? [Y/n] y ... Success!

Falls keine Testdatenbank existiert, kann diese auch nicht gelöscht werden, es erscheint die Meldung "Failed Database doesn't exists".

Der MySQL Server ist nun fertig eingerichtet.

Mit dem Befehl "mysql -u root -p" könnt ihr euch auf die SQL Konsole einloggen, um Datenbanken anzulegen.

Sollte eine andere IP als 127.0.0.1 verwendet werden, so muss "sudo nano /etc/mysql/my.cnf" editiert werden:

bind-address = 127.0.0.1

3. PHP5 installieren

sudo apt-get install php5 libapache2-mod-php5 php5-mcrypt

Neben dem bereits weiter oben installierten php5-mysql Paket gibt es weitere Pakete, die installiert werden können, je nach Anforderung.

Eine Liste der bereits installierten Module kann mit Hilfe einer "info.php" abgerufen werden. Hierzu ist noch etwas Konfigurationsaufwand nötig:

sudo nano /var/www/html/info.php

lamp-php-info

Danach kann unter http://localhost/info.php eine Übersicht der Installation abgerufen werden.

Weitere Module lassen sich mit "apt-cache search php5" auflisten und mit "sudo apt-get install modulname" nachinstallieren.

lamp-php5

Abschluss

Die Installation des LAMP Servers ist nun abgeschlossen. Jedoch ist es sinnvoll den Server weiter zu härten.

Es empfiehlt sich ein Umstellung auf HTTPS, sowie das Abschalten unsicherer Protokolle wie SSL 3.0.

Die Umstellung auf HTTPS werde ich noch einmal kurz erläutern.

4. LAMP Server auf HTTPS umstellen

Zunächst muss das SSL Modul installiert werden.

sudo a2enmod ssl

sudo service apache2 restart

Danach sollte ein Zertifikat erzeugt werden. Um die etwas kryptische Zeile zu verstehen, gebe ich eine eine kurze Erklärung zu dem Befehl.

  • Es wird ein selbstsigniertes Zertifikat erzeugt, dieses ist 1 Jahr gültig ("-days 365") und hat einen 4096bit RSA Schlüssel ("-newkey rsa:4096").
  • Die Option "-x509" sorgt für ein selbstsigniertes Zertifikat und keine Anfrage für einen CA (csr).
  • Indem der Wert "-nodes" verwendet wird, fällt die Abfrage nach einer Passphrase für den Schlüssel weg.

sudo mkdir /etc/apache2/crypt

sudo openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/apache2/crypt/srv.key -out /etc/apache2/crypt/srv.crt

Bitte darauf achten den richtigen CN zu vergeben.

Nachdem das Zertifikat erstellt wurde, muss dem Apache Server beigebracht werden, auf HTTPS zu lauschen.

Hierzu müssen ein paar Werte angepasst werden.

sudo nano /etc/apache2/sites-available/default-ssl.conf

SSLCertificateFile /etc/apache2/crypt/srv.crt

SSLCertificateKeyFile /etc/apache2/crypt/srv.key

Folgende Werte sollten zusätzlich eingefügt werde, um unsichere Protokolle zu deaktivieren:

SSLProtocol All -SSLv2 -SSLv3

SSLCompression off

Die neue Konfiguration muss abschließend aktiviert werden

sudo a2ensite default-ssl.conf

sudo service apache2 restart

Zur Erklärung: Durch den Befehl “a2ensite” wird ein symbolischer Link im sites-enabled Verzeichnis auf die .conf Datei des virtuellen Hosts im sites-available Verzeichnis gesetzt.

lamp-apache2-server-https

5. Ende

Nun ist der LAMP Server unter einer HTTPS Adresse zu erreichen. Für eine produktive Nutzung müssen natürlich noch weitere Schritte unternommen werden, auf die ich hier nicht weiter eingehe.

Die Grundinstallation ist jedoch geschafft und der Server kann zu Testzwecken verwendet werden.

Cryptocat 2.2 - Unterstützung für verschlüsselten Facebook Chat

Das OpenSource Projekt für verschlüsselte Chats "Cryptocat" wurde in einer neuen Version 2.2 veröffentlicht. Wesentliche Neuerung des Verschlüsselungstools ist die Integration des Facebook Chat Systems. 

Cryptocat

Innerhalb des sozialen Netzwerks werden Nachrichten zwar bereits verschlüsselt, sind aber für den Konzern selbst nach wie vor einsehbar. Mit der Verwendung von Cryptocat kann dies verhindert werden. Das Browser Addon für Firefox, Chrome, Opera und Safari verbindet sich mit euerem Facebook Konto und ermöglicht danach eine sichere Kommunikation durch Ende zu Ende Verschlüsselung mit Hilfe des OTR Protokolls.

Ende zu Ende Verschlüsselung für Facebook einrichten

Addon für Chrome Firefox oder Opera herunterladen (Firefox Anwender müssen sich noch bis Ende der Woche gedulden) und starten. Danach über den Reiter die Facebook Integration aktivieren.

cryptocat_facebook

 Nun müssen ein paar Berechtigungen für den Facebookzugriff freigegeben werden.

cryptocat_facebook_zugriff

Danach wird die Verschlüsselung generiert.

cryptocat_facebook_chat

Ab sofort steht dem sicheren Chat Vergnügen Nichts mehr im Wege. Vorausgesetzt der Chat Partner nutzt ebenfalls Cryptocat

Cryptocat_FB

Abschließend sollte erwähnt werden, dass Facebook immer noch Meta Daten von euch speichern kann, also wann und mit wem ihr gechattet habt, ist auch weiterhin nicht geheim. 

Cloud Dienste verschlüsseln mit BoxCryptor

Cloud Dienste wie Dropbox oder Ubuntu One (10 weitere Diente mit kostenlosen Webspace) sind immer noch in aller Munde und erfreuen sich großer Beliebtheit.

Da Daten unverschlüsselt in der Wolke liegen, ist es gerade bei sensiblen bzw. persönlichen Daten, sinnvoll diese zu verschlüsseln. Eine Möglichkeit wäre das bekannte TrueCrypt einzusetzen, diese stößt aber nicht überall auf Zustimmung. Eine einfachere Lösung ist das Tool BoxCryptor.

Dropbox mit BoxCryptor verschlüsseln

Das Tool hat eine automatische Dropbox Erkennung und bietet nach der Installation das Einrichten eines verschlüsselten Ordners an

boxcryptor

Im Zuge dieser Konfiguration muss das Quelllaufwerk (Dropboxordner) festgelegt werden, dieses wird normalerweise automatisch erkannt. Der zukünftige Laufwerksbuchstabe, sowie der Name müssen selbst gewählt werden, hier werden später die zu verschlüsselnden Daten abgelegt.

boxcryptor-einstellungen

Nun muss nur noch ein Passwort vergeben werden und schon können die Daten verschlüsselt im Netz abgelegt werden.

boxcryptor-passwort

Beim verschlüsselten Ablegen der Daten ist zu beachten, dass die Dateien nicht in den Boxcryptor Ordner innerhalb der Dropbox abgelegt, sondern einfach in das verbundene Boxcryptor Laufwerk (hier L:) gespeichert werden. Dies ist die Schnittstelle zur Dropbox und legt die Daten verschlüsselt in besagtem Dropboxordner ab bzw. speichert Dateien im Falle, dass die Dropbox nicht verfügbar ist.

boxcryptor-anleitung

Die nicht kommerzielle Version des BoxCryptor ist frei verfügbar und verschlüsselt bis zu 2GB mit dem AES-256 Standard. Das Tool kann zusätzlich auch unter Android, Ubuntu und MacOS verwendet werden.

Boxcryptor mit anderen Cloud Diensten

Das Verschlüsselungstool unterstützt inzwischen auch andere Cloud Services. So können StratoHiDrive und SugarSync nun auch mit erhöhter Datensicherheit verwendet werden.

Fernwartung mit Chrome Remote Desktop einrichten

Vor ein paar Tagen hat Google eine Remote Desktop App veröffentlicht. Dieses erlaubt es Desktopinhalte zu teilen oder sich bei Problemen von anderen helfen zu lassen. Für Besitzer eines Chromebook ermöglicht es zusätzlich den Zugriff auf Software anderer Betriebssysteme, die normalerweise nicht unterstützt wird.

Auch für Nutzer kommerzieller Anwendungen, wie TeamViewer, PCVisit oder VNC könnte die App eine freie Alternative darstellen, da sie systemunabhängig und kostenlos ist, wobei andererseits der Funktionsumfang sicherlich geringer ist.

Bevor sich jeder ein Urteil über Chrome Remote Desktop machen kann muss es zuerst installiert und eingerichtet werden.

Chrome Remote Desktop einrichten

  1. Die Anwendung kann im Chrome Webstore heruntergeladen und sofort installiert werden. Zur Verwendung ist ein Google Account nötig, der spätestens jetzt angelegt werden sollte.

    chrome-remote-desktop

  2. Sobald die Erweiterung mit "Hinzufügen" installiert ist, erscheint sie unter den persönlichen Anwendung auf der Startseite.

    chrome-remote-desktop-start

  3. Per Doppelklick startet der Einrichtungsassistent, welcher zunächst weitere Zugriffsberechtigungen auf dem PC einrichten möchte: "Zur Verwendung von Chrome Remote Desktop müssen Sie zunächst erweiterte Zugriffsberechtigungen auf Ihren Computer gewähren. Klicken Sie auf "Weiter", um die erforderlichen Berechtigungen anzuzeigen. Sie müssen dies nur einmal durchführen."

    chrome-remote-desktop-berechtigungen
  4. Nach dem Klick auf "Weiter" listet Chrome die benötigten Berechtigungen im Detail auf, dazu zählen die E-Mailadresse des Kontos, der Desktop und Chat Nachrichten über Google Talk

    chrome-remote-desktop-rechte

  5. Sobald "Zugriff gewähren" ausgewählt ist, erscheint die Freigabeaufforderung des Computers. Links in der Ecke wird zusätzlich die angemeldete Benutzermailadresse angezeigt.

    chrome-remote-desktop-freigabe
  6. Mit dem Klick auf "Diesen Computer freigeben" beginnt der Browser einen Zugriffscode zu generieren.

    chrome-remote-desktop-code

    Es kann dazu kommen, dass die Generierung abbricht und die Meldung erscheint "Ihre Chrome Desktop Sitzung wurde beendet". Dieser Fehler entsteht zur Zeit nur bei der Verwendung von "@googlemail.com" Adressen. Scheint noch ein grober Fehler in der Beta Version zu sein. Im Test konnten allen anderen E-Mailadressen verwendet werden.


  7. Sollte die Codegenerierung erfolgreich sein, geht der Computer automatisch in einen Wartemodus, damit ein anderer Client sich darauf verbinden kann. Sollte das in einem Zeitrahmen von wenigen Minuten nicht der Fall sein, verfällt der Zugangscode und muss neu generiert werden.

    chrome-remote-desktop-code2

Chrome Remote Desktop verwenden

  1. Die ersten Punkte, also die Installation der Anwendung muss natürlich auch auf dem Wartungscomputer stattfinden. D.h. bis Punkt 5 bleibt die Einrichtung gleich. Sollte alles richtig verlaufen müsste der Bildschirm "Diesen Computer freigeben" angezeigen. Dort muss aber in diesem Fall "Klicken Sie hier, um auf einen freigegebenen Computer zuzugreifen" gewählt und der vom Partner generierte Code hinterlegt werden (ohne Leerzeichen). Mit einem Klick auf "Verbinden" kann die Remote Verbindung auch schon genutzt werden.

    chrome-remote-desktop-zugriff

    chrome-remote-desktop-zugriffscode

    Als Client ist es zur Zeit egal welche E-Mailadresse verwendet wird. Solltet ihr nur eine @googlemail.com Adresse besitzen und einen Host einrichten, findet ihr hier eine andere Lösung, um das hoffentlich temporäre Problem zu umgehen.

Chrome Remote Desktop in Aktion

  1. Sobald der Freigabecode ohne Leerzeichen eingegeben und überprüft wurde, öffnet sich eine Verbindung und man hat die Kontrolle über den entfernten Desktop.

    chrome-remote-desktop-freigabe-beenden


    Der Nutzer des freigegebenen Desktop hat jederzeit die Möglichkeit eine Verbindung zu beenden. Zusätzlich zu der Anzeige in Chrome, wird dauerhaft ein Infofenster im Vordergrund angezeigt, um den Anwender über eine offene Verbindung zu informieren. Per Hotkey "Strg + Alt + Esc" kann eine Remote Verbindung im Notfall ebenfalls getrennt werden.

chrome-remote-desktop-trennen