% ============================================
% 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.