% ============================================ % STEP 01: SERVER-ABSICHERUNG (UBUNTU 24.04) % ============================================ \section{Server-Absicherung (Ubuntu 24.04 auf Contabo VPS)} \label{sec:step01} In diesem Schritt richten wir einen frisch installierten Ubuntu 24.04 Server bei Contabo ein und härten ihn gegen Angriffe. Folgende Maßnahmen werden durchgeführt: \begin{enumerate} \item SSH-Verbindung mit Passwort testen \item System-Updates einspielen \item SSH-Key-Authentifizierung einrichten (Login ohne Passwort) \item SSH-Client-Konfiguration mit Alias (Kurzbefehl) \item SSH-Timeout auf 20 Minuten verlängern \item Fail2Ban installieren (Bruteforce-Schutz) \end{enumerate} \textbf{Server-Daten:} \begin{itemize} \item Hostname: \texttt{vmd147914} \item IP: \texttt{185.209.229.167} \item OS: Ubuntu 24.04.4 LTS \item Speicher: 386 GB SSD \end{itemize} % ============================================ \subsection{Schritt 1: SSH-Verbindung testen} % ============================================ Die erste Verbindung zum Server erfolgt per SSH (Secure Shell) mit Benutzername und Passwort. SSH ist ein verschlüsseltes Netzwerkprotokoll, mit dem du sicher auf entfernte Server zugreifen kannst. \textbf{Ausgeführt auf deinem lokalen PC:} \begin{lstlisting}[language=Bash, caption={SSH-Verbindung zum Server aufbauen}] ssh root@185.209.229.167 \end{lstlisting} \textbf{Erklärung des Befehls:} \begin{itemize} \item \texttt{ssh} -- der Befehl zum Starten einer SSH-Verbindung \item \texttt{root} -- der Benutzername (root ist der Administrator unter Linux) \item \texttt{@} -- trennt Benutzername und Server-Adresse \item \texttt{185.209.229.167} -- die öffentliche IPv4-Adresse deines Servers \end{itemize} Nach Eingabe des Passworts erscheint der Ubuntu-Willkommensbildschirm mit Systeminformationen. \textbf{Hinweis:} Bei einer neu installierten Maschine kann folgende Warnung erscheinen: \begin{lstlisting}[language=Bash, caption={WARNUNG: REMOTE HOST IDENTIFICATION HAS CHANGED}] @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \end{lstlisting} Das passiert, weil der Server einen neuen SSH-Fingerabdruck hat (durch die Neuinstallation). Dein PC erinnert sich an den alten Fingerabdruck und warnt dich vor einem möglichen Man-in-the-Middle-Angriff. Da du den Server selbst neu installiert hast, ist das harmlos. \textbf{Lösung:} Den alten Eintrag löschen mit: \begin{lstlisting}[language=Bash, caption={Alten SSH-Fingerabdruck entfernen}] ssh-keygen -f '/home/computer/.ssh/known_hosts' -R '185.209.229.167' \end{lstlisting} Danach erneut verbinden und den neuen Fingerabdruck mit \texttt{yes} bestätigen. % ============================================ \subsection{Schritt 2: System-Updates} % ============================================ Nach dem ersten Login wird das System auf den neuesten Stand gebracht. \textbf{Ausgeführt auf dem Server (root@vmd147914):} \begin{lstlisting}[language=Bash, caption={System-Updates ausführen}] apt update && apt upgrade -y \end{lstlisting} \textbf{Erklärung des Befehls:} \begin{itemize} \item \texttt{apt} -- Advanced Package Tool, der Paketmanager von Ubuntu/Debian \item \texttt{update} -- holt die neuesten Paketlisten von den Ubuntu-Servern \item \texttt{\&\&} -- führt den zweiten Befehl nur aus, wenn der erste erfolgreich war \item \texttt{upgrade} -- installiert alle verfügbaren Aktualisierungen \item \texttt{-y} -- beantwortet alle Rückfragen automatisch mit "Yes" \end{itemize} % ============================================ \subsection{Schritt 3: SSH-Key-Authentifizierung} % ============================================ Ein SSH-Key ist sicherer als ein Passwort, da er nicht durch Ausprobieren (Bruteforce) erraten werden kann. Er besteht aus zwei Teilen: \begin{itemize} \item \textbf{Private Key} (\texttt{id\_ed25519}) -- bleibt auf deinem PC, niemals weitergeben! \item \textbf{Public Key} (\texttt{id\_ed25519.pub}) -- wird auf den Server kopiert \end{itemize} Das Verfahren nennt sich \textbf{asymmetrische Kryptographie}: Der Server schickt eine zufällige Nachricht, dein PC "unterschreibt" sie mit dem privaten Schlüssel, der Server prüft die Unterschrift mit dem öffentlichen Schlüssel. Stimmt sie überein, bist du eingeloggt -- ohne Passwort. \textbf{Schritt 3a: Key-Paar erstellen -- auf deinem lokalen PC:} \begin{lstlisting}[language=Bash, caption={SSH-Key generieren}] ssh-keygen -t ed25519 -C "robert@local" \end{lstlisting} \textbf{Erklärung des Befehls:} \begin{itemize} \item \texttt{ssh-keygen} -- Programm zum Erstellen von SSH-Schlüsselpaaren \item \texttt{-t ed25519} -- verwendet den modernen Ed25519-Algorithmus (kurz, schnell, sicher) \item \texttt{-C "robert@local"} -- Kommentar, damit du später erkennst, wofür der Key ist \end{itemize} Bei den Rückfragen einfach Enter drücken -- der Key wird im Standardverzeichnis \texttt{\textasciitilde/.ssh/} gespeichert. \textbf{Schritt 3b: Public Key auf den Server kopieren -- auf deinem lokalen PC:} \begin{lstlisting}[language=Bash, caption={Public Key auf den Server übertragen}] ssh-copy-id root@185.209.229.167 \end{lstlisting} Einmal das Server-Passwort eingeben. Der Befehl kopiert deinen Public Key in die Datei \texttt{\textasciitilde/.ssh/authorized\_keys} auf dem Server. \textbf{Schritt 3c: Testen -- auf deinem lokalen PC:} \begin{lstlisting}[language=Bash, caption={Login ohne Passwort testen}] ssh root@185.209.229.167 \end{lstlisting} Du wirst jetzt ohne Passwort-Abfrage eingeloggt. % ============================================ \subsection{Schritt 4: SSH-Client-Konfiguration (Alias)} % ============================================ Damit du nicht jedes Mal die IP-Adresse eintippen musst, wird ein Alias in der lokalen SSH-Konfiguration eingerichtet. \textbf{Auf deinem lokalen PC:} \begin{lstlisting}[language=Bash, caption={SSH-Konfiguration bearbeiten}] nano ~/.ssh/config \end{lstlisting} Folgenden Inhalt einfügen: \begin{lstlisting}[language=Bash, caption={Inhalt von \textasciitilde/.ssh/config}] Host testserver HostName 185.209.229.167 User root IdentityFile ~/.ssh/id_ed25519 \end{lstlisting} \textbf{Erklärung der Konfiguration:} \begin{itemize} \item \texttt{Host testserver} -- der Alias, unter dem du den Server ansprichst \item \texttt{HostName 185.209.229.167} -- die tatsächliche Server-Adresse \item \texttt{User root} -- Benutzername für die Verbindung \item \texttt{IdentityFile \textasciitilde/.ssh/id\_ed25519} -- Pfad zum privaten Schlüssel \end{itemize} \textbf{Testen:} \begin{lstlisting}[language=Bash, caption={Mit Alias verbinden}] ssh testserver \end{lstlisting} Ab jetzt reicht dieser kurze Befehl. % ============================================ \subsection{Schritt 5: SSH-Timeout auf 20 Minuten} % ============================================ Standardmäßig trennt Ubuntu inaktive SSH-Verbindungen nach etwa 5 Minuten. Das wird nun auf 20 Minuten erhöht. \textbf{Auf dem Server (als root):} \begin{lstlisting}[language=Bash, caption={SSH-Server-Konfiguration bearbeiten}] nano /etc/ssh/sshd_config \end{lstlisting} Folgende Zeilen suchen oder am Ende der Datei einfügen: \begin{lstlisting}[language=Bash, caption={Timeout-Konfiguration}] ClientAliveInterval 120 ClientAliveCountMax 10 \end{lstlisting} \textbf{Erklärung der Werte:} \begin{itemize} \item \texttt{ClientAliveInterval 120} -- Der Server sendet alle 120 Sekunden (2 Minuten) ein Signal an den Client \item \texttt{ClientAliveCountMax 10} -- Nach 10 unbeantworteten Signalen wird die Verbindung getrennt \end{itemize} Die gesamte Timeout-Zeit berechnet sich: 120 Sekunden $\times$ 10 = 1200 Sekunden = 20 Minuten. \textbf{SSH-Dienst neustarten:} \begin{lstlisting}[language=Bash, caption={SSH-Dienst neustarten}] systemctl restart ssh \end{lstlisting} \textbf{Wichtig:} Auf Ubuntu heißt der Dienst \texttt{ssh}, nicht \texttt{sshd} (im Gegensatz zu anderen Distributionen). Die aktuelle Verbindung bleibt beim Neustart bestehen. Die neue Einstellung gilt für alle zukünftigen Verbindungen. % ============================================ \subsection{Schritt 6: Fail2Ban (Bruteforce-Schutz)} % ============================================ Fail2Ban ist ein Dienst, der Logdateien überwacht und IP-Adressen automatisch sperrt, wenn zu viele fehlgeschlagene Login-Versuche erkannt werden. \textbf{Was ist Bruteforce?} Ein Angreifer probiert tausende Passwörter durch, bis er das richtige findet. Fail2Ban unterbindet das, indem es die IP des Angreifers nach einer bestimmten Anzahl Fehlversuche temporär sperrt. \textbf{Standard-Konfiguration (ab Werk):} \begin{itemize} \item 5 Fehlversuche in 10 Minuten \item Sperrdauer: 10 Minuten \item Überwacht wird der SSH-Dienst \end{itemize} \textbf{Wo wird installiert?} Die Programmdateien liegen unter \texttt{/usr/bin/}, die Konfiguration unter \texttt{/etc/fail2ban/}. \textbf{Wo kann ich es konfigurieren?} Die Datei \texttt{/etc/fail2ban/jail.local} wird bei Updates nicht überschrieben und ist für eigene Anpassungen gedacht. Beispiel: \begin{lstlisting}[language=Bash, caption={Beispiel: /etc/fail2ban/jail.local}][DEFAULT] bantime = 600 findtime = 600 maxretry = 3 [sshd] enabled = true \end{lstlisting} \textbf{Installation auf dem Server:} \begin{lstlisting}[language=Bash, caption={Fail2Ban installieren}] apt install -y fail2ban \end{lstlisting} \textbf{Automatischen Start aktivieren und sofort starten:} \begin{lstlisting}[language=Bash, caption={Fail2Ban aktivieren und starten}] systemctl enable fail2ban && systemctl start fail2ban \end{lstlisting} \textbf{Status prüfen:} \begin{lstlisting}[language=Bash, caption={Fail2Ban-Status abfragen}] systemctl status fail2ban \end{lstlisting} Die Ausgabe sollte \texttt{active (running)} zeigen. \begin{lstlisting}[language=Bash, caption={Erfolgreiche Ausgabe}] - fail2ban.service - Fail2Ban Service Active: active (running) ... Server ready \end{lstlisting} % ============================================ \subsection{Zusammenfassung} % ============================================ Nach Abschluss dieses Schritts ist der Server grundlegend abgesichert: \begin{itemize} \item Passwort-Login funktioniert weiterhin (als Backup) \item SSH-Key-Login ist eingerichtet (bequem \& sicher) \item Alias \texttt{ssh testserver} ist konfiguriert \item Verbindung trennt nach 20 Minuten Inaktivität \item Fail2Ban sperrt Angreifer nach 5 Fehlversuchen \end{itemize} Als nächstes folgt die Firewall-Konfiguration mit ufw.