Zum Inhalt

Server-Sicherheit (Teil 1)

Letzte Aktualisierung: Mai 2022. Für fortgeschrittene BenutzerInnen. Solide technische Kenntnisse erforderlich.

Warnhinweis

Kein System ist sicher. Dies ist das erste von zwei Kapiteln über Serversicherheit. Es legt zwar grundlegende Maßnahmen zum Schutz Eures Ubuntu-Servers vor unmittelbaren Bedrohungen dar. Aber geschickte Hacker oder eine Organisation mit ausreichenden Ressourcen können vermutlich trotzdem einen Weg in Euer System finden.

Firewall

Server sichern

Ein Server interagiert ständig mit Geräten innerhalb und außerhalb seines Netzwerks. Er sollte daher durch ein Sicherheitssystem namens Firewall geschützt werden, welches den ein- und ausgehenden Datenverkehr kontrolliert. Die Uncomplicated Firewall (ufw) ist eine beliebte Wahl auf Ubuntu-Servern, mehr dazu weiter unten.

Hier geht's zur Schritt-für-Schritt-Anleitung

Installation

Installiert die Uncomplicated Firewall, stellt sicher, dass sie nach jedem Neustart automatisch geladen wird und überprüft, ob alles richtig läuft (der Status sollte Active sein):

sudo apt install ufw
sudo ufw enable
sudo systemctl status ufw

Firewall-Regeln

Lehnt erst einmal jeglichen ein- und ausgehenden Verkehr ab:

sudo ufw default deny outgoing
sudo ufw default deny incoming

Stellt nun sicher, dass die Firewall nur den wirklich erforderlichen Datenverkehr zulässt. Dies geschieht durch das Öffnen der entsprechenden Kommunikationsendpunkte, auch Ports genannt. Im Rahmen dieses Tutorials werden wir nur einige dieser Ports öffnen. Passt die Befehle an Eure eigenen spezifischen Bedürfnisse an:

sudo ufw allow 80,443/tcp
sudo ufw allow 22/tcp
sudo ufw allow 123/udp
sudo ufw allow in from any to any port 53
sudo ufw allow out 80,443/tcp
sudo ufw allow out 22/tcp
sudo ufw allow out 123/udp
sudo ufw allow out from any to any port 53

Ein paar Zusatzinformationen zu diesen Ports:

Port Beschreibung
80 HTTP-Anfragen: sind dem allgemein verwendeten Internet-Kommunikationsprotokoll Hypertext Transfer Protocol (HTTP) zugeordnet. Euer Server verwendet diesen Port, um Daten ins Netz zu senden und von dort zu empfangen.
443 HTTPS-Anfragen: Standardport für den gesamten gesicherten HTTP-Verkehr (HTTPS). Euer Server verwendet diesen Port, um verschlüsselte Daten ins Netz zu senden und von dort zu empfangen.
22 SSH-Anfragen: werden in der Regel verwendet, um das Secure-Shell-Protokoll (SSH) auszuführen. Euer Server verwendet diesen Port für Fernanmeldungen.
123 NTP-Synchronisierung: ermöglicht die Synchronisierung der Zeit zwischen Rechnern.
53 DNS-Anfragen: werden für die Auflösung von Domänennamen verwendet. Euer Server nutzt diesen Port, um für Menschen lesbare Domänennamen in IP-Adressen umzuwandeln.

Prüft abschließend, ob alle Firewall-Regeln korrekt eingestellt sind:

sudo ufw status numbered

Die Regeln sollten folgendermaßen aussehen:

Status: active

        To                  Action          From
        --                  ------          ----
[ 1]    80,443/tcp          ALLOW IN        Anywhere
[ 2]    22/tcp              ALLOW IN        Anywhere
[ 3]    123/udp             ALLOW IN        Anywhere
[ 4]    53                  ALLOW IN        Anywhere
[ 5]    80,443/tcp          ALLOW OUT       Anywhere
[ 6]    22/tcp              ALLOW OUT       Anywhere
[ 7]    123/udp             ALLOW OUT       Anywhere
[ 8]    53                  ALLOW OUT       Anywhere
[ 9]    80,443/tcp (v6)     ALLOW IN        Anywhere (v6)
[10]    22/tcp  (v6)        ALLOW IN        Anywhere (v6)
[11]    123/udp  (v6)       ALLOW IN        Anywhere (v6)
[12]    53  (v6)            ALLOW IN        Anywhere (v6)
[13]    80,443/tcp  (v6)    ALLOW OUT       Anywhere (v6)
[14]    22/tcp  (v6)        ALLOW OUT       Anywhere (v6)
[15]    123/udp  (v6)       ALLOW OUT       Anywhere (v6)
[16]    53  (v6)            ALLOW OUT       Anywhere (v6)

Router-Einstellungen

Möglicherweise solltet Ihr auch Eure Router-Einstellungen überprüfen und sicherstellen, dass alle ungenutzten Ports deaktiviert sind. Weitere Informationen finden Ihr im Handbuch Eures Routers.

Hier geht's zum 1-minütigen Zusammenfassungsvideo


Serverzeit NTP

Serverzeit

Viele Sicherheitsprotokolle hängen von der Systemzeit ab. Eine falsche Zeitangabe kann sich daher negativ auf die Sicherheit auswirken. Das sogenannte Network Time Protocol (NTP) sorgt dafür, dass die Serverzeit mit Referenzrechnern synchronisiert bleibt. Diese so genannten NTP-Server sind in hierarchischen Ebenen oder Schichten (sogenannte Strata) organisiert. Nachstehend erfahrt Ihr, wie Ihr NTP auf Eurem Server einrichtet.

Serverzeit NTP

Ebene Beschreibung
Stratum 0 Hardware-Uhren, zum Beispiel Atomuhren, GPS oder Funkzeitempfänger.
Stratum 1 Rechner mit einer direkten Verbindung zu Hardware-Uhren.
Stratum 2 Rechner, die über ein Netzwerk mit Stratum-1-Servern synchronisiert werden.
NTP-Clients Rechner, die in regelmäßigen Abständen die Zeit von NTP-Servern abfragen.

Hier geht's zur Schritt-für-Schritt-Anleitung

Konfiguration

Legt eine Sicherungskopie der Konfigurationsdatei an:

sudo cp --archive /etc/systemd/timesyncd.conf /etc/systemd/timesyncd.conf-COPY-$(date +"%Y%m%d%H%M%S")

Öffnet die Konfigurationsdatei the file:

sudo vi /etc/systemd/timesyncd.conf

Ändert den Datei-Inhalt, um auf öffentliche und quelloffene Zeitserver zuzugreifen, die vom Projekt pool.ntp.org oder Ubuntu betrieben werden:

[Time]
NTP=0.pool.ntp.org 1.pool.ntp.org
FallbackNTP=ntp.ubuntu.com

Speichert und schließt die Datei (:wq!). Startet schließlich den Dienst systemd-timesyncd neu und stellt sicher, dass alles läuft (der Status sollte Active sein):

sudo systemctl restart systemd-timesyncd
sudo systemctl status systemd-timesyncd

Zeitzone

Konfiguriert als nächstes die Server-Zeitzone:

timedatectl | grep Time

Mal angenommen, Ihr wohnt in der Nähe von Budapest. Dann sollte das Terminal folgendes anzeigen:

Time zone: Europe/Budapest (CEST, +0200)

Falls nicht, stellt die richtige Zeitzone ein (passt die Zeitzone entsprechend an):

sudo timedatectl set-timezone Europe/Budapest
Hier geht's zum 1-minütigen Zusammenfassungsvideo


SSH sichern

SSH sichern

Wir haben bereits erklärt, wie man von einem anderen Rechner aus eine Fernverbindung zum Server herstellt. Weiter unten erfahrt Ihr, wie die Fernverbindung weiter gesichert werden kann:

Sicherheitsmerkmal Beschreibung
SSH-Port Ändert den SSH-Port von 22 auf einen anderen Wert. Im Rahmen dieses Tutorials wählen wir den Port "2222"; Ihr könnt natürlich einen anderen Wert wählen, stellt dabei lediglich sicher die jeweiligen Befehle entsprechend anzupassen.
Anmeldebeschränkungen Begrenzt die Anzahl der Anmeldeversuche.
Zugangsbeschränkungen Erlaubt nur bestimmten BenutzerInnen, sich anzumelden. In diesem Fall der Administrator gofossadmin (passt den Namen entsprechend an).
Protokollierung Verzeichnet jede Anmeldung.
Root-Beschränkungen Verhindert den SSH-Fernzugriff auf das Root-Konto.
Authentifizierung Verwendet passwortgeschützte Authentifizierungsschlüssel anstelle der Passwortauthentifizierung.
Unterbrechung der Verbindung Aktiviert die automatische Trennung der Verbindung nach 5 Minuten Untätigkeit.
Verschlüsselungscodes Entfernt kurze Verschlüsselungscodes für mehr Sicherheit.
Rechtlicher Hinweis Fügt einen rechtlichen Hinweis hinzu, um unbefugte BenutzerInnen zu warnen.

Hier geht's zur Schritt-für-Schritt-Anleitung

SSH-Port und Sicherheitseinstellungen

Öffnet den neuen SSH-Port 2222 (passt den Wert entsprechend an):

sudo ufw allow 2222/tcp
sudo ufw allow out 2222/tcp

Legt eine Sicherungskopie der Konfigurationsdatei an. Sollte etwas schief gehen, könnt Ihr die ursprünglichen Einstellungen wiederherstellen:

sudo cp --preserve /etc/ssh/sshd_config /etc/ssh/sshd_config.$(date +"%Y%m%d%H%M%S")

Öffnet die SSH-Konfigurationsdatei:

sudo vi /etc/ssh/sshd_config

Löscht den Inhalt der Datei durch Eingabe von :%d. Gebt dann den folgenden Inhalt ein oder kopiert/fügt ihn in die Datei ein. Stellt dabei sicher, dass Ihr die Einstellungen je nach Bedarf anpasst (z. B. den SSH-Port oder den Administrator-Benutzernamen):

# Unterstützte HostKey-Algorithmen in der Reihenfolge ihrer Bevorzugung:

HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com

# Verschiedene Sicherheitseinstellungen:

Port                            2222        # von Standard-SSH-Port 22 abweichen (entsprechend anpassen)
LogLevel                        VERBOSE     # den Fingerabdruck des Benutzers bei der Anmeldung protokollieren, um einen eindeutigen Nachweis darüber zu haben, welcher Schlüssel zur Anmeldung verwendet wurde
Protocol                        2           # nur das neuere, sicherere Protokoll verwenden
PermitUserEnvironment           no          # BenutzerInnen keine Umgebungsvariablen setzen lassen
PermitRootLogin                 no          # Root-Anmeldung nicht zulassen
PubkeyAuthentication            yes         # Authentifizierung mit öffentlichem Schlüssel erlauben
PasswordAuthentication          no          # Anmeldung mit Passwort verbieten
PermitEmptyPasswords            no          # Keine Anmeldung zulassen, wenn das Konto ein leeres Passwort hat
MaxAuthTries                    3           # Maximal erlaubte Anmeldeversuche
MaxSessions                     2           # Maximale Anzahl von offenen Sitzungen
X11Forwarding                   no          # X11-Weiterleitung deaktivieren
IgnoreRhosts                    yes         # .rhosts und .shosts ignorieren
UseDNS                          no          # Übereinstimmung von Hostname und IP überprüfen
ClientAliveCountMax             0           # Maximale Anzahl von unbeantworteten Client-Alive-Nachrichten
ClientAliveInterval             300         # Wartezeit in Sekunden, bevor eine Antwort angefordert wird
AllowUsers                      gofossadmin # nur dem Benutzer gofossadmin erlauben, sich aus der Ferne anzumelden (entsprechend anpassen)

# Portweiterleitung deaktivieren:

AllowAgentForwarding            no
AllowTcpForwarding              no
AllowStreamLocalForwarding      no
GatewayPorts                    no
PermitTunnel                    no

# Dateizugriff auf sftp-Ebene protokollieren (read/write/etc.):

Subsystem sftp  /usr/lib/openssh/sftp-server

# Andere Sicherheitseinstellungen:

Compression                     no
PrintMotd                       no
TCPKeepAlive                    no
ChallengeResponseAuthentication no
UsePAM                          yes
AcceptEnv LANG LC_*

Speichert und schließt die SSH-Konfigurationsdatei (:wq!). Startet den SSH-Server neu und überprüft, ob der neue SSH-Port auf 2222 (bzw. den von Euch gewählten Port) eingestellt ist:

sudo systemctl restart sshd
sudo ss -tlpn | grep ssh

Inaktiver Verbindungen trennen

Stellen Sie sicher, dass alle entfernten SSH-Verbindungen nach 5 Minuten Untätigkeit deaktiviert werden:

echo 'TMOUT=300' >> .bashrc
tail .bashrc

Kurze Verschlüsselungscodes entfernen

SSH verwendet den Diffie-Hellman-Algorithmus, um eine sichere Verbindung herzustellen. Aus Sicherheitsgründen wird empfohlen, Schlüssel mit einer Länge von mindestens 3072 Bit zu verwenden.

Legt eine Sicherungskopie der SSH-Konfigurationsdatei an. Sollte etwas schief gehen, könnt Ihr die ursprünglichen Einstellungen wiederherstellen:

sudo cp --archive /etc/ssh/moduli /etc/ssh/moduli-COPY-$(date +"%Y%m%d%H%M%S")

Entfernt Schlüssel, die kürzer als 3072 Bit sind:

sudo awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.tmp
sudo mv /etc/ssh/moduli.tmp /etc/ssh/moduli

Rechtlicher Hinweis

Bei der Fernanmeldung am Server sollten BenutzerInnen eine Warnmeldung erhalten. Öffnet dazu die folgende Datei:

sudo vi /etc/issue.net

Fügt einen rechtlichen Hinweis hinzu, zum Beispiel:

Dieses System darf nur von befugten Benutzern bedient werden.

Personen, die dieses Computersystem unbefugt oder unter Überschreitung ihrer Befugnisse benutzen, müssen damit rechnen, dass alle ihre Aktivitäten in diesem System vom Systempersonal überwacht und aufgezeichnet werden.

Im Rahmen der Überwachung von Personen, die dieses System missbräuchlich benutzen, oder im Rahmen der Systemwartung können auch die Aktivitäten von autorisierten Benutzern überwacht werden.

Jeder, der dieses System benutzt, erklärt sich ausdrücklich mit einer solchen Überwachung einverstanden und wird darauf hingewiesen, dass das Systempersonal den Strafverfolgungsbehörden die Beweise für eine solche Überwachung zur Verfügung stellen kann, wenn diese Überwachung mögliche Beweise für kriminelle Aktivitäten ergibt.

Konfiguration testen und Port 22 schließen

Das war's! Von nun an könnt Ihr Euch sicher über Euren Client-Rechner beim Server anmelden. Öffnet einfach ein Terminal, wechselt zum Administratorkonto und verbindet Euch mit dem Server unter Verwendung Eurer Passwörter. Vergesst nicht, den Benutzernamen, die IP-Adresse und den SSH-Port nach Bedarf anzupassen:

su - gofossadmin
ssh -p 2222 gofossadmin@192.168.1.100

Probiert das ein paar Mal aus. Funktioniert alles wie erwartet, könnt Ihr den ungenutzten Port 22 schließen:

sudo ufw delete allow 22/tcp
sudo ufw delete allow out 22/tcp
Hier geht's zum 2-minütigen Zusammenfassungsvideo


MySQL sichern

MySQL sichern

MySQL-Datenbanken laufen als Backend für viele Webdienste. Folgt den nachstehenden Anweisungen, um die von MySQL verwalteten Informationen vor unbefugtem Zugriff zu schützen.

Hier geht's zur Schritt-für-Schritt-Anleitung

MySQL sichern

Startet MySQL:

sudo mysql

Ändert die Authentifizierungsparameter für den Root-Benutzer. Vergesst nicht im untenstehenden Befehl die Zeichenfolge StrongPassword durch ein sicheres, individuelles Password zu ersetzen:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by 'StrongPassword';

Verlasst MySQL:

exit

Führt nun das MySQL-Sicherheitsskript aus:

sudo mysql_secure_installation

Folgt den Anweisungen auf dem Bildschirm:

  • das Root-Passwort, das soeben festgelegt wurde, muss nicht geändert werden
  • entfernt den anonymen Benutzer
  • verbietet dem Root-Konto, sich aus der Ferne anzumelden
  • entfernt die Testdatenbank
  • ladet die Privilegien-Tabelle neu

Unbefugten Zugang verhindern

Legt eine Sicherungskopie der MySQL-Konfigurationsdatei an. Sollte etwas schief gehen, könnt Ihr die ursprünglichen Einstellungen wiederherstellen:

sudo cp --archive /etc/mysql/mysql.conf.d/mysqld.cnf /etc/mysql/mysql.conf.d/mysqld.cnf-COPY-$(date +"%Y%m%d%H%M%S")

Öffnet die Konfigurationsdatei:

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

Fügt folgende Zeilen ein bzw. passt sie an, um den Fernzugriff auf MySQL zu deaktivieren und unbefugten Zugriff auf lokale Dateien zu verhindern:

bind-address = 127.0.0.1
local-infile = 0

Speichert und schließt die MySQL-Konfigurationsdatei (:wq!).

Benutzerberechtigungen

Es empfiehlt sich, für jede Anwendung mit MySQL-Zugang einen eigenen Benutzer mit eingeschränkten Rechten zu erstellen. Zum Beispiel werden dem Cloud-Speicher oder der Fotogalerie, die wir in weiteren Kapiteln behandeln, jeweils eigene MySQL-Benutzer zugeteilt. Auf diese Weise bleiben die Anwendungen voneinander abgeschottet und greifen nur bei Bedarf auf Datenbanken zu.

Hier geht's zum 1-minütigen Zusammenfassungsvideo


Apache sichern

Apache sichern

Apache ist der weltweit meistgenutzte Webserver. Konfiguriert ihn richtig, um die Sicherheit zu erhöhen. Mehr dazu unten.

Hier geht's zur Schritt-für-Schritt-Anleitung

Sicherheitsmodule aktivieren

Installiert die folgenden beiden Apache-Module:

sudo apt install libapache2-mod-security2 libapache2-mod-evasive

Aktiviert die Sicherheitsmodule sowie weitere für dieses Tutorial benötigte Module und startet Apache neu:

sudo a2enmod security2
sudo a2enmod evasive
sudo a2enmod rewrite
sudo a2enmod headers
sudo a2enmod ssl
sudo a2enmod proxy
sudo a2enmod proxy_html
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel
sudo a2enmod xml2enc
sudo a2enmod expires
sudo systemctl restart apache2

Einige zusätzliche Informationen zu diesen Modulen:

Modul Beschreibung
Security2 Schützt Euren Server vor verschiedenen Angriffen, wie z. B. SQL-Injection, Session Hijacking, Cross-Site-Scripting, Böswilligen User Agents, usw.
Evasive Bietet Ausweichmöglichkeiten im Falle eines verteilten Dienstverweigerungsangriffs (DDoS) oder eines Brute Force Angriffs.
Rewrite Ermöglicht das Umschreiben von URLs, zum Beispiel um http:// nach https:// umzuleiten.
Headers Ermöglicht die Kontrolle und Änderung von HTTP-Anfragen und Antwort-Headern.
SSL Aktiviert die SSL- und TLS-Verschlüsselung.
Proxy, proxy_html, proxy_http Erstellt einen Proxy/Gateway für Euren Server, stellt sicher, dass Links für BenutzerInnen außerhalb des Proxys funktionieren, und übermittelt HTTP- sowie HTTPS-Anfragen.
Xml2enc Bietet erweiterte Unterstützung für die Internationalisierung.
Expires Verbessert die Ladezeit von Webseiten, indem es festlegt, wie lange ein Bild vom Browser gespeichert wird.

Empfindliche Informationen verbergen

Standardmäßig versendet der Server HTTP-Header mit Informationen über die Apache-Version, die installierten Module, das Betriebssystem usw. Diese Daten können zum Ausnutzen von Sicherheitslücken verwendet werden. Erstellt daher eine benutzerdefinierte Apache-Konfigurationsdatei, um solche empfindlichen Informationen zu verbergen:

sudo vi /etc/apache2/conf-available/custom.conf

Fügt folgenden Inhalt ein:

ServerTokens        Prod
ServerSignature     Off
TraceEnable         Off
Options all -Indexes
Header always unset X-Powered-By

Speichert und schließt die Datei (:wq!).

Wendet die angepasste Konfiguration an, prüft diese auf Syntaxfehler (das Terminal sollte OK anzeigen) und startet Apache neu:

sudo a2enconf custom.conf
sudo apachectl configtest
sudo systemctl restart apache2

Ein paar zusätzliche Informationen zu den obigen Einstellungen:

Einstellung Beschreibung
ServerTokens Prod Der Server-Header gibt lediglich "Apache" zurück.
ServerSignature Off Blendet die Serverversion auf von Apache generierten Seiten aus.
TraceEnable Off Deaktiviert die HTTP TRACE-Methode, die Euren Server für Cross-Site-Scripting-Angriffe anfällig machen kann.
Options all -Indexes Deaktiviert die Verzeichnisansicht.
Header always unset X-Powered-By Versteckt die Information "X-Powered-By ..." und vermeidet die Anzeige der Programmversion.

ModSecurity konfigurieren

ModSecurity ist eine quelloffene Webanwendungsfirewall. Das Programm kann Euren Server vor verschiedenen Angriffen schützen. Öffnet hierzu die Konfigurationsdatei:

sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
sudo vi /etc/modsecurity/modsecurity.conf

Ändert bzw. ergänzt die folgenden Einstellungen:

SecRuleEngine                   On
SecResponseBodyAccess           Off
SecRequestBodyLimit             8388608
SecRequestBodyNoFilesLimit      131072
SecRequestBodyInMemoryLimit     262144

Speichert und schließt die Datei (:wq!).

Ein paar zusätzliche Informationen zu den obigen Einstellungen:

Einstellung Beschreibung
SecRuleEngine On Aktiviert ModSecurity unter Verwendung der Standardregeln.
SecResponseBodyAccess Off Deaktiviert die Pufferung von Anfragen, um weniger Arbeitsspeicher und Rechenpower zu beanspruchen.
SecRequestBodyLimit 8388608 Legt die maximale Puffer-Größe für Anfragen auf 8 MB fest.
SecRequestBodyNoFilesLimit 131072 Legt die maximale Puffer-Größe für Datenpakete auf 128 KB fest.
SecRequestBodyInMemoryLimit 262144 Legt die maximale im Arbeitsspeicher abgelegte Größe für Anfragen auf 256 KB fest.

Aktiviert den neuesten OWASP ModSecurity Regelsatz (Core Rule Set, bzw. CRS). Dies sind generische Regeln zur Erkennung von Angriffen, die auf GitHub gepflegt werden:

sudo rm -rf /usr/share/modsecurity-crs
sudo apt install git
sudo git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /usr/share/modsecurity-crs
cd /usr/share/modsecurity-crs
sudo mv crs-setup.conf.example crs-setup.conf

Legt eine Sicherungskopie der ModSecurity-Konfigurationsdatei an. Sollte etwas schief gehen, könnt Ihr die ursprünglichen Einstellungen wiederherstellen:

sudo cp --archive /etc/apache2/mods-enabled/security2.conf /etc/apache2/mods-enabled/security2.conf-COPY-$(date +"%Y%m%d%H%M%S")

Öffnet die Konfigurationsdatei:

sudo vi /etc/apache2/mods-enabled/security2.conf

Löscht deren Inhalt durch Eingabe der Zeichenfolge :%d. Gebt anschließend die folgenden Zeilen ein bzw. kopiert/fügt diese in die Konfigurationsdatei ein:

<IfModule security2_module>
    SecDataDir /var/cache/modsecurity
    IncludeOptional /etc/modsecurity/*.conf
    IncludeOptional /usr/share/modsecurity-crs/*.conf
    IncludeOptional /usr/share/modsecurity-crs/rules/*.conf
</IfModule>

Speichert und schließt die Datei (:wq!). Prüft die Datei auf Syntaxfehler (das Terminal sollte OK anzeigen) und startet Apache neu, um die neue Konfiguration zu übernehmen:

sudo apachectl configtest
sudo systemctl restart apache2

Legt eine Sicherungskopie der ModEvasive-Konfigurationsdatei an. Sollte etwas schief gehen, könnt Ihr die ursprünglichen Einstellungen wiederherstellen:

sudo cp --archive /etc/apache2/mods-enabled/evasive.conf /etc/apache2/mods-enabled/evasive.conf-COPY-$(date +"%Y%m%d%H%M%S")

Konfiguriert ModEvasive zum Schutz Eures Servers vor verteilten Dienstverweigerungsangriffen (DDoS) oder Brute Force Angriffen.

Öffnet die Konfigurationsdatei:

sudo vi /etc/apache2/mods-enabled/evasive.conf

Ändert oder ergänzt folgende Einstellungen:

<IfModule mod_evasive20.c>
    DOSPageCount        5
    DOSSiteCount        50
    DOSPageInterval     1
    DOSSiteInterval     1
    DOSBlockingPeriod   600
    DOSLogDir           "/var/log/mod_evasive"
</IfModule>

Speichert und schließt die Datei (:wq!). Die folgenden Befehle erstellen ein Verzeichnis für die Protokolldateien, prüfen auf Syntaxfehler (das Terminal sollte OK anzeigen), starten Apache neu und überprüfen, ob der Status Active ist:

sudo mkdir /var/log/mod_evasive
sudo chown -R www-data: /var/log/mod_evasive
sudo apachectl configtest
sudo systemctl restart apache2
sudo systemctl status apache2
Hier geht's zum 2-minütigen Zusammenfassungsvideo


PHP sichern

PHP sichern

PHP ist eine weit verbreitete Programmiersprache für Webdienste. Eine richtige Konfiguration ist wichtig, um die Sicherheit Eures Servers zu erhöhen. Mehr Details unten.

Hier geht's zur Schritt-für-Schritt-Anleitung

PHP-Version

PHP unterstützt verschiedene Versionen. Zum Zeitpunkt der Abfassung dieses Textes ist PHP 8.1 standardmäßig in den Paketquellen von Ubuntu 22.04 enthalten. Prüft, welche Version auf Eurem System installiert ist:

php -v

PHP-Module

Installiert einige gängige PHP-Module, die für dieses Tutorial benötigt werden. Benutzt dabei dieselbe Versionsnummer wie oben:

sudo apt install php8.1-common php8.1-mbstring php8.1-xmlrpc php8.1-gd php8.1-xml php8.1-intl php8.1-mysql php8.1-cli php8.1-ldap php8.1-zip php8.1-curl php8.1-pgsql php8.1-opcache php8.1-sqlite3

PHP-Sicherheitseinstellungen

Die php.ini-Konfigurationsdateien enthalten alle relevanten PHP-Sicherheitseinstellungen. Lasst uns zunächst herausfinden, wo diese Dateien gespeichert sind:

sudo find / -name php.ini

Je nach PHP-Version sollte der Befehl in etwa folgende Terminal-Ausgabe liefern:

/etc/php/8.1/apache2/php.ini
/etc/php/8.1/cli/php.ini

Die Datei /etc/php/8.1/apache2/php.ini wird vom Apache-Server verwendet, während die Datei /etc/php/8.1/cli/php.ini vom CLI-PHP-Programm verwendet wird.

Legt eine Sicherungskopie beider Konfigurationsdateien an. Sollte etwas schief gehen, könnt Ihr die ursprünglichen Einstellungen wiederherstellen:

sudo cp --archive /etc/php/8.1/apache2/php.ini /etc/php/8.1/apache2/php.ini-COPY-$(date +"%Y%m%d%H%M%S")
sudo cp --archive /etc/php/8.1/cli/php.ini /etc/php/8.1/cli/php.ini-COPY-$(date +"%Y%m%d%H%M%S")

Öffnet die erste Konfigurationsdatei:

sudo vi /etc/php/8.1/apache2/php.ini

Ändert oder ergänzt folgende Einstellungen:

expose_php          =   Off
allow_url_fopen     =   Off
allow_url_include   =   Off
display_errors      =   Off
mail.add_x_header   =   Off
disable_functions   =   show_source,system,passthru,phpinfo,proc_open,allow_url_fopen,curl_exec
max_execution_time  =   90
max_input_time      =   90
memory_limit        =   1024M

Speichert und schließt die Datei (:wq!).

Öffnet die zweite Konfigurationsdatei:

sudo vi /etc/php/8.1/cli/php.ini

Ändert oder ergänzt folgende Einstellungen:

expose_php = Off
allow_url_fopen = Off

Speichert und schließt die Datei (:wq!).

Ein paar zusätzliche Informationen zu den obigen Einstellungen:

Einstellung Beschreibung
expose_php = Off Versteckt die PHP-Version in den Headern.
allow_url_fopen = Off Deaktiviert die Fernausführung von PHP-Code, um Code-Injection-Schwachstellen zu mindern.
allow_url_include = Off Deaktiviert die Fernausführung von PHP-Code, um Code-Injection-Schwachstellen zu mindern.
display_errors = Off Deaktiviert die Fehleranzeige.
mail.add_x_header = Off Entfernt PHP-Header aus E-Mails.
disable_functions = show_source, system, passthru, phpinfo, proc_open, allow_url_fopen, curl_exec Deaktiviert potentiell schädliche PHP-Funktionen. Die folgenden drei Funktionen wurden nicht deaktiviert, da dies Pihole v5.2 beeinträchtigt: exec, shell_exec, popen.
max_execution_time = 90 Legt die maximale Zeit fest, die ein Skript laufen darf (in Sekunden).
max_input_time = 90 Legt die maximale Zeit fest, in der ein Skript Daten auswerten kann (in Sekunden).
memory_limit = 1024M Legt die maximale Menge an Speicher fest, die einem Skript zugewiesen wird.

Hier geht's zum 2-minütigen Zusammenfassungsvideo


Sicherheits-Updates

Sicherheits-Updates

Der Server sollte stets auf den neuesten Stand gebracht werden, um Sicherheitslücken zu schließen. Aktiviert daher die automatische Aufspielung der wichtigsten Sicherheitskorrekturen, wie unten beschrieben.

Hier geht's zur Schritt-für-Schritt-Anleitung

Aktiviert automatische Updates:

sudo apt install unattended-upgrades

Erstellt eine Konfigurationsdatei:

sudo vi /etc/apt/apt.conf.d/51myunattended-upgrades

Fügt den folgenden Inhalt hinzu, um unbeaufsichtigte Upgrades zu ermöglichen:

// Aktiviert das Update/Upgrade-Skript (0=deaktivieren)
APT::Periodic::Enable "1";

// Führt "apt-get update" automatisch alle n-Tage aus (0=deaktivieren)
APT::Periodic::Update-Package-Lists "1";

// Führt "apt-get upgrade --download-only" alle n-Tage aus (0=deaktivieren)
APT::Periodic::Download-Upgradeable-Packages "1";

// Führt "apt-get autoclean" alle n-Tage aus (0=deaktivieren)
APT::Periodic::AutocleanInterval "7";

// Sendet Berichtsmail an Root
//     0:  kein Bericht             (oder Null-String)
//     1:  Sachstandsbericht       (jede Zeichenkette)
//     2:  + Befehlsausgaben     (-qq entfernen, 2>/dev/null entfernen, -d hinzufügen)
//     3:  + Aufzeichnung aktiviert
APT::Periodic::Verbose "2";
APT::Periodic::Unattended-Upgrade "1";

// Automatisches Upgrade von Paketen
Unattended-Upgrade::Origins-Pattern {
    "o=Ubuntu,a=stable";
    "o=Ubuntu,a=stable-updates";
    "origin=Ubuntu,codename=${distro_codename},label=Ubuntu-Security";
};

// Gebt Eure eigenen Pakete an, die NICHT automatisch aktualisiert werden sollen
Unattended-Upgrade::Package-Blacklist {
};

// Führt dpkg --force-confold --configure -a aus, wenn ein unsauberer dpkg-Status erkannt wird, um sicherzustellen, dass Updates auch dann installiert werden, wenn das System während eines vorherigen Laufs unterbrochen wurde
Unattended-Upgrade::AutoFixInterruptedDpkg "true";

// Führt die Aktualisierung bei laufendem Betrieb durch, damit Euer Server nicht oft heruntergefahren wird
Unattended-Upgrade::InstallOnShutdown "false";

// Sendet eine E-Mail mit Informationen über die aktualisierten Pakete an diese Adresse.
Unattended-Upgrade::Mail "root";

// E-Mail immer senden
Unattended-Upgrade::MailOnlyOnError "false";

// Entfernt alle ungenutzten Abhängigkeiten nach Abschluss der Aktualisierung
Unattended-Upgrade::Remove-Unused-Dependencies "true";

// Entfernt alle neuen, ungenutzten Abhängigkeiten nach Abschluss der Aktualisierung
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";

// NICHT OHNE BESTÄTIGUNG automatisch neu starten, wenn die Datei /var/run/reboot-required nach der Aktualisierung gefunden wird
Unattended-Upgrade::Automatic-Reboot "false";

// NICHT automatisch neu starten, selbst wenn Benutzer angemeldet sind
Unattended-Upgrade::Automatic-Reboot-WithUsers "false";

Speichert und schließt die Datei (:wq!). Führt einen Testlauf durch, um sicherzustellen, dass alles funktioniert:

sudo unattended-upgrade -d --dry-run
Hier geht's zum 1-minütigen Zusammenfassungsvideo


Server-Sicherheit