Einfache Serververwaltung mit PHP und MySQL Sicherheit: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „= Sicherheitserweiterung für das Projekt "Serververwaltung" = == Ziel == Dieses Dokument verbessert die Sicherheit des bestehenden Projekts „Serververwaltu…“)
 
 
Zeile 154: Zeile 154:
 
<pre>
 
<pre>
 
&lt;VirtualHost *:80&gt;
 
&lt;VirtualHost *:80&gt;
     ServerName server.it123.int
+
     ServerName server.it113.int
     Redirect permanent / https://server.it123.int/
+
     Redirect permanent / https://server.it113.int/
 
&lt;/VirtualHost&gt;
 
&lt;/VirtualHost&gt;
 
</pre>
 
</pre>

Aktuelle Version vom 26. März 2025, 07:59 Uhr

Sicherheitserweiterung für das Projekt "Serververwaltung"

Ziel

Dieses Dokument verbessert die Sicherheit des bestehenden Projekts „Serververwaltung“, indem es unsichere Praktiken durch sichere Alternativen ersetzt – konkret am bestehenden Quellcode und Setup.

Übersicht der Verbesserungen

  • Kein Datenbankzugriff mit Root-Rechten
  • Kein Klartextpasswort im Webverzeichnis
  • Nutzung von Prepared Statements gegen SQL-Injection
  • Keine Fehlermeldungen an Benutzer
  • Sessions korrekt abgesichert

Sicherer Datenbankbenutzer

Statt root wird ein eingeschränkter Benutzer webapp verwendet:

CREATE USER 'webapp'@'localhost' IDENTIFIED BY 'sicheres-passwort';
GRANT SELECT, INSERT, UPDATE, DELETE ON serververwaltung.* TO 'webapp'@'localhost';
FLUSH PRIVILEGES;

Zugangsdaten auslagern

Die Datei mit Zugangsdaten wird außerhalb des Webroots gespeichert: /etc/serververwaltung/db.conf.php

<?php
return [
  'host' => '127.0.0.1',
  'user' => 'webapp',
  'pass' => 'sicheres-passwort',
  'name' => 'serververwaltung'
];

Dateiberechtigungen setzen:

chmod 640 /etc/serververwaltung/db.conf.php
chown root:www-data /etc/serververwaltung/db.conf.php

Überarbeitung der Datei db.php

<?php
$config = require('/etc/serververwaltung/db.conf.php');

$conn = new mysqli($config['host'], $config['user'], $config['pass'], $config['name']);

if ($conn->connect_error) {
    error_log("DB-Verbindung fehlgeschlagen: " . $conn->connect_error);
    die("Interner Fehler. Bitte später erneut versuchen.");
}

Absicherung der Datei login.php

Verwendung von Prepared Statements statt direktem SQL und sichere Passwort-Hashes.

<?php
session_start();
include 'db.php';

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $benutzername = $_POST["benutzername"];
    $passwort = $_POST["passwort"];

    $stmt = $conn->prepare("SELECT passwort, rolle FROM benutzer WHERE benutzername = ?");
    $stmt->bind_param("s", $benutzername);
    $stmt->execute();
    $result = $stmt->get_result();

    if ($row = $result->fetch_assoc()) {
        if (password_verify($passwort, $row['passwort'])) {
            $_SESSION["benutzername"] = $benutzername;
            $_SESSION["rolle"] = $row["rolle"];
            header("Location: auswahl.html");
            exit;
        }
    }

    echo "Falsche Anmeldedaten.";
}

Passwort-Hash bei Benutzeranlage

Beim Erstellen neuer Benutzer:

insert into benutzer (benutzername, passwort, rolle)
values ('admin', 'REPLACE_DURCH_HASH', 'admin');

Beispiel für Passwort-Hash in PHP generieren:

php -r "echo password_hash('radler', PASSWORD_DEFAULT);"

Eintrag mit Prepared Statement (eintragen.php)

<?php
include 'db.php';
session_start();

if (!isset($_SESSION["benutzername"])) {
    header("Location: login.html");
    exit;
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $stmt = $conn->prepare("INSERT INTO server (rechnername, ip_adresse, betriebssystem, festplattenspeicher, ram, hauptdienst)
                            VALUES (?, ?, ?, ?, ?, ?)");
    $stmt->bind_param("sssdds",
        $_POST["rechnername"],
        $_POST["ip_adresse"],
        $_POST["betriebssystem"],
        $_POST["festplattenspeicher"],
        $_POST["ram"],
        $_POST["hauptdienst"]
    );

    if ($stmt->execute()) {
        header("Location: liste.php");
        exit;
    } else {
        error_log("Fehler beim Eintrag: " . $stmt->error);
        echo "Interner Fehler beim Eintrag.";
    }
}

Session-Absicherung

Session-Cookie absichern:

In PHP-Ini oder am Anfang des Scripts:

session_set_cookie_params([
  'lifetime' => 0,
  'path' => '/',
  'domain' => '', // ggf. setzen
  'secure' => true,
  'httponly' => true,
  'samesite' => 'Strict'
]);
session_start();

HTTPS

Das Projekt läuft nur über HTTPS. HTTP wird per Apache umgeleitet:

Datei: /etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
    ServerName server.it113.int
    Redirect permanent / https://server.it113.int/
</VirtualHost>

Aktivieren:

a2ensite default-ssl
a2enmod rewrite
a2enmod ssl
systemctl reload apache2

Zusammenfassung

  • Root-Nutzer ersetzt
  • Passwörter aus Webverzeichnis entfernt
  • Alle SQL-Zugriffe auf Prepared Statements umgestellt
  • Passwörter gehasht
  • Fehlerprotokollierung statt Benutzeranzeige
  • Sessions und HTTPS korrekt konfiguriert