One place for hosting & domains

      So installieren und sichern Sie Redis unter Ubuntu 20.04


      Eine frühere Version dieses Tutorials wurde von Justin Ellingwood verfasst

      Einführung

      Redis ist ein In-Memory-Schlüsselwertspeicher, der für seine Flexibilität, Leistung und breite Sprachunterstützung bekannt ist. Dieses Tutorial zeigt, wie Sie Redis auf einem Ubuntu 20.04-Server installieren, konfigurieren und sichern.

      Voraussetzungen

      Um diesen Leitfaden auszuführen, benötigen Sie Zugriff auf einen Ubuntu 20.04-Server, der einen non-root user mit sudo-Berechtigungen und eine mit ufw konfigurierte Firewall aufweist. Hierzu können Sie unserem Leitfaden zur Ersteinrichtung eines Servers unter Ubuntu 20.04 folgen.

      Schritt 1 — Installieren und Konfigurieren von Redis

      Wir verwenden den APT-Paketmanager, um Redis aus den offiziellen Ubuntu-Repositorys zu installieren. Zum Zeitpunkt dieses Schreibens ist die in den Standard-Repositorys verfügbare Version 5.0.7.

      Als Erstes aktualisieren Sie Ihren lokalen apt-Paketcache:

      Installieren Sie anschließend Redis, indem Sie Folgendes eingeben:

      • sudo apt install redis-server

      Dadurch werden Redis und seine Abhängigkeiten heruntergeladen und installiert. Danach müssen Sie eine wichtige Konfigurationsänderung in der Redis-Konfigurationsdatei vornehmen, die bei der Installation automatisch generiert wurde.

      Öffnen Sie diese Datei mit Ihrem bevorzugten Texteditor:

      • sudo nano /etc/redis/redis.conf

      Suchen Sie in der Datei die Anweisung supervised. Mit dieser Anweisung können Sie ein Init-System deklarieren, um Redis als Dienst zu verwalten. Damit erhalten Sie mehr Kontrolle über seine Funktion. Die Anweisung supervised ist standardmäßig auf no eingestellt. Da Ubuntu das Init-System systemd verwendet, ändern Sie die Anweisung zu systemd:

      /etc/redis/redis.conf

      . . .
      
      # If you run Redis from upstart or systemd, Redis can interact with your
      # supervision tree. Options:
      #   supervised no      - no supervision interaction
      #   supervised upstart - signal upstart by putting Redis into SIGSTOP mode
      #   supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
      #   supervised auto    - detect upstart or systemd method based on
      #                        UPSTART_JOB or NOTIFY_SOCKET environment variables
      # Note: these supervision methods only signal "process is ready."
      #       They do not enable continuous liveness pings back to your supervisor.
      supervised systemd
      
      . . .
      

      Das ist die einzige Änderung, die Sie an dieser Stelle in der Redis-Konfigurationsdatei vornehmen müssen. Wenn Sie fertig sind, speichern und schließen Sie die Datei. Wenn Sie nano zum Bearbeiten der Datei verwendet haben, drücken Sie dazu STRG + X, Y und dann ENTER.

      Starten Sie dann den Redis-Dienst neu, damit die Änderungen, die Sie in der Konfigurationsdatei vorgenommen haben, angewendet werden:

      • sudo systemctl restart redis.service

      Redis ist nun installiert und konfiguriert und läuft auf Ihrem Rechner. Bevor Sie Redis benutzen, ist es jedoch ratsam, zunächst zu prüfen, ob es korrekt funktioniert.

      Schritt 2 — Testen von Redis

      Wie bei jeder neu installierten Software ist es sinnvoll, sicherzustellen, dass Redis wie erwartet funktioniert, bevor weitere Änderungen an der Konfiguration vorgenommen werden. Wir behandeln in diesem Schritt verschiedene Möglichkeiten, um zu prüfen, ob Redis korrekt funktioniert.

      Zuerst überprüfen Sie, ob der Redis-Dienst ausgeführt wird:

      • sudo systemctl status redis

      Wenn er ohne Fehler ausgeführt wird, gibt dieser Befehl eine Ausgabe, die der folgenden ähnelt:

      Output

      ● redis-server.service - Advanced key-value store Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2020-04-30 23:26:54 UTC; 4s ago Docs: http://redis.io/documentation, man:redis-server(1) Process: 36552 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS) Main PID: 36561 (redis-server) Tasks: 4 (limit: 2345) Memory: 1.8M CGroup: /system.slice/redis-server.service └─36561 /usr/bin/redis-server 127.0.0.1:6379 . . .

      Hier können Sie sehen, dass Redis ausgeführt wird und bereits aktiviert ist. Das bedeutet, dass Redis bei jedem Boot des Servers automatisch startet.

      Anmerkung: Diese Einstellung ist für viele häufige Anwendungsfälle von Redis wünschenswert. Falls Sie Redis lieber manuell bei jedem Boot des Servers starten möchten, können Sie das mit folgendem Befehl konfigurieren:

      • sudo systemctl disable redis

      Um zu testen, ob Redis richtig funktioniert, stellen Sie mit dem Redis-Befehlszeilenclient redis-cli eine Verbindung zum Server her:

      Testen Sie in der folgenden Eingabeaufforderung die Verbindung mit dem Befehl ping:

      Output

      PONG

      Diese Ausgabe bestätigt, dass die Serververbindung nach wie vor besteht. Als Nächstes überprüfen Sie, ob Sie Schlüssel festlegen können, indem Sie Folgendes ausführen:

      Output

      OK

      Rufen Sie den Wert ab, indem Sie Folgendes eingeben:

      Wenn alles funktioniert, können Sie den gespeicherten Wert abrufen:

      Output

      "It's working!"

      Nachdem Sie die Bestätigung haben, dass Sie den Wert abrufen können, beenden Sie die Redis-Eingabeaufforderung, um wieder zur Shell zu gelangen:

      Als Letztes testen wir, ob Redis auch nach einem Stopp oder Neustart die Daten noch enthält. Dazu starten Sie die Redis-Instanz zunächst neu:

      • sudo systemctl restart redis

      Stellen Sie dann erneut mit dem Befehlszeilenclient eine Verbindung her:

      Bestätigen Sie, dass Ihr Testwert immer noch verfügbar ist:

      Der Wert Ihres Schlüssels sollte immer noch zugänglich sein:

      Output

      "It's working!"

      Wenn Sie fertig sind, beenden Sie und kehren zur Shell zurück:

      Damit ist die Redis-Installation voll funktionsfähig und kann von Ihnen verwendet werden. Einige der Standardkonfigurationseinstellungen sind jedoch unsicher und bieten böswilligen Akteuren die Möglichkeit, Ihren Server und seine Daten anzugreifen und sich Zugang dazu zu verschaffen. Die verbleibenden Schritte in diesem Tutorial behandeln Methoden zur Milderung dieser Schwachstellen, wie sie in der offiziellen Redis-Website beschrieben sind. Diese Schritte sind optional und Redis wird auch dann noch funktionieren, wenn Sie sie nicht befolgen. Es wird jedoch dringend empfohlen, die Schritte auszuführen, um die Sicherheit Ihres Systems zu erhöhen.

      Schritt 3 — Binden an localhost

      Standardmäßig ist Redis nur von localhost zugänglich. Wenn Sie Redis jedoch mit einem anderen Tutorial als diesem installiert und konfiguriert haben, haben Sie die Konfigurationsdatei eventuell so geändert, dass sie Verbindungen von überall zulässt. Das ist nicht so sicher wie eine Bindung an localhost.

      Um dies zu korrigieren, öffnen Sie die Redis-Konfigurationsdatei zur Bearbeitung:

      • sudo nano /etc/redis/redis.conf

      Suchen Sie diese Zeile und stellen Sie sicher, dass die Kommentierung aufgehoben ist (entfernen Sie das #, falls vorhanden):

      /etc/redis/redis.conf

      bind 127.0.0.1 ::1
      

      Danach speichern und schließen Sie die Datei (drücken Sie STRG + X, Y und dann ENTER).

      Starten Sie dann den Dienst neu, um sicherzustellen, dass systemd Ihre Änderungen liest:

      • sudo systemctl restart redis

      Um zu prüfen, ob diese Änderung angenommen wurde, führen Sie den folgenden netstat-Befehl aus:

      • sudo netstat -lnp | grep redis

      Output

      tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 14222/redis-server tcp6 0 0 ::1:6379 :::* LISTEN 14222/redis-server

      Anmerkung: Der Befehl netstat ist möglicherweise nicht standardmäßig auf Ihrem System verfügbar. In diesem Fall können Sie ihn (sowie eine Reihe anderer praktischer Netzwerktools) mit dem folgenden Befehl installieren:

      • sudo apt install net-tools

      Die Ausgabe zeigt, dass das redis-server-Programm an localhost (127.0.0.1) gebunden ist und zeigt die Änderung, die Sie gerade in der Konfigurationsdatei vorgenommen haben. Wenn Sie eine andere IP-Adresse in dieser Spalte sehen, z. B. (0.0.0.0), sollten Sie überprüfen, ob Sie die Kommentierung in der korrekten Zeile aufgehoben haben und den Redis-Dienst erneut starten.

      Nachdem die Redis-Installation nun nur auf localhost lauscht, wird es für böswillige Akteure schwieriger, Anfragen zu stellen oder Zugriff auf Ihren Server zu erhalten. Allerdings ist Redis derzeit nicht so eingestellt, dass Benutzer sich authentifizieren müssen, bevor sie Änderungen an der Konfiguration oder den gespeicherten Daten von Redis vornehmen können. Um hier Abhilfe zu schaffen, können Sie mit Redis verlangen, dass Benutzer sich mit einem Passwort authentifizieren, bevor sie Änderungen über den Redis-Client redis-cli vornehmen.

      Schritt 4 — Konfigurieren eines Redis-Passworts

      Durch die Konfiguration eines Redis-Passworts wird eine der beiden in Redis integrierten Sicherheitsfunktionen befähigt – der Befehl auth, mit dem sich Clients für den Zugriff auf die Datenbank authentifizieren müssen. Das Passwort wird direkt in der Konfigurationsdatei von Redis, /etc/redis/redis.conf, konfiguriert. Öffnen Sie diese Datei erneut mit Ihrem bevorzugten Editor:

      • sudo nano /etc/redis/redis.conf

      Scrollen Sie zum Abschnitt SECURITY und suchen Sie eine Anweisung mit der Kommentierung:

      /etc/redis/redis.conf

      . . .
      # requirepass foobared
      . . .
      

      Heben Sie die Kommentierung auf, indem Sie # entfernen, und ändern Sie foobared in ein sicheres Passwort.

      Anmerkung: Über der Anweisung requirepass in der Datei redis.conf gibt es eine kommentierte Warnung:

      /etc/redis/redis.conf

      . . .
      # Warning: since Redis is pretty fast an outside user can try up to
      # 150k passwords per second against a good box. This means that you should
      # use a very strong password otherwise it will be very easy to break.
      #
      . . .
      

      Daher ist es wichtig, dass Sie einen sehr starken und sehr langen Wert als Ihr Passwort angeben. Anstatt ein Passwort selbst einzurichten, können Sie den Befehl openssl verwenden, um ein Zufallspasswort zu generieren, wie im folgenden Beispiel. Durch Weiterleiten der Ausgabe des ersten Befehls an den zweiten openssl-Befehl, wie hier gezeigt, werden alle durch den ersten Befehl erzeugten Zeilenumbrüche entfernt:

      • openssl rand 60 | openssl base64 -A

      Ihre Ausgabe sollte ungefähr wie folgt aussehen:

      Output

      RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

      Nach dem Kopieren und Einfügen der Ausgabe dieses Befehls als den neuen Wert für requirepass sollte es so aussehen:

      /etc/redis/redis.conf

      requirepass RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

      Nach dem Einrichten des Passworts speichern und schließen Sie die Datei. Starten Sie erneut Redis:

      • sudo systemctl restart redis.service

      Öffnen Sie den Redis-Client, um zu testen, ob das Passwort funktioniert:

      Folgendes zeigt eine Sequenz von Befehlen, mit denen getestet wird, ob das Redis-Passwort funktioniert. Der erste Befehl versucht, einen Schlüssel auf einen Wert vor der Authentifizierung einzustellen:

      Das funktioniert nicht, da Sie keine Authentifizierung durchgeführt haben. Daher gibt Redis einen Fehler aus:

      Output

      (error) NOAUTH Authentication required.

      Der nächste Befehl führt die Authentifizierung mit dem Passwort durch, das in der Redis-Konfigurationsdatei angegeben ist:

      Redis bestätigt:

      Output

      OK

      Danach wird der vorherige Befehl erfolgreich ausgeführt:

      Output

      OK

      get key1 fragt Redis nach dem Wert des neuen Schlüssels.

      Output

      "10"

      Nachdem Sie die Bestätigung haben, dass Sie Befehle im Redis ausführen können, beenden Sie redis-cli:

      Als Nächstes befassen wir uns mit der Umbenennung von Redis-Befehlen, die Ihrem Rechner schweren Schaden zufügen können, falls sie versehentlich oder durch einen bösartigen Akteur eingegeben werden.

      Schritt 5 — Umbenennen von gefährlichen Befehlen

      Die andere in Redis integrierte Sicherheitsfunktion besteht in der Umbenennung oder vollständigen Deaktivierung bestimmter Befehle, die als gefährlich eingestuft werden.

      Diese Befehle können von unautorisierten Benutzern dazu verwendet werden, Ihre Daten anders zu konfigurieren, zu zerstören oder anderweitig zu löschen. Wie das Authentifizierungs-Passwort wird das Umbenennen oder Deaktivieren von Befehlen im gleichen SECURITY-Abschnitt der Datei /etc/redis/redis.conf konfiguriert.

      Einige der Befehle, die als gefährlich eingestuft werden, sind: FLUSHDB, FLUSHALL, KEYS, PEXPIRE, DEL, CONFIG, SHUTDOWN, BGREWRITEAOF, BGSAVE, SAVE, SPOP, SREM, RENAME und DEBUG. Die Liste ist nicht umfassend, aber das Umbenennen oder Deaktivieren aller Befehle in dieser Liste ist ein guter Ausgangspunkt, um die Sicherheit Ihres Redis-Servers zu erhöhen.

      Ob Sie einen Befehl deaktivieren oder umbenennen sollten, hängt von Ihren spezifischen Bedürfnissen oder von denen Ihrer Website ab. Wenn Sie für einen Befehl, der missbraucht werden könnte, keine Verwendung haben, können Sie ihn deaktivieren. Andernfalls liegt es in Ihrem Interesse, diesen umzubenennen.

      Um Redis-Befehle umzubenennen oder zu deaktivieren, öffnen Sie erneut die Konfigurationsdatei:

      • sudo nano /etc/redis/redis.conf

      Achtung: Die folgenden Schritte zur Deaktivierung und Umbenennung von Befehlen sind Beispiele. Sie sollten nur die Befehle deaktivieren oder umbenennen, die für Sie sinnvoll sind. Sie können die vollständige Liste der Befehle unter redis.io/commands selbst überprüfen und eruieren, wie diese missbraucht werden könnten.

      Um einen Befehl zu deaktivieren, benennen Sie ihn einfach wie unten gezeigt in eine leere Zeichenfolge um (gekennzeichnet durch ein Paar Anführungszeichen ohne Zeichen dazwischen):

      /etc/redis/redis.conf

      . . .
      # It is also possible to completely kill a command by renaming it into
      # an empty string:
      #
      rename-command FLUSHDB ""
      rename-command FLUSHALL ""
      rename-command DEBUG ""
      . . .
      

      Zur Umbenennung eines Befehls geben Sie diesem wie bei den unten gezeigten Beispielen einen anderen Namen. Umbenannte Befehle sollten für andere schwierig zu erraten und für Sie selbst leicht zu merken sein:

      /etc/redis/redis.conf

      . . .
      # rename-command CONFIG ""
      rename-command SHUTDOWN SHUTDOWN_MENOT
      rename-command CONFIG ASC12_CONFIG
      . . .
      

      Speichern Sie Ihre Änderungen und schließen Sie die Datei.

      Nach der Umbenennung eines Befehls wenden Sie die Änderung an, indem Sie Redis neu starten:

      • sudo systemctl restart redis.service

      Um den neuen Befehl zu testen, gehen Sie in die Redis-Befehlszeile:

      Führen Sie eine Authentifizierung durch:

      Output

      OK

      Nehmen wir an, dass Sie den Befehl CONFIG so wie im voherigen Beispiel in ASC12_CONFIG umbenannt haben. Versuchen Sie zunächst, den ursprünglichen Befehl CONFIG zu verwenden. Das sollte fehlschlagen, da Sie diesen umbenannt haben:

      Output

      (error) ERR unknown command `config`, with args beginning with:

      Der umbenannte Befehl kann jedoch erfolgreich aufgerufen werden. Die Groß- und Kleinschreibung muss nicht beachtet werden:

      • asc12_config get requirepass

      Output

      1) "requirepass" 2) "your_redis_password"

      Zum Schluss können Sie redis-cli verlassen:

      Beachten Sie, dass Sie sich erneut authentifizieren müssen, wenn Sie bereits die Befehlszeile von Redis verwenden und Redis neu starten. Andernfalls erhalten Sie diesen Fehler, wenn Sie einen Befehl eingeben:

      Output

      NOAUTH Authentication required.

      Bezüglich der Umbenennung von Befehlen wird am Ende des Abschnitts SECURITY in /etc/redis/redis.conf folgende Warnung angegeben:

      /etc/redis/redis.conf

      . . .
      # Please note that changing the name of commands that are logged into the
      # AOF file or transmitted to replicas may cause problems.
      . . .
      

      Hinweis: Das Redis-Projekt verwendet die Begriffe „master“ und „slave“, während DigitalOcean generell die Alternativen „primary“ und „secondary“ bevorzugt. Um Verwirrungen zu vermeiden, werden an dieser Stelle die in der Redis-Dokumentation genutzten Begriffe verwendet.

      Das bedeutet, dass es kein Problem geben sollte, wenn der umbenannte Befehl nicht in der AOF-Datei enthalten ist, oder wenn er enthalten ist, aber die AOF-Datei nicht an Slaves übertragen wurde.

      Denken Sie bitte daran, wenn Sie Befehle umbenennen möchten. Der beste Zeitpunkt zur Umbenennung eines Befehls ist dann, wenn Sie keine AOF-Persistenz nutzen. Ein anderer Zeitpunkt ist direkt nach der Installation, bevor die Anwendung bereitgestellt wird, die Redis verwendet.

      Wenn Sie AOF verwenden und mit einer Master-Slave-Installation arbeiten, sollten Sie diese Antwort von der GitHub-Frageseite des Projekts beachten. Nachfolgend eine Antwort auf die Frage des Autors:

      Die Befehle werden in der AOF protokolliert und auf die gleiche Weise, in der sie gesendet werden, an den Slave repliziert. Wenn Sie also versuchen, die AOF auf einer Instanz, die nicht die gleiche Umbenennung hat, erneut wiederzugeben, kann es zu Inkonsistenzen kommen, da der Befehl nicht ausgeführt werden kann (dasselbe gilt für Slaves).

      Daher ist es in Fällen wie diesen am besten, bei der Umbenennung sicherzustellen, dass umbenannte Befehle auf alle Instanzen in Master-Slave-Installationen angewendet werden.

      Zusammenfassung

      In diesem Tutorial haben Sie Redis installiert und konfiguriert, die korrekte Funktion Ihrer Redis-Installation überprüft und die integrierten Sicherheitsfunktionen genutzt, um sie weniger anfällig für Angriffe böswilliger Akteure zu machen.

      Denken Sie daran, dass die Sicherheitsfunktionen von Redis, die wir eingerichtet haben, sehr leicht zu umgehen sind, sobald sich jemand auf Ihrem Server angemeldet hat. Daher ist die wichtigste Sicherheitseinrichtung auf Ihrem Redis-Server Ihre Firewall (die Sie konfiguriert haben, wenn Sie in den Voraussetzungen dem Leitfaden zur Ersteinrichtung eines Servers gefolgt sind). Diese Barriere ist für böswillige Akteure nur sehr schwer zu überwinden.



      Source link

      So installieren Sie Drupal mit Docker Compose


      Der Autor hat die United Nations Foundation dazu ausgewählt, im Rahmen des Programms Write for DOnations eine Spende zu erhalten.

      Die ursprüngliche WordPress-Version dieses Tutorials wurde von Kathleen Juell verfasst.

      Einführung

      Drupal ist ein Content-Management-System (CMS), das in PHP geschrieben und unter der Open-Source-Lizenz GNU General Public License vergeben wird. Menschen und Organisationen in der ganzen Welt verwenden Drupal, um öffentliche Websites, persönliche Blogs, Unternehmen und mehr zu betreiben. Was Drupal von anderen CMS-Frameworks abhebt, ist seine wachsende Community und eine Reihe von Funktionen, die sichere Prozesse, zuverlässige Leistung, Modularität und Flexibilität zur Anpassung umfassen.

      Drupal erfordert die Installation des LAMP-Stacks (Linux, Apache, MySQL und PHP) oder des LEMP-Stacks (Linux, Nginx, MySQL und PHP), aber das Installieren einzelner Komponenten ist eine zeitaufwendige Aufgabe. Wir können Tools wie Docker und Docker Compose verwenden, um den Prozess der Installation von Drupal zu vereinfachen. Dieses Tutorial verwendet Docker-Images zur Installation einzelner Komponenten in den Docker-Containern. Mit der Verwendung von Docker Compose können wir mehrere Container für die Datenbank, die Anwendung und für die Vernetzung/Kommunikation zwischen ihnen definieren und verwalten.

      In diesem Tutorial installieren wir Drupal mit Docker Compose, damit wir die Containerisierung nutzen und unsere Drupal-Website auf Servern bereitstellen können. Wir führen Container für eine MySQL-Datenbank, einen Nginx-Webserver und Drupal aus. Außerdem sichern wir unsere Installation, indem wir TLS/SSL Zertifikate mit Let’s Encrypt für die Domäne erlangen, die wir mit unserer Website verknüpfen möchten. Schließlich richten wir einen cron-Job ein, um unsere Zertifikate zu erneuern, damit unsere Domäne sicher bleibt.

      Voraussetzungen

      Um diesem Tutorial zu folgen, benötigen Sie:

      • Einen Server, auf dem Ubuntu 18.04 ausgeführt wird, zusammen mit einem non-root user mit sudo-Privilegien und einer aktiven Firewall. Eine Anleitung für das Setup finden Sie im Leitfaden für die Ersteinrichtung des Servers.
      • Docker, gemäß Schritt 1 und 2 unter So installieren und verwenden Sie Docker unter Ubuntu 18.04 auf Ihrem Server installiert. Dieses Tutorial wurde unter der Version 19.03.8 getestet.
      • Docker Compose, gemäß Schritt 1 unter So installieren Sie Compose unter Ubuntu 18.04 auf Ihrem Server installiert. Dieses Tutorial wurde unter der Version 1.21.2 getestet.
      • Einen registrierten Domänennamen. Dieses Tutorial verwendet in allen Bereichen your_domain. Einen Domänennamen können Sie kostenlos bei Freenom erhalten oder Sie nutzen eine Domänenregistrierungsstelle Ihrer Wahl.
      • Die beiden folgenden DNS-Einträge für Ihren Server eingerichtet. Falls Sie ein DigitalOcean-Konto nutzen, können Sie in der Einführung in DigitalOcean-DNS im Einzelnen nachlesen, wie Sie diese hinzufügen:
        • Einen A-Eintrag mit your_domain, der auf die öffentliche IP-Adresse Ihres Servers verweist.
        • Einen A-Eintrag mit www.your_domain, der auf die öffentliche IP-Adresse Ihres Servers verweist.

      Schritt 1 — Definieren der Webserver-Konfiguration

      Bevor wir Container ausführen, müssen wir die Konfiguration für unseren Nginx-Webserver definieren. Unsere Konfigurationsdatei enthält einige Drupal-spezifische Location-Blocks, zusammen mit einem Location-Block zur Weiterleitung von Verifizierungsanforderungen von Let’s Encrypt an den Certbot-Client für automatisierte Zertifikatserneuerungen.

      Zuerst erstellen wir ein Projektverzeichnis für unser Drupal-Setup namens drupal:

      Rufen Sie das neu erstellte Verzeichnis auf:

      Nun können wir ein Verzeichnis für unsere Konfigurationsdatei erstellen:

      Öffnen Sie die Datei mit nano oder Ihrem bevorzugten Texteditor:

      • nano nginx-conf/nginx.conf

      In dieser Datei fügen wir einen Serverblock mit Anweisungen für unseren Servernamen und die Dokumenten-root hinzu sowie Location-Blocks, um die Anforderung des Certbot-Clients nach Zertifikaten, PHP-Verarbeitung und statischen Asset-Anforderungen zu leiten.

      Fügen Sie den folgenden Code in die Datei ein. Achten Sie darauf, your_domain durch Ihren eigenen Domänennamen zu ersetzen:

      ~/drupal/nginx-conf/nginx.conf

      server {
          listen 80;
          listen [::]:80;
      
          server_name your_domain www.your_domain;
      
          index index.php index.html index.htm;
      
          root /var/www/html;
      
          location ~ /.well-known/acme-challenge {
              allow all;
              root /var/www/html;
          }
      
          location / {
              try_files $uri $uri/ /index.php$is_args$args;
          }
      
          rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;
      
          location ~ .php$ {
              try_files $uri =404;
              fastcgi_split_path_info ^(.+.php)(/.+)$;
              fastcgi_pass drupal:9000;
              fastcgi_index index.php;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_param PATH_INFO $fastcgi_path_info;
          }
      
          location ~ /.ht {
              deny all;
          }
      
          location = /favicon.ico {
              log_not_found off; access_log off;
          }
          location = /robots.txt {
              log_not_found off; access_log off; allow all;
          }
          location ~* .(css|gif|ico|jpeg|jpg|js|png)$ {
              expires max;
              log_not_found off;
          }
      }
      

      Unser Serverblock enthält folgende Informationen:

      Anweisungen:

      • listen: Diese weist Nginx an, an Port 80 zu lauschen, sodass wir das Webroot-Plugin von Certbot für unsere Zertifikatsanforderungen nutzen können. Beachten Sie, dass wir noch nicht Port 443 einschließen – wir aktualisieren unsere Konfiguration, um SSL einzuschließen, sobald wir erfolgreich unsere Zertifikate erlangt haben.

      • server_name: Damit definieren Sie den Servernamen und den Serverblock, der für Anfragen an den Server verwendet werden sollte. Achten Sie darauf, your_domain in dieser Zeile durch Ihren eigenen Domänennamen zu ersetzen.

      • index: Die Anweisung index definiert die Dateien, die als Indizes bei der Verarbeitung von Anfragen an unseren Server dienen. Wir haben hier die Standardreihenfolge der Priorität geändert und index.php vor index.html geschoben, damit Nginx Dateien namens index.php wenn möglich priorisiert.

      • root: Unsere root-Anweisung benennt das root-Verzeichnis für Anfragen an unseren Server. Dieses Verzeichnis, /var/www/html, wird als Bereitstellungspunkt in der Erstellungszeit durch Anweisungen in unserer Drupal Dockerfile erstellt. Diese Dockerfile-Anweisungen stellen auch sicher, dass die Dateien aus der Drupal-Version auf diesem Volume bereitgestellt werden.

      • rewrite: Wenn die angegebene reguläre Expression (^/core/authorize.php/core/authorize.php(.*)$) mit einer URI-Anfrage übereinstimmt, wird die URI wie in der Ersatzzeichenfolge (/core/authorize.php$1) angegeben geändert.

      Location-Blocks:

      • location ~ /.well-known/acme-challenge: Dieser Location-Block verwaltet Anfragen an das Verzeichnis .well-known, in dem Certbot eine temporäre Datei ablegt, um zu validieren, dass das DNS für unsere Domäne auf unserem Server aufgelöst wird. Mit dieser Konfiguration können wir das Webroot-Plugin von Certbot verwenden, um Zertifikate für unsere Domäne zu erlangen.

      • location /: In diesem Location-Block verwenden wir eine try_files-Anweisung, um nach Dateien zu suchen, die individuellen URI-Anfragen entsprechen. Anstatt jedoch einen 404 Not Found-Status auszugeben, übergeben wir die Steuerung an die Datei index.php von Drupal mit den Anforderungsargumenten.

      • location ~ .php$: Dieser Location-Block verwaltet die PHP-Verarbeitung und überträgt diese Anfragen an unseren drupal-Container. Da unser Drupal-Docker-Image auf dem php:fpm-Image basiert, schließen wir auch Konfigurationsoptionen ein, die in diesem Block für das FastCGI-Protokoll spezifisch sind. Nginx erfordert einen unabhängigen PHP-Prozessor für PHP-Anfragen: In unserem Fall werden diese Anfragen vom php-fpm-Prozessor verwaltet, der im php:fpm-Image enthalten ist. Außerdem enthält dieser Location-Block FastCGI-spezifische Anweisungen, Variablen und Optionen, die Anfragen an die in unserem Drupal-Container ausgeführte Drupal-Anwendung überträgt, den bevorzugten Index für die analysierte Anfrage-URI festlegt und URI-Anfragen analysiert.

      • location ~ /.ht: Dieser Block verwaltet .htaccess-Dateien, da Nginx diese nicht bedient. Die Anweisung deny_all stellt sicher, dass .htaccess-Dateien nie für Benutzer bereitgestellt werden.

      • location = /favicon.ico, location = /robots.txt: Diese Blocks stellen sicher, dass Anfragen an /favicon.ico und /robots.txt nicht protokolliert werden.

      • location ~* . (css|gif|ico|jpeg|jpg|js|png)$: Dieser Block schaltet die Protokollierung für statische Asset-Anfragen ab und stellt sicher, dass diese Assets in hohem Maße zwischenspeicherbar sind, da ihre Bereitstellung in der Regel aufwendig ist.

      Weitere Informationen zu FastCGI-Proxying finden Sie in Verstehen und Implementieren von FastCGI-Proxying in Nginx. Informationen zu Server- und Location-Blocks finden Sie in Verstehen von Nginx-Server- und Location-Block-Auswahlalgorithmen.

      Wenn die Bearbeitung abgeschlossen wurde, speichern und schließen Sie die Datei.

      Nach Einrichtung der Nginx-Konfiguration können Sie Umgebungsvariablen erstellen, die zur Laufzeit an Ihre Anwendungs- und Datenbankcontainer übergeben werden.

      Schritt 2 — Definieren der Umgebungsvariablen

      Unsere Drupal-Anwendung benötigt eine Datenbank (MySQL, PostgresSQL, etc.) zum Speichern von Informationen im Zusammenhang mit der Website. Der Drupal-Container benötigt Zugriff auf bestimmte Umgebungsvariablen zur Laufzeit, um Zugriff auf den Datenbank-Container (MySQL) zu ermöglichen. Diese Variablen enthalten sensible Informationen wie die Zugangsdaten der Datenbank, sodass wir sie nicht direkt in der Docker-Compose-Datei offenlegen können – der Hauptdatei, die Informationen darüber enthält, wie unsere Container ausgeführt werden.

      Es wird immer empfohlen, die sensiblen Werte in der .env-Datei festzulegen und ihre Zirkulation zu beschränken. Dadurch werden diese Werte nicht in unsere Projekt-Repositorys kopiert und öffentlich verfügbar gemacht.

      Erstellen und öffnen Sie im Haupt-Projektverzeichnis ~/drupal eine Datei namens .env:

      Fügen Sie die folgenden Variablen in die .env-Datei ein und ersetzen Sie dabei die hervorgehobenen Abschnitte mit den Zugangsdaten, die Sie verwenden möchten:

      ~/drupal/.env

      MYSQL_ROOT_PASSWORD=root_password
      MYSQL_DATABASE=drupal
      MYSQL_USER=drupal_database_user
      MYSQL_PASSWORD=drupal_database_password
      

      Wir haben nun das Passwort für das MySQL-root-Administratorkonto sowie unseren bevorzugten Benutzernamen und das Passwort für unsere Anwendungsdatenbank hinzugefügt.

      Unsere .env-Datei enthält sensible Informationen. Es wird daher immer empfohlen, sie in die .gitignore– und .dockerignore-Dateien des Projekts einzufügen, damit sie nicht in unseren Git-Repositorys und Docker-Images hinzugefügt werden.

      Wenn Sie mit Git zur Versionskontrolle arbeiten möchten, initialisieren Sie Ihr aktuelles Arbeitsverzeichnis als ein Repository mit git init:

      Öffnen Sie die .gitignore-Datei:

      Fügen Sie Folgendes hinzu:

      ~/drupal/.gitignore

      .env
      

      Speichern und schließen Sie die Datei.

      Öffnen Sie in ähnlicher Weise die .dockerignore-Datei:

      Fügen Sie Folgendes hinzu:

      ~/drupal/.dockerignore

      .env
      .git
      

      Speichern und schließen Sie die Datei.

      Wir haben nun die Maßnahmen zur Sicherung unserer Zugangsdaten als Umgebungsvariablen ergriffen. Im nächsten Schritt definieren wir unsere Dienste in einer docker-compose.yml-Datei.

      Schritt 3 — Definieren der Dienste mit Docker Compose

      Docker Compose ist ein Tool zum Definieren und Ausführen von Docker-Anwendungen mit mehreren Containern. Wir definieren eine YAML-Datei, um die Dienste unserer Anwendung zu konfigurieren. Ein Dienst oder service in Docker Compose ist ein Container, der ausgeführt wird. Compose ermöglicht uns, diese Dienste zusammen mit geteilten Volumes und Netzwerken zu verknüpfen.

      Wir erstellen verschiedene Container für die Drupal-Anwendung, die Datenbank und den Webserver. Außerdem erstellen wir einen Container, der Certbot ausführt, um Zertifikate für unseren Webserver zu erlangen.

      Erstellen Sie eine docker-compose.yml-Datei:

      Fügen Sie den folgenden Code hinzu, um die Compose-Dateiversion und den mysql-Datenbankdienst zu definieren:

      ~/drupal/docker-compose.yml

      version: "3"
      
      services:
        mysql:
          image: mysql:8.0
          container_name: mysql
          command: --default-authentication-plugin=mysql_native_password
          restart: unless-stopped
          env_file: .env
          volumes:
            - db-data:/var/lib/mysql
          networks:
            - internal
      

      Wir behandeln diese nacheinander mit allen Konfigurationsoptionen des mysql-Dienstes:

      • image: Hiermit wird das Image festgelegt, das wir zum Erstellen des Containers verwenden/pullen. Es wird immer empfohlen, das Image mit dem richtigen Versions-Tag unter Ausschluss des latest-Tags zu verwenden, um zukünftige Konflikte zu vermeiden. Lesen Sie dazu mehr in Best Practices für Dockerfiles in der Docker-Dokumentation.

      • container_name: Hiermit wird der Name des Containers definiert.

      • command: Diese Option wird verwendet, um den Standardbefehl (CMD-Instruktion) im Image zu überschreiben. MySQL hat verschiedene Authentifizierungs-Plugins unterstützt, aber mysql_native_password ist die traditionelle Methode zur Authentifizierung. Da PHP und damit Drupal nicht die neuere MySQL-Authentifizierung unterstützen, müssen wir das --default-authentication-plugin=mysql_native_password als standardmäßigen Authentifizierungsmechanismus festlegen.

      • restart: Diese Option wird verwendet, um die Neustartregel des Containers festzulegen. Die Regel unless-stopped startet einen Container neu, bis er manuell gestoppt wird.

      • env_file: Hiermit werden die Umgebungsvariablen aus einer Datei hinzugefügt. In unserem Fall werden die Umgebungsvariablen aus der im vorherigen Schritt definierten .env-Datei gelesen.

      • volumes: Hiermit werden Host-Pfade oder benannte Volumes, die als Suboptionen eines Dienstes angegeben sind, bereitgestellt. Wir stellen ein benanntes Volume namens db-data im Verzeichnis /var/lib/mysql des Containers bereit, in der MySQL standardmäßig seine Datendateien schreibt.

      • networks: Hiermit wird das internal-Netzwerk, an das sich unser Anwendungsdienst anschließt, definiert. Wir definieren die Netzwerke am Ende der Datei.

      Wir haben unsere mysql-Dienstdefiniton definiert. Nun fügen wir die Definition des drupal-Anwendungsdienstes am Ende der Datei hinzu:

      ~/drupal/docker-compose.yml

      ...
        drupal:
          image: drupal:8.7.8-fpm-alpine
          container_name: drupal
          depends_on:
            - mysql
          restart: unless-stopped
          networks:
            - internal
            - external
          volumes:
            - drupal-data:/var/www/html
      

      In dieser Dienstdefinition benennen wir unseren Container und definieren eine Neustartregel, wie wir es beim mysql-Dienst getan haben. Außerdem fügen wir einige Optionen hinzu, die für diesen Container spezifisch sind:

      • image: Hier verwenden wir Drupal-Image 8.7.8-fpm-alpine. Dieses Image verfügt über den php-fpm-Prozessor, den unser Nginx-Webserver zur Verwaltung der PHP-Verarbeitung benötigt. Darüber hinaus verwenden wir das aus dem Alpine-Linux-Projekt erlangte alpine-Image, das die Größe des Gesamtimages reduziert und in den Best Practices für Dockerfiles empfohlen wird. Drupal verfügt über weitere Versionen von Images, die Sie auf Dockerhub finden können.

      • depends_on: Diese Option wird verwendet, um Abhängigkeit zwischen Diensten auszudrücken. Das Definieren des mysql-Dienstes als Abhängigkeit unseres drupal-Containers stellt sicher, dass unser drupal-Container nach dem mysql-Container erstellt wird und ermöglicht einen reibungslosen Start unserer Anwendung.

      • networks: Hier haben wir diesen Container zusammen mit dem internal-Netzwerk dem external-Netzwerk hinzugefügt. Dadurch wird sichergestellt, dass unser mysql-Dienst nur über das internal-Netzwerk aus dem drupal-Container zugänglich ist, während dieser Container über das external-Netzwerk für andere Container weiterhin zugänglich bleibt.

      • volumes: Wir stellen ein benanntes Volume namens drupal-data im Bereitstellungspunkt /var/www/html bereit, der vom Drupal-Image erstellt wurde. Wenn wir ein benanntes Volume auf diese Weise verwenden, können wir unseren Anwendungscode mit anderen Containern teilen.

      Als Nächstes fügen wir die Nginx-Dienstdefinition nach der drupal-Dienstdefinition hinzu:

      ~/drupal/docker-compose.yml

      ...
        webserver:
          image: nginx:1.17.4-alpine
          container_name: webserver
          depends_on:
            - drupal
          restart: unless-stopped
          ports:
            - 80:80
          volumes:
            - drupal-data:/var/www/html
            - ./nginx-conf:/etc/nginx/conf.d
            - certbot-etc:/etc/letsencrypt
          networks:
            - external
      

      Auch hier benennen wir unseren Container und machen ihn in der Reihenfolge des Starts vom Drupal-Container abhängig. Außerdem verwenden wir ein alpine-Image – das Nginx-Image 1.17.4-alpine.

      Diese Dienstdefinition enthält auch die folgenden Optionen:

      • ports: Hiermit wird Port 80 zur Verfügung gestellt, um die Konfigurationsoptionen zu aktivieren, die wir in unserer Datei nginx.conf in Schritt 1 definiert haben.

      • volumes: Hier definieren wir sowohl das benannte Volume als auch den Host-Pfad:

        • drupal-data:/var/www/html: Hiermit wird unser Drupal-Anwendungscode im Verzeichnis /var/www/html, das wir als die root in unserem Nginx-Serverblock festgelegt haben, bereitgestellt.
        • ./nginx-conf:/etc/nginx/conf.d: Hiermit wird das Nginx-Konfigurationsverzeichnis auf dem Host in dem entsprechenden Verzeichnis im Container bereitgestellt. Dadurch wird sichergestellt, dass alle Änderungen, die wir an Dateien auf dem Host vornehmen, im Container reflektiert werden.
        • certbot-etc:/etc/letsencrypt: Hiermit werden die relevanten Let’s-Encrypt-Zertifikate und die Schlüssel für unsere Domäne in dem entsprechenden Verzeichnis des Containers bereitgestellt.
        • networks: Wir haben das external-Netzwerk nur definiert, damit dieser Container mit dem drupal-Container, aber nicht mit dem mysql-Container kommunizieren kann.

      Schließlich fügen wir unsere letzte Dienstdefinition für den certbot-Dienst hinzu. Achten Sie darauf, sammy@your_domain und your_domain durch Ihre eigene E-Mail-Adresse und den Domänennamen zu ersetzen:

      ~/drupal/docker-compose.yml

      ...
        certbot:
          depends_on:
            - webserver
          image: certbot/certbot
          container_name: certbot
          volumes:
            - certbot-etc:/etc/letsencrypt
            - drupal-data:/var/www/html
          command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
      

      Diese Definition weist Compose an, das Image certbot/certbot von Docker Hub zu pullen. Außerdem werden benannte Volumes verwendet, um Ressourcen für den Nginx-Container freizugeben, einschließlich der Domänenzertifikate und des Schlüssels in certbot-etc und des Anwendungscodes in drupal-data.

      Wir haben auch depends_on verwendet, um sicherzustellen, dass der certbot-Container gestartet wird, nachdem der webserver-Dienst ausgeführt wird.

      Wir haben hier keine networks angegeben, da dieser Container mit keinem Dienst über das Netzwerk kommunizieren wird. Es werden nur die Domänenzertifikate und der Schlüssel hinzugefügt, die wir mit den benannten Volumes bereitgestellt haben.

      Außerdem haben wir die Option command eingeschlossen, die einen Unterbefehl angibt, der mit dem Standardbefehl certbot des Containers ausgeführt werden soll. Der Certbot-Client unterstützt Plugins zur Erstellung und Installation von Zertifikaten. Wir verwenden das webroot-Plugin, um ein Zertifikat zu erlangen, indem wir certonly und --webroot in die Befehlszeile einfügen. Lesen Sie mehr über das Plugin und zusätzliche Befehle in der offiziellen Certbot-Dokumentation.

      Fügen Sie nach der certbot-Dienstdefinition die Netzwerk- und Volume-Definitionen hinzu:

      ~/drupal/docker-compose.yml

      ...
      networks:
        external:
          driver: bridge
        internal:
          driver: bridge
      
      volumes:
        drupal-data:
        db-data:
        certbot-etc:
      

      Mit dem networks-Schlüssel der obersten Ebene können wir die zu erstellenden Netzwerke angeben. networks ermöglicht die Kommunikation über die Dienste/Container auf allen Ports, da sie sich auf demselben Docker-Daemon-Host befinden. Wir haben zwei Netzwerke, internal und external, definiert, um die Kommunikation der Dienste webserver, drupal und mysql zu sichern.

      Der volumes-Schlüssel wird verwendet, um die benannten Volumes drupal-data, db-data und certbot-etc zu definieren. Wenn Docker Volumes erstellt, werden die Inhalte des Volumes in einem Verzeichnis des Host-Dateisystems, /var/lib/docker/volumes/, gespeichert, das von Docker verwaltet wird. Die Inhalte jedes Volumes werden dann von diesem Verzeichnis in jedem Container bereitgestellt, der das Volume verwendet. Auf diese Weise können Code und Daten zwischen Containern geteilt werden.

      Die fertige docker-compose.yml-Datei sieht so aus:

      ~/drupal/docker-compose.yml

      version: "3"
      
      services:
        mysql:
          image: mysql:8.0
          container_name: mysql
          command: --default-authentication-plugin=mysql_native_password
          restart: unless-stopped
          env_file: .env
          volumes:
            - db-data:/var/lib/mysql
          networks:
            - internal
      
        drupal:
          image: drupal:8.7.8-fpm-alpine
          container_name: drupal
          depends_on:
            - mysql
          restart: unless-stopped
          networks:
            - internal
            - external
          volumes:
            - drupal-data:/var/www/html
      
        webserver:
          image: nginx:1.17.4-alpine
          container_name: webserver
          depends_on:
            - drupal
          restart: unless-stopped
          ports:
            - 80:80
          volumes:
            - drupal-data:/var/www/html
            - ./nginx-conf:/etc/nginx/conf.d
            - certbot-etc:/etc/letsencrypt
          networks:
            - external
      
        certbot:
          depends_on:
            - webserver
          image: certbot/certbot
          container_name: certbot
          volumes:
            - certbot-etc:/etc/letsencrypt
            - drupal-data:/var/www/html
          command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --staging -d your_domain -d www.your_domain
      
      networks:
        external:
          driver: bridge
        internal:
          driver: bridge
      
      volumes:
        drupal-data:
        db-data:
        certbot-etc:
      

      Nun sind unsere Dienstdefinitionen fertig. Als Nächstes starten wir den Container und testen unsere Zertifikatsanforderungen.

      Schritt 4 — Erlangen der SSL-Zertifikate und Zugangsdaten

      Wir können unsere Container mit dem Befehl docker-compose up starten, der die Container in der von uns angegebenen Reihenfolge erstellt und ausführt. Wenn unsere Domain-Anfragen erfolgreich sind, sehen wir den richtigen Exit-Status in unserer Ausgabe und die richtigen Zertifikate, die im Ordner /etc/letsencrypt/live im Webservercontainer bereitgestellt werden.

      Um die Container im Hintergrund auszuführen, verwenden Sie den Befehl docker-compose up mit dem Flag -d:

      Sie sehen eine ähnliche Ausgabe, die bestätigt, dass Ihre Dienste erstellt wurden:

      Output

      ... Creating mysql ... done Creating drupal ... done Creating webserver ... done Creating certbot ... done

      Überprüfen Sie den Status der Dienste mit dem Befehl docker-compose ps:

      Wir sehen die Dienste mysql, drupal und webserver mit einem State von Up, während certbot mit einer Statusmeldung von 0 beendet wird:

      Output

      Name Command State Ports -------------------------------------------------------------------------- certbot certbot certonly --webroot ... Exit 0 drupal docker-php-entrypoint php-fpm Up 9000/tcp mysql docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp webserver nginx -g daemon off; Up 0.0.0.0:80->80/tcp

      Wenn Sie in der Spalte State für die Dienste mysql, drupal oder webserver etwas anderes als Up sehen, oder für den certbot-Container einen anderen Exit-Status als 0, überprüfen Sie die Dienstprotokolle mit dem Befehl docker-compose logs:

      • docker-compose logs service_name

      Wir können nun mit dem Befehl docker-compose exec überprüfen, dass unsere Zertifikate auf dem webserver bereitgestellt wurden:

      • docker-compose exec webserver ls -la /etc/letsencrypt/live

      Dadurch erhalten Sie folgende Ausgabe:

      Output

      total 16 drwx------ 3 root root 4096 Oct 5 09:15 . drwxr-xr-x 9 root root 4096 Oct 5 09:15 .. -rw-r--r-- 1 root root 740 Oct 5 09:15 README drwxr-xr-x 2 root root 4096 Oct 5 09:15 your_domain

      Nachdem nun alles erfolgreich ausgeführt wird, können wir unsere certbot-Dienstdefinition bearbeiten, um das Flag --staging zu entfernen.

      Öffnen Sie die Datei docker-compose.yml, gehen Sie zur certbot-Dienstdefinition und ersetzen Sie das Flag --staging in der Befehlsoption mit dem Flag --force-renewal, das Certbot mitteilt, dass Sie ein neues Zertifikat mit denselben Domänen wie ein vorhandenes Zertifikat anfordern möchten. Die aktualisierte Definition von certbot sieht wie folgt aus:

      ~/drupal/docker-compose.yml

      ...
        certbot:
          depends_on:
            - webserver
          image: certbot/certbot
          container_name: certbot
          volumes:
            - certbot-etc:/etc/letsencrypt
            - drupal-data:/var/www/html
          command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
      ...
      

      Wir müssen docker-compose erneut ausführen, um den certbot-Container neu zu erstellen. Wir schließen auch die Option --no-deps ein, um Compose mitzuteilen, dass das Starten des webserver-Dienstes übersprungen werden kann, da dieser bereits ausgeführt wird:

      • docker-compose up --force-recreate --no-deps certbot

      In der Ausgabe sehen wir, dass unsere Zertifikatsanforderung erfolgreich war:

      Output

      Recreating certbot ... done Attaching to certbot certbot | Saving debug log to /var/log/letsencrypt/letsencrypt.log certbot | Plugins selected: Authenticator webroot, Installer None certbot | Renewing an existing certificate certbot | Performing the following challenges: certbot | http-01 challenge for your_domain certbot | http-01 challenge for www.your_domain certbot | Using the webroot path /var/www/html for all unmatched domains. certbot | Waiting for verification... certbot | Cleaning up challenges certbot | IMPORTANT NOTES: certbot | - Congratulations! Your certificate and chain have been saved at: certbot | /etc/letsencrypt/live/your_domain/fullchain.pem certbot | Your key file has been saved at: certbot | /etc/letsencrypt/live/your_domain/privkey.pem certbot | Your cert will expire on 2020-01-03. To obtain a new or tweaked certbot | version of this certificate in the future, simply run certbot certbot | again. To non-interactively renew *all* of your certificates, run certbot | "certbot renew" certbot | - Your account credentials have been saved in your Certbot certbot | configuration directory at /etc/letsencrypt. You should make a certbot | secure backup of this folder now. This configuration directory will certbot | also contain certificates and private keys obtained by Certbot so certbot | making regular backups of this folder is ideal. certbot | - If you like Certbot, please consider supporting our work by: certbot | certbot | Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate certbot | Donating to EFF: https://eff.org/donate-le certbot | certbot exited with code 0

      Nachdem wir unsere Zertifikate erfolgreich generiert haben, können wir unsere Nginx-Konfiguration aktualisieren, um SSL einzuschließen.

      Schritt 5 — Ändern der Webserver-Konfiguration und Dienstdefinition

      Nach der Installation von SSL-Zertifikaten in Nginx müssen wir alle HTTP-Anfragen an HTTPS umleiten. Außerdem müssen wir unser SSL-Zertifikat und unsere Schlüsselpositionen angeben und Sicherheitsparameter sowie Header hinzufügen.

      Da Sie den webserver-Dienst neu erstellen, um diese Ergänzungen einzuschließen, können Sie diesen jetzt stoppen:

      • docker-compose stop webserver

      Dadurch erhalten Sie folgende Ausgabe:

      Output

      Stopping webserver ... done

      Als Nächstes entfernen wir die zuvor erstellte Nginx-Konfigurationsdatei:

      Öffnen Sie eine andere Version der Datei:

      • nano nginx-conf/nginx.conf

      Fügen Sie der Datei den folgenden Code hinzu, um HTTP an HTTPS umzuleiten und SSL-Zugangsdaten, Protokolle und Sicherheitsheader hinzuzufügen. Denken Sie daran, your_domain durch Ihre eigene Domäne zu ersetzen:

      ~/drupal/nginx-conf/nginx.conf

      server {
          listen 80;
          listen [::]:80;
      
          server_name your_domain www.your_domain;
      
          location ~ /.well-known/acme-challenge {
              allow all;
              root /var/www/html;
          }
      
          location / {
              rewrite ^ https://$host$request_uri? permanent;
          }
      }
      server {
          listen 443 ssl;
          listen [::]:443 ssl;
          server_name your_domain www.your_domain;
      
          index index.php index.html index.htm;
      
          root /var/www/html;
      
          server_tokens off;
      
          ssl_certificate /etc/letsencrypt/live/your_domain/fullchain.pem;
          ssl_certificate_key /etc/letsencrypt/live/your_domain/privkey.pem;
      
          add_header X-Frame-Options "SAMEORIGIN" always;
          add_header X-XSS-Protection "1; mode=block" always;
          add_header X-Content-Type-Options "nosniff" always;
          add_header Referrer-Policy "no-referrer-when-downgrade" always;
          add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
      
          location / {
              try_files $uri $uri/ /index.php$is_args$args;
          }
      
          rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;
      
          location ~ .php$ {
              try_files $uri =404;
              fastcgi_split_path_info ^(.+.php)(/.+)$;
              fastcgi_pass drupal:9000;
              fastcgi_index index.php;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_param PATH_INFO $fastcgi_path_info;
          }
      
          location ~ /.ht {
              deny all;
          }
      
          location = /favicon.ico {
              log_not_found off; access_log off;
          }
          location = /robots.txt {
              log_not_found off; access_log off; allow all;
          }
          location ~* .(css|gif|ico|jpeg|jpg|js|png)$ {
              expires max;
              log_not_found off;
          }
      }
      

      Der HTTP-Serverblock gibt das Webroot-Plugin für Certbot-Erneuerungsanfragen an das Verzeichnis .well-known/acme-challenge an. Er enthält auch eine rewrite-Anweisung, die HTTP-Anfragen an das root-Verzeichnis an HTTPS leitet.

      Der HTTPS-Serverblock aktiviert ssl und http2. Weitere Informationen dazu, wie HTTP/2 über HTTP-Protokolle iteriert und welche Vorteile es für die Website-Leistung haben kann, lesen Sie bitte in der Einführung Einrichten von Nginx mit HTTP/2-Support unter Ubuntu 18.04.

      Diese Blocks aktivieren SSL, da wir unser SSL-Zertifikat und die Schlüsselpositionen zusammen mit den empfohlenen Headern eingefügt haben. Diese Header ermöglichen uns eine A-Bewertung auf den Server-Testseiten SSL-Labs und Security Headers.

      Unsere Anweisungen root und index befinden sich ebenfalls in diesem Block, ebenso wie die restlichen Drupal-spezifischen Location-Blocks, die in Schritt 1 behandelt wurden.

      Speichern und schließen Sie die aktualisierte Nginx-Konfigurationsdatei.

      Bevor wir den webserver-Container neu erstellen, müssen wir unserem webserver-Dienst ein 443-Port-Mapping hinzufügen, da wir SSL-Zertifikate aktiviert haben.

      Öffnen Sie die Datei docker-compose.yml:

      Führen Sie die folgenden Änderungen in der webserver-Dienstdefinition aus:

      ~/drupal/docker-compose.yml

      ...
        webserver:
          image: nginx:1.17.4-alpine
          container_name: webserver
          depends_on:
            - drupal
          restart: unless-stopped
          ports:
            - 80:80
            - 443:443
          volumes:
            - drupal-data:/var/www/html
            - ./nginx-conf:/etc/nginx/conf.d
            - certbot-etc:/etc/letsencrypt
          networks:
            - external
      ...
      

      Nach dem Aktivieren der SSL-Zertifikate sieht unsere docker-compose.yml wie folgt aus:

      ~/drupal/docker-compose.yml

      version: "3"
      
      services:
        mysql:
          image: mysql:8.0
          container_name: mysql
          command: --default-authentication-plugin=mysql_native_password
          restart: unless-stopped
          env_file: .env
          volumes:
            - db-data:/var/lib/mysql
          networks:
            - internal
      
        drupal:
          image: drupal:8.7.8-fpm-alpine
          container_name: drupal
          depends_on:
            - mysql
          restart: unless-stopped
          networks:
            - internal
            - external
          volumes:
            - drupal-data:/var/www/html
      
        webserver:
          image: nginx:1.17.4-alpine
          container_name: webserver
          depends_on:
            - drupal
          restart: unless-stopped
          ports:
            - 80:80
            - 443:443
          volumes:
            - drupal-data:/var/www/html
            - ./nginx-conf:/etc/nginx/conf.d
            - certbot-etc:/etc/letsencrypt
          networks:
            - external
      
        certbot:
          depends_on:
            - webserver
          image: certbot/certbot
          container_name: certbot
          volumes:
            - certbot-etc:/etc/letsencrypt
            - drupal-data:/var/www/html
          command: certonly --webroot --webroot-path=/var/www/html --email sammy@your_domain --agree-tos --no-eff-email --force-renewal -d your_domain -d www.your_domain
      
      networks:
        external:
          driver: bridge
        internal:
          driver: bridge
      
      volumes:
        drupal-data:
        db-data:
        certbot-etc:
      

      Speichern und schließen Sie die Datei. Wir erstellen den webserver-Dienst mit unserer aktualisierten Konfiguration nun neu:

      • docker-compose up -d --force-recreate --no-deps webserver

      Dadurch erhalten Sie folgende Ausgabe:

      Output

      Recreating webserver ... done

      Überprüfen Sie die Dienste mit docker-compose ps:

      Wir sehen die Dienste mysql, drupal und webserver als Up, während certbot mit der Statusmeldung 0 beendet wird:

      Output

      Name Command State Ports -------------------------------------------------------------------------- certbot certbot certonly --webroot ... Exit 0 drupal docker-php-entrypoint php-fpm Up 9000/tcp mysql docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp webserver nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp

      Jetzt werden alle unsere Dienste ausgeführt und wir können mit der Installation von Drupal über die Web-Oberfläche fortfahren.

      Schritt 6 – Abschließen der Installation über die Weboberfläche

      Beenden wir die Installation über die Weboberfläche von Drupal.

      Navigieren Sie in einem Webbrowser zur Domäne des Servers. Denken Sie daran, your_domain hier mit Ihrem eigenen Domänennamen zu ersetzen:

      https://your_domain
      

      Wählen Sie die Sprache aus, die Sie verwenden möchten:

      Sprachauswahlseite auf der Drupal-Weboberfläche

      Klicken Sie auf Speichern und fortfahren. Wir werden zur Seite der Installationsprofile geleitet. Drupal bietet verschiedene Profile. Wählen Sie das Profil Standard und klicken Sie auf Speichern und fortfahren.

      Profilauswahlseite auf der Drupal-Weboberfläche

      Nach Auswahl des Profils gehen wir weiter zur Seite der Datenbankkonfiguration. Wählen Sie als Datenbanktyp MySQL, MariaDB, Percona Server oder äquivalent aus. Geben Sie die Werte für Datenbankname, Benutzername und Passwort entsprechend der Werte von MYSQL_DATABASE, MYSQL_USER und MYSQL_PASSWORD ein, die jeweils in der .env-Datei in Schritt 2 definiert wurden. Klicken Sie auf Erweiterte Optionen und setzen Sie den Wert für Host auf den Namen des mysql-Dienstcontainers. Klicken Sie auf Speichern und fortfahren.

      Datenbankeinrichtungsseite auf der Drupal-Weboberfläche

      Nach Konfiguration der Datenbank beginnt die Installation der Standardmodule und Themen von Drupal:

      Installationsseite der Website auf der Drupal-Weboberfläche

      Nachdem die Website installiert ist, werden wir auf die Einrichtungsseite der Drupal-Website geleitet, um den Namen der Website, die E-Mail-Adresse, den Benutzernamen, das Passwort und die Ländereinstellungen zu konfigurieren. Geben Sie die Informationen an und klicken Sie auf Speichern und fortfahren:

      Konfigurationsseite der Website auf der Drupal-Weboberfläche

      Nachdem wir auf Speichern und fortfahren geklickt haben, sehen wir die Seite Willkommen bei Drupal. Diese zeigt uns, dass unsere Drupal-Website eingerichtet ist und erfolgreich ausgeführt wird.

      Seite Willkommen bei Drupal auf der Drupal-Weboberfläche

      Nachdem die Installation von Drupal nun abgeschlossen ist, müssen wir sicherstellen, dass unsere SSL-Zertifikate automatisch erneuert werden.

      Schritt 7 — Erneuern der Zertifikate

      Let’s-Encrypt-Zertifikate sind 90 Tage gültig. Daher müssen wir einen automatisierten Erneuerungsprozess einrichten, um sicherzustellen, dass sie nicht ablaufen. Eine Möglichkeit hierzu ist das Erstellen eines Jobs mit dem Planungsprogramm cron. In diesem Fall erstellen wir einen cron-Job, der in regelmäßigen Abständen ein Skript ausführt, das unsere Zertifikate erneuert und die Nginx-Konfiguration neu lädt.

      Wir erstellen die Datei ssl_renew.sh, um unsere Zertifikate zu erneuern:

      Fügen Sie folgenden Code hinzu. Denken Sie daran, den Verzeichnisnamen durch Ihren eigenen non-root user zu ersetzen:

      ~/drupal/ssl_renew.sh

      
      #!/bin/bash
      
      cd /home/sammy/drupal/
      /usr/local/bin/docker-compose -f docker-compose.yml run certbot renew --dry-run && 
      /usr/local/bin/docker-compose -f docker-compose.yml kill -s SIGHUP webserver
      

      Das Skript wechselt zum ~/drupal-Projektverzeichnis und führt die folgenden docker-compose-Befehle aus.

      • docker-compose run: Hiermit wird ein certbot-Container gestartet und der in unserer certbot-Dienstdefinition verfügbare command überschrieben. Anstatt des Unterbefehls certonly verwenden wir hier den Unterbefehl renew, mit dem Zertifikate, die kurz vor Ablauf stehen, erneuert werden. Wir haben hier die Option --dry-run zum Testen unseres Skripts hinzugefügt.

      • docker-compose kill: Hiermit wird ein SIGHUP-Signal an den webserver-Container gesendet, um die Nginx-Konfiguration neu zu laden.

      Schließen Sie die Datei und machen Sie sie mit folgendem Befehl ausführbar:

      • sudo chmod +x ssl_renew.sh

      Öffnen Sie als Nächstes die Datei root crontab, um das Erneuerungsskript in einem angegebenen Intervall auszuführen:

      Wenn Sie die Datei zum ersten Mal bearbeiten, werden Sie dazu aufgefordert, einen Texteditor zum Öffnen der Datei zu wählen:

      Output

      no crontab for root - using an empty one Select an editor. To change later, run 'select-editor'. 1. /bin/nano 2. /usr/bin/vim.basic 3. /usr/bin/vim.tiny 4. /bin/ed Choose 1-4 [1]: ...

      Fügen Sie am Ende der Datei die folgende Zeile hinzu und ersetzen Sie sammy mit Ihrem Benutzernamen:

      crontab

      ...
      */5 * * * * /home/sammy/drupal/ssl_renew.sh >> /var/log/cron.log 2>&1
      

      Hiermit wird das Job-Intervall auf alle fünf Minuten festgelegt, sodass wir testen können, ob unsere Erneuerungsanfrage wie beabsichtigt funktioniert hat oder nicht. Außerdem haben wir eine Protokolldatei, cron.log, zum Aufzeichnen der relevanten Ausgabe erstellt.

      Verwenden Sie nach fünf Minuten den Befehl tail, um cron.log zu prüfen und zu sehen, ob die Erneuerungsanfrage erfolgreich war oder nicht:

      • tail -f /var/log/cron.log

      Sie sehen eine Ausgabe, die eine erfolgreiche Erneuerung bestätigt:

      Output

      ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates below have not been saved.) Congratulations, all renewals succeeded. The following certs have been renewed: /etc/letsencrypt/live/your_domain/fullchain.pem (success) ** DRY RUN: simulating 'certbot renew' close to cert expiry ** (The test certificates above have not been saved.) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

      Drücken Sie STRG+C, um den tail-Prozess zu beenden.

      Wir können jetzt die Datei crontab ändern, um das Skript jeden zweiten Tag der Woche um 02:00 Uhr auszuführen. Ändern Sie die letzte Zeile der crontab wie folgt:

      crontab

      ...
      * 2 * * 2 /home/sammy/drupal/ssl_renew.sh >> /var/log/cron.log 2>&1
      

      Speichern und schließen Sie die Datei.

      Nun entfernen wir die Option --dry-run aus dem Skript ssl_renew.sh. Öffnen Sie es zunächst:

      Ändern Sie dann den Inhalt wie folgt:

      ~/drupal/ssl_renew.sh

      #!/bin/bash
      
      cd /home/sammy/drupal/
      /usr/local/bin/docker-compose -f docker-compose.yml run certbot renew && 
      /usr/local/bin/docker-compose -f docker-compose.yml kill -s SIGHUP webserver
      

      Unser cron-Job kümmert sich nun um den Ablauf unserer SSL-Zertifikate, indem er sie erneuert, wenn sie hierfür infrage kommen.

      Zusammenfassung

      In diesem Tutorial haben wir Docker Compose verwendet, um eine Drupal-Installation mit einem Nginx-Webserver zu erstellen. Als Teil des Workflows haben wir TLS/SSL-Zertifikate für die Domäne erlangt, mit der wir unsere Drupal-Website verknüpfen wollten, und einen cron-Job erstellt, um diese Zertifikate bei Bedarf zu erneuern.

      Wenn Sie mehr über Docker erfahren möchten, besuchen Sie unsere Docker-Themenseite.



      Source link

      So installieren Sie Linux, Nginx, MySQL und PHP (LEMP-Stack) unter Ubuntu 20.04


      Einführung

      Der LEMP-Software-Stack ist eine Gruppe von Software, die zur Bereitstellung von dynamischen Webseiten und Webanwendungen verwendet werden kann, die in PHP geschrieben sind. Es handelt sich um ein Akronym, das ein Linux-Betriebssystem mit einem Nginx-Webserver (ausgesprochen wie „Engine-X“) beschreibt. Die Backend-Daten werden in einer MySQL-Datenbank gespeichert und die dynamische Verarbeitung wird mit PHP gehandhabt.

      Dieser Leitfaden zeigt, wie Sie einen LEMP-Stack auf einem Ubuntu 20.04-Server installieren. Das Ubuntu-Betriebssystem erfüllt die erste Anforderung. Wir beschreiben, wie Sie den Rest der Komponenten einrichten und ausführen.

      Voraussetzungen

      Um dieses Tutorial zu absolvieren, benötigen Sie Zugriff auf einen Ubuntu-20.04-Server als ein regulärer non-root sudo user und eine auf Ihrem Server aktivierte Firewall. Sie können zur Einrichtung unserem Leitfaden zur Ersteinrichtung eines Servers für Ubuntu 20.04 folgen.

      Schritt 1 — Installieren des Nginx-Webservers

      Um den Besuchern unserer Website die Webseiten anzuzeigen, stellen wir den leistungsfähigen Webserver Nginx zur Verfügung. Wir verwenden den apt-Paketmanager, um diese Software zu erlangen.

      Da wir apt für diese Sitzung zum ersten Mal verwenden, beginnen Sie mit der Aktualisierung des Paketindexes Ihres Servers. Danach können Sie apt install zum Installieren von Nginx verwenden:

      • sudo apt update
      • sudo apt install nginx

      Geben Sie bei der entsprechenden Aufforderung Y ein, um zu bestätigen, dass Sie Nginx installieren möchten. Sobald die Installation abgeschlossen ist, ist der Nginx-Webserver aktiv und wird auf Ihrem Ubuntu-20.04-Server ausgeführt.

      Wenn Sie die in unserem Leitfaden zur Ersteinrichtung eines Servers empfohlene ufw aktiviert haben, müssen Sie Verbindungen zu Nginx zulassen. Nginx registriert bei der Installation einige verschiedene UFW-Anwendungsprofile. Um zu prüfen, welche UFW-Profile verfügbar sind, führen Sie nun Folgendes aus:

      Output

      Available applications: Nginx Full Nginx HTTP Nginx HTTPS OpenSSH

      Es wird empfohlen, das restriktivste Profil zu aktivieren, das den von Ihnen benötigten Datenverkehr immer noch zulässt. Da Sie SSL für Ihren Server in diesem Leitfaden nicht konfiguriert haben, müssen Sie nur den regulären HTTP-Verkehr auf Port 80 zulassen.

      Aktivieren Sie dies durch die Eingabe von:

      • sudo ufw allow 'Nginx HTTP'

      Sie können die Änderung überprüfen, indem Sie Folgendes ausführen:

      Die Ausgabe des Befehls zeigt, dass der HTTP-Verkehr jetzt zugelassen wird:

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx HTTP ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6)

      Nachdem die neue Firewall-Regel hinzugefügt wurde, können Sie testen, ob der Server ausgeführt wird, indem Sie auf Ihren Domänennamen oder die öffentliche IP-Adresse Ihres Servers in Ihrem Webbrowser zugreifen.

      Wenn Sie keinen Domänennamen haben, der auf den Server verweist, und Sie die öffentliche IP-Adresse Ihres Servers nicht kennen, können Sie diese mit dem folgenden Befehl finden:

      • ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's//.*$//'

      Hierdurch erhalten Sie einige IP-Adressen. Sie können diese abwechselnd in Ihrem Webbrowser ausprobieren.

      Als Alternative können Sie prüfen, welche IP-Adresse von anderen Stellen im Internet aus erreichbar ist:

      Geben Sie die Adresse ein, die Sie in Ihrem Webbrowser erhalten, und Sie werden zur Standard-Startseite von Nginx weitergeleitet:

      http://server_domain_or_IP
      

      Nginx-Standardseite

      Wenn Sie diese Seite sehen können, haben Sie Nginx erfolgreich installiert und den HTTP-Verkehr für Ihren Webserver aktiviert.

      Schritt 2 — Installieren von MySQL

      Nachdem Sie nun einen funktionierenden Webserver eingerichtet haben, müssen Sie das Datenbanksystem installieren, um Daten für Ihre Website speichern und verwalten zu können. MySQL ist ein beliebtes Datenbankverwaltungssystem, das in PHP-Umgebungen verwendet wird.

      Verwenden Sie auch hier wieder apt zur Beschaffung und Installation der Software:

      • sudo apt install mysql-server

      Wenn Sie dazu aufgefordert werden, bestätigen Sie die Installation, indem Sie Y eingeben und dann ENTER drücken.

      Wenn die Installation abgeschlossen ist, wird empfohlen, ein Sicherheitsskript auszuführen, das in MySQL vorinstalliert ist. Dieses Skript entfernt einige unsichere Standardeinstellungen und sperrt den Zugriff auf Ihr Datenbanksystem. Starten Sie das interaktive Skript, indem Sie Folgendes ausführen:

      • sudo mysql_secure_installation

      Sie werden gefragt, ob Sie das VALIDATE PASSWORD PLUGIN konfigurieren möchten.

      Anmerkung: Die Aktivierung dieser Funktion bleibt Ihnen überlassen. Sollten Sie sie aktivieren, werden Passwörter, die nicht den angegebenen Kriterien entsprechen, als Fehler von MySQL abgelehnt. Sie können die Validierung deaktiviert lassen, aber sollten immer starke, eindeutige Passwörter für die Datenbankinformationen verwenden.

      Geben Sie Y für Ja oder etwas Anderes ein, um ohne Aktivierung weiterzumachen.

      VALIDATE PASSWORD PLUGIN can be used to test passwords
      and improve security. It checks the strength of password
      and allows the users to set only those passwords which are
      secure enough. Would you like to setup VALIDATE PASSWORD plugin?
      
      Press y|Y for Yes, any other key for No:
      

      Wenn Sie mit „ja“ antworten, werden Sie dazu aufgefordert, eine Stufe der Passwortvalidierung zu wählen. Denken Sie daran, dass die Auswahl von 2 als stärkste Validierungsstufe Fehler ergibt, wenn Sie ein Passwort ohne Zahlen, Buchstaben, Klein- oder Großbuchstaben und Sonderzeichen einrichten oder eines aus geläufigen Wörtern aus einem Wörterbuch.

      There are three levels of password validation policy:
      
      LOW    Length >= 8
      MEDIUM Length >= 8, numeric, mixed case, and special characters
      STRONG Length >= 8, numeric, mixed case, special characters and dictionary              file
      
      Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 1
      

      Unabhängig davon, ob Sie sich für die Einrichtung des VALIDATE PASSWORD PLUGIN entschieden haben, wird der Server Sie als Nächstes auffordern, ein Passwort für den MySQL root user zu wählen und zu bestätigen. Verwechseln Sie dies nicht mit dem Benutzer für system root. Der Datenbank-root user ist ein administrativer Benutzer mit vollen Berechtigungen über das Datenbank-System. Zwar entbindet die Standardauthentifizierungsmethode für den MySQL root user von der Verwendung eines Passworts, selbst wenn eines festgelegt ist, doch sollten Sie hier als zusätzliche Sicherheitsmaßnahme ein starkes Passwort definieren. Darüber werden wir gleich noch sprechen.

      Wenn Sie Passwortvalidierung aktiviert haben, wird Ihnen die Passwortstärke des soeben eingegebenen root-Passworts gezeigt und Sie werden gefragt, ob Sie das Passwort beibehalten möchten. Wenn Sie mit Ihrem aktuellen Passwort zufrieden sind, geben Sie in der Eingabeaufforderung Y für „ja“ ein:

      Estimated strength of the password: 100
      Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
      

      Drücken Sie bei den restlichen Fragen auf Y und bei jeder Eingabeaufforderung ENTER. Damit werden einige anonyme Benutzer und die Testdatenbank entfernt, ferngesteuerte root-Logins deaktiviert und diese neuen Regeln geladen, damit MySQL die Änderungen, die Sie gerade vorgenommen haben, unverzüglich anwendet.

      Wenn Sie damit fertig sind, testen Sie, ob Sie sich bei der MySQL-Konsole anmelden können, indem Sie Folgendes eingeben:

      Damit wird eine Verbindung zum MySQL-Server als administrativer Datenbank-Benutzer root hergestellt, was durch die Verwendung von sudo abgeleitet wird, wenn dieser Befehl ausgeführt wird. Sie sollten eine Ausgabe wie diese sehen:

      Output

      Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 22 Server version: 8.0.19-0ubuntu5 (Ubuntu) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or 'h' for help. Type 'c' to clear the current input statement. mysql>

      Um die MySQL-Konsole zu beenden, geben Sie Folgendes ein:

      Beachten Sie, dass Sie kein Passwort angeben müssen, um als root user eine Verbindung herzustellen, obwohl Sie bei der Ausführung des Skripts mysql_secure_installation ein Passwort festgelegt haben. Das liegt daran, dass die standardmäßige Authentifizierungsmethode für den administrativen MySQL-Benutzer unix_socket ist und nicht password. Auch wenn dies zunächst wie ein Sicherheitsproblem aussieht, macht es den Datenbankserver sicherer, da sich nur die Systembenutzer mit sudo-Berechtigungen über die Konsole oder über eine Anwendung, die mit den gleichen Berechtigungen läuft, als root MySQL user anmelden dürfen. Praktisch bedeutet dies, dass Sie den administrativen Datenbank-root user nicht verwenden können, um sich von Ihrer PHP-Anwendung zu verbinden. Das Einrichten eines Passworts für das root-MySQL-Konto funktioniert als Schutz für den Fall, dass die Standardauthentifizierungsmethode von unix_socket in password geändert wird.

      Um die Sicherheit zu erhöhen, richten Sie am besten für jede Datenbank zugeordnete Benutzerkonten mit weniger expansiven Berechtigungen ein, insbesondere dann, wenn Sie mehrere Datenbanken auf Ihrem Server hosten möchten.

      Anmerkung: Zum Zeitpunkt der Verfassung dieses Dokuments unterstützt die native MySQL-PHP-Bibliothek mysqlnd keine caching_sha2_authentication, die standardmäßige Authentifizierungsmethode für MySQL 8. Wenn Sie Datenbankbenutzer für PHP-Anwendungen unter MySQL 8 erstellen, müssen Sie daher so konfigurieren, dass sie stattdessen mysql_native_password verwenden. In Schritt 6 zeigen wir, wie das geht.

      Ihr MySQL-Server ist nun installiert und gesichert. Als Nächstes installieren wir PHP, die letzte Komponente im LEMP-Stack.

      Schritt 3 — Installieren von PHP

      Sie haben Nginx installiert, um Ihre Inhalte bereitzustellen, und MySQL, um Ihre Daten zu speichern und zu verwalten. Jetzt können Sie PHP installieren, um Code zu verarbeiten und dynamische Inhalte für den Webserver zu generieren.

      Während Apache den PHP-Interpreter in jede Anfrage einbindet, benötigt Nginx ein externes Programm, das die PHP-Verarbeitung handhabt und als Brücke zwischen dem PHP-Interpreter selbst und dem Webserver fungiert. Dies ermöglicht eine bessere Gesamtleistung in den meisten PHP-basierten Websites, erfordert jedoch eine zusätzliche Konfiguration. Sie müssen php-fpm installieren, was für „PHP fastCGI-Prozessmanager“ steht, und Nginx anweisen, PHP-Anfragen zur Verarbeitung an diese Software zu übergeben. Außerdem benötigen Sie php-mysql, ein PHP-Modul, das PHP ermöglicht, mit MySQL-basierten Datenbanken zu kommunizieren. Core-PHP-Pakete werden automatisch als Abhängigkeiten installiert.

      Um die php-fpm– und php-mysql-Pakete zu installieren, führen Sie Folgendes aus:

      • sudo apt install php-fpm php-mysql

      Wenn Sie dazu aufgefordert werden, geben Sie Y und ENTER ein, um die Installation zu bestätigen.

      Sie haben nun Ihre PHP-Komponenten installiert. Als Nächstes konfigurieren Sie Nginx, um sie zu verwenden.

      Schritt 4 — Konfigurieren von Nginx zum Verwenden des PHP-Prozessors

      Bei Verwendung des Nginx-Webservers können wir Serverblocks (ähnlich wie virtuelle Hosts in Apache) erstellen, um Konfigurationsdetails einzuschließen und mehr als eine Domäne auf einem einzelnen Server zu hosten. In diesem Leitfaden verwenden wir your_domain als Beispielnamen für die Domäne. Um mehr über die Einrichtung eines Domänennamens mit DigitalOcean zu erfahren, lesen Sie unsere Einführung zu DigitalOcean DNS.

      Auf Ubuntu 20.04 hat Nginx einen Serverblock standardmäßig aktiviert und ist so konfiguriert, dass Dokumente aus einem Verzeichnis in /var/www/html bereitgestellt werden. Das eignet sich gut für eine Website, kann aber umständlich werden, wenn Sie mehrere hosten. Statt /var/www/html zu ändern, erstellen wir eine Verzeichnisstruktur innerhalb von /var/www für die Website your_domain und belassen dabei /var/www/html als Standardverzeichnis, das genutzt wird, wenn eine Clientanfrage keine übereinstimmenden Websites ergibt.

      Erstellen Sie das root-Webverzeichnis für your_domain wie folgt:

      • sudo mkdir /var/www/your_domain

      Als Nächstes weisen Sie die Eigentumsrechte des Verzeichnisses mit der Umgebungsvariablen $USER zu, die auf Ihren aktuellen Systembenutzer verweisen wird:

      • sudo chown -R $USER:$USER /var/www/your_domain

      Öffnen Sie dann mit Ihrem bevorzugten Befehlszeileneditor eine neue Konfigurationsdatei im Verzeichnis sites-available von Nginx. Wir verwenden hier nano:

      • sudo nano /etc/nginx/sites-available/your_domain

      Dadurch wird eine neue Leerdatei erstellt. Fügen Sie die folgende Basiskonfiguration ein:

      /etc/nginx/sites-available/your_domain

      server {
          listen 80;
          server_name your_domain www.your_domain;
          root /var/www/your_domain;
      
          index index.html index.htm index.php;
      
          location / {
              try_files $uri $uri/ =404;
          }
      
          location ~ .php$ {
              include snippets/fastcgi-php.conf;
              fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
           }
      
          location ~ /.ht {
              deny all;
          }
      
      }
      
      
      

      Hier eine Auflistung der Funktionen dieser Anweisungen und Location-Blocks:

      • listen — Hiermit wird definiert, auf welchem Port Nginx lauscht. In diesem Fall lauscht er auf Port 80, dem Standardport für HTTP.
      • root — Hiermit wird die Dokumentenroot definiert, in der die von der Website bereitgestellten Dateien gespeichert werden.
      • index — Hiermit wird die Reihenfolge definiert, in der Nginx die Indexdateien für die Website priorisiert. Es ist gängige Praxis, index.html-Dateien mit einer höheren Priorität als index.php-Dateien aufzulisten, um die schnelle Einrichtung einer Wartungsstartseite in PHP-Anwendungen zu ermöglichen. Sie können diese Einstellungen so anpassen, dass sie Ihren Anwendungsanforderungen entsprechen.
      • server_name — Hiermit wird definiert, auf welche Domänennamen und/oder IP-Adressen dieser Serverblock antworten soll. Verweisen Sie diese Anweisung auf den Domänennamen oder die öffentliche IP-Adresse Ihres Servers.
      • location / — Der erste Location-Block enthält eine Anweisung try_files, die überprüft, ob Dateien oder Verzeichnisse vorhanden sind, die einer URI-Anfrage entsprechen. Wenn Nginx die entsprechende Ressource nicht finden kann, wird der Fehler 404 ausgegeben.
      • location ~ .php$ — Dieser Location-Block handhabt die eigentliche PHP-Verarbeitung, indem er Nginx auf die Konfigurationsdatei fastcgi-php.conf und die Datei php7.4-fpm.sock verweist, wodurch deklariert wird, welche Socket mit php-fpm verknüpft ist.
      • location ~ /.ht — Der letzte Location-Block befasst sich mit .htaccess-Dateien, die Nginx nicht prozessiert. Durch Hinzufügen der Anweisung deny all werden .htaccess-Dateien, die ihren Weg in die Dokumentenroot finden, nicht für Besucher bereitgestellt.

      Wenn Sie mit der Bearbeitung fertig sind, speichern und schließen Sie die Datei. Wenn Sie nano verwenden, geben Sie hierfür STRG+X ein und dann y und ENTER zur Bestätigung.

      Aktivieren Sie Ihre Konfiguration, indem Sie eine Verknüpfung mit der Konfigurationsdatei aus dem sites-enabled-Verzeichnis von Nginx herstellen:

      • sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

      Dadurch wird Nginx angewiesen, die Konfiguration beim nächsten Neuladen zu verwenden. Sie können Ihre Konfiguration auf Syntaxfehler testen, indem Sie Folgendes eingeben:

      Wenn Fehler gemeldet werden, gehen Sie zurück zu Ihrer Konfigurationsdatei, um den Inhalt vor dem Fortfahren zu überprüfen.

      Wenn Sie fertig sind, laden Sie Nginx neu, um die Änderungen anzuwenden:

      • sudo systemctl reload nginx

      Ihre neue Website ist nun aktiv, aber die Web-root /var/www/your_domain ist immer noch leer. Erstellen Sie an diesem Ort eine index.html-Datei, um zu testen, ob Ihr neuer Serverblock wie erwartet funktioniert:

      • nano /var/www/your_domain/index.html

      Fügen Sie in dieser Datei folgende Inhalte ein:

      /var/www/your_domain/index.html

      <html>
        <head>
          <title>your_domain website</title>
        </head>
        <body>
          <h1>Hello World!</h1>
      
          <p>This is the landing page of <strong>your_domain</strong>.</p>
        </body>
      </html>
      

      Gehen Sie nun zu Ihrem Browser und greifen Sie auf den Domänennamen oder die IP-Adresse Ihres Servers zu, wie sie in der server_name-Anweisung in Ihrer Serverblock-Konfigurationsdatei aufgeführt sind:

      http://server_domain_or_IP
      

      Sie sehen in etwa folgende Seite:

      Nginx Serverblock

      Wenn Sie diese Seite sehen, bedeutet das, dass Ihr Nginx-Serverblock wie erwartet funktioniert.

      Sie können diese Datei als temporäre Startseite für Ihre Anwendung so lange belassen, bis Sie sie durch eine index.php-Datei ersetzen. Sobald Sie dies tun, vergessen Sie nicht, die Datei index.html aus Ihrem Dokument-root zu entfernen oder umzubenennen, da sie standardmäßig Vorrang gegenüber einer index.php-Datei erhalten würde.

      Ihr LEMP-Stack ist nun vollständig konfiguriert. Im nächsten Schritt erstellen wir ein PHP-Skript, um zu testen, ob Nginx tatsächlich in der Lage ist, .php-Dateien in Ihrer neu konfigurierten Website zu verarbeiten.

      Schritt 5 — Testen von PHP mit Nginx

      Ihr LEMP-Stack sollte nun vollständig eingerichtet sein. Sie können ihn testen, um zu bestätigen, dass Nginx .php-Dateien korrekt an Ihren PHP-Prozessor übergeben kann.

      Hierfür können Sie eine PHP-Testdatei in Ihrer Dokumentenroot erstellen. Öffnen Sie innerhalb Ihrer Dokumentenroot in Ihrem Texteditor eine neue Datei namens info.php:

      • nano /var/www/your_domain/info.php

      Schreiben oder fügen Sie die folgenden Zeilen in die neue Datei ein. Es handelt sich um einen gültigen PHP-Code, der Informationen über Ihren Server ausgibt:

      /var/www/your_domain/info.php

      <?php
      phpinfo();
      

      Wenn Sie fertig sind, speichern und schließen Sie die Datei durch Eingabe von STRG+X und dann y und ENTER zur Bestätigung.

      Sie können nun in Ihrem Webbrowser auf diese Seite zugreifen, indem Sie den Domänennamen oder die öffentliche IP-Adresse besuchen, die Sie in Ihrer Nginx-Konfigurationsdatei eingerichtet haben, gefolgt von /info.php:

      http://server_domain_or_IP/info.php
      

      Sie sehen dann eine Webseite, die detaillierte Informationen über Ihren Server enthält:

      PHPInfo Ubuntu 20.04

      Nachdem Sie über diese Seite die relevanten Informationen zu Ihrem PHP-Server überprüft haben, ist es am besten, die von Ihnen erstellte Datei zu entfernen, da sie sensible Informationen über Ihre PHP-Umgebung und Ihren Ubuntu-Server enthält. Sie können diese Datei mithilfe von rm entfernen:

      • sudo rm /var/www/your_domain/info.php

      Sie können diese Datei jederzeit regenerieren, falls Sie sie später benötigen.

      Schritt 6 — Testen der Datenbankverbindung von PHP (optional)

      Wenn Sie testen möchten, ob PHP eine Verbindung mit MySQL herstellen kann und Datenbankabfragen ausführt, können Sie eine Testtabelle mit Pseudodaten erstellen und die Inhalte mit einem PHP-Skript abfragen. Bevor wir das tun können, müssen wir eine Testdatenbank und einen neuen MySQL-Benutzer erstellen, der für den Zugriff richtig konfiguriert ist.

      Zum Zeitpunkt der Verfassung dieses Dokuments unterstützt die native MySQL-PHP-Bibliothek mysqlnd nicht caching_sha2_authentication, die standardmäßige Authentifizierungsmethode für MySQL 8. Wir müssen einen neuen Benutzer mit der Authentifizierungsmethode mysql_native_password erstellen, um über PHP eine Verbindung zur MySQL-Datenbank herzustellen.

      Wir erstellen eine Datenbank namens example_database und einen Benutzer namens example_user. Sie können diese Namen jedoch durch andere Werte ersetzen.

      Stellen Sie zuerst unter Verwendung des root-Kontos eine Verbindung zur MySQL-Konsole her:

      Um eine neue Datenbank zu erstellen, führen Sie den folgenden Befehl von Ihrer MySQL-Konsole aus:

      • CREATE DATABASE example_database;

      Jetzt können Sie einen neuen Benutzer erstellen und ihm volle Berechtigungen auf der benutzerdefinierten Datenbank gewähren, die Sie gerade erstellt haben:

      Der folgende Befehl erstellt einen neuen Benutzer namens example_user, wobei mysql_native_password als standardmäßige Authentifizierungsmethode verwendet wird. Wir definieren das Passwort dieses Benutzers als password, aber Sie sollten diesen Wert durch ein sicheres Passwort Ihrer Wahl ersetzen:

      • CREATE USER 'example_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

      Nun müssen wir diesem Benutzer eine Berechtigung für die Datenbank example_database erteilen:

      • GRANT ALL ON example_database.* TO 'example_user'@'%';

      Damit werden dem Benutzer example_user volle Berechtigungen über die example_database gewährt, während dieser Benutzer gleichzeitig daran gehindert wird, andere Datenbanken auf Ihrem Server zu erstellen oder zu ändern.

      Beenden Sie nun die MySQL-Shell mit:

      Sie können testen, ob der neue Benutzer die richtigen Berechtigungen hat, indem Sie sich erneut bei der MySQL-Konsole anmelden, diesmal mit den benutzerdefinierten Anmeldedaten:

      Beachten Sie das -p-Flag in diesem Befehl, das Sie nach dem Passwort fragt, das Sie bei der Erstellung des Benutzers example_user gewählt haben. Nach der Anmeldung bei der MySQL-Konsole bestätigen Sie, dass Sie Zugriff auf die Datenbank example_database haben:

      Damit erhalten Sie die folgende Ausgabe:

      Output

      +--------------------+ | Database | +--------------------+ | example_database | | information_schema | +--------------------+ 2 rows in set (0.000 sec)

      Als Nächstes erstellen wir eine Testtabelle namens todo_list. Führen Sie die folgende Anweisung in der MySQL-Konsole aus:

      • CREATE TABLE example_database.todo_list (
      • item_id INT AUTO_INCREMENT,
      • content VARCHAR(255),
      • PRIMARY KEY(item_id)
      • );

      Geben Sie einige Zeilen an Inhalt in die Testtabelle ein. Sie können den nächsten Befehl ein paar Mal wiederholen, indem Sie verschiedene Werte verwenden:

      • INSERT INTO example_database.todo_list (content) VALUES ("My first important item");

      Um zu bestätigen, dass die Daten erfolgreich in Ihrer Tabelle gespeichert wurden, führen Sie Folgendes aus:

      • SELECT * FROM example_database.todo_list;

      Sie sehen die folgende Ausgabe:

      Output

      +---------+--------------------------+ | item_id | content | +---------+--------------------------+ | 1 | My first important item | | 2 | My second important item | | 3 | My third important item | | 4 | and this one more thing | +---------+--------------------------+ 4 rows in set (0.000 sec)

      Nachdem Sie bestätigt haben, dass Sie gültige Daten in Ihrer Testtabelle haben, können Sie die MySQL-Konsole verlassen:

      Sie können nun das PHP-Skript erstellen, das sich mit MySQL verbindet, und Ihre Inhalte abfragen. Erstellen Sie mit Ihrem bevorzugten Editor eine neue PHP-Datei in Ihrem benutzerdefinierten Web-Stammverzeichnis. Verwenden Sie hierzu nano:

      • nano /var/www/your_domain/todo_list.php

      Das folgende PHP-Skript verbindet sich mit der MySQL-Datenbank und den Abfragen für den Inhalt der Tabelle todo_list, wobei die Ergebnisse in einer Liste angezeigt werden. Wenn ein Problem mit der Datenbankverbindung besteht, wird eine Ausnahme ausgegeben. Kopieren Sie diesen Inhalt in Ihr todo_list.php-Skript:

      /var/www/your_domain/todo_list.php

      <?php
      $user = "example_user";
      $password = "password";
      $database = "example_database";
      $table = "todo_list";
      
      try {
        $db = new PDO("mysql:host=localhost;dbname=$database", $user, $password);
        echo "<h2>TODO</h2><ol>";
        foreach($db->query("SELECT content FROM $table") as $row) {
          echo "<li>" . $row['content'] . "</li>";
        }
        echo "</ol>";
      } catch (PDOException $e) {
          print "Error!: " . $e->getMessage() . "<br/>";
          die();
      }
      

      Speichern und schließen Sie die Datei, wenn die Bearbeitung abgeschlossen ist.

      Sie können diese Seite nun in Ihrem Webbrowser aufrufen, indem Sie den Domänennamen oder die öffentliche IP-Adresse für Ihre Website besuchen, gefolgt von /todo_list.php:

      http://server_domain_or_IP/todo_list.php
      

      Sie sollten nun eine Seite ähnlich wie diese sehen, die den Inhalt anzeigt, den Sie in Ihre Testtabelle eingefügt haben:

      Beispiel PHP To-Do-List

      Das bedeutet, dass Ihre PHP-Umgebung zur Verfügung steht, um mit Ihrem MySQL-Server zu interagieren.

      Zusammenfassung

      In diesem Leitfaden haben wir eine flexible Basis für die Bereitstellung von PHP-Websites und Anwendungen für Ihre Besucher eingerichtet, wobei Nginx als Webserver und MySQL als Datenbanksystem dienen.

      Von hier aus können Sie nun verschiedene weitere Schritte ausführen. Sie sollten beispielsweise sicherstellen, dass Verbindungen zu Ihrem Server gesichert sind. Zu diesem Zweck könnten Sie Ihre Nginx-Installation mit Let’s Encrypt sichern. Wenn Sie diesem Leitfaden folgen, erwerben Sie ein kostenloses TLS/SSL-Zertifikat für Ihren Server, mit dem er Inhalte über HTTPS bereitstellen kann.



      Source link