371 lines
17 KiB
TeX
371 lines
17 KiB
TeX
\chapter{Vorwort}
|
|
Diese Dokumentation beschreibt die Installation und den Betrieb des IPv6-VPN-Dienst auf Basis von OpenVPN.
|
|
Die Hintergründe zu der hier vorgestellten Konfiguration können in der dazugehörigen Masterarbeit \enquote{Konzeption und Umsetzung eines IPv6-VPN für die Abteilung Informatik} nachgelesen werden.
|
|
|
|
\section{Konfigurationsvorgaben}
|
|
Folgende Parameter wurden für die Konfiguration des Servers in Absprache mit dem IT-Team festgelegt:
|
|
\begin{itemize}
|
|
\item Hostname der Maschine: \texttt{aither.inform.hs-hannover.de}
|
|
\item Hostname des OpenVPN-Dienstes: \texttt{vpn-test.inform.hs-hannover.de}
|
|
\item IP-Adressen der Maschine
|
|
\begin{itemize}
|
|
\item \texttt{141.71.38.70/24}
|
|
\item \texttt{2001:638:614:1780::131/64}
|
|
\end{itemize}
|
|
\item IP-Adressen der zu benutzenden Gateways
|
|
\begin{itemize}
|
|
\item \texttt{141.71.38.254}
|
|
\item \texttt{2001:638:614:1780::1}
|
|
\end{itemize}
|
|
\item IP-Adressen des OpenVPN-Dienstes
|
|
\begin{itemize}
|
|
\item \texttt{141.71.38.7}
|
|
\item \texttt{2001:638:614:1780::7}
|
|
\end{itemize}
|
|
\item IP-Adressbereiche für VPN-Clients
|
|
\begin{itemize}
|
|
\item \texttt{10.2.0.0/16}
|
|
\item \texttt{2001:638:614:1750::/64}
|
|
\end{itemize}
|
|
\item Zu verwendender DNS-Server: \texttt{141.71.38.1}
|
|
\end{itemize}
|
|
|
|
|
|
\chapter{Installation}
|
|
Mit den abgesprochenen Parametern kann nun die Installation des VPN-Servers erfolgen.
|
|
Eine bereits vorhandene Zertifizierungsstelle mit Webserver unter dem Hostnamen \texttt{vpnca.inform.hs-hannover.de} wird vorausgesetzt.
|
|
|
|
\section{Konfiguration des Grundsystems}
|
|
s\paragraph{Hostname:}
|
|
Sofern der Hostname bei der Installation von Debian nicht schon gesetzt wurde, so muss dies in den Dateien \texttt{/etc/hostname}, \texttt{/etc/mailname} und \texttt{/etc/hosts} nachgeholt werden.
|
|
\begin{lstlisting}
|
|
echo "aither" > /etc/hostname
|
|
echo "aither.inform.hs-hannover.de" > /etc/mailname
|
|
\end{lstlisting}
|
|
In \texttt{/etc/hosts} muss der Eintrag für \texttt{127.0.1.1} angepasst werden:
|
|
\begin{lstlisting}
|
|
127.0.1.1 aither.inform.hs-hannover.de aither
|
|
\end{lstlisting}
|
|
|
|
\paragraph{OpenSSH:}
|
|
In der Datei \texttt{/etc/ssh/sshd\_config} muss folgende Option auskommentiert und angepasst werden:
|
|
\begin{lstlisting}
|
|
PermitRootLogin yes
|
|
\end{lstlisting}
|
|
|
|
Anschließend wird der OpenSSH-Dienst aktiviert und gestartet.
|
|
\begin{lstlisting}
|
|
systemctl enable ssh.service
|
|
systemctl start ssh.service
|
|
\end{lstlisting}
|
|
|
|
\paragraph{sudo:}
|
|
Das IT-Team arbeitet mit passwortbasierten SSH-Sitzungen unter dem Benutzer \texttt{root}.
|
|
Damit in der Übergangsphase auf dem Server Anpassungen auch ohne Kenntnis des \texttt{root}-Passworts durchgeführt werden können, wird ein lokaler Benutzer eingerichtet.
|
|
\begin{lstlisting}
|
|
apt-get install sudo
|
|
adduser jpt
|
|
gpasswd -a jpt sudo
|
|
\end{lstlisting}
|
|
Nach erfolgreicher Übergabe des Servers an das IT-Team kann dieser Benutzer wieder entfernt werden.
|
|
|
|
\paragraph{apt:}
|
|
Um in der DMZ weiterhin Updates einspielen zu können, wird der vom IT-Team zur Verfügung gestellte Proxyserver in die Konfiguration von \texttt{apt} eingetragen.
|
|
\begin{lstlisting}
|
|
echo 'Acquire::http::Proxy "http://proxy.inform.hs-hannover.de:3128";'
|
|
> /etc/apt/apt.conf.d/80proxy
|
|
\end{lstlisting}
|
|
Das IT-Team stellt Debian-Pakete zur Verfügung, mit die Grundkonfiguration des Servers an die Vorgaben des IT-Teams angepasst werden kann.
|
|
Um diese Pakete zu installieren, werden die Paketquellen des IT-Teams konfiguriert:
|
|
\begin{lstlisting}
|
|
echo "deb http://http.edu.inform.hs-hannover.de/depot/debian/stretch/ Packages/"
|
|
> /etc/apt/sources.list.d/inform.list
|
|
\end{lstlisting}
|
|
Als nächstes wird der GPG-Key importiert, mit dem die Pakete signiert sind:
|
|
\begin{lstlisting}
|
|
wget -O repositoryKeyFile http://http.edu.inform.hs-hannover.de/repository/repositoryKeyFile
|
|
apt-key add repositoryKeyFile
|
|
\end{lstlisting}
|
|
Anschließend können die Pakete über \texttt{apt-get} installiert werden
|
|
\begin{lstlisting}
|
|
apt-get update
|
|
apt-get install f4-i-srv-config-all-* f4-i-srv-config-dmz-adminscripts
|
|
\end{lstlisting}
|
|
|
|
\paragraph{Systemzeit über Zeitserver beziehen:}
|
|
Für Vorgänge wie zum Beispiel die Gültigkeitsprüfung von Zertifikaten ist eine korrekt gestellte Systemuhr wichtig.
|
|
Dafür wird dem bereits installierten Dienst \texttt{systemd-timesyncd} der Zeitserver der Abteilung Informatik bekannt gemacht.
|
|
Die Datei \texttt{/etc/systemd/timesyncd.conf} enthält dafür folgenden Abschnitt:
|
|
\begin{lstlisting}
|
|
[Time]
|
|
NTP=time.inform.hs-hannover.de
|
|
\end{lstlisting}
|
|
|
|
\paragraph{Netzwerkkonfiguration:}
|
|
Als nächstes werden die IP-Adressen der Maschine und des Dienstes in \texttt{/etc/network/interfaces} konfiguriert.
|
|
Die IP-Adressen der Maschine werden direkt für die Netzwerkkarte des Servers konfiguriert.
|
|
|
|
Die IP-Adressen für den VPN-Dienst werden als zusätzliche IP-Adressen konfiguriert.
|
|
Durch die Verwendung von separaten Dienst-Adressen ist es möglich, einen Server im laufenden Betrieb durch einen zweiten, identisch konfigurierten Server zu ersetzen.
|
|
Dazu müssen lediglich die zusätzlichen IP-Adressen von dem einen Server entfernt werden, und anschließend auf dem zweiten Server hinzugefügt werden.
|
|
VPN-Benutzer bekommen davon nur eine kurze Unterbrechung der VPN-Sitzung mit.
|
|
|
|
Die resultierende Konfiguration für die IP-Adressen der Maschine sieht so aus:
|
|
\begin{lstlisting}
|
|
auto eno1
|
|
allow-hotplug eno1
|
|
|
|
#-primary network interface
|
|
iface eno1 inet static
|
|
address 141.71.38.70/24
|
|
gateway 141.71.38.254
|
|
post-up /sbin/ip addr add 141.71.38.7/24 dev eno1
|
|
pre-down /sbin/ip addr del 141.71.38.7/24 dev eno1
|
|
|
|
iface eno1 inet6 static
|
|
address 2001:638:614:1780::0131/64
|
|
gateway 2001:638:614:1780::1
|
|
post-up /sbin/ip addr add 2001:638:614:1780::0007/64 dev eno1
|
|
pre-down /sbin/ip addr del 2001:638:614:1780::0007/64 dev eno1
|
|
\end{lstlisting}
|
|
|
|
\paragraph{DNS:}
|
|
In der DMZ soll der DNS-Resolver mit der IP-Adresse \texttt{141.71.38.1} verwendet werden.
|
|
\begin{lstlisting}
|
|
echo "nameserver 141.71.38.1" > /etc/resolv.conf
|
|
\end{lstlisting}
|
|
|
|
\paragraph{Paketweiterleitung einschalten:}
|
|
Mit dem VPN-Server verbundene Clients befinden sich in einem eigenen IPv4- beziehungsweise IPv6-Netz.
|
|
Damit die VPN-Clients trotzdem über die Grenze ihres eigenen Netzes hinaus Kontakt zum Netz der Abteilung Informatik aufnehmen können, ist es notwendig für IPv4 und IPv6 die Paketweiterleitung einzuschalten.
|
|
\begin{lstlisting}
|
|
echo "net.ipv4.conf.all.forwarding = 1" > /etc/sysctl.d/04-enable-ipv4-forwarding.conf
|
|
echo "net.ipv6.conf.all.forwarding = 1" > /etc/sysctl.d/06-enable-ipv6-forwarding.conf
|
|
\end{lstlisting}
|
|
Anschließend werden die vorgenommenen Einstellungen aktiviert.
|
|
\begin{lstlisting}
|
|
sysctl --system
|
|
\end{lstlisting}
|
|
|
|
|
|
\section{Firewallregeln}
|
|
Welcher Datenverkehr für VPN-Clients erlaubt oder verboten ist, wurde im Rahmen der Masterarbeit bereits festgelegt.
|
|
Diese Vorgaben werden jetzt über Filterregeln mit \texttt{iptables} und \texttt{ip6tables} umgesetzt.
|
|
|
|
Als Standardpolicy wird \texttt{DROP} gewählt.
|
|
\begin{lstlisting}
|
|
iptables -P INPUT DROP
|
|
iptables -P OUTPUT DROP
|
|
iptables -P FORWARD DROP
|
|
ip6tables -P INPUT DROP
|
|
ip6tables -P OUTPUT DROP
|
|
ip6tables -P FORWARD DROP
|
|
\end{lstlisting}
|
|
|
|
Datenverkehr über das Loopback-Interface ist immer erlaubt.
|
|
\begin{lstlisting}
|
|
iptables -A INPUT -i lo -j ACCEPT
|
|
iptables -A OUTPUT -o lo -j ACCEPT
|
|
ip6tables -A INPUT -i lo -j ACCEPT
|
|
ip6tables -A OUTPUT -o lo -j ACCEPT
|
|
\end{lstlisting}
|
|
|
|
Die Protokolle ICMP und ICMPv6 sind immer erlaubt.
|
|
\begin{lstlisting}
|
|
iptables -A INPUT -p icmp -j ACCEPT
|
|
iptables -A OUTPUT -p icmp -j ACCEPT
|
|
iptables -A FORWARD -p icmp -j ACCEPT
|
|
ip6tables -A INPUT -p icmpv6 -j ACCEPT
|
|
ip6tables -A OUTPUT -p icmpv6 -j ACCEPT
|
|
ip6tables -A FORWARD -p icmpv6 -j ACCEPT
|
|
\end{lstlisting}
|
|
|
|
Zugriffe auf den VPN-Server sind für die Dienste SSH und OpenVPN erlaubt.
|
|
\begin{lstlisting}
|
|
iptables -A INPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
|
|
ip6tables -A INPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
|
|
|
|
iptables -A INPUT -p udp --dport 1194 -j ACCEPT
|
|
ip6tables -A INPUT -p udp --dport 1194 -j ACCEPT
|
|
\end{lstlisting}
|
|
|
|
Antwortpakete für eingehende Pakete auf SSH und OpenVPN-Dienst sind erlaubt.
|
|
\begin{lstlisting}
|
|
iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
|
|
ip6tables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
|
|
|
|
iptables -A OUTPUT -p udp --sport 1194 -j ACCEPT
|
|
ip6tables -A OUTPUT -p udp --sport 1194 -j ACCEPT
|
|
\end{lstlisting}
|
|
|
|
Vom VPN-Server ausgehende Pakete sind grundsätzlich erlaubt.
|
|
\begin{lstlisting}
|
|
iptables -A OUTPUT -m state --state NEW,ESTABLISHED -j ACCEPT
|
|
ip6tables -A OUTPUT -m state --state NEW,ESTABLISHED -j ACCEPT
|
|
\end{lstlisting}
|
|
|
|
Zum VPN-Server eingehende Pakete sind als Antwort auf ausgehende Pakete erlaubt.
|
|
\begin{lstlisting}
|
|
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
\end{lstlisting}
|
|
|
|
Für IPv4-Verkehr aus dem VPN in andere Netze soll NAT auf die \texttt{141.71.38.7} durchgeführt werden.
|
|
\begin{lstlisting}
|
|
iptables -t nat -A POSTROUTING -s 10.2.0.0/16 -d ! 10.2.0.0/16 -j SNAT --to 141.71.38.7
|
|
\end{lstlisting}
|
|
|
|
Datenverkehr zwischen VPN-Clients ist verboten und wird verworfen.
|
|
\begin{lstlisting}
|
|
iptables -A FORWARD -s 10.2.0.0/16 -d 10.2.0.0/16 -j DROP
|
|
ip6tables -A FORWARD -s 2001:638:614:1750::/64 -d 2001:683:614:1750::/64 -j DROP
|
|
\end{lstlisting}
|
|
|
|
Jeglicher weiterer Datenverkehr aus dem VPN ist erlaubt.
|
|
\begin{lstlisting}
|
|
iptables -A FORWARD -s 10.2.0.0/16 -m state --state NEW,ESTABLISHED -j ACCEPT
|
|
ip6tables -A FORWARD -s 2001:638:614:1750::/64 -m state --state NEW,ESTABLISHED -j ACCEPT
|
|
\end{lstlisting}
|
|
|
|
In das VPN eingehender Verkehr ist nur als Antwort auf ausgehende Pakete erlaubt.
|
|
\begin{lstlisting}
|
|
iptables -A FORWARD -d 10.2.0.0/16 -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
ip6tables -A FORWARD -d 2001:638:614:1750::/64 -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|
\end{lstlisting}
|
|
|
|
\paragraph{Persistente Firewallregeln:}
|
|
Um die mit \texttt{iptables} und \texttt{ip6tables} umgesetzten Regeln auch über Neustarts hinweg zu behalten, wird das Paket \texttt{iptables-persistent} installiert.
|
|
\begin{lstlisting}
|
|
apt-get install iptables-persistent
|
|
\end{lstlisting}
|
|
Anschließend können die aktuell aktiven Regeln in Dateien abgelegt werden, aus denen sie nach einem Neustart durch die von \texttt{iptables-persistent} installierten Skripte wieder geladen werden.
|
|
\begin{lstlisting}
|
|
iptables-save > /etc/iptables/rules.v4
|
|
ip6tables-save > /etc/iptables/rules.v6
|
|
\end{lstlisting}
|
|
|
|
|
|
\section{OpenVPN}
|
|
Nun wird OpenVPN installiert und konfiguriert.
|
|
\begin{lstlisting}
|
|
apt-get install openvpn
|
|
\end{lstlisting}
|
|
|
|
Anhand des separaten Dokuments \enquote{Dokumentation der Zertifizierungsstelle für den IPv6-VPN-Dienst} wird ein neues Serverzertifikat für den VPN-Server beantragt und anschließend durch die Zertifizierungsstelle ausgestellt.
|
|
Zusätzlich werden auf dem lokalen Server die Diffie-Hellman-Parameter generiert.
|
|
|
|
Außerdem wird das Wurzelzertifikat der Zertifizierungsstelle, sowie eine aktuelle \textit{Certificate Revocation List} (CRL) benötigt.
|
|
In diesem Szenario wird davon ausgegangen, dass beide Dateien in aktueller Version über einen HTTP-Server von der CA angeboten werden:
|
|
\begin{lstlisting}
|
|
wget http://vpnca.inform.hs-hannover.de/ca.crt
|
|
wget http://vpnca.inform.hs-hannover.de/crl.pem
|
|
\end{lstlisting}
|
|
|
|
Die beschafften Dateien werden nun wie folgt auf dem VPN-Server abgelegt:
|
|
\begin{itemize}
|
|
\item Wurzelzertifikat: \texttt{/etc/openvpn/inform/ca.crt}
|
|
\item Serverzertifikat: \texttt{/etc/openvpn/inform/aither.inform.hs-hannover.de.crt}
|
|
\item Privater Schlüssel: \texttt{/etc/openvpn/inform/aither.inform.hs-hannover.de.key}
|
|
\item Diffie-Hellman-Parameter: \texttt{/etc/openvpn/inform/dh.pem}
|
|
\item Certificate Revocation List: \texttt{/etc/openvpn/inform/crl.pem}
|
|
\end{itemize}
|
|
|
|
Die folgende Konfiguration wird als Datei unter \texttt{/etc/openvpn/inform.conf} abgelegt.
|
|
\lstinputlisting[]{./openvpn-config/server.conf}
|
|
|
|
Da die CRL durch die Zertifizierungsstelle jederzeit aktualisiert werden kann, ist es sinnvoll diese täglich mit einem Cronjob zu erneuern.
|
|
Dafür wird dieser Eintrag als \texttt{root} mittels \texttt{crontab -e} angelegt:
|
|
\begin{lstlisting}
|
|
15 2 * * * bash -c 'curl http://vpnca.inform.hs-hannover.de/crl.pem > /etc/openvpn/inform/crl.pem; systemctl restart openvpn@inform.service'
|
|
\end{lstlisting}
|
|
\textbf{Anmerkung}: Ein \texttt{systemctl reload} ist aufgrund der Abgabe von Berechtigungen nach dem Start nicht möglich.
|
|
Deshalb muss auf \texttt{systemctl restart} zurückgegriffen werden.
|
|
|
|
Nun wird der OpenVPN-Dienst aktiviert und gestartet:
|
|
\begin{lstlisting}
|
|
systemctl enable openvpn@inform.service
|
|
systemctl start openvpn@inform.service
|
|
\end{lstlisting}
|
|
|
|
|
|
\chapter{Administrative Aufgaben}
|
|
\paragraph{Dienst aktivieren/deaktivieren:}
|
|
Mit dem folgenden Befehl kann der VPN-Dienst aktiviert werden.
|
|
Dadurch ist es möglich, den Dienst zu starten.
|
|
Außerdem startet der aktivierte Dienst nach dem Neustart des Servers automatisch.
|
|
\begin{lstlisting}
|
|
systemctl enable openvpn@inform.service
|
|
\end{lstlisting}
|
|
Mit dem folgenden Befehl kann der Dienst wieder deaktiviert werden.
|
|
\begin{lstlisting}
|
|
systemctl disable openvpn@inform.service
|
|
\end{lstlisting}
|
|
|
|
\paragraph{Dienststatus abfragen:}
|
|
Ob der OpenVPN-Dienst gerade läuft oder nicht läuft, lässt sich mit diesem Befehl herausfinden.
|
|
\begin{lstlisting}
|
|
systemctl status openvpn@inform.service
|
|
\end{lstlisting}
|
|
|
|
\paragraph{Dienst starten/stoppen/neustarten:}
|
|
Wurde der OpenVPN-Dienst aktiviert, kann er mit den folgenden Befehlen gestartet, gestoppt oder neu gestartet werden.
|
|
\begin{lstlisting}
|
|
systemctl start openvpn@inform.service
|
|
systemctl stop openvpn@inform.service
|
|
systemctl restart openvpn@inform.service
|
|
\end{lstlisting}
|
|
Details zur Handhabung von Systemdiensten mit \texttt{systemctl} können im \enquote{Debian Administrator's Handbook} Kapitel 9.1.1 nachgeschlagen werden\footnote{Siehe \url{https://debian-handbook.info/browse/stable/unix-services.html\#sect.systemd}}.
|
|
|
|
\paragraph{Manuelles Failover:}
|
|
Sollte der Bedarf bestehen, dass ein identisch konfigurierter Server den aktuell aktiven VPN-Server ablöst, so müssen lediglich die IP-Adressen des VPN-Dienstes auf den zweiten Server umgezogen werden.
|
|
|
|
\textbf{Hinweis}: Gegebenenfalls muss der Name des verwendeten Netzwerkinterfaces - hier \texttt{eno1} - den aktuellen Umständen angepasst werden.
|
|
|
|
Zunächst müssen die Dienst-IPs auf dem aktuell aktiven Server deaktiviert werden und im Anschluss gegen versehentliche beziehungsweise automatische Reaktivierung nach einem Neustart gesichert werden.
|
|
Deaktivieren der Dienst-IPs:
|
|
\begin{lstlisting}
|
|
ip addr del 141.71.38.7 dev eno1
|
|
ip addr del 2001:638:614:1780::7 dev eno1
|
|
\end{lstlisting}
|
|
Datei \texttt{/etc/network/interfaces} angepasst, um die Reaktivierung der Dienst-IPs zu verhindern.
|
|
In dieser müssen die Befehle \texttt{post-up} und \texttt{pre-down} auskommentiert werden, wie hier gezeigt wird:
|
|
\begin{lstlisting}
|
|
iface eno1 inet static
|
|
address 141.71.38.70/24
|
|
gateway 141.71.38.254
|
|
#post-up /sbin/ip addr add 141.71.38.7/24 dev eno1
|
|
#pre-down /sbin/ip addr del 141.71.38.7/24 dev eno1
|
|
|
|
iface eno1 inet6 static
|
|
address 2001:638:614:1780::0131/64
|
|
gateway 2001:638:614:1780::1
|
|
#post-up /sbin/ip addr add 2001:638:614:1780::0007/64 dev eno1
|
|
#pre-down /sbin/ip addr del 2001:638:614:1780::0007/64 dev eno1
|
|
\end{lstlisting}
|
|
|
|
Auf dem zweiten Server können nun analog die (wie oben gezeigt) einkommentierten Einträge in der \texttt{/etc/network/interfaces} wieder auskommentiert werden.
|
|
Anschließend werden die folgenden Befehle verwendet, um die Dienst-IPs auf dem zweiten Server zu konfigurieren:
|
|
\begin{lstlisting}
|
|
ip addr add 141.71.38.7 dev eno1
|
|
ip addr add 2001:638:614:1780::7 dev eno1
|
|
\end{lstlisting}
|
|
Im Anschluss muss sichergestellt werden, dass der OpenVPN-Dienst auf dem zweiten Server aktiviert ist und läuft.
|
|
|
|
\paragraph{Backups:}
|
|
Da der VPN-Dienst sich anhand dieser Installationsanleitung von Grund auf neu einrichten lässt, sind im Prinzip keine Sicherheitskopien notwendig.
|
|
Um eine Neueinrichtung des Dienstes zu erleichtern können bei Bedarf die Inhalte von \texttt{/etc}, sowie die Ausgabe von \texttt{crontab -l} als Benutzer \texttt{root} gesichert werden.
|
|
|
|
\paragraph{Einspielen von Updates:}
|
|
Das Einspielen von Updates erfolgt in zwei Schritten.
|
|
Im ersten Schritt werden die Paketquellen aktualisiert, damit der Paketmanager die Versionen der aktuell verfügbaren Pakete kennt.
|
|
\begin{lstlisting}
|
|
apt-get update
|
|
\end{lstlisting}
|
|
Anschließend können alle verfügbaren Aktualisierungen mit dem folgenden Befehl eingespielt werden.
|
|
\begin{lstlisting}
|
|
apt-get dist-upgrade
|
|
\end{lstlisting}
|
|
Es folgt eine Auflistung aller zu aktualisierenden Pakete mit der Abfrage, ob die Aktion durchgeführt werden soll.
|
|
Bestätigt man die Abfrage, so werden die Updates installiert.
|
|
Details zur Handhabung des Debian-Paketmanagers können im \enquote{Debian Administrator's Handbook} in Kapitel 6 nachgelesen werden\footnote{Siehe \url{https://debian-handbook.info/browse/stable/apt.html}}.
|