Files
fitness-app/LateX/step_02.tex
T

191 lines
8.9 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
% ============================================
% STEP 02: FIREWALL MIT UFW
% ============================================
\section{Firewall mit UFW einrichten}
\label{sec:step02}
In diesem Schritt konfigurieren wir die Firewall des Servers mit \textbf{UFW} (Uncomplicated Firewall). UFW ist eine benutzerfreundliche Schnittstelle für \texttt{iptables}, die seit Ubuntu 8.04 standardmäßig installiert ist.
\subsection{Was ist eine Firewall und warum brauchen wir sie?}
Eine Firewall ist wie ein \textbf{Türsteher vor einem Club}: Sie entscheidet, welche Datenpakete (Gäste) hereinkommen und welche draußen bleiben. Ohne Firewall steht der Server "nackt" im Internet und jeder kann an jede Tür (Port) klopfen.
\textbf{Das Prinzip der minimalen Angriffsfläche:}
\begin{itemize}
\item Jeder offene Port ist eine potenzielle \textbf{Eintrittspforte} für Angreifer
\item Je weniger Ports offen sind, desto weniger Möglichkeiten gibt es für einen Angriff
\item Standard-Dienste haben oft \textbf{bekannte Sicherheitslücken} selbst wenn wir sie nicht aktiv nutzen
\end{itemize}
\subsection{Die 65.535 Ports: Ein kurzer Überblick}
Ein Server hat 65.535 TCP-Ports und 65.535 UDP-Ports. Jeder Netzwerkdienst lauscht auf einem bestimmten Port. Hier sind die bekanntesten:
\begin{table}[h]
\centering
\caption{Bekannte Ports und ihre Dienste}
\begin{tabular}{@{}cll@{}}
\toprule
\textbf{Port} & \textbf{Dienst} & \textbf{Risiko/Bemerkung} \\
\midrule
21 & FTP & Uralt, Passwörter im Klartext -- niemals offen lassen \\
22 & SSH & Unser Verwaltungszugang -- MUSS offen sein \\
23 & Telnet & Wie SSH, aber unverschlüsselt -- Todesurteil für Server \\
25 & SMTP & Mail-Versand -- Angreifer könnten Spam verschicken \\
53 & DNS & Namensauflösung -- Ziel für DDoS-Angriffe \\
80 & HTTP & Standard-Webport -- für unsere Fitness-App \\
110 & POP3 & E-Mail-Abruf -- veraltet, unsicher \\
143 & IMAP & E-Mail-Abruf -- veraltet \\
443 & HTTPS & Verschlüsselter Webport -- PFLICHT für PWAs! \\
3306 & MySQL & Datenbank -- beliebtes Bruteforce-Ziel \\
5432 & PostgreSQL & Datenbank -- ebenso populär bei Angreifern \\
6379 & Redis & Oft ohne Passwort vorkonfiguriert -- sehr gefährlich \\
8080 & HTTP-Alt & Häufig für Entwicklertools mit schwacher Absicherung \\
27017& MongoDB & Bekannt für katastrophale Standardkonfigurationen \\
\bottomrule
\end{tabular}
\end{table}
\textbf{Merksatz:} Alles, was du nicht explizit brauchst, wird blockiert. Das ist keine Paranoia, sondern Best Practice im Server-Management.
\subsection{Die drei Ports, die wir öffnen}
Wir öffnen nur drei Ports das absolute Minimum für einen Webserver:
\begin{table}[h]
\centering
\caption{Geöffnete Ports und ihre Begründung}
\begin{tabular}{@{}clp{5cm}@{}}
\toprule
\textbf{Port} & \textbf{Dienst} & \textbf{Warum offen?} \\
\midrule
22 & SSH & Unser \textbf{einziger Verwaltungszugang}. Ohne Port 22 könnten wir den Server nicht mehr fernsteuern -- wir wären ausgesperrt. \\
80 & HTTP & \textbf{Standard-Webport} für alle Browser. Wenn jemand deine Domain aufruft, landet er zuerst hier. Leitet später automatisch auf HTTPS (Port 443) um. \\
443 & HTTPS & \textbf{Verschlüsselte Webseiten}. Seit 2018 Pflicht für moderne Web-Apps! Ohne HTTPS verweigern Browser Funktionen wie PWA-Installation, Kamera-Zugriff oder Standort. \\
\bottomrule
\end{tabular}
\end{table}
\subsection{Warum HTTPS für PWAs Pflicht ist}
Eine Progressive Web App (PWA) \textbf{kann ohne HTTPS nicht installiert werden}. Das ist eine Sicherheitsanforderung von Google und Apple:
\begin{itemize}
\item Der \textbf{Service Worker} (das Herzstück einer PWA) benötigt zwingend HTTPS
\item Nur so kann der Browser garantieren, dass die App nicht manipuliert wurde
\item HTTP-Verbindungen können von Angreifern verändert werden (Man-in-the-Middle)
\end{itemize}
\textbf{Praxis-Beispiel:} Wenn du \texttt{http://deine-domain.de} aufrufst und dort die PWA installieren willst, verweigert Chrome die Installation. Erst mit \texttt{https://deine-domain.de} und einem gültigen SSL-Zertifikat funktioniert es.
\subsection{Durchführung}
\subsubsection{Standardrichtlinien setzen}
Zuerst definieren wir die grundlegenden Regeln: Alles Eingehende wird blockiert, alles Ausgehende erlaubt.
\textbf{Auf dem Server:}
\begin{lstlisting}[language=Bash, caption={Firewall-Standardregeln definieren}]
ufw default deny incoming
ufw default allow outgoing
\end{lstlisting}
\textbf{Erklärung der Befehle:}
\begin{itemize}
\item \texttt{ufw} -- das Firewall-Programm (Uncomplicated Firewall)
\item \texttt{default} -- setzt die Standardregel für alle Ports, die nicht explizit konfiguriert sind
\item \texttt{deny incoming} -- alle eingehenden Verbindungen werden \textbf{abgelehnt} (geblockt)
\item \texttt{allow outgoing} -- alle ausgehenden Verbindungen sind \textbf{erlaubt} (Server kann selbst ins Internet)
\end{itemize}
\textbf{Warum outgoing erlauben?} Der Server muss Updates herunterladen können (\texttt{apt update}), auf externe APIs zugreifen und im Internet kommunizieren. Das sind alles ausgehende Verbindungen -- die der Server selbst initiiert.
\subsubsection{Benötigte Ports öffnen}
Jetzt geben wir gezielt die drei Ports frei, die von außen erreichbar sein sollen.
\begin{lstlisting}[language=Bash, caption={Ports 22, 80, 443 für TCP freigeben}]
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
\end{lstlisting}
\textbf{Erklärung der Befehle:}
\begin{itemize}
\item \texttt{allow} -- dieser Port wird geöffnet
\item \texttt{22/tcp} -- Port 22, nur TCP-Protokoll (nicht UDP)
\item \texttt{80/tcp} -- Port 80 (HTTP), nur TCP
\item \texttt{443/tcp} -- Port 443 (HTTPS), nur TCP
\end{itemize}
\textbf{Warum nur TCP?} SSH, HTTP und HTTPS verwenden ausschließlich das TCP-Protokoll. UDP wird von diesen Diensten nicht benötigt. Würden wir nur \texttt{ufw allow 80} (ohne \texttt{/tcp}) schreiben, wäre auch UDP offen -- unnötige Angriffsfläche.
\subsubsection{Firewall aktivieren}
Die Firewall wurde bisher nur konfiguriert, ist aber noch nicht aktiv. Erst mit dem Enable-Befehl greifen die Regeln.
\begin{lstlisting}[language=Bash, caption={Firewall aktivieren}]
ufw --force enable
\end{lstlisting}
\textbf{Erklärung:}
\begin{itemize}
\item \texttt{enable} -- schaltet die Firewall ein
\item \texttt{--force} -- überspringt die Sicherheitsabfrage ("Bist du sicher?") und führt den Befehl direkt aus
\end{itemize}
\textbf{Achtung:} Wenn du Port 22 vergessen hättest, wärst du jetzt vom Server ausgesperrt! Die Firewall würde deine aktuelle SSH-Verbindung zwar nicht sofort trennen, aber ein erneuter Login wäre unmöglich. Deshalb prüfen wir im nächsten Schritt die Konfiguration.
\subsubsection{Konfiguration überprüfen}
\begin{lstlisting}[language=Bash, caption={Firewall-Status mit Details anzeigen}]
ufw status verbose
\end{lstlisting}
\textbf{Erklärung:}
\begin{itemize}
\item \texttt{status} -- zeigt an, ob die Firewall aktiv ist und welche Regeln gelten
\item \texttt{verbose} -- erweiterte Ausgabe mit zusätzlichen Details wie Logging-Einstellungen und Standardrichtlinien
\end{itemize}
Die erwartete Ausgabe:
\begin{lstlisting}[language=Bash, caption={Erwartete Firewall-Ausgabe (gekürzt)}]
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
\end{lstlisting}
\textbf{Wichtige Details der Ausgabe:}
\begin{itemize}
\item \texttt{Status: active} -- die Firewall läuft und blockt unerwünschten Traffic
\item \texttt{Default: deny (incoming)} -- alle nicht explizit erlaubten eingehenden Verbindungen werden geblockt
\item \texttt{Anywhere} -- diese Ports sind von \textbf{jeder} IP-Adresse aus erreichbar (für Webseiten notwendig)
\item \texttt{(v6)} -- die Regeln gelten identisch für IPv6, sodass auch moderne Netzwerke geschützt sind
\end{itemize}
\subsection{Zusammenfassung}
Nach diesem Schritt ist die Firewall aktiv und schützt den Server:
\begin{itemize}
\item \textbf{65.532 Ports sind dicht} -- nur 3 sind offen
\item \textbf{SSH} (22) bleibt als einziger Verwaltungszugang offen
\item \textbf{HTTP/HTTPS} (80/443) sind für die spätere Web-App vorbereitet
\item \textbf{IPv4 und IPv6} werden beide geschützt
\item Die Firewall startet automatisch bei jedem Server-Neustart
\end{itemize}
\textbf{Praxis-Tipp:} Mit dem Befehl \texttt{ufw status numbered} kannst du jederzeit alle Regeln mit Nummern anzeigen. Eine einzelne Regel löschst du dann mit \texttt{ufw delete [Nummer]}.