*Stand: November 2026
Ein frisch installierter VPS ist schnell verfügbar. Das heißt aber noch nicht, dass er sinnvoll oder sicher eingerichtet ist. In den ersten Minuten nach der Installation legst du fest, ob dein System später ruhig wartbar bleibt – oder ob du dir mit kleinen Versäumnissen dauerhaft Komplexität einhandelst.
Dieser Beitrag baut bewusst nur das Fundament: Debian 13 installieren, SSH per Schlüssel einrichten und eine saubere Linux-Basis herstellen. Keine Anwendungen, kein Docker, kein Webserver – das kommt in den nächsten Artikeln. Diese Basis soll später möglichst unverändert bleiben.
Am Ende hast du
- Debian 13 (Trixie) installiert und aktualisiert
- Einen normalen Benutzer eingerichtet (Beispiel:
martin) mit UID 1000 - SSH-Zugriff ohne Passwort, nur per Schlüssel – unter einem eigenen Schlüsselnamen, der vorhandene Schlüssel nicht überschreibt
- Eine benannte Verbindung:
ssh vpsstatt IP und Benutzername - Die Passphrase deines Schlüssels im Schlüsselbund – eingegeben wird sie einmal, danach nicht mehr
- Verstanden, was beim ersten SSH-Login passiert (Host-Key, Passphrase)
- Basispakete installiert, Zeitzone und Locale gesetzt
- SSH gehärtet, Firewall aktiviert, automatische Sicherheitsupdates konfiguriert
Voraussetzungen
- VPS mit öffentlicher IPv4
- Zugriff auf das Provider-Panel (Installation, SSH-Key-Hinterlegung)
- macOS, Linux oder Windows mit Terminal / SSH-Client
Getestet mit: Debian 13 (Trixie) · macOS als Rechner
Zuletzt durchgespielt: 05.11.2026 auf einem frisch installierten VPS 500 G12 bei Netcup
1. SSH-Key lokal erstellen (ed25519)
SSH arbeitet mit einem Schlüsselpaar:
- Private Key: bleibt auf deinem Rechner. Er ist dein Zugang.
- Public Key: wird auf dem Server hinterlegt. Er erlaubt genau deinem Private Key den Login.
Das ist der entscheidende Unterschied zu Passwörtern: Der Server muss kein Passwort akzeptieren, das jemand erraten könnte. Er akzeptiert nur den Nachweis, dass du den passenden Schlüssel besitzt.
Key erzeugen
Auf deinem lokalen Rechner:
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519_vps -C "martin@vps"
- Passphrase: unbedingt setzen
Warum ein eigener Dateiname?
Ohne
-flegtssh-keygenimmer~/.ssh/id_ed25519an. Liegt dort schon ein Schlüssel – für eine NAS, einen anderen Server, einen Git-Dienst –, fragt das Programm, ob es ihn überschreiben soll. Ein Ja an dieser Stelle lässt sich nicht rückgängig machen: Der alte Schlüssel ist weg, und mit ihm der Zugang zu allem, was ihn kannte. Ein sprechender Name pro Ziel kostet nichts und schließt diesen Fehler aus.
Warum eine Passphrase wichtig ist
Die Datei mit dem Private Key ist der Zugang zu deinem Server – wer sie hat, ist drin. Geht dein Rechner verloren oder wird gestohlen, oder landet der Schlüssel irgendwann unbemerkt woanders, weil
~/.sshin einem Cloud-Ordner liegt oder auf einer alten Sicherungsplatte mitgelaufen ist, dann ist die Passphrase das Einzige, was noch dazwischensteht. Sie ist der zweite Schutz hinter dem Schlüssel selbst. Tippen musst du sie nur einmal: In Abschnitt 4.1 landet sie im Schlüsselbund deines Rechners.
Danach existieren:
~/.ssh/id_ed25519_vps(Private Key – niemals teilen!)~/.ssh/id_ed25519_vps.pub(Public Key – dieser kommt auf den Server)
Check
ls -l ~/.ssh/id_ed25519_vps*
Ausgabe: zwei Dateien – id_ed25519_vps und id_ed25519_vps.pub.
2. Public Key ≠ Fingerprint
Hier passieren die meisten Anfängerfehler, weil die Begriffe ähnlich wirken.
Fingerprint (nicht für Login geeignet)
Beispiel:
SHA256:abc123def456...
Das ist nur eine Prüfsumme zur Kontrolle. Damit loggst du dich nicht ein.
Public Key (das, was der Server braucht)
Den Public Key gibst du ins Provider-Panel oder kopierst ihn auf den Server:
cat ~/.ssh/id_ed25519_vps.pub
Er beginnt typischerweise mit:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5... martin@vps
Merksatz
Ein SSH-Key beginnt mit
ssh-ed25519. Alles, was mitSHA256:beginnt, ist ein Fingerprint, kein Login-Key.
Check
Wenn deine Ausgabe mit ssh-ed25519 beginnt, hast du den richtigen Inhalt zum Hinterlegen.
3. Debian 13 installieren
martinsteht in dieser Reihe überall für deinen eigenen Benutzernamen. Du legst ihn gleich bei der Installation fest und setzt ihn ab dann überall dort ein, womartinsteht – in Befehlen, Dateien und Pfaden wie/home/martin.
Option A: Provider mit SSH-Key-Support (z. B. Netcup, Hetzner)
Benutzer und Public Key werden hier schon während der Installation angelegt. Du kommst also gleich beim ersten Login als dein eigener Benutzer per Schlüssel auf den Server, ohne vorher als root etwas einrichten zu müssen.
Das sind zwei getrennte Vorgänge: Den Schlüssel legst du einmalig in deinem Konto ab, bei der Installation wählst du ihn nur noch aus. Bei Netcup im Server Control Panel (SCP) hat er dafür einen eigenen Menüpunkt ganz oben im Menü, nicht etwa ein Feld im Installationsdialog.

Schritt 1: Den Schlüssel im Konto ablegen
Dort legst du einen neuen Schlüssel an und fügst die Ausgabe von cat ~/.ssh/id_ed25519_vps.pub aus Abschnitt 2 ein – die komplette Zeile, von ssh-ed25519 bis zum Kommentar am Ende, ohne Zeilenumbruch. Dazu ein Name, unter dem du ihn später wiedererkennst.
Ein versehentlich abgeschnittener Schlüssel wird klaglos angenommen; auffallen wird es dir erst, wenn der erste Login scheitert. Und der Fehler, den Abschnitt 2 verhindern soll: Was mit SHA256: beginnt, ist der Fingerprint und gehört hier nicht hinein.


Einmal abgelegt, steht der Schlüssel für jeden Server im Konto zur Verfügung – auch für spätere.
Schritt 2: Debian installieren
Im SCP unter Medien → Images:
- Debian 13 (UEFI) als Abbild auswählen
- Sprache auf Englisch umstellen – vorbelegt ist Deutsch
- Partitionen: eine große Partition für das Betriebssystem, die den kompletten freien Speicherplatz beinhaltet
- Hostname:
vps - Zusätzlichen Benutzer erstellen aktivieren (Benutzername z. B.
martin, dazu ein Passwort wählen) - Den eben abgelegten SSH-Schlüssel auswählen
- Keine Extras, keine Skripte
- Auf Installieren klicken




Warum Englisch?
Ein englisch aufgesetztes System bringt
en_US.UTF-8mit, und darauf baut Schritt 2 weiter unten auf. Wichtiger im Alltag: Fehlermeldungen bleiben in der Sprache, in der auch die Antworten stehen. Eine übersetzte Meldung findest du in keiner Suchmaschine wieder. Die Anzeigesprache des Panels bleibt davon unberührt.
Schritt 3: Bestätigen und warten
Nach dem Klick fragt das Panel nach, ob das Abbild wirklich installiert werden soll – mit dem Hinweis, dass alle Daten auf der primären Festplatte dauerhaft gelöscht werden. Anschließend musst du dich in einem Popup noch einmal ausweisen. Beides ist Absicht: Der Vorgang setzt den Server komplett zurück.
Danach erscheint oben rechts eine kleine Anzeige „Image Installation wird durchgeführt" samt Fortschrittsbalken. Die ist leicht zu übersehen – sie ist aber die einzige Rückmeldung, dass überhaupt etwas läuft.

Schritt 4: Das Installationsergebnis sichern
Ist die Installation durch, zeigt das Panel das Ergebnis an: die IP-Adresse des Servers und ein root-Passwort.
⚠️ Diese Zugangsdaten werden nur einmal angezeigt
Das root-Passwort taucht später nirgends wieder auf. Speichere es sofort in deinem Passwortmanager – nicht in einer Textdatei auf dem Schreibtisch.
Für den Alltag brauchst du es nicht: Du arbeitest gleich als
martinmit deinem Schlüssel. Gebraucht wird es, wenn SSH einmal nicht mehr geht und nur die Konsole im Panel bleibt – dort zählt kein Schlüssel. Fehlt es dann, setzt du im SCP unter Zugang ein neues; aufgehoben erspart es dir diesen Umweg.
Die IP-Adresse brauchst du im nächsten Abschnitt.

Option B: Provider ohne SSH-Key-Support
- Debian 13 (Trixie) installieren
- Per Root-Passwort einloggen (wird vom Provider generiert)
- Manuell User anlegen und SSH-Key kopieren (siehe unten)
Nach Installation: User anlegen (falls nicht vom Provider gemacht)
Falls dein Provider keinen User angelegt hat, auf dem Server als root:
# Als root einloggen
ssh root@<SERVER-IP>
# User erstellen (UID 1000 wird automatisch vergeben, wenn erster User)
adduser martin
# Sudo-Rechte geben
usermod -aG sudo martin
# SSH-Verzeichnis anlegen
mkdir -p /home/martin/.ssh
chmod 700 /home/martin/.ssh
Public Key kopieren – diesen Befehl führst du auf deinem lokalen Rechner aus:
cat ~/.ssh/id_ed25519_vps.pub | ssh root@<SERVER-IP> "cat >> /home/martin/.ssh/authorized_keys"
Anschließend wieder als root auf dem Server – Rechte korrekt setzen:
chmod 600 /home/martin/.ssh/authorized_keys
chown -R martin:martin /home/martin/.ssh
Test – ausloggen und als martin einloggen. Weil der Schlüssel nicht am Standardpfad liegt, gibst du ihn hier noch mit -i an; Abschnitt 4.1 macht das gleich überflüssig:
exit
ssh -i ~/.ssh/id_ed25519_vps martin@<SERVER-IP>
4. Erster SSH-Login – Meldungen verstehen
4.1 Die Verbindung benennen
Dein Schlüssel heißt nicht mehr id_ed25519, also findet SSH ihn nicht mehr von allein. Statt ihn bei jedem Aufruf mit -i mitzugeben, trägst du die Verbindung einmal in deine persönliche SSH-Konfiguration ein.
Auf deinem lokalen Rechner:
nano ~/.ssh/config
Die Datei gibt es standardmäßig noch nicht – nano legt sie an. Inhalt:
Host vps
HostName <SERVER-IP>
User martin
IdentityFile ~/.ssh/id_ed25519_vps
AddKeysToAgent yes
UseKeychain yes
Für <SERVER-IP> trägst du die echte IP-Adresse deines Servers ein – spitze Klammern weg, nur die Zahlen. Die Adresse hat dir das Panel nach der Installation angezeigt; sie steht außerdem in der Server-Übersicht deines Anbieters. Der Rest der Datei bleibt so stehen: vps ist der Name, den du dir selbst gibst, martin dein Benutzer vom Server.
Die letzten beiden Zeilen nehmen dir die Passphrase ab. AddKeysToAgent yes übergibt den entschlüsselten Schlüssel nach der ersten Eingabe an den SSH-Agenten deines Rechners, UseKeychain yes legt die Passphrase zusätzlich in den Schlüsselbund. Du tippst sie also einmal und danach nicht wieder – auch nicht nach einem Neustart und auch nicht, wenn in Artikel 07 ein Editor die Verbindung aufbaut.
Nicht auf einem Mac?
UseKeychaingibt es nur dort; unter Linux und Windows lässt du die Zeile weg.AddKeysToAgent yesgenügt, dann hält der Rechner die Passphrase für die Dauer der Sitzung. Unter Windows muss der Dienst „OpenSSH Authentication Agent" dafür laufen – ab Werk ist er nicht gestartet.
Speichern (Ctrl+X, dann Y), anschließend die Rechte setzen:
chmod 600 ~/.ssh/config
Ab jetzt genügt ssh vps. Kein Benutzername, keine IP, kein -i.
Der Name bleibt, die Adresse wandert
In Artikel 05 wird der Zugang auf ein VPN umgestellt und der SSH-Port nach außen geschlossen. Dann änderst du in dieser Datei nur die Zeile
HostNameauf die VPN-Adresse. Der Befehlssh vpsbleibt derselbe – und VS Codium in Artikel 07 greift auf genau diesen Eintrag zurück.
4.2 Host-Key-Abfrage
Jetzt der erste Login:
ssh vps
Statt einer Eingabeaufforderung erscheint zunächst das hier:
The authenticity of host '...' can't be established.
ED25519 key fingerprint is SHA256:...
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Was passiert hier?
SSH kennt diesen Server noch nicht. Der Server präsentiert seinen Host-Key. Dein Client fragt dich, ob du diesem Schlüssel vertraust. Das schützt vor Man-in-the-Middle-Angriffen.
Wenn du den Server gerade selbst installiert hast, bestätige mit yes.
Danach steht oft:
Warning: Permanently added '...' to the list of known hosts.
Der Host-Key wird lokal gespeichert: ~/.ssh/known_hosts.
Wenn du den Server noch einmal neu installierst
Dann bekommt er neue Host-Keys, dein Rechner kennt aber noch die alten – und meldet sich mit einer Warnung in Rahmen und Großbuchstaben:
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! ... Host key verification failed.Das ist keine Fehlfunktion, sondern genau der Schutz aus dem Absatz oben: SSH sieht einen anderen Schlüssel als beim letzten Mal und verweigert die Verbindung. Nach einer Neuinstallation ist der Grund bekannt, also entfernst du den alten Eintrag:
ssh-keygen -R <SERVER-IP>Danach
ssh vpserneut aufrufen und mityesbestätigen wie beim ersten Mal.Nur wenn du weißt, warum sich der Schlüssel geändert hat. Erscheint die Warnung, ohne dass du am Server etwas verändert hast, ist sie ernst zu nehmen – dann ist das Löschen des Eintrags genau der falsche Schritt.
4.3 Passphrase-Abfrage
Wenn du eine Passphrase gesetzt hast:
Enter passphrase for key '.../id_ed25519_vps':
Was bedeutet das?
- Du nutzt Schlüssel-Login
- Dein Private Key ist zusätzlich geschützt
- Du gibst keinen Server-Login per Passwort frei
Check
Melde dich mit exit ab und verbinde dich erneut:
ssh vps
Ausgabe: Diesmal weder Host-Key- noch Passphrase-Abfrage, sondern direkt die Eingabeaufforderung des Servers. Der Host-Key steht jetzt in known_hosts, die Passphrase im Schlüsselbund – beides aus Abschnitt 4.1 und 4.2.
Fragt er weiterhin nach der Passphrase, fehlen die beiden Zeilen aus Abschnitt 4.1 oder stehen im falschen Host-Block.
Nebeneffekt, der verwirren kann: Sobald der Schlüssel im Agenten liegt, funktioniert auch der lange Aufruf
ssh martin@<SERVER-IP>ohne Eingabe. SSH bietet dem Gegenüber alle Schlüssel an, die es zur Hand hat – nicht nur den aus dem passendenHost-Eintrag. Der Eintrag spart dir also vor allem Tipparbeit und sorgt dafür, dass es beim ersten Mal überhaupt klappt.
5. Benutzer und UID 1000
Nachdem der erste Login funktioniert, prüfen wir die Benutzer- und Rechtebasis.
Best Practice: Der primäre Admin-User (im Beispiel martin) sollte die Standard-UID/GID 1000:1000 haben.
Warum das wichtig ist
Viele Container- und NAS-Workflows arbeiten mit
PUID/PGID. Wenn dein Standardbenutzer konsistent 1000:1000 ist, werden Dateirechte bei Volumes, Backups und Migrationen deutlich einfacher.
Check
whoami
id martin
Ausgabe:
martin
uid=1000(martin) gid=1000(martin) groups=1000(martin)
Entscheidend ist die zweite Zeile: UID und GID stehen beide auf 1000.
Hinweis zur sudo-Gruppe
Ob
27(sudo)zusätzlich in der Ausgabe erscheint, hängt vom Provider ab: Manche Installer legen den User direkt mit Sudo-Rechten an (z. B. Netcup), andere nicht. Falls die Gruppe fehlt, holen wir das in Sektion 7 nach – wichtig ist hier nur, dass UID und GID stimmen.
6. Die fünf Basisschritte
Schritt 1: System aktualisieren & Basispakete installieren
Zuerst Updates:
sudo apt update && sudo apt upgrade -y
Basispakete
Ein frisch installiertes Debian ist sehr minimal gehalten. Das ist gut für Sicherheit, aber im Alltag fehlen ein paar Werkzeuge, die wir für Administration, Fehlersuche und spätere Installationen ständig brauchen.
sudo apt install -y curl ca-certificates gnupg nano htop git unzip rsync bash-completion needrestart qemu-guest-agent
| Paket | Zweck |
|---|---|
curl |
HTTP(S)-Requests, Downloads, API-Checks |
ca-certificates |
Vertrauenswürdige Zertifikate für HTTPS/TLS |
gnupg |
Signaturen prüfen (z. B. bei externen Quellen) |
nano |
Konfigurationsdateien bearbeiten |
htop |
Prozesse und Ressourcen übersichtlich prüfen |
git |
Versionierung für Doku und Configs |
unzip |
ZIP-Archive entpacken |
rsync |
Effiziente Backups und Syncs |
bash-completion |
Weniger Tippfehler, bessere CLI-Erfahrung |
needrestart |
Zeigt nach Updates an, welche Dienste neu gestartet werden müssen – wichtig für unattended-upgrades |
qemu-guest-agent |
Verbindung zwischen Server und Virtualisierungs-Host – siehe Kasten |
Wofür der Guest Agent gut ist
Wenn dein Panel meldet, der QEMU Guest Agent laufe nicht, ist das kein Fehler: Das minimale Abbild bringt ihn nicht mit. Er ist ein kleiner Dienst im Server, über den der Virtualisierungs-Host mit dem laufenden System sprechen kann. Ohne ihn sieht der Host nur eine Blackbox.
Zwei Dinge hängen daran. Erstens das Herunterfahren aus dem Panel: Mit Agent wird das System gebeten, sich ordentlich zu beenden – ohne ihn kommt der Knopf im Zweifel dem Ziehen des Stromsteckers näher. Zweitens, und wichtiger, die Snapshots des Anbieters: Der Agent hält vor einem Snapshot kurz das Dateisystem an und sorgt dafür, dass noch offene Schreibvorgänge auf der Platte landen. Ohne ihn entspricht ein Snapshot dem Zustand nach einem Stromausfall. Meistens übersteht ein System das – aber „meistens" ist bei Sicherungen das falsche Wort.
Aktivieren musst du ihn nicht. Das Paket bringt eine udev-Regel mit, die den Dienst startet, sobald die passende Schnittstelle da ist. Ein
systemctl enablelehnt systemd deshalb mit einem langen Hinweis ab („The unit files have no installation config") – das ist kein Fehler, sondern der Normalfall auf Debian.Check
systemctl is-active qemu-guest-agentAusgabe:
active. Steht dortinactive, fehlt dem Server die virtio-Schnittstelle – daran lässt sich im System selbst nichts ändern.
Schritt 2: Zeitzone und Locale prüfen
Beides hast du bei der Installation festgelegt. Zwei Befehle bestätigen, dass es auch so angekommen ist:
timedatectl
locale
Ausgabe: bei Time zone steht Europe/Berlin, bei locale steht LANG=en_US.UTF-8.
Eine falsche Zeitzone fällt erst Wochen später auf, wenn ein Log-Zeitstempel nicht zu dem passt, was du erlebt hast – und dann kostet sie eine Stunde Fehlersuche. Deshalb der Blick jetzt.
Falls etwas anderes dasteht
Das kommt vor, wenn die Vorbelegung im Installationsdialog stehen geblieben ist oder dein Anbieter diese Felder gar nicht anbietet. Nachträglich:
sudo timedatectl set-timezone Europe/Berlin sudo update-locale LANG=en_US.UTF-8Die Locale-Änderung greift erst bei der nächsten Anmeldung – also einmal abmelden und
ssh vpsneu aufrufen.
Das Tastaturlayout bleibt von alldem unberührt: Deine Eingaben kommen über SSH von deinem eigenen Rechner.
Schritt 3: SSH weiter absichern
Konfiguration öffnen:
sudo nano /etc/ssh/sshd_config
Diese Datei steuert, wie sich der SSH-Server verhält. Die folgenden Einstellungen sorgen dafür, dass nur das Nötigste erlaubt ist.
Empfohlene Kerneinstellungen
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers martin
| Einstellung | Bedeutung |
|---|---|
PermitRootLogin no |
Niemand kann sich direkt als Root anmelden. Selbst wenn jemand einen Root-Schlüssel hätte, wäre der Login blockiert. |
PasswordAuthentication no |
Der Server akzeptiert keine Passwörter mehr. Damit fallen die meisten automatisierten Angriffe weg. |
PubkeyAuthentication yes |
Anmeldung ist nur noch mit SSH-Schlüsseln erlaubt – also mit deinem Key. |
AllowUsers martin |
Nur der Benutzer martin darf sich per SSH anmelden. Selbst wenn später weitere Nutzer existieren, kommen sie nicht automatisch per SSH rein. |
Nicht einfach ans Ende schreiben
In dieser Datei gewinnt der erste Treffer, nicht der letzte. Steht ein Schlüsselwort weiter oben schon aktiv drin, wird deine Zeile am Dateiende stillschweigend ignoriert – ohne Fehler, ohne Warnung.
Such deshalb mit Ctrl+W in nano nach jedem der vier Begriffe. Findest du eine aktive Zeile, änderst du sie dort. Nur was gar nicht vorkommt, schreibst du neu dazu.
Zeilen mit
#davor zählen nicht mit – das ist nur Dokumentation des Standardwerts. Bei manchen Anbietern stehen am Dateiende allerdings schon fertige Zeilen, etwaPasswordAuthentication noundPermitRootLogin yes. Die sind aktiv und wollen angepasst werden.
Nach der Änderung nano mit Ctrl+X beenden und mit Y speichern bestätigen.
Vor dem Reload: Syntax prüfen
Bevor du den Dienst neu lädst, prüfst du die Konfiguration auf Tippfehler:
sudo sshd -t
Wenn der Befehl ohne Ausgabe zurückkehrt, ist die Syntax in Ordnung. Bei Fehlern wirst du auf die Zeile hingewiesen – korrigieren, bevor du weitermachst.
Aktivieren:
sudo systemctl reload ssh
Check
sshd -t prüft nur die Rechtschreibung. Ob deine Einstellungen auch wirklich greifen, zeigt erst dieser Befehl:
sudo sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|pubkeyauthentication|allowusers'
Ausgabe:
permitrootlogin no
pubkeyauthentication yes
passwordauthentication no
allowusers martin
-T gibt die tatsächlich wirksame Konfiguration aus – die Schlüsselwörter erscheinen dabei kleingeschrieben. Steht dort etwas anderes als erwartet, gewinnt an anderer Stelle eine konkurrierende Zeile.
Wenn die Ausgabe nicht passt
Ganz oben in der Datei steht
Include /etc/ssh/sshd_config.d/*.conf. Alles aus diesem Verzeichnis wird an dieser Stelle eingelesen, also vor deinen Zeilen weiter unten – und gewinnt damit. Manche Anbieter legen dort eine Datei ab. Was drinliegt, zeigt:ls /etc/ssh/sshd_config.d/Findet sich dort eine konkurrierende Einstellung, änderst du sie in dieser Datei statt in
sshd_config.
Warum das wichtig ist:
- Root-Login über SSH ist ein unnötiges Risiko
- Passwort-Login ist die häufigste Angriffsfläche bei VPS-Systemen
- Weniger SSH-Features bedeutet weniger Überraschungen
⚠️ Wichtiger Check – aussperren vermeiden
Öffne ein zweites Terminal und teste den Login erneut, bevor du die alte Session schließt:
ssh vpsDer Login klappt. Ein Login mit
ssh root@<SERVER-IP>wird dagegen sofort verweigert. Erst danach die alte Session schließen.
Schritt 4: Firewall aktivieren (UFW, minimal offen)
UFW installieren und Default-Policy setzen:
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
IPv6 kurz prüfen
Fast jeder VPS hat heute neben der IPv4- auch eine IPv6-Adresse. Filtert UFW nur IPv4, wäre der Server über IPv6 ungeschützt erreichbar. Ein Blick genügt:
grep IPV6 /etc/default/ufw
Ausgabe: IPV6=yes. Das ist auf Debian 13 der Vorgabewert, du musst also nichts ändern. UFW legt damit zu jeder Regel automatisch eine IPv6-Variante an – zu sehen gleich im Check unten an den Zeilen mit (v6).
Falls dort
nostehtDann die Datei öffnen, den Wert auf
yessetzen und speichern (Ctrl+X, dann Y):sudo nano /etc/default/ufwSolange UFW noch nicht aktiv ist, genügt das. Änderst du den Wert später einmal an einer laufenden Firewall, reicht
sudo ufw reloaddafür nicht – dann brauchst dusudo ufw disableund anschließendsudo ufw enable.
SSH erlauben:
sudo ufw allow OpenSSH
Firewall aktivieren:
sudo ufw enable
UFW warnt, dass bestehende SSH-Verbindungen betroffen sein könnten. Da wir SSH oben explizit erlaubt haben, kannst du mit y bestätigen:
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
Warum
OpenSSHund nicht22/tcp?UFW kennt für viele Dienste vordefinierte „Application Profiles".
OpenSSHist eines davon. Funktional ist es bei SSH dasselbe wie22/tcp, aber die Schreibweise ist klarer und konsistent mit Profilen wieNginx Full, die später für Web-Dienste sinnvoll werden.
Warum Firewall überhaupt?
Prinzip: Alles ist gesperrt – nur explizit erlaubte Ports sind offen. So behältst du die Kontrolle, auch wenn später Dienste installiert werden.
⚠️ Die zweite Firewall, die du nicht siehst
UFW läuft auf dem Server. Manche Anbieter betreiben zusätzlich eine eigene Firewall im Netzwerk davor – bei Netcup gehört sie seit Server-Generation 12 zum Lieferumfang und ist bei neu bestellten Servern von Anfang an aktiv. Ein Paket muss beide Ebenen passieren; was die vorgelagerte Firewall verwirft, erreicht dein Debian nie und taucht in keinem Log auf.
Eingehend lässt sie zunächst alles durch – die Regeln, die hier zählen, sind also deine UFW-Regeln. Ausgehend bringt sie zwei fertige Regelsätze mit: einen, der Ping erlaubt, und
netcup Mail block, der die Mail-Ports 25, 465 und 587 sperrt. Der zweite wird in Artikel 08 zum Thema, wenn der Mail-Versand zum ersten Mal daran scheitert.Ansonsten lass sie in diesem Artikel unangetastet. Sobald du dort eine eigene Regel anlegst, wechselt die Grundeinstellung für diese Richtung automatisch von „erlauben" auf „verwerfen" – wer dabei SSH vergisst, kommt nicht mehr auf den Server. Dazu behandelt sie UDP zustandslos: Dienste wie DNS und Zeitabgleich brauchen dann Regeln in beide Richtungen, sonst klemmt plötzlich die Namensauflösung.
Warum UFW und nicht nftables direkt?
UFW nutzt unter der Haube nftables (auf Debian 13), bietet aber eine deutlich einfachere Syntax für Homelab-Szenarien. Für komplexe Enterprise-Setups wäre nftables direkt besser – für Self-Hosting ist UFW perfekt.
Check
sudo ufw status verbose
Ausgabe:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
Schritt 5: Automatische Sicherheitsupdates aktivieren
Debian sollte automatisch Sicherheits-Patches installieren:
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure unattended-upgrades
Der Dialog fragt, ob du es aktivieren willst – bestätige mit „Yes".
Was passiert?
- Täglich werden Sicherheitsupdates automatisch heruntergeladen und installiert
- Nur aus dem
Debian-Security-Repository (keine Breaking Changes) - Logs liegen unter
/var/log/unattended-upgrades/
Automatischen Reboot konfigurieren
Manche Updates – Kernel, Glibc, systemd – werden erst nach einem Reboot wirksam. Ohne automatischen Reboot bleibt dein Server bis zum manuellen Neustart mit der alten, möglicherweise verwundbaren Version laufen.
Die Standard-Datei /etc/apt/apt.conf.d/50unattended-upgrades ist lang, komplett auf Englisch und alle relevanten Zeilen sind auskommentiert. Statt darin die richtigen Stellen zu suchen und zu entkommentieren, legen wir eine eigene kleine Datei an, die nur unsere Einstellungen enthält:
sudo nano /etc/apt/apt.conf.d/52unattended-upgrades-local
Folgenden Inhalt einfügen:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
Speichern mit Ctrl+X, dann Y.
Warum eine eigene Datei?
Die höhere Nummer (
52) gewinnt gegen die Defaults in der50-Datei – APT liest die Dateien in/etc/apt/apt.conf.d/der Reihe nach, spätere überschreiben frühere. Du musst nichts suchen, nichts entkommentieren. Und bei einem Paket-Update der50-Datei bleibt deine Einstellung erhalten, weil sie in einer separaten Datei steht.
Wann lieber
falsesetzen?Wenn du echte Mission-Critical-Dienste betreibst, bei denen ungeplante Reboots problematisch wären. Für klassische Self-Hosting-Setups (Vaultwarden, Immich, Blog) ist
truemit nächtlichem Zeitfenster die ehrlichere Wahl: Sicherheitslücken werden zeitnah geschlossen, Downtime fällt mitten in die Nacht.needrestart(haben wir oben mit installiert) zeigt dir auf jedem Login an, ob ein Reboot nötig ist – Überraschungen ausgeschlossen.
Check
Zuerst prüfen, ob der Service läuft und beim Boot startet:
sudo systemctl status unattended-upgrades
sudo systemctl is-enabled unattended-upgrades
Ausgabe: active (running) und enabled.
Hinweis: Der Service heißt vollständig „Unattended Upgrades Shutdown" – das ist normal und hat nichts mit Herunterfahren zu tun. Es ist ein Wächter-Prozess, der im Hintergrund läuft und beim Systemstart-/Shutdown noch ausstehende Updates sauber abschließt. Die täglichen Updates selbst laufen über einen separaten Timer.
Dann prüfen, ob deine Reboot-Einstellungen wirklich greifen:
apt-config dump | grep -i "Unattended-Upgrade::Automatic-Reboot"
Ausgabe:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
Tauchen beide Zeilen auf, wird deine 52unattended-upgrades-local korrekt eingelesen und überschreibt die Defaults.
Warum das wichtig ist
Sicherheitsupdates manuell zu machen heißt: vergessen. Automatisierung ist 2026 Standard für VPS-Betrieb.
7. sudo statt Root: das Least-Privilege-Prinzip
In den Schritten oben hast du schon mehrmals sudo benutzt. Hier nochmal kurz, warum das so läuft – und wie du sicherstellst, dass es bei dir auch wirklich funktioniert.
Warum nicht einfach als root arbeiten?
Der Root-Benutzer hat uneingeschränkte Systemrechte. Ein Tippfehler – etwa ein rm -rf an der falschen Stelle – kann das ganze System unbrauchbar machen. Deshalb gilt im Server-Alltag das Prinzip Least Privilege: Du arbeitest standardmäßig als normaler Benutzer und holst dir Administratorrechte nur dann, wenn du sie wirklich brauchst – über sudo.
Das ist nicht nur Sicherheits-Hygiene, sondern auch ein Konzept, das später überall wieder auftaucht: Container laufen mit eingeschränkten Rechten, Apps haben eigene Service-User, Backups schreiben mit minimalen Berechtigungen. Wer das Prinzip einmal verinnerlicht hat, versteht später vieles automatisch mit.
Prüfen, ob dein Benutzer in der sudo-Gruppe ist
groups martin
Erscheint sudo in der Ausgabe, ist alles korrekt.
Falls sudo fehlt (einmalig als Root oder über die Provider-Konsole):
sudo usermod -aG sudo martin
Danach einmal neu einloggen – Gruppenrechte werden erst beim Login geladen.
Hinweis
Auf manchen Providern (z. B. Netcup) wird der erste User direkt mit Sudo-Rechten angelegt – dann ist hier nichts zu tun. Auf anderen musst du nachhelfen. Der Check oben zeigt dir, was zutrifft.
Wenn es nicht klappt
| Was du siehst | Ursache | Weiter |
|---|---|---|
Permission denied (publickey) beim ersten Login |
Im Installationsdialog war Zusätzlichen Benutzer erstellen nicht angehakt – sshd meldet ein fehlendes Konto genauso wie einen fehlenden Schlüssel. Seltener: abgeschnittener Schlüssel oder der Fingerprint statt des Public Keys | → Abschnitt 3, Schritt 1 und 2 |
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! |
Server neu installiert, dein Rechner kennt noch die alten Host-Keys | → Abschnitt 4.2, Kasten |
| Jede Verbindung fragt erneut nach der Passphrase | AddKeysToAgent/UseKeychain fehlen oder stehen im falschen Host-Block |
→ Abschnitt 4.1 |
sshd -T zeigt andere Werte, als du eingetragen hast |
Eine Datei in /etc/ssh/sshd_config.d/ wird vorher eingelesen und gewinnt |
→ Abschnitt 6, Schritt 3 |
The unit files have no installation config bei qemu-guest-agent |
Kein Fehler – der Dienst startet auf Debian über eine udev-Regel, nicht über enable |
→ Abschnitt 6, Schritt 1 |
Und jetzt?
Du hast jetzt eine saubere, gehärtete Linux-Basis: SSH per Schlüssel, Firewall aktiv, automatische Sicherheitsupdates, klare Benutzerrechte. Diese Basis bleibt von hier an möglichst unverändert – alles, was du an Diensten brauchst, läuft ab dem nächsten Artikel in Containern darüber. Docker und Docker Compose sind das nächste Fundament-Stück.
Was mit Port 22 noch passiert
In Schritt 4 hast du Port 22 in der Firewall bewusst offen gelassen – ohne ihn kämst du nicht mehr auf den Server. Durch die Schlüssel-Anmeldung sind Anmeldeversuche von außen chancenlos, sichtbar ist der Port aber trotzdem. Das ist ein Zwischenstand, kein Endzustand: In Artikel 05 kommt ein VPN dazu, danach ist SSH nur noch darüber erreichbar und Port 22 verschwindet vollständig aus dem öffentlichen Netz.
👉 Nächster Artikel: 03. Docker auf dem VPS: Engine, Compose und zwei Netzwerke
Discussion