Ubuntu 22.04 Server / Apache, PHP und MariaDB installieren

Unter Ubuntu 22.04 Server richten Sie eine grundlegende Web-Laufzeitumgebung ein, indem Sie Apache, dessen PHP-Modul, MariaDB und die PHP-Datenbankerweiterung installieren. Trennen Sie anschließend das MariaDB-Administratorkonto vom Anwendungskonto und prüfen Sie, ob PHP einen Datenbankwert lesen kann.

Geltungsbereich und Pakete

Diese Anleitung verwendet die Standard-Paketquellen von Ubuntu 22.04 auf einem neuen Server, auf dem Apache und MariaDB gemeinsam laufen. Sie benötigen sudo-Rechte und Internetzugang für die Pakete. Sichern Sie auf vorhandenen Servern zunächst Web-Konfiguration und Datenbanken und prüfen Sie, ob die Beispielnamen für Dateien, Konten und Datenbanken frei sind. Wenn bereits PHP-FPM eingesetzt wird, mischen Sie diese Apache-Modul-Konfiguration nicht in die bestehende Einrichtung.

  1. Aktualisieren Sie den Paketindex und installieren Sie die Komponenten. libapache2-mod-php verarbeitet PHP in Apache; php-mysql liefert die Erweiterungen für den MariaDB-Zugriff. Installieren Sie auch php-cli für Prüfungen in der Kommandozeile. Einzelheiten zur Konfiguration enthält die Ubuntu-Anleitung zur PHP-Installation.
sudo apt update
sudo apt install apache2 mariadb-server php php-cli libapache2-mod-php php-mysql
  1. Starten Sie die Dienste und aktivieren Sie den automatischen Start beim Booten. Prüfen Sie, ob der Apache-Konfigurationstest Syntax OK meldet. Starten Sie Apache dann neu, um das PHP-Modul zu laden.
sudo systemctl enable --now apache2 mariadb
sudo apache2ctl configtest
sudo systemctl restart apache2
systemctl is-active apache2 mariadb

Der letzte Befehl zeigt für jeden laufenden Dienst active an. Die installierten Versionen prüfen Sie mit apache2 -v, php -v und mariadb --version. Zusätzliche Paketquellen können eine andere PHP-Version als die Standardquellen bereitstellen.

MariaDB-Administratorauthentifizierung prüfen

Die standardmäßigen MariaDB-Pakete unter Ubuntu verwenden für die lokale Administration üblicherweise Unix-Socket-Authentifizierung. Dabei wird die Identität des Betriebssystembenutzers geprüft. Das bedeutet nicht, dass sich jeder mit einem leeren root-Passwort anmelden kann. Öffnen Sie die folgende Administrationssitzung und prüfen Sie das aktuelle Konto und dessen Konfiguration.

sudo mariadb --protocol=socket
SELECT VERSION(), CURRENT_USER();
SHOW CREATE USER 'root'@'localhost';
EXIT;

Die root-Authentifizierung kann bei vorhandenen Installationen abweichen. Dieses Beispiel behält die Socket-Authentifizierung bei und erstellt ein separates Anwendungskonto, wie in der Erklärung zur MariaDB-Authentifizierung seit Version 10.4 beschrieben. Ändern Sie den plugin-Wert in mysql.user nicht direkt per UPDATE und verwenden Sie root nicht in einer Webanwendung.

Mit dem folgenden Werkzeug lassen sich die anfänglichen Sicherheitseinstellungen prüfen. Wortlaut und Reihenfolge der Fragen hängen von Version und Konfiguration ab. Antworten Sie daher nicht pauschal auf alles mit Y.

sudo mariadb-secure-installation
  • Wenn die Administration bereits per Socket-Authentifizierung erfolgt, können Sie diese beibehalten. Laut offizieller Dokumentation des MariaDB-Werkzeugs ist ein neues root-Passwort bei dieser Konfiguration normalerweise nicht erforderlich.
  • Auf einem neuen Server ist es sinnvoll, anonyme Benutzer und die unnötige test-Datenbank zu entfernen und entfernte root-Anmeldungen einzuschränken. Prüfen Sie bei vorhandenen Diensten zuerst, ob diese Ressourcen genutzt werden. Übernehmen Sie die Änderungen, wenn das Werkzeug zum Neuladen der Berechtigungstabellen auffordert.

Datenbank und Konto für die Anwendung erstellen

Verbinden Sie sich erneut mit sudo mariadb --protocol=socket und führen Sie das folgende SQL aus. lampdemo und lamp_app sind neue Namen für diese Übung. Sind sie bereits vorhanden, wählen Sie andere Namen und passen Sie alle weiteren Beispiele entsprechend an; überschreiben oder löschen Sie keine bestehenden Objekte. Ersetzen Sie den Passwortplatzhalter durch ein langes, eindeutiges Passwort und verwenden Sie denselben Wert in PHP. Enthält es einfache Anführungszeichen, beachten Sie jeweils die Escape-Regeln für SQL- und PHP-Zeichenketten.

CREATE DATABASE lampdemo CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'lamp_app'@'localhost' IDENTIFIED BY 'REPLACE_WITH_A_LONG_UNIQUE_PASSWORD';
GRANT SELECT, INSERT, UPDATE, DELETE ON lampdemo.* TO 'lamp_app'@'localhost';
CREATE TABLE lampdemo.health_check (
    id INT PRIMARY KEY,
    message VARCHAR(100) NOT NULL
);
INSERT INTO lampdemo.health_check (id, message) VALUES (1, 'database-ok');
EXIT;

Der Administrator erstellt die Tabelle. Die Anwendung erhält nur Lese-, Einfüge-, Änderungs- und Löschrechte für diese Datenbank. Benötigt ein Installationsprogramm Rechte zum Erstellen von Tabellen, prüfen Sie diese gesondert. Nach der Rechtevergabe mit GRANT ist kein zusätzliches FLUSH PRIVILEGES nötig.

Führen Sie die Abfrage im Terminal mit dem Anwendungskonto aus und prüfen Sie, ob database-ok erscheint. Schreiben Sie das Passwort nicht hinter -p, sondern geben Sie es erst nach Aufforderung ein.

mariadb --protocol=socket -u lamp_app -p lampdemo -e "SELECT message FROM health_check WHERE id=1;"

PHP-Dateien für das Verbindungsbeispiel anlegen

Das Web-Dokumentverzeichnis der Apache-Standardwebsite unter Ubuntu ist normalerweise /var/www/html. Prüfen Sie bei einem vorhandenen virtuellen Host sudo apache2ctl -S und dessen DocumentRoot, und passen Sie den Pfad der Webdatei an. Existiert eine der folgenden Dateien schon, verwenden Sie einen anderen Namen. Bewahren Sie die Konfiguration mit dem Passwort außerhalb des Webverzeichnisses auf.

  1. Erstellen Sie das Konfigurationsverzeichnis und öffnen Sie einen Editor. Die folgenden Rechte setzen voraus, dass Apache unter dem Ubuntu-Standardbenutzer und der Gruppe www-data läuft.
sudo install -d -o root -g www-data -m 0750 /etc/lamp-demo
sudoedit /etc/lamp-demo/database.php

Speichern Sie den gesamten folgenden Inhalt in /etc/lamp-demo/database.php. Ersetzen Sie password durch das zuvor festgelegte Anwendungspasswort. Wie die PHP-Dokumentation zur PDO_MYSQL-Verbindung erläutert, verwendet host=localhost unter Unix einen Socket. 127.0.0.1 wählt dagegen TCP und kann Kontozuordnung und Verbindungsbedingungen verändern.

<?php
return [
    'dsn' => 'mysql:host=localhost;dbname=lampdemo;charset=utf8mb4',
    'user' => 'lamp_app',
    'password' => 'REPLACE_WITH_A_LONG_UNIQUE_PASSWORD',
];
  1. Belassen Sie root als Eigentümer der Konfiguration und erlauben Sie das Lesen nur dem Eigentümer und der Apache-Gruppe. Öffnen Sie anschließend die Web-Prüfdatei.
sudo chown root:www-data /etc/lamp-demo/database.php
sudo chmod 0640 /etc/lamp-demo/database.php
sudoedit /var/www/html/lamp-check.php

Speichern Sie den gesamten folgenden Inhalt in /var/www/html/lamp-check.php. PDO (PHP Data Objects) ist eine Schnittstelle für Datenbankzugriffe aus PHP. Der Code prüft den tatsächlichen Tabellenwert, bevor er Erfolg meldet. Bei einem Fehler liefert er HTTP 500 mit einer allgemeinen Meldung und schreibt die genaue Ursache ins Serverprotokoll.

<?php
declare(strict_types=1);
header('Content-Type: text/plain; charset=UTF-8');

try {
    $config = require '/etc/lamp-demo/database.php';
    $pdo = new PDO($config['dsn'], $config['user'], $config['password'], [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    ]);
    $message = $pdo->query('SELECT message FROM health_check WHERE id = 1')->fetchColumn();
    if ($message !== 'database-ok') {
        throw new RuntimeException('Unexpected database result');
    }
    echo "PHP OK\nDatabase OK\n";
} catch (Throwable $e) {
    http_response_code(500);
    error_log('lamp-check failed: ' . $e->getMessage());
    echo "Check failed; review server logs.\n";
}
  1. Geben Sie der Web-Prüfdatei Leserechte und prüfen Sie die PHP-Syntax beider Dateien. No syntax errors detected bestätigt nur die Syntax, nicht eine erfolgreiche Datenbankverbindung.
sudo chown root:root /var/www/html/lamp-check.php
sudo chmod 0644 /var/www/html/lamp-check.php
sudo php -l /etc/lamp-demo/database.php
php -l /var/www/html/lamp-check.php

Da gewöhnliche Benutzer die Konfiguration möglicherweise nicht lesen dürfen, erfolgt deren Syntaxprüfung mit sudo. Es ist nicht nötig, das gesamte Webverzeichnis beschreibbar zu machen oder chmod 777 anzuwenden.

HTTP-Antwort und Datenbankverbindung prüfen

Rufen Sie die folgende URL auf dem Server selbst ab. Falls curl fehlt, installieren Sie es mit sudo apt install curl. HTTP-Status 200 und die beiden folgenden Zeilen im Antworttext bedeuten, dass Apache PHP ausgeführt und PHP die Beispielzeile aus MariaDB gelesen hat.

curl -i http://127.0.0.1/lamp-check.php
PHP OK
Database OK

Öffnen Sie auf einem anderen Rechner http://SERVER-IP/lamp-check.php im Browser. Verwenden Sie für einen virtuellen Host den konfigurierten Hostnamen. Allein die Standard-Begrüßungsseite oder php -v prüft dieses Zusammenspiel nicht.

Funktioniert der Zugriff lokal, aber nicht von einem anderen Rechner, prüfen Sie sudo ufw status verbose, Cloud-Sicherheitsgruppen und Routing. In einem privaten Testnetz mit bereits aktivem UFW erlaubt die folgende Regel HTTP-Port 80 nur aus dem vorgesehenen Subnetz. Ersetzen Sie 192.168.10.0/24 durch Ihr vertrauenswürdiges Subnetz. Deaktivieren Sie für diesen Test nicht die Firewall und aktivieren Sie sie nicht erstmals, ohne entfernten SSH-Zugriff zu erlauben.

sudo ufw allow from 192.168.10.0/24 to any port 80 proto tcp

PHP und MariaDB kommunizieren über einen Socket auf demselben Server. Port 3306 muss daher nicht nach außen geöffnet werden. Führen Sie die HTTP-Übung in einer vertrauenswürdigen Umgebung durch. Konfigurieren Sie vor der Übertragung von Anmeldedaten oder anderen Daten im Produktivbetrieb Domain, virtuellen Host und HTTPS-Zertifikat gesondert.

Fehler eingrenzen und Testdaten aufräumen

Prüfen Sie bei Verbindungsfehlern nacheinander Dienststatus, PHP-Module, Konten und Dateirechte. Die folgenden Befehle zeigen Apache-Konfiguration und Module sowie aktuelle Protokolle beider Dienste. Protokolle können Betriebsinformationen enthalten; veröffentlichen Sie sie nicht ungeprüft.

sudo apache2ctl configtest
sudo apache2ctl -M
sudo tail -n 50 /var/log/apache2/error.log
sudo journalctl -u apache2 -u mariadb -n 50 --no-pager
  • PHP-Quelltext wird angezeigt oder heruntergeladen: unterbrechen Sie den öffentlichen Zugriff und prüfen Sie zuerst, ob das Apache-PHP-Modul aktiv ist und Apache neu gestartet wurde. Bleibt das Problem nach Installation von libapache2-mod-php bestehen, prüfen Sie auch vorhandene PHP-FPM- und virtuelle Host-Konfigurationen.
  • could not find driver: prüfen Sie, ob die zur Apache-PHP-Version passende Erweiterung php-mysql installiert und aktiviert ist, und starten Sie Apache neu. PHP in der Kommandozeile und PHP in Apache können unterschiedliche Konfigurationen verwenden.
  • Access denied: prüfen Sie Anwendungspasswort, Konto 'lamp_app'@'localhost' und dessen Rechte. Umgehen Sie den Fehler nicht durch Änderungen an root oder globale Rechte. Bei einem fehlenden Socket vergleichen Sie das MariaDB-Ergebnis von SHOW VARIABLES LIKE 'socket'; mit den PHP-Socket-Einstellungen.
  • Permission denied oder 404: prüfen Sie, ob der Apache-Benutzer die Konfiguration lesen kann und ob die Webdatei im DocumentRoot der aufgerufenen Website liegt. Kontrollieren Sie auch die Zugriffsrechte des Verzeichnisses /etc/lamp-demo.

Löschen Sie nach der Prüfung mit dem folgenden Befehl nur die hier erstellte Web-Testdatei und kontrollieren Sie, dass dieselbe URL keine Erfolgsmeldung mehr liefert. Lassen Sie auch keine vorhandene phpinfo.php oder ähnliche Dateien mit Umgebungsinformationen öffentlich liegen. Nutzt eine echte Anwendung die Konfiguration, behalten Sie sie außerhalb des Webverzeichnisses mit eingeschränkten Rechten.

sudo rm -- /var/www/html/lamp-check.php

Um auch die Übungsdaten zu entfernen, prüfen Sie zunächst, ob kein anderer Dienst sie benötigt, und führen Sie das folgende SQL als Administrator aus. Das Löschen einer Datenbank lässt sich nicht rückgängig machen; sichern Sie benötigte Daten vorher. Wenden Sie dies nur auf die für diese Übung neu erstellten Namen an.

DROP DATABASE lampdemo;
DROP USER 'lamp_app'@'localhost';

Bei einer Installation auf einem Server bleibt die lokale Bindung von MariaDB bestehen. Falls zusätzlich entfernter Datenbankzugriff nötig ist, entfernen Sie bind-address nicht einfach: Planen Sie Listen-Adresse, erlaubte Quellen, eigenes Konto und verschlüsselte Verbindung gemeinsam.