Add step 02: Configure firewall with UFW
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
% ============================================
|
||||
% 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]}.
|
||||
Reference in New Issue
Block a user