← Übersicht
Linux

Linux-Grundlagen

Herkunft: von UNIX über GNU zu Linux

Linux steht in der Tradition von UNIX: 1969 entwickelten Mitarbeiter der Bell Labs ein schlankes, von Anfang an auf Multitasking und Mehrbenutzerbetrieb ausgelegtes Betriebssystem, das in den 1970ern in der eigens dafür geschaffenen Sprache C neu geschrieben wurde. Kernfunktionen wurden später unter POSIX standardisiert. 1983 startete Richard Stallman das GNU-Projekt mit dem Ziel eines freien Betriebssystems und schuf 1989 die Lizenz GPL (GNU General Public License). Es fehlte nur noch der Kern – den steuerte 1991 Linus Torvalds mit dem Linux-Kernel bei. „Frei“ meint dabei Freiheit, nicht Kostenlosigkeit: „free as in free speech, not free beer“.

Der Linux-Kernel

Der Kernel ist die Schnittstelle zwischen Hard- und Software. Er nimmt Anfragen der Anwendungen entgegen und steuert die Zuteilung der Ressourcen – Rechenzeit, Arbeitsspeicher, Geräte. Er ist überwiegend in C geschrieben, zeitkritische Teile in Assembler. Eine Grundphilosophie von Linux lautet „everything is a file“: Geräte, Prozesse und Schnittstellen erscheinen als Dateien und lassen sich so mit denselben Werkzeugen (Texteditor, cat, Umleitungen) ansprechen.

EigenschaftBedeutung
Präemptives MultitaskingMehrere Prozesse laufen scheinbar gleichzeitig; der Kernel teilt nach Priorität Rechenzeit zu
MehrprozessorfähigkeitAuf mehreren CPU-Kernen laufen Prozesse echt parallel
Mehrbenutzer-/MehrsitzungsfähigkeitMehrere Benutzer bzw. Sitzungen arbeiten gleichzeitig am selben System
Open SourceQuellcode frei einsehbar und anpassbar (GPL)

Shells: sh, bash & Co.

Die Shell ist der Kommando-Interpreter zwischen Benutzer und System. Es gibt mehrere Varianten – die bei modernen Linux-Systemen übliche Standardshell ist die bash (Bourne-Again-Shell).

ShellBeschreibung
sh (Bourne-Shell)Basis der meisten heutigen Shells
csh (C-Shell)Bedienung mit Kommandos in C-Syntax
ksh (Korn-Shell)Klassische Standardshell vieler UNIX-Systeme
bash (Bourne-Again-Shell)Standardshell moderner Linux-Systeme
cat /etc/shells # registrierte (gültige) Login-Shells anzeigen echo $0 # welche Shell läuft gerade? (z. B. -bash) /bin/dash # in eine andere Shell wechseln exit # zurück zur vorherigen Shell (im Login-Prompt: abmelden)

Der Eingabeprompt: $ und #

Der Prompt verrät, mit welchen Rechten du angemeldet bist:

ZeichenBedeutung
$ (Dollar)Du bist als normaler Benutzer angemeldet
# (Raute)Du bist root (Systemadministrator, UID 0)
Achtung: Das Konto root hat vollen Zugriff auf das gesamte System. Arbeite nur dann als root, wenn eine Aufgabe es erfordert – das Risiko, mit root versehentlich Schaden anzurichten, ist hoch. Für einzelne Befehle nutzt man besser sudo.

Interne vs. externe Kommandos

Jeder Befehl folgt dem Schema kommandoname [optionen] [argumente]. Man unterscheidet zwei Arten: interne Kommandos sind in der Shell selbst eingebaut (z. B. cd), externe sind eigenständige Programme im Dateisystem (z. B. /bin/mount). Mit type findest du heraus, um welche Art es sich handelt.

type cd # -> cd ist eine von der Shell mitgelieferte Funktion (intern) type mount # -> mount ist /bin/mount (externes Programm)

Systemstart: von init zu systemd

Früher startete der Prozess /sbin/init als erster Prozess (er erhält die PID 1) und rief alle weiteren Dienste als Kindprozesse auf. Die Startreihenfolge regelten sogenannte Runlevel. Nachteil: Jeder Dienst musste vollständig hochgefahren sein, bevor der nächste startete – das machte den Bootvorgang langsam. Heute übernimmt systemd (ebenfalls PID 1) diese Rolle und startet voneinander unabhängige Dienste parallel. Die alten Runlevel entsprechen heute den systemd-Targets.

Runlevelsystemd-TargetBedeutung
0poweroff.targetSystem herunterfahren
1 / Srescue.targetEinzelbenutzer- / Rettungsmodus
3multi-user.targetMehrbenutzer mit Netzwerk, ohne grafische Oberfläche
5graphical.targetMehrbenutzer mit grafischer Oberfläche
6reboot.targetSystem neu starten
# Target zur Laufzeit wechseln (langer Weg) systemctl isolate poweroff.target # herunterfahren systemctl isolate reboot.target # neu starten # Kurzbefehle (Links auf die systemctl-Kommandos) shutdown -h now # sofort herunterfahren (poweroff) shutdown -r now # sofort neu starten (reboot) reboot # neu starten
Vertiefung: Wie man einzelne Dienste mit systemctl steuert, eigene Unit-Dateien schreibt und Logs mit journalctl liest, behandelt der Abschnitt systemd & Dienste.

Hilfe zur Selbsthilfe

Linux bringt eine umfangreiche, meist englischsprachige Dokumentation mit. Vier Wege führen zum Ziel:

help exit # Kurzhilfe für ein INTERNES Kommando (Shell-Builtin) bash --help # Kurzhilfe für ein EXTERNES Programm (auch -h ) man ls # ausführliche Handbuchseite (q = beenden, / = suchen) whatis reboot # Einzeiler + in welchen man-Kapiteln es Infos gibt apropos netzwerk # Stichwortsuche über alle Handbuchseiten

Die man-Seiten sind in Kapitel gegliedert. Mit man <Nummer> <Thema> ruft man gezielt das passende Kapitel auf:

KapitelInhalt
1Kommandos / Programme
2Systemaufrufe und Fehlercodes
5Formate von Konfigurationsdateien
8Kommandos zur Systemadministration
man 1 whatis # whatis als Programm (Kapitel 1) man 5 sshd_config # das Konfig-Datei-Format (Kapitel 5)
Linux

Linux-Distributionen im Überblick

Was ist eine Distribution?

„Linux“ ist streng genommen nur der Kernel. Eine Distribution bündelt Kernel, Werkzeuge, Paketmanager, Installer und Support zu einem fertigen Betriebssystem.

Debian-, Red-Hat- und weitere Distributionsfamilien
Abb. – Die drei großen Familien und ihre wichtigsten Vertreter

Die wichtigsten Server-Distributionen

DistributionFamiliePaketmanagerTypischer Einsatz
DebianDebianaptsehr stabile Server, Basis vieler anderer Distributionen
Ubuntu ServerDebianaptweit verbreitet, Cloud, 5 Jahre LTS-Support
RHELRed HatdnfUnternehmen mit Herstellersupport (kostenpflichtig)
Rocky / AlmaLinuxRed Hatdnfkostenlose, RHEL-kompatible Alternative
SUSE / openSUSESUSEzypperUnternehmen, v. a. im deutschsprachigen Raum
Alpineeigenständigapkwinzige Container-Images

LTS vs. Rolling Release

  • LTS (Long Term Support): Feste Versionen mit jahrelangen Sicherheitsupdates (z. B. Ubuntu 24.04 LTS). Ideal für Server – nichts ändert sich überraschend.
  • Rolling Release: Keine Versionen, ständig die neuesten Pakete (z. B. Arch Linux). Spannend für Desktops, riskant für Server.
cat /etc/os-release # welche Distribution und Version läuft? uname -r # Kernel-Version hostnamectl # Überblick inkl. Betriebssystem und Kernel
Für den Alltag: Wer Debian/Ubuntu und einen RHEL-Klon beherrscht, kommt auf praktisch jedem Server zurecht. Die Befehle sind zu 90 % gleich – Unterschiede liegen vor allem bei Paketmanager, Log-Dateinamen und Netzwerk-Konfiguration.
Linux

Wichtige Befehle

Die Linux-Shell

Die Shell (meist bash oder zsh) ist die Kommandozeilen-Schnittstelle zum System. Ein Befehl folgt immer dem gleichen Muster: kommando [optionen] [argumente]. Optionen werden mit einem Bindestrich (kurz, z. B. -l) oder zwei Bindestrichen (lang, z. B. --all) eingeleitet. Mit man <befehl> öffnest du jederzeit die Handbuchseite.

Tipp: Drücke Tab zur automatischen Vervollständigung von Befehlen und Pfaden. Mit den Pfeiltasten ↑/↓ blätterst du durch die Befehlshistorie, mit Strg+R durchsuchst du sie rückwärts.

Navigation im Dateisystem

BefehlFunktionBeispiel
pwdAktuelles Arbeitsverzeichnis anzeigen (print working directory)pwd
lsVerzeichnisinhalt auflistenls -lah
cdVerzeichnis wechseln (change directory)cd /var/log
cd ~In das eigene Home-Verzeichnis wechselncd ~
cd ..Eine Ebene nach oben wechselncd ../..
cd -Zurück zum vorherigen Verzeichniscd -
# ls mit den wichtigsten Optionen ls -l # ausführliche Liste (Rechte, Besitzer, Größe, Datum) ls -a # auch versteckte Dateien (beginnen mit .) ls -h # Größen menschenlesbar (K, M, G) ls -lt # nach Änderungszeit sortiert, neuste zuerst ls -lahR /etc # rekursiv, alle Dateien, lesbar

Dateien & Verzeichnisse verwalten

# Kopieren, Verschieben, Löschen cp quelle.txt ziel.txt # Datei kopieren cp -r ordner/ /backup/ # Verzeichnis rekursiv kopieren mv alt.txt neu.txt # umbenennen / verschieben mv datei.txt /tmp/ # in anderes Verzeichnis verschieben rm datei.txt # Datei löschen rm -r ordner/ # Verzeichnis rekursiv löschen rm -i datei.txt # vor dem Löschen nachfragen mkdir -p projekt/src/lib # Verzeichnisbaum mit Eltern anlegen touch neu.txt # leere Datei erstellen / Zeitstempel
Achtung: rm -rf / löscht rekursiv und ohne Rückfrage das gesamte System. Prüfe bei rm -rf immer den Pfad doppelt – es gibt keinen Papierkorb auf der Kommandozeile.

Suchen: find & grep

find sucht Dateien anhand von Namen, Größe, Alter oder Typ im Dateibaum. grep durchsucht den Inhalt von Dateien nach Textmustern (regulären Ausdrücken).

# find – Dateien im Dateisystem finden find /etc -name "*.conf" # alle .conf-Dateien unter /etc find / -type f -size +100M # Dateien größer als 100 MB find /home -mtime -7 # in den letzten 7 Tagen geändert find . -name "*.log" -delete # gefundene Logs direkt löschen # grep – Inhalt durchsuchen grep "error" /var/log/syslog # Zeilen mit "error" grep -i "warning" datei.log # ohne Groß-/Kleinschreibung grep -r "TODO" ./src/ # rekursiv im Verzeichnis grep -n "root" /etc/passwd # mit Zeilennummer grep -c "404" access.log # nur Treffer zählen

Inhalte anzeigen

BefehlFunktion
cat dateiGesamte Datei am Stück ausgeben
less dateiSeitenweise blättern (q = beenden, / = suchen)
head -n 20 dateiErste 20 Zeilen
tail -n 20 dateiLetzte 20 Zeilen
tail -f dateiDatei live verfolgen (z. B. Logdateien)
wc -l dateiZeilen zählen

Pipes & Umleitung

Eine Pipe (|) leitet die Ausgabe eines Befehls als Eingabe an den nächsten weiter. Mit Umleitungen schreibst du Ausgaben in Dateien statt auf den Bildschirm.

OperatorBedeutung
|Pipe – Ausgabe an nächsten Befehl weiterreichen
>Standardausgabe in Datei umleiten (überschreibt)
>>Anhängen an Datei
2>Fehlerausgabe (stderr) umleiten
<Datei als Standardeingabe verwenden
2>&1Fehlerkanal in Standardausgabe umleiten
# Pipes verketten cat /var/log/syslog | grep "error" | wc -l # Fehler zählen ps aux | grep nginx # nur nginx-Prozesse ls -l /etc | less # lange Liste blättern # Umleitungen echo "Start" > log.txt # neue Datei (überschreibt) date >> log.txt # ans Ende anhängen befehl 2> fehler.log # nur Fehler in Datei befehl > alles.log 2>&1 # Ausgabe + Fehler zusammen

Prozesse verwalten

Jeder laufende Prozess hat eine eindeutige PID (Process ID). Mit Signalen kannst du Prozesse beenden oder neu laden.

# Prozesse anzeigen ps aux # alle Prozesse aller Benutzer ps aux | grep apache # gezielt filtern top # interaktive Live-Übersicht (q = beenden) htop # komfortable Alternative (sofern installiert) # Prozesse beenden kill 1234 # SIGTERM (sanftes Beenden) an PID 1234 kill -9 1234 # SIGKILL (hartes Beenden, nicht abfangbar) killall firefox # alle Prozesse mit diesem Namen pkill -f "python app" # nach Kommandozeile beenden
Tipp: Beende einen Prozess zuerst sanft mit kill (SIGTERM, Signal 15) – so kann er offene Dateien sauber schließen. Greife erst zu kill -9 (SIGKILL), wenn er nicht reagiert.

Archivieren & Komprimieren: tar

Mit tar (tape archive) fasst du viele Dateien zu einem Archiv zusammen – meist gleich komprimiert. Eselsbrücke für die Optionen: create, extract, table (Inhalt), verbose, file, z = gzip, j = bzip2, J = xz.

# Archiv erstellen (gzip-komprimiert) tar -czvf backup.tar.gz /etc /home/anna # c=create z=gzip v=verbose f=file tar -cJvf backup.tar.xz projekt/ # stärker komprimiert (xz) # Inhalt ansehen, ohne zu entpacken tar -tzvf backup.tar.gz # Entpacken tar -xzvf backup.tar.gz # x=extract, in aktuelles Verzeichnis tar -xzvf backup.tar.gz -C /tmp/wiederher # gezielt in ein Zielverzeichnis

Befehlsketten: &&, || und ;

Mehrere Befehle lassen sich in einer Zeile verketten – mit unterschiedlicher Logik:

OperatorBedeutung
;Befehle nacheinander ausführen – unabhängig vom Erfolg
&&Nächsten Befehl nur ausführen, wenn der vorige erfolgreich war (Exit-Code 0)
||Nächsten Befehl nur ausführen, wenn der vorige fehlgeschlagen ist
&Befehl im Hintergrund starten
apt update && apt upgrade -y # upgrade nur, wenn update klappte cd /var/log || echo "Pfad fehlt" # Meldung nur bei Fehler make ; echo "fertig" # echo läuft in jedem Fall

Wildcards (Globbing)

Die Shell ersetzt sogenannte Wildcards vor der Ausführung durch passende Dateinamen. So lassen sich viele Dateien auf einmal ansprechen.

ZeichenBedeutungBeispiel
*Beliebig viele Zeichen (auch keine)ls *.log
?Genau ein beliebiges Zeichenls datei?.txt
[…]Ein Zeichen aus der angegebenen Mengels log[1-3].txt
ls *.conf # alle Dateien mit Endung .conf rm temp?.dat # temp1.dat, tempA.dat … (genau 1 Zeichen) cp bild[1-3].png /backup/ # bild1.png, bild2.png, bild3.png

Aliase dauerhaft anlegen

Ein Alias ist ein selbst definierter Kurzbefehl. In der Sitzung gesetzte Aliase gehen beim Abmelden verloren – dauerhaft werden sie, wenn man sie in ~/.bashrc einträgt.

alias ll='ls -lah' # nur für die aktuelle Sitzung # Dauerhaft: Zeile in ~/.bashrc eintragen und neu einlesen echo "alias ll='ls -lah'" >> ~/.bashrc source ~/.bashrc # .bashrc neu laden (oder neu anmelden)
Linux

Dateisystem & Verzeichnisse

Filesystem Hierarchy Standard (FHS)

Unter Linux gibt es keine Laufwerksbuchstaben wie unter Windows. Alles hängt an einem einzigen Wurzelverzeichnis / (root). Der FHS legt fest, welche Daten in welchem Verzeichnis liegen – das ist über alle Distributionen hinweg weitgehend einheitlich.

VerzeichnisInhalt
/Wurzelverzeichnis – Ausgangspunkt der gesamten Hierarchie
/bin, /sbinEssenzielle Programme (Benutzer / Systemadministration)
/etcSystemweite Konfigurationsdateien (Textdateien)
/homePersönliche Verzeichnisse der Benutzer (/home/user)
/rootHome-Verzeichnis des Superusers root
/varVariable Daten: Logs (/var/log), Mails, Caches, Webroot
/tmpTemporäre Dateien (wird oft beim Neustart geleert)
/usrAnwendungen und Bibliotheken der Benutzer (read-only)
/optZusätzliche / proprietäre Software von Drittanbietern
/devGerätedateien (Festplatten, Terminals, /dev/null …)
/proc, /sysVirtuelle Dateisysteme – Kernel- und Prozessinfos
/mnt, /mediaEinhängepunkte für Wechseldatenträger und Netzlaufwerke
/bootKernel, Initramfs und Bootloader (GRUB)
FHS-Verzeichnisbaum mit / an der Spitze und den Verzeichnissen /etc, /var, /home, /usr, /bin, /tmp, /opt samt Funktionsbeschreibung
Abb. – Filesystem Hierarchy Standard: zentrale Verzeichnisse unterhalb des Wurzelverzeichnisses /
Hintergrund (Stand 2026): Der FHS in Version 3.0 (Linux Foundation, Juni 2015) ist nach wie vor der gültige Standard. Praktisch alle modernen Distributionen (Ubuntu, Debian, Fedora, Arch) haben jedoch den sogenannten /usr-Merge vollzogen: /bin, /sbin und /lib sind nur noch Symlinks nach /usr/bin, /usr/sbin bzw. /usr/lib. Die historische Trennung „essenzielle vs. nachträglich installierte Programme“ ist damit hinfällig.

Dateitypen

Der erste Buchstabe in der Ausgabe von ls -l verrät den Dateityp:

ZeichenTypBeschreibung
-Reguläre DateiText, Programm, Bild …
dVerzeichnis (directory)Enthält weitere Dateien
lSymbolischer LinkVerweis auf eine andere Datei
bBlockgerätz. B. Festplatte /dev/sda
cZeichengerätz. B. Terminal, /dev/null
pNamed Pipe (FIFO)Interprozess-Kommunikation
sSocketLokale Netzwerk-/Prozesskommunikation

Festplatten einhängen: mount & fstab

Ein Datenträger wird mit mount an einem Verzeichnis (Mountpoint) ins Dateisystem eingehängt. Dauerhafte Einhängungen werden in /etc/fstab definiert und beim Booten automatisch aktiviert.

# Manuell einhängen / aushängen mount /dev/sdb1 /mnt/usb # Partition an /mnt/usb einhängen umount /mnt/usb # wieder aushängen mount # alle aktiven Einhängungen anzeigen lsblk # Blockgeräte als Baum anzeigen blkid # UUIDs der Partitionen anzeigen # Beispiel-Eintrag in /etc/fstab (UUID empfohlen, stabiler als /dev/sdX): # <Gerät> <Mountpoint> <Typ> <Optionen> <dump> <pass> UUID=1a2b-3c4d /data ext4 defaults 0 2 # Nach Änderung an fstab testen, ohne Neustart: mount -a # alle fstab-Einträge einhängen
Tipp: Verwende in /etc/fstab immer die UUID statt /dev/sdb1. Gerätenamen können sich beim Booten oder beim Anschluss weiterer Platten verschieben – die UUID bleibt konstant.

Speicherplatz analysieren: df & du

df -h # freier/belegter Platz pro Dateisystem (lesbar) df -i # belegte Inodes anzeigen du -sh /var/log # Gesamtgröße eines Verzeichnisses du -h --max-depth=1 / # Größe der Unterverzeichnisse von / du -sh * | sort -rh # größte Einträge zuerst

Verknüpfungen: ln (Hard- & Symlinks)

Ein Hardlink ist ein zweiter Name für dieselben Daten (gleiche Inode) – nur innerhalb desselben Dateisystems möglich. Ein symbolischer Link (Softlink) ist ein eigener Verweis auf einen Pfad und funktioniert auch über Dateisystemgrenzen hinweg.

EigenschaftHardlinkSymbolischer Link (-s)
Verweist aufInode (Daten direkt)Pfadname
Über DateisystemeNeinJa
Auf VerzeichnisseNeinJa
Original gelöschtDaten bleiben erhaltenLink ist defekt (dangling)
ln datei.txt hardlink.txt # Hardlink erstellen ln -s /opt/app/bin /usr/local/bin/app # symbolischen Link erstellen ls -l /usr/local/bin/app # zeigt: app -> /opt/app/bin

Praxis: „Disk full“ trotz freiem Platz?

Ein Dateisystem kann sich aus zwei Gründen als „voll“ melden: entweder ist der Speicherplatz erschöpft (df -h) oder die Inodes (df -i). Inodes speichern die Metadaten jeder Datei – viele winzige Dateien (z. B. Mail-Queues, Sessions, Caches) können sie aufbrauchen, obwohl noch GB frei sind.

# 1. Belegung prüfen – beide Achsen! df -h # Speicherplatz df -i # Inodes (IUse% beachten) # 2. Größte Verbraucher unterhalb von / finden du -h --max-depth=1 / 2>/dev/null | sort -rh | head # 3. Klassiker: eine bereits gelöschte, aber von einem Prozess # noch offen gehaltene Datei belegt weiter Platz lsof +L1 # zeigt gelöschte Dateien mit Link-Count 0 -> Dienst neu starten
Achtung: Wenn ein Prozess (z. B. ein Logger) eine bereits gelöschte Datei noch offen hält, gibt das Löschen keinen Platz frei – erst ein Neustart des Prozesses schließt den Datei-Handle. Genau dann zeigt df belegten Platz, den du nicht mehr findet.
Linux

Benutzer & Rechte

Benutzer verwalten

Jeder Benutzer hat eine eindeutige UID (User ID). Die root-Kennung (UID 0) ist der Superuser mit allen Rechten. Reguläre Benutzer beginnen je nach Distribution bei UID 1000.

# Benutzer anlegen / ändern / löschen useradd -m -s /bin/bash anna # Benutzer + Home-Verzeichnis + Shell passwd anna # Passwort setzen / ändern usermod -aG sudo anna # zur Gruppe sudo HINZUFÜGEN (-a wichtig!) usermod -L anna # Konto sperren (lock) userdel -r anna # Benutzer inkl. Home löschen id anna # UID, GID und Gruppen anzeigen whoami # aktuellen Benutzer anzeigen
Achtung: Bei usermod -G ohne -a werden alle bestehenden Zusatzgruppen überschrieben. Verwende für das Hinzufügen immer usermod -aG gruppe benutzer.

/etc/passwd & /etc/shadow

Benutzerkonten stehen in /etc/passwd (für alle lesbar), die verschlüsselten Passwörter in /etc/shadow (nur root lesbar).

# Aufbau einer Zeile in /etc/passwd: # name:x:UID:GID:Kommentar:Home-Verzeichnis:Login-Shell anna:x:1001:1001:Anna Admin:/home/anna:/bin/bash # ^ x = Passwort liegt in /etc/shadow # Aufbau einer Zeile in /etc/shadow: # name:gehashtes-Passwort:letzte-Änderung:min:max:warn:... anna:$6$xyz...:19800:0:99999:7:::
DateiInhaltRechte
/etc/passwdBenutzerkonten (Name, UID, Home, Shell)für alle lesbar (644)
/etc/shadowPasswort-Hashes & Ablaufdatennur root (640/600)
/etc/groupGruppendefinitionenfür alle lesbar
/etc/sudoerssudo-Berechtigungennur root (440)

Gruppen

groupadd entwickler # Gruppe anlegen gpasswd -a anna entwickler # Benutzer zur Gruppe hinzufügen groups anna # Gruppenmitgliedschaften anzeigen newgrp entwickler # zur Gruppe in aktueller Sitzung wechseln

Dateirechte verstehen (rwx)

Jede Datei hat drei Rechte-Tripel: für den Besitzer (user), die Gruppe (group) und alle anderen (others). Jedes Tripel besteht aus r (lesen), w (schreiben) und x (ausführen).

# Beispielausgabe von ls -l -rwxr-xr-- 1 anna entwickler 4096 3. Jun 10:00 skript.sh │└┬┘└┬┘└┬┘ └┬─┘ └───┬────┘ │ │ │ └ others: r-- (nur lesen) │ │ └─── group: r-x (lesen + ausführen) │ └────── user: rwx (alle Rechte) └──────── Dateityp: - = reguläre Datei
Aufschlüsselung der Dateirechte rwxr-xr-- in Besitzer, Gruppe und Andere mit den Oktalwerten r=4, w=2, x=1 ergibt 754
Abb. – Dateirechte rwxr-xr-- aufgeschlüsselt: Besitzer (7) · Gruppe (5) · Andere (4) = 754

Oktale Schreibweise

Rechte lassen sich als dreistellige Oktalzahl ausdrücken. Pro Tripel werden die Werte addiert: r = 4, w = 2, x = 1.

OktalSymbolischBedeutung
7rwxlesen + schreiben + ausführen
6rw-lesen + schreiben
5r-xlesen + ausführen
4r--nur lesen
0---keine Rechte
755rwxr-xr-xtypisch für Programme/Verzeichnisse
644rw-r--r--typisch für normale Dateien
600rw-------nur Besitzer (z. B. SSH-Schlüssel)

chmod & chown

# Rechte ändern (chmod) chmod 755 skript.sh # oktal setzen: rwxr-xr-x chmod u+x skript.sh # Besitzer Ausführrecht GEBEN chmod go-w datei.txt # Gruppe + others Schreibrecht ENTZIEHEN chmod -R 644 /var/www/html # rekursiv auf ganzes Verzeichnis # Besitzer/Gruppe ändern (chown) chown anna datei.txt # Besitzer ändern chown anna:entwickler datei.txt # Besitzer UND Gruppe ändern chown -R www-data:www-data /var/www # rekursiv (z.B. Webroot) chgrp entwickler datei.txt # nur Gruppe ändern

sudo & sudoers

Mit sudo führt ein berechtigter Benutzer einzelne Befehle mit root-Rechten aus, ohne sich als root anzumelden. Berechtigungen werden in /etc/sudoers verwaltet – immer mit visudo bearbeiten (prüft die Syntax und verhindert Aussperren).

sudo apt update # einzelnen Befehl als root ausführen sudo -i # interaktive root-Shell starten sudo -u anna befehl # Befehl als anderer Benutzer ausführen # /etc/sudoers (mit visudo bearbeiten!) anna ALL=(ALL:ALL) ALL # anna darf alles als jeder Benutzer %sudo ALL=(ALL:ALL) ALL # Mitglieder der Gruppe sudo backup ALL=(root) NOPASSWD: /usr/bin/rsync # nur rsync, ohne Passwort

Spezielle Bits: SUID, SGID, Sticky

Drei Sonder-Bits erweitern das klassische Rechtemodell. Sie werden als vierte (führende) Oktalziffer angegeben.

BitOktalWirkungBeispiel
SUID4xxxProgramm läuft mit Rechten des Besitzers (oft root)/usr/bin/passwd
SGID2xxxAuf Verzeichnis: neue Dateien erben die Gruppegemeinsame Projektordner
Sticky1xxxNur Besitzer darf eigene Dateien löschen/tmp (1777)
chmod 4755 programm # SUID setzen -> rwsr-xr-x chmod 2775 projektordner # SGID setzen -> rwxrwsr-x chmod 1777 /tmp # Sticky Bit -> rwxrwxrwt # Alle SUID-Programme im System finden (Sicherheits-Audit): find / -perm -4000 -type f 2>/dev/null
Sicherheitshinweis: SUID-root-Programme sind ein beliebtes Ziel für Privilege Escalation. Prüfe regelmäßig mit find / -perm -4000, welche Dateien das SUID-Bit tragen, und entferne es, wo es nicht nötig ist.

Standardrechte neuer Dateien: umask

Welche Rechte eine neu erzeugte Datei erhält, bestimmt die umask. Sie ist eine Maske, deren Bits von den Maximalrechten abgezogen werden: Dateien starten bei 666 (rw für alle), Verzeichnisse bei 777. Übliche Vorgabe ist 022.

umaskNeue DateiNeues VerzeichnisCharakter
022644 (rw-r--r--)755 (rwxr-xr-x)Standard – alle dürfen lesen
027640 (rw-r-----)750 (rwxr-x---)others ausgesperrt (gehärtet)
077600 (rw-------)700 (rwx------)nur Besitzer (privat)
umask # aktuelle Maske anzeigen (z. B. 0022) umask 027 # für die aktuelle Sitzung setzen touch test.txt && ls -l test.txt # Ergebnis prüfen: -rw-r----- # Dauerhaft pro Benutzer: in ~/.bashrc bzw. ~/.profile eintragen echo "umask 027" >> ~/.bashrc
Linux

sudo & su

su – die Identität wechseln

Administrative Aufgaben brauchen root-Rechte. Da ein dauerhaftes Arbeiten als root riskant ist, wird man nur für die jeweilige Aufgabe zu root und arbeitet danach wieder als normaler Benutzer weiter. Mit su (substitute user) wechselt man die Identität – im Hintergrund startet eine neue Shell mit der UID/GID des Zielbenutzers. Voraussetzung ist die Kenntnis des entsprechenden Passworts.

su root # zu root wechseln (fragt das root-Passwort ab) su - anna # zu anna wechseln UND deren Login-Umgebung laden exit # zurück zur ursprünglichen Identität su root -c ps # nur EIN Programm als root ausführen, dann zurück

sudo – einzelne Befehle mit root-Rechten

Bei sudo (SuperUserDo) wird kein kompletter Identitätswechsel durchgeführt. Stattdessen führt ein berechtigter Benutzer einen einzelnen Befehl mit erweiterten Rechten aus – und gibt dabei das eigene Passwort ein, nicht das von root. Wer sudo nutzen darf, muss dafür berechtigt sein (auf Debian/Ubuntu: Mitglied der Gruppe sudo).

sudo mkdir /etc/KonfigNeu # einzelnen Befehl als root ausführen sudo -i # interaktive root-Shell starten sudo -u anna befehl # Befehl als Benutzer anna ausführen # Benutzer der Gruppe sudo hinzufügen (-a wichtig, sonst Überschreiben!) usermod -aG sudo user01
Drei sudo-Grundregeln (erscheinen beim ersten Aufruf): 1) Respektiere die Privatsphäre anderer. 2) Denke nach, bevor du tippst. 3) Mit großer Macht kommt große Verantwortung.

su vs. sudo im Vergleich

Eigenschaftsusudo
WirkungVollständiger Identitätswechsel (neue Shell)Einzelner Befehl mit root-Rechten
Abgefragtes PasswortDas des Zielbenutzers (root)Das eigene Passwort
Protokollierungkaumjeder Aufruf wird geloggt
Feinsteuerungalles oder nichtspro Benutzer/Befehl in /etc/sudoers

Die sudoers-Datei & visudo

Wer sudo nutzen darf und wofür, legt die Datei /etc/sudoers fest. Sie wird immer mit visudo bearbeitet – dieses Werkzeug prüft die Syntax vor dem Speichern und verhindert so, dass ein Tippfehler sudo unbrauchbar macht und dich aussperrt.

visudo # /etc/sudoers sicher bearbeiten (NIE direkt!) # Syntax: Benutzer Host=(als wem) Befehle anna ALL=(ALL:ALL) ALL # anna darf alles als jeder Benutzer %sudo ALL=(ALL:ALL) ALL # Mitglieder der GRUPPE sudo (% = Gruppe) backup ALL=(root) NOPASSWD: /usr/bin/rsync # nur rsync, ohne Passwort
Tipp: Eigene Regeln legt man besser als separate Datei unter /etc/sudoers.d/ ab (per visudo -f /etc/sudoers.d/meineregel) – so bleiben sie bei einem System-Update erhalten und die Hauptdatei unangetastet.

Troubleshooting: „user is not in the sudoers file“

Diese Meldung beim sudo-Aufruf bedeutet schlicht, dass der Benutzer keine sudo-Berechtigung hat. Prüfe zuerst die Gruppenmitgliedschaft – fehlt die Gruppe sudo, füge sie hinzu und melde dich neu an (Gruppen werden erst bei einer neuen Sitzung wirksam).

groups anna # in welchen Gruppen ist der Benutzer? usermod -aG sudo anna # zur Gruppe sudo hinzufügen # danach: abmelden und neu anmelden, dann erneut versuchen
Linux

systemd & Dienste

Was ist systemd?

systemd ist das moderne Init- und Service-Management-System nahezu aller aktuellen Distributionen (Ubuntu, Debian, RHEL, Fedora, openSUSE). Es löste die älteren Init-Systeme System V und Upstart ab. systemd startet als erster Prozess (PID 1) und verwaltet das Hochfahren, alle Dienste sowie deren Abhängigkeiten parallel. Gesteuert wird es über systemctl, die Logs liest man mit journalctl.

Zustandsdiagramm eines systemd-Dienstes: inactive, activating, active(running), deactivating und failed mit den Übergängen start, stop und restart
Abb. – Zustände eines systemd-Dienstes und die Übergänge durch start / stop / restart

Dienste steuern mit systemctl

# Status & Steuerung eines Dienstes (Unit) systemctl status nginx # Status, letzte Logzeilen, PID systemctl start nginx # Dienst starten systemctl stop nginx # Dienst stoppen systemctl restart nginx # neu starten systemctl reload nginx # Konfiguration neu laden (ohne Neustart) # Autostart beim Booten systemctl enable nginx # beim Systemstart automatisch starten systemctl disable nginx # Autostart deaktivieren systemctl enable --now nginx # aktivieren UND sofort starten systemctl is-enabled nginx # prüfen: enabled / disabled systemctl is-active nginx # prüfen: active / inactive
Tipp: start startet einen Dienst nur jetzt; enable sorgt für den Autostart nach dem nächsten Reboot. Beides auf einmal erledigt systemctl enable --now <dienst>.

Übersicht verschaffen

systemctl list-units --type=service # laufende Dienste systemctl list-units --type=service --all # auch inaktive systemctl list-unit-files --state=enabled # alle Autostart-Dienste systemctl --failed # fehlgeschlagene Units systemctl daemon-reload # nach Bearbeiten einer Unit-Datei

Unit-Typen

systemd verwaltet verschiedene Arten von Ressourcen als sogenannte Units. Ihre Definitionsdateien liegen in /etc/systemd/system/ (eigene) und /lib/systemd/system/ (Pakete).

EndungTypBeschreibung
.serviceServiceEin Dienst / Daemon (z. B. nginx, ssh)
.socketSocketNetzwerk-/IPC-Socket zur Dienst-Aktivierung
.timerTimerZeitgesteuerter Start (Cron-Ersatz)
.targetTargetGruppe von Units (ersetzt Runlevels)
.mountMountEinhängepunkt eines Dateisystems

Eigene Service-Unit

# Datei: /etc/systemd/system/meinapp.service [Unit] Description=Meine Anwendung After=network.target [Service] ExecStart=/usr/local/bin/meinapp Restart=on-failure User=appuser [Install] WantedBy=multi-user.target # Danach: systemctl daemon-reload systemctl enable --now meinapp

Targets & Runlevels

Targets sind die systemd-Entsprechung der alten Runlevels. Sie definieren den Systemzustand beim Booten.

systemd-TargetAlter RunlevelBedeutung
poweroff.target0System herunterfahren
rescue.target1Einzelbenutzer / Rettungsmodus
multi-user.target3Mehrbenutzer, ohne grafische Oberfläche
graphical.target5Mehrbenutzer mit grafischer Oberfläche
reboot.target6System neu starten
systemctl get-default # aktuelles Standard-Target systemctl set-default multi-user.target # Standard ändern systemctl isolate graphical.target # sofort wechseln

Logs lesen mit journalctl

systemd schreibt alle Logs in ein zentrales, binäres Journal. journalctl liest und filtert es komfortabel.

journalctl # gesamtes Journal (älteste zuerst) journalctl -e # ans Ende springen (neueste) journalctl -f # live verfolgen (wie tail -f) journalctl -u nginx # nur Logs eines Dienstes journalctl -u nginx --since today journalctl --since "2026-06-15 08:00" --until "2026-06-15 12:00" journalctl -b # Logs des aktuellen Bootvorgangs journalctl -b -1 # Logs des vorherigen Boots journalctl -p err # nur Fehler und schwerwiegender journalctl --disk-usage # Speicherbedarf des Journals journalctl --vacuum-time=2weeks # Logs älter als 2 Wochen löschen
Tipp: Für die Fehlersuche nach einem Absturz ist journalctl -b -1 -p err ideal: Es zeigt nur die Fehlermeldungen aus dem letzten Bootvorgang vor dem Neustart.

Timer statt Cron

# Datei: /etc/systemd/system/backup.timer [Unit] Description=Tägliches Backup um 02:00 [Timer] OnCalendar=*-*-* 02:00:00 Persistent=true [Install] WantedBy=timers.target # Aktivieren und alle Timer auflisten: systemctl enable --now backup.timer systemctl list-timers --all

Units anpassen ohne Original zu ändern: Drop-ins

Paket-Units in /lib/systemd/system/ sollte man nie direkt bearbeiten – ein Paket-Update überschreibt sie. Stattdessen legt man mit systemctl edit eine Override-Datei (Drop-in) an, die nur die geänderten Werte enthält.

systemctl edit nginx # legt /etc/systemd/system/nginx.service.d/override.conf an # Inhalt der override.conf – überschreibt gezielt einzelne Direktiven: [Service] Restart=always RestartSec=5 MemoryMax=512M # Wirksam machen: systemctl daemon-reload systemctl restart nginx systemctl cat nginx # zeigt Original + alle Drop-ins zusammengefügt
Tipp: systemctl cat <unit> zeigt die effektive, zusammengesetzte Konfiguration aus Original-Unit und allen Drop-ins – ideal, um zu verstehen, welcher Wert am Ende wirklich gilt.

Wichtige Restart-Direktiven

Wert von Restart=Neustart, wenn der Dienst…
nonie automatisch neu startet (Standard)
on-failuremit Fehler-Exit-Code, Signal oder Timeout endet
on-abnormaldurch Signal oder Timeout endet (nicht bei sauberem Exit)
alwaysaus jedem Grund endet – auch nach sauberem Beenden
Linux

Netzwerkkonfiguration

Hostname: /etc/hostname & hostnamectl

Der Hostname ist die innerhalb eines Netzwerks eindeutige Bezeichnung eines Rechners und erleichtert das Arbeiten bei Freigaben, Webseiten und beim Troubleshooting (Ping). Er steht in der Datei /etc/hostname. Der Name localhost wird nie als Hostname vergeben, da er systemseitig für die Loopback-Adressen im Netz 127.0.0.0/8 reserviert ist.

cat /etc/hostname # aktuell hinterlegten Hostnamen anzeigen hostname # Hostnamen ausgeben (Anzeige am Prompt) # Variante 1 – Datei direkt bearbeiten nano /etc/hostname # neuen Namen eintragen (eine Zeile) # Variante 2 – Inhalt per echo überschreiben echo deb-srv > /etc/hostname # > überschreibt den kompletten Inhalt # Variante 3 (empfohlen, systemd): set-hostname hostnamectl set-hostname deb-srv # setzt /etc/hostname + sofort aktiv

Bei den Varianten 1 und 2 muss die Änderung anschließend wirksam gemacht werden – per Neustart oder ohne Reboot:

hostname -F /etc/hostname # Datei neu einlesen exec bash # neue Shell-Instanz -> Prompt zeigt neuen Namen # alternativ: ab- und neu anmelden (logout)
Hinweis: Der am Prompt angezeigte Name spiegelt nicht zwingend den aktuellen Inhalt von /etc/hostname wider – er dient nur der Orientierung (z. B. um zu erkennen, ob noch eine Verbindung zu einem Remote-Gerät besteht). hostnamectl set-hostname ist die robusteste Methode, weil sie den Namen neu einliest und sofort aktiviert.

Namensauflösung & FQDN: /etc/hosts

Die Datei /etc/hosts ist eine Zuordnungstabelle von Hostnamen zu IP-Adressen und liefert die Namensauflösung, wenn kein DNS-Server verfügbar ist. Der Eintrag der Loopback-Zeile 2 (127.0.1.1) ist nötig, damit der eigene Hostname aufgelöst werden kann – diese Zeile muss stehen bleiben. Der FQDN (Fully Qualified Domain Name) identifiziert den Rechner eindeutig und besteht aus <Hostname>.<Domainname>; er wird ebenfalls in /etc/hosts hinterlegt (FQDN vor dem kurzen Hostnamen).

# Datei: /etc/hosts 1 127.0.0.1 localhost 2 127.0.1.1 debian.corp.example.com debian # <FQDN> <Hostname> (Zeile 2 muss bleiben!) 3 4 # The following lines are desirable for IPv6 capable hosts 5 ::1 localhost ip6-localhost ip6-loopback 6 ff02::1 ip6-allnodes 7 ff02::2 ip6-allrouters # Da 127.0.0.0/8 komplett auf die eigene Maschine zeigt, dürfen unter # Zeile 2 weitere Namen ergänzt werden (jeweils Adresse + Name).
hostname # nur den kurzen Hostnamen ausgeben hostname -f # den GESAMTEN FQDN ausgeben (Hostname.Domain) hostname -d # nur den Domainnamen ausgeben
Merke: Eine DNS-Struktur ist nötig, um die Zuordnung Hostname → IP netzwerkweit zu realisieren. Solange kein DNS-Server existiert, übernimmt /etc/hosts diese Aufgabe lokal. Hat eine Maschine mehrere Schnittstellen/Adressen, kann sie laut man hostname auch mehrere oder gar keine FQDNs haben.

Der ip-Befehl (iproute2)

Der ip-Befehl aus dem Paket iproute2 ist das moderne Standardwerkzeug für die Netzwerkkonfiguration. Er ersetzt die veralteten Befehle ifconfig, route und arp. Wichtig: Mit ip gesetzte Änderungen sind nicht persistent – nach einem Neustart sind sie weg. Für dauerhafte Konfiguration nutzt man netplan oder NetworkManager.

Alter BefehlModerner Ersatz (iproute2)
ifconfigip addr / ip link
routeip route
arpip neigh
netstatss
# Adressen & Interfaces anzeigen ip addr show # alle IP-Adressen (kurz: ip a) ip link show # Interfaces + Status (up/down) ip route show # Routing-Tabelle (kurz: ip r) ip neigh show # ARP-Cache (Nachbartabelle) # Temporär konfigurieren (nicht persistent!) ip addr add 192.168.1.50/24 dev eth0 # IP-Adresse zuweisen ip addr del 192.168.1.50/24 dev eth0 # IP entfernen ip link set eth0 up # Interface aktivieren ip link set eth0 down # Interface deaktivieren ip route add default via 192.168.1.1 # Default-Gateway setzen

Persistente Konfiguration: /etc/network/interfaces (Debian/ifupdown)

Auf klassischem Debian regelt die Datei /etc/network/interfaces die dauerhafte Konfiguration. Beim Systemstart bzw. Neustart des networking.service wird sie eingelesen. Mit auto <ifname> wird ein Interface beim Booten automatisch hochgefahren; iface ... inet static legt eine feste Adresse fest (statt static sorgt dhcp für den Bezug per DHCP-Lease).

# Datei: /etc/network/interfaces source /etc/network/interfaces.d/* # The loopback network interface (hier ist keine Änderung nötig) auto lo iface lo inet loopback # Primäre Netzwerkschnittstelle – statische IP auto eth0 iface eth0 inet static address 192.168.1.0 # IP-Adresse des Interfaces netmask 255.255.255.0 # alternativ in Zeile darüber: address 192.168.1.0/24 gateway 192.168.1.254 # Default-Gateway (ein Router darf KEINS setzen) dns-nameservers 192.168.1.2 # DNS-Server (mehrere durch Leerzeichen getrennt) dns-search corp.example.com # Suchdomäne(n) -> schreibt auch /etc/resolv.conf
systemctl restart networking # Konfiguration übernehmen systemctl status networking # fehlerfreien Neustart prüfen ip address # kurz: ip a – IP-Adressen kontrollieren
Hinweis: Die Subnetzmaske wird entweder als CIDR-Suffix am address (z. B. 192.168.1.0/24) oder über die Zeile netmask angegeben – nicht beides gleichzeitig. ifconfig zum Prüfen funktioniert nur, wenn das Paket net-tools installiert ist; auf neueren Distributionen ist stattdessen ip a Standard.

Persistente Konfiguration: netplan (Ubuntu)

Aktuelle Ubuntu-Server verwenden netplan. Die Konfiguration erfolgt in YAML-Dateien unter /etc/netplan/ und wird mit netplan apply aktiviert.

# Datei: /etc/netplan/01-netcfg.yaml (YAML – Einrückung mit Leerzeichen!) network: version: 2 renderer: networkd ethernets: eth0: dhcp4: false addresses: - 192.168.1.50/24 routes: - to: default via: 192.168.1.1 nameservers: addresses: [8.8.8.8, 1.1.1.1] # Konfiguration testen und anwenden: netplan try # mit automatischem Rollback nach 120 s netplan apply # endgültig aktivieren
Tipp: YAML ist sehr empfindlich gegenüber Einrückung – verwende ausschließlich Leerzeichen, niemals Tabs. Mit netplan try wird die Konfiguration nach 120 Sekunden automatisch zurückgerollt, falls du dich aus einer SSH-Sitzung aussperrst.

Persistente Konfiguration: nmcli (RHEL/Fedora)

Auf RHEL, Rocky Linux und Fedora steuert der NetworkManager die Netzwerkverbindungen. Über die Kommandozeile geschieht das mit nmcli.

nmcli device status # Geräte und Verbindungsstatus nmcli connection show # alle gespeicherten Verbindungen # Statische IP für eine Verbindung setzen nmcli con mod "eth0" ipv4.addresses 192.168.1.50/24 nmcli con mod "eth0" ipv4.gateway 192.168.1.1 nmcli con mod "eth0" ipv4.dns "8.8.8.8 1.1.1.1" nmcli con mod "eth0" ipv4.method manual # DHCP deaktivieren nmcli con up "eth0" # Änderungen aktivieren

DNS – Namensauflösung

Die DNS-Server stehen klassisch in /etc/resolv.conf. Auf modernen Systemen wird diese Datei meist automatisch von systemd-resolved oder NetworkManager verwaltet – manuelle Einträge nicht direkt dort vornehmen, sondern über netplan/nmcli.

# Aufbau von /etc/resolv.conf nameserver 8.8.8.8 nameserver 1.1.1.1 search firma.local # DNS-Auflösung testen dig example.com # ausführliche DNS-Abfrage nslookup example.com # einfache Abfrage resolvectl status # systemd-resolved Status

Offene Ports & Verbindungen: ss

ss -tulpn # TCP+UDP, lauschend, mit Prozess & Portnummer ss -t state established # nur bestehende TCP-Verbindungen ss -s # zusammenfassende Statistik # t=TCP u=UDP l=listening p=Prozess n=numerisch (keine Namen)

Firewall: ufw & firewalld

ToolDistributionCharakter
ufwUbuntu / DebianUncomplicated Firewall – einfaches Frontend für nftables
firewalldRHEL / FedoraZonenbasiert, dynamisch
# ufw (Ubuntu/Debian) ufw enable # Firewall aktivieren ufw allow 22/tcp # SSH erlauben ufw allow 80,443/tcp # HTTP + HTTPS erlauben ufw status verbose # Regeln anzeigen # firewalld (RHEL/Fedora) firewall-cmd --add-service=https --permanent firewall-cmd --add-port=8080/tcp --permanent firewall-cmd --reload # Änderungen aktivieren firewall-cmd --list-all # aktive Zone & Regeln
Achtung: Bevor du eine Firewall über eine SSH-Verbindung aktivierst, erlaube zuerst Port 22 (ufw allow 22/tcp). Sonst sperrst du dich selbst aus.

Praxis: Verbindungsprobleme systematisch eingrenzen

Bei „Das Internet geht nicht“ arbeitet man sich am besten Schicht für Schicht von unten nach oben durch – vom eigenen Interface über das Gateway bis zur DNS-Auflösung.

# 1. Hat das Interface eine IP und ist es UP? ip addr show eth0 # 2. Erreiche ich das Gateway im lokalen Netz? ip route show # Gateway-Adresse ablesen ping -c 3 192.168.1.1 # Gateway anpingen # 3. Erreiche ich das Internet per IP (ohne DNS)? ping -c 3 1.1.1.1 # klappt das, aber Domains nicht -> DNS-Problem # 4. Funktioniert die Namensauflösung? dig +short example.com # liefert eine IP zurück? resolvectl status # welche DNS-Server werden genutzt? # 5. Weg zum Ziel verfolgen (wo bricht es ab?) traceroute example.com mtr example.com # kombiniert ping + traceroute, live
SymptomWahrscheinliche Ursache
Keine IP-Adresse am InterfaceDHCP / Kabel / Interface down
Gateway nicht erreichbar (ping fehlt)lokales Netz / falsche Route / Firewall
IP geht (1.1.1.1), Domains nichtDNS falsch oder nicht erreichbar
Alles geht, aber nur ein Dienst nichtPort blockiert / Dienst down
Linux

Linux als Router

Voraussetzung: mehrere Schnittstellen

Damit ein Linux-System als Router arbeitet, müssen mindestens zwei Netzwerkschnittstellen in unterschiedlichen Netzen vorhanden sein. Jede Schnittstelle stellt das Gateway ihres Netzes dar und verbindet die Netze miteinander. Die Konfiguration ähnelt der eines Clients (siehe Netzwerkkonfiguration), mit einem wichtigen Unterschied: Auf dem Router wird je Interface nur eine IP-Adresse vergeben – kein gateway-Eintrag, denn der Router ist das Gateway.

Adress-Konvention (Lehrgang): Die ersten Adressen (10–20) eines Netzes sind in der Regel für Server reserviert; als Gateway-Adresse dient stets die letzte verfügbare IP des Netzes. Beispiel: im Netz 192.168.1.0/24 ist 192.168.1.254 das Gateway.
# Datei: /etc/network/interfaces (Router mit zwei Netzen) auto lo iface lo inet loopback # Netz 1 – Router ist hier Gateway, daher KEIN gateway-Eintrag auto eth0 iface eth0 inet static address 192.168.1.254/24 # Netz 2 auto eth1 iface eth1 inet static address 172.16.32.254/24 # Übernehmen: # systemctl restart networking

IP-Forwarding aktivieren

Standardmäßig leitet ein Linux-System keine Pakete zwischen seinen Interfaces weiter. Das Routing (die Paketweiterleitung) wird über den Kernel-Parameter net.ipv4.ip_forward aktiviert. Dauerhaft geschieht das in der Datei /etc/sysctl.conf, indem die entsprechende Zeile einkommentiert wird (führendes # entfernen).

# Datei: /etc/sysctl.conf -> Zeile einkommentieren: net.ipv4.ip_forward=1 # aktiviert die IPv4-Paketweiterleitung # Änderung an den Kernel übergeben (sysctl.conf neu einlesen): sysctl -p # Schnell zur Laufzeit prüfen/setzen (nicht persistent): sysctl net.ipv4.ip_forward # aktuellen Wert anzeigen sysctl -w net.ipv4.ip_forward=1 # temporär aktivieren
Wichtig: Erst net.ipv4.ip_forward=1 und ein sysctl -p machen das Linux-System tatsächlich zum Router. Der reine Eintrag in der Datei wirkt erst nach dem nächsten Reboot, wenn er nicht mit sysctl -p sofort übernommen wird.

Routing prüfen

Welche Clients/Server über die Interfaces direkt angeschlossen sind und welche Routen der Kernel kennt, zeigen folgende Kommandos:

ip neigh show # direkt angeschlossene Nachbarn (ARP-Tabelle) ip route # Routing-Tabelle – kurz: ip r

Die direkt verbundenen Netze trägt der Kernel automatisch ein (Kennung proto kernel ... scope link). Nicht direkt erreichbare Netze müssen als statische Route ergänzt werden.

Statische Routen & Default-Route

Persistente Routen werden in /etc/network/interfaces über die post-up-Direktive eingetragen – sie wird ausgeführt, nachdem das Interface hochgefahren wurde. Eine Default-Route (Netz-ID 0.0.0.0/0) fängt alle Pakete mit unbekanntem Ziel und schickt sie in eine bestimmte Richtung (meist Richtung Internet). Greifen mehrere Routen, gewinnt der Eintrag mit der längsten übereinstimmenden Subnetzmaske („longest prefix match").

# in /etc/network/interfaces unter dem jeweiligen iface-Block: post-up ip route add <TargetNetID>/<Prefix> via <GatewayIP> # Beispiel: entferntes Netz über einen Nachbar-Router erreichen post-up ip route add 192.168.200.0/24 via 192.168.1.254 # Default-Route (alle unbekannten Ziele): post-up ip route add default via <GatewayIP> # Änderungen aktivieren: # systemctl restart networking

DHCP-Relay-Agent auf dem Router

DHCP-DISCOVER-Pakete sind Broadcasts und werden von Routern nicht über Subnetzgrenzen weitergeleitet. Steht der DHCP-Server in einem anderen Netz als die Clients, übernimmt der Relay-Agent auf dem Router die Vermittlung: Er lauscht auf den zugewiesenen Interfaces, nimmt die Broadcasts entgegen und leitet sie gezielt (Unicast) an den entfernten Server weiter. Die Konfiguration des Relay-Agents ist im Abschnitt DHCP-Server beschrieben.

Linux

DHCP-Server (isc-dhcp-server)

Was DHCP leistet

Das DHCP (Dynamic Host Configuration Protocol) verteilt die komplette IP-Konfiguration automatisch an die Clients im Netz: IP-Adresse, Subnetzmaske, Gateway, DNS-Server, Domäne und die Leasezeit (Gültigkeitsdauer der Zuweisung). Auf Debian/Ubuntu liefert das Paket isc-dhcp-server den Server. Wichtig: Der Server selbst braucht eine statische IP-Adresse – ein DHCP-Server, der sich seine Adresse selbst per DHCP holt, wäre widersinnig.

Zwei zentrale Dateien

DateiFunktion
/etc/default/isc-dhcp-serverLegt fest, auf welchen Interfaces der Server lauscht (INTERFACES="eth0 eth1")
/etc/dhcp/dhcpd.confLegt fest, was verteilt wird (Subnetze, Pools, Optionen)
# Datei: /etc/default/isc-dhcp-server # Interfaces, auf denen der DHCP-Server Anfragen entgegennimmt INTERFACESv4="eth0 eth1"

Aufbau der dhcpd.conf

Die dhcpd.conf besteht aus globalen Optionen (gelten für alle Subnetze) und einem oder mehreren subnet-Blöcken. Ein subnet-Block ohne range vergibt keine Adressen – er dient nur als Topologie-Hilfe, damit der Server das Netz kennt. Erst die Direktive range definiert den vergebbaren Adress-Pool. Bereichsspezifische Werte wie option routers, DNS oder die Leasezeit überschreiben die globalen Vorgaben für dieses Subnetz.

# Datei: /etc/dhcp/dhcpd.conf # --- Globale Optionen (gelten für alle Subnetze) --- option domain-name "beispiel.intern"; option domain-name-servers 192.168.1.2, 192.168.1.3; default-lease-time 3600; # Leasezeit in Sekunden (Standard) max-lease-time 7200; # maximale Leasezeit # --- Subnetz mit vergebbarem Pool --- subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.10 192.168.1.200; # Pool: .10 bis .200 option routers 192.168.1.254; # Gateway für dieses Subnetz option domain-name-servers 192.168.1.2; default-lease-time 3600; }
Hinweis: Ein subnet-Block ohne range vergibt nichts – er teilt dem Server lediglich mit, dass dieses Netz existiert (z. B. das Netz, in dem der Server selbst hängt). Nur wo ein range steht, werden tatsächlich Adressen verteilt.

authoritative & Serverbereich vs. Clientbereich

Mit der Direktive authoritative; erklärt sich der Server als die offizielle, maßgebliche Instanz für die lokalen Netze – er darf dann fehlerhafte Anfragen verbindlich ablehnen (DHCPNAK). In der Vorlage ist die Zeile auskommentiert und sollte für den produktiven Betrieb aktiviert werden. Bei der Topologie unterscheidet man zwei Fälle:

BegriffWann nötig
ServerbereichDer Server steht dediziert allein in einem eigenen Netz und bedient nur Clients anderer Netze. Dann braucht sein eigenes Subnetz einen subnet-Block ohne range (keine vergebbaren Clients), damit der Server die Topologie kennt.
ClientbereichDer Server ist selbst Host in einem Subnetz, in dem er auch Clients bedient. Dann genügt ein gemeinsamer Bereich für Server und Clients (subnet mit range).
# Datei: /etc/dhcp/dhcpd.conf (Auszug Kopfbereich) authoritative; # Server ist verbindliche Instanz (Vorlage: auskommentiert) # BEREICH 1 – Clientbereich (mit range -> verteilt Adressen) subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.10 192.168.1.200; # mehrere Bereiche möglich option routers 192.168.1.254; option domain-name-servers 192.168.1.2; option domain-name "its.schule"; # FQDN als DNS ist ebenfalls erlaubt default-lease-time 3600; # oder global in den Serveroptionen } # BEREICH 2 – Serverbereich (OHNE range -> nur Topologie, keine Vergabe) subnet 10.254.239.0 netmask 255.255.255.0 { }

Feste Adressen: host-Reservierungen

Soll ein bestimmter Client immer dieselbe IP-Adresse erhalten (z. B. Drucker, Server), bindet man die Adresse über einen host-Block fest an seine MAC-Adresse. Die reservierte Adresse sollte außerhalb des dynamischen range liegen, damit es keine Doppelvergabe gibt.

# Datei: /etc/dhcp/dhcpd.conf host drucker01 { hardware ethernet 00:1a:2b:3c:4d:5e; # MAC-Adresse des Clients fixed-address 192.168.1.5; # immer diese IP (außerhalb der range) }

Dienst steuern

systemctl restart isc-dhcp-server # nach jeder Konfig-Änderung systemctl status isc-dhcp-server # Zustand prüfen systemctl enable isc-dhcp-server # Autostart aktivieren
Tipp: Im status bedeutet active (running), dass der Server läuft. Erscheint stattdessen failed oder exit-code, steckt fast immer ein Syntaxfehler in der dhcpd.conf – die genaue Zeile findest du mit journalctl -u isc-dhcp-server -e.

DHCP-Relay-Agent (isc-dhcp-relay)

DHCP-Anfragen sind Broadcasts – und Broadcasts werden von Routern nicht über Subnetzgrenzen weitergeleitet. Steht der DHCP-Server in einem anderen Netz als die Clients, übernimmt der Relay-Agent (Paket isc-dhcp-relay) die Vermittlung: Er nimmt die Broadcasts lokal entgegen und leitet sie gezielt (Unicast) an den entfernten Server weiter.

# Datei: /etc/default/isc-dhcp-relay SERVERS="192.168.1.1" # Adresse des entfernten DHCP-Servers INTERFACES="eth0 eth1" # Interfaces, an denen der Relay lauscht

Client auf DHCP umstellen

Auf der Client-Seite (klassisches Debian/ifupdown) genügt ein Eintrag in /etc/network/interfaces:

# Datei: /etc/network/interfaces iface eth0 inet dhcp # Netzwerkdienst neu starten, damit der Client eine Adresse anfordert: systemctl restart networking
Linux

SSH-Server (OpenSSH)

Was ist SSH?

SSH (Secure Shell) ermöglicht die verschlüsselte Fernverwaltung eines Systems über das Netzwerk. Es läuft standardmäßig über TCP-Port 22 und löste die unverschlüsselten Vorgänger telnet und rsh ab, bei denen Passwörter im Klartext übertragen wurden. Die freie Referenzimplementierung ist OpenSSH.

WerkzeugFunktion
sshVerbindung zu einem entfernten Host aufbauen
sshdDer Server-Dienst (SSH-Daemon)
scp / sftpDateien verschlüsselt übertragen
ssh-keygenSchlüsselpaar erzeugen
ssh-agent / ssh-addPrivate Schlüssel im Speicher verwalten
ssh-copy-idÖffentlichen Schlüssel zum Server kopieren

Pakete

PaketInhalt
openssh-clientClient-Werkzeuge (ssh, scp, …) – um sich zu verbinden
openssh-serverDer Dienst sshd; nach der Installation lauscht das System auf Port 22
apt install openssh-client # auf dem PC, von dem aus man sich verbindet apt install openssh-server # auf dem Zielsystem, das verwaltet werden soll systemctl status sshd # nach der Installation prüfen, ob er läuft

Server konfigurieren: sshd_config

Das Verhalten des Servers steuert die Datei /etc/ssh/sshd_config. Nach jeder Änderung muss der Dienst neu gestartet werden: systemctl restart sshd.

DirektiveBedeutung
PermitRootLoginno = sicher (kein Root-Login); prohibit-password = root nur per Schlüssel
PubkeyAuthentication yesAnmeldung per Schlüsselpaar erlauben
MaxAuthTriesMaximale Anzahl Anmeldeversuche pro Verbindung
LoginGraceTimeZeitfenster, in dem die Anmeldung abgeschlossen sein muss
AllowGroups <gruppe>Nur Mitglieder dieser Gruppe dürfen sich anmelden
AuthorizedKeysFile .ssh/authorized_keysPfad zur Liste der erlaubten öffentlichen Schlüssel
# Auszug aus /etc/ssh/sshd_config (gehärtet) PermitRootLogin no PubkeyAuthentication yes MaxAuthTries 3 LoginGraceTime 30 AllowGroups sshgroup # Nach jeder Änderung: systemctl restart sshd

Härtung per Gruppe

Eine bewährte Methode: nur eine bestimmte Gruppe darf sich überhaupt per SSH anmelden. Wer nicht in der Gruppe ist, wird abgewiesen – unabhängig von einem gültigen Passwort.

groupadd sshgroup # Gruppe anlegen usermod -aG sshgroup anna # Benutzer zur Gruppe hinzufügen (-a wichtig!) # In /etc/ssh/sshd_config: AllowGroups sshgroup # danach: systemctl restart sshd

Verbindung aufbauen & Host-Fingerprint

Eine Verbindung startest du mit ssh benutzer@host. Beim ersten Connect zeigt der Client den Host-Fingerprint des Servers. Bestätigst du mit yes, wird er in ~/.ssh/known_hosts gespeichert. Ändert sich der Fingerprint später unerwartet, warnt SSH eindringlich – das kann auf einen Man-in-the-Middle-Angriff hindeuten (oder schlicht eine Neuinstallation des Servers).

ssh anna@192.168.1.50 # Verbindung als Benutzer anna ssh -p 2222 anna@host # abweichenden Port verwenden ssh-copy-id anna@host # eigenen öffentlichen Schlüssel hinterlegen # Erster Connect zeigt den Fingerprint: # The authenticity of host '...' can't be established. # ED25519 key fingerprint is SHA256:... # Are you sure you want to continue connecting (yes/no)?

Verbindung von Windows: PuTTY

Linux- und macOS-Systeme bringen den ssh-Client mit. Unter Windows nutzt man entweder den seit Windows 10 mitgelieferten OpenSSH-Client (ssh in PowerShell) oder das verbreitete grafische Programm PuTTY: Dort trägt man Hostnamen bzw. IP und Port 22 ein und stellt die Verbindung her. Auch PuTTY zeigt beim ersten Connect den Host-Fingerprint zur Bestätigung an.

Troubleshooting: Anmeldung schlägt fehl

Wurde der Zugriff per AllowGroups auf eine Gruppe beschränkt, werden Benutzer abgewiesen, die nicht Mitglied sind – selbst mit korrektem Passwort. Prüfe daher zuerst die Gruppenzugehörigkeit; Logs liefert journalctl.

groups anna # ist anna in der erlaubten Gruppe (z. B. sshgroup)? usermod -aG sshgroup anna # ggf. hinzufügen (danach neu anmelden) journalctl -u sshd -e # Fehlermeldungen des SSH-Dienstes ansehen
Firewall nicht vergessen: Damit Verbindungen ankommen, muss Port 22 in der Firewall freigegeben sein – siehe Abschnitt Netzwerkkonfiguration (ufw allow 22/tcp bzw. firewall-cmd --add-service=ssh --permanent). Aktivierst du eine Firewall über eine SSH-Sitzung, gib Port 22 zuerst frei, sonst sperrst du dich aus.
Linux

Paketmanager

Zwei Welten: DEB und RPM

Linux-Software wird in Paketen verteilt. Es gibt zwei große Paketformat-Familien. Jede hat ein Low-Level-Werkzeug (einzelne Pakete, keine Abhängigkeitsauflösung) und einen High-Level-Manager (Repositories + automatische Abhängigkeiten).

FamilieFormatDistributionenLow-LevelHigh-Level
Debian.debDebian, Ubuntu, Mintdpkgapt
Red Hat.rpmRHEL, Fedora, Rocky, AlmaLinuxrpmdnf (früher yum)

Der Debian-Werkzeug-Stapel

Auf Debian/Ubuntu bauen die Werkzeuge aufeinander auf. Ganz unten steht das Grundprogramm dpkg, darauf setzt apt auf (das die Repositories und Abhängigkeiten verwaltet), und ganz oben bedienen Menschen es über Frontends.

EbeneWerkzeugAufgabe
Frontendapt-get, aptitudeBedienung (Skripte bzw. textbasiertes Menü)
PaketverwaltungaptRepositories & automatische Abhängigkeiten
GrundprogrammdpkgInstalliert einzelne .deb-Dateien (ohne Auflösung)
apt vs. apt-get: apt ist das modernere, für Menschen gedachte Kommando (mit Fortschrittsanzeige und Farbe); apt-get ist das ältere, stabile Kommando für Skripte. Für die tägliche Arbeit auf der Kommandozeile nimmt man apt.

apt – Debian & Ubuntu

apt update # Paketlisten aktualisieren (zuerst!) apt upgrade # installierte Pakete aktualisieren apt full-upgrade # Upgrade inkl. Entfernen von Konflikten apt dist-upgrade # wie full-upgrade, inkl. Abhängigkeitsänderungen apt install nginx # Paket installieren apt remove nginx # Paket entfernen (Konfig bleibt) apt purge nginx # Paket inkl. Konfiguration entfernen apt search webserver # in Repositories suchen apt show nginx # Paketinformationen anzeigen apt list --installed # installierte Pakete auflisten apt autoremove # nicht mehr benötigte Abhängigkeiten löschen
Tipp: Führe vor jeder Installation apt update aus. Dieser Befehl lädt nur die aktuellen Paketlisten herunter – ohne ihn installiert apt möglicherweise veraltete Versionen oder findet ein Paket gar nicht.

dpkg – einzelne .deb-Dateien

dpkg -i paket.deb # lokale .deb-Datei installieren dpkg -r paket # Paket entfernen dpkg -l # alle installierten Pakete auflisten dpkg -L nginx # Dateien eines Pakets anzeigen dpkg -S /usr/sbin/nginx # herausfinden, welches Paket eine Datei stellt # Nach dpkg -i fehlende Abhängigkeiten nachholen: apt install -f

dnf – RHEL & Fedora

dnf check-update # auf Updates prüfen dnf upgrade # alle Pakete aktualisieren dnf install httpd # Paket installieren dnf remove httpd # Paket entfernen dnf search webserver # in Repositories suchen dnf info httpd # Paketinformationen dnf list installed # installierte Pakete dnf autoremove # verwaiste Abhängigkeiten entfernen dnf history # Transaktionsverlauf (rückgängig machbar!)
Tipp: Anders als bei apt kann dnf history undo <ID> eine komplette Installations- oder Update-Transaktion rückgängig machen – sehr nützlich, wenn ein Update Probleme verursacht.

rpm – einzelne .rpm-Dateien

rpm -i paket.rpm # lokale .rpm-Datei installieren rpm -e paket # Paket entfernen (erase) rpm -qa # alle installierten Pakete (query all) rpm -ql httpd # Dateien eines Pakets auflisten rpm -qf /usr/sbin/httpd # welches Paket stellt diese Datei?

Befehls-Vergleich apt ↔ dnf

Aufgabeapt (Debian/Ubuntu)dnf (RHEL/Fedora)
Paketlisten aktualisierenapt update(automatisch)
System aktualisierenapt upgradednf upgrade
Paket installierenapt install <p>dnf install <p>
Paket entfernenapt remove <p>dnf remove <p>
Suchenapt search <w>dnf search <w>
Infos anzeigenapt show <p>dnf info <p>
Verwaiste entfernenapt autoremovednf autoremove

Repositories verwalten

Pakete kommen aus Repositories (Paketquellen). Diese sind in Konfigurationsdateien hinterlegt.

# Debian/Ubuntu – Quellen liegen in: # /etc/apt/sources.list und /etc/apt/sources.list.d/*.list (bzw. *.sources) add-apt-repository ppa:name/ppa # PPA hinzufügen (Ubuntu) apt update # neue Quelle einlesen # RHEL/Fedora – Quellen liegen in: # /etc/yum.repos.d/*.repo dnf config-manager --add-repo URL # Repository hinzufügen dnf repolist # aktivierte Repositories anzeigen
Sicherheitshinweis: Füge nur vertrauenswürdige Repositories hinzu und prüfe deren GPG-Signaturschlüssel. Ein bösartiges Repository kann beliebige Software mit root-Rechten auf dein System bringen.

Quellen abseits des Internets (offline / Schleusenrechner)

In abgeschotteten Umgebungen ohne direkten Internetzugang trägt man die Pakete aus anderen Medien in /etc/apt/sources.list ein – etwa von einem FTP-/HTTP-Server, einer CD/DVD oder einem lokalen Verzeichnis. Eine Zeile beginnt mit deb, gefolgt von der Quelle. Nach jeder Änderung folgt apt update, damit die neue Quelle eingelesen wird.

# FTP-Server als Quelle deb ftp://ftp.debian.org/debian stable main # CD/DVD einbinden (trägt sich automatisch in sources.list ein) apt-cdrom add # Lokale Paketquelle (trusted=yes umgeht die Signaturprüfung – mit Bedacht!) deb [trusted=yes] file:/pfad/zur/freigabe main deb [trusted=yes] http://192.168.1.1/packages /
Hinweis: [trusted=yes] schaltet die GPG-Signaturprüfung für diese Quelle ab. Das ist für eigene, kontrollierte lokale Repositories praktisch, sollte aber niemals für fremde Internetquellen verwendet werden.

Pakete festhalten & Cache aufräumen

Manchmal soll ein Paket bewusst nicht mit aktualisiert werden (z. B. eine bestimmte Kernel- oder Datenbankversion). Dafür lässt es sich „halten“ (hold / lock).

# Debian/Ubuntu – Paket von Updates ausnehmen apt-mark hold nginx # Version einfrieren apt-mark unhold nginx # wieder freigeben apt-mark showhold # alle gehaltenen Pakete anzeigen apt clean # heruntergeladene .deb aus dem Cache löschen # RHEL/Fedora – per Plugin versionlock dnf versionlock add nginx # Version festnageln dnf versionlock list dnf clean all # Metadaten- und Paket-Cache leeren

Distributionsunabhängige Formate

Neben den klassischen Paketmanagern haben sich (Stand 2026) drei distributionsübergreifende Formate etabliert. Sie liefern die Abhängigkeiten gebündelt mit und laufen sandboxed.

FormatHerkunftCharakter
FlatpakFreedesktop / FlathubDesktop-Apps, sandboxed, große Verbreitung
SnapCanonical (Ubuntu)Desktop + Server, mit auto-Update
AppImageCommunityEinzeldatei, keine Installation nötig
# Flatpak flatpak install flathub org.gimp.GIMP flatpak list flatpak update # Snap snap install vlc snap list snap refresh # alle Snaps aktualisieren
Tipp: Universelle Formate lösen das „Dependency Hell“-Problem, brauchen aber mehr Speicher (jede App bringt ihre Bibliotheken mit). Für systemnahe Server-Software bleiben apt/dnf erste Wahl; für aktuelle Desktop-Anwendungen sind Flatpak/Snap oft praktischer.
Linux

Wichtige Konfigurationsdateien

Alles ist eine Textdatei

Unter Linux gibt es keine Registry. Fast jede Einstellung steht in einer Textdatei unter /etc und wird im Terminal mit einem Editor wie nano oder vim geändert.

Wichtige Konfigurationsdateien unter /etc nach Bereichen
Abb. – Die wichtigsten Dateien unter /etc, nach Aufgabe gruppiert

Was steht wo?

DateiInhalt
/etc/hostnameName des Rechners
/etc/hostsfeste Namensauflösung, wird vor DNS gefragt
/etc/resolv.confDNS-Server (oft automatisch von systemd-resolved verwaltet)
/etc/fstabwelche Partitionen beim Start wo eingehängt werden
/etc/passwd, /etc/shadowBenutzerkonten und Passwort-Hashes
/etc/groupGruppen und ihre Mitglieder
/etc/sudoerswer was mit sudo darf – nur mit visudo bearbeiten
/etc/ssh/sshd_configEinstellungen des SSH-Servers
/etc/netplan/*.yamlNetzwerk unter Ubuntu
/etc/apt/sources.list.d/Paketquellen (Debian/Ubuntu)
/etc/crontab, /etc/cron.d/systemweite Cronjobs

Sicher ändern – Schritt für Schritt

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak # 1. Sicherung anlegen sudo nano /etc/ssh/sshd_config # 2. bearbeiten (Strg+O speichern, Strg+X beenden) sudo sshd -t # 3. Syntax prüfen (viele Dienste haben so einen Test) sudo systemctl reload ssh # 4. Dienst neu laden diff /etc/ssh/sshd_config.bak /etc/ssh/sshd_config # 5. Änderungen nachvollziehen
Drop-in-Verzeichnisse nutzen: Viele Dienste lesen zusätzlich Ordner wie /etc/ssh/sshd_config.d/ oder /etc/sudoers.d/. Eigene Einstellungen dort als eigene Datei ablegen – dann überschreibt ein Paket-Update sie nicht.

Benutzerspezifische Einstellungen liegen im Home-Verzeichnis als versteckte Dateien, z. B. ~/.bashrc (Aliase, Prompt) oder ~/.ssh/config (SSH-Verbindungen). Anzeigen mit ls -a.

Linux

Logfiles auswerten

Woher kommen die Logs?

Dienste schreiben über journald und rsyslog in Journal und /var/log
Abb. – journald sammelt alles, rsyslog schreibt zusätzlich klassische Textdateien
  • systemd-journald sammelt Meldungen von Kernel und Diensten in einem binären Journal → lesen mit journalctl (siehe systemd).
  • rsyslog schreibt Meldungen zusätzlich als Text nach /var/log → lesen mit less, tail, grep.
  • Viele Anwendungen (Webserver, Datenbanken) schreiben eigene Logs in Unterordner von /var/log.

Die wichtigsten Befehle

tail -f /var/log/syslog # live mitlesen (Strg+C beendet) tail -n 50 /var/log/auth.log # die letzten 50 Zeilen grep -i "failed" /var/log/auth.log # fehlgeschlagene Anmeldungen suchen grep -c "error" /var/log/syslog # Fehler zählen less +G /var/log/syslog # im Pager öffnen, ans Ende springen zgrep "error" /var/log/syslog.2.gz # in alten, gepackten Logs suchen journalctl -u nginx --since "1 hour ago" # Logs eines Dienstes der letzten Stunde journalctl -p err -b # nur Fehler seit dem letzten Boot journalctl -k # nur Kernel-Meldungen (wie dmesg)

Logrotation

Damit Logs die Platte nicht füllen, rotiert logrotate sie regelmäßig: syslog wird zu syslog.1, ältere Dateien werden gepackt (.gz) und nach einiger Zeit gelöscht. Die Regeln stehen in /etc/logrotate.conf und /etc/logrotate.d/.

Systematisch vorgehen: Zeitpunkt des Fehlers bestimmen → im passenden Log genau dieses Zeitfenster ansehen → nach error, fail, denied filtern → die erste Fehlermeldung ist meist die Ursache, alle weiteren sind Folgefehler.
Linux

Cronjobs – Aufgaben automatisieren

Was ist cron?

cron ist ein Dienst, der Befehle und Skripte zeitgesteuert ausführt – z. B. nächtliche Backups, Bereinigungen oder Berichte. Jeder Benutzer hat seine eigene Tabelle, die crontab.

Die fünf Zeitfelder eines Cronjobs mit Beispielen
Abb. – Minute, Stunde, Tag, Monat, Wochentag – und dann der Befehl

crontab bearbeiten

crontab -e # eigene crontab bearbeiten crontab -l # eigene crontab anzeigen sudo crontab -u max -l # crontab eines anderen Benutzers anzeigen crontab -r # ACHTUNG: löscht die komplette crontab ohne Nachfrage

Sonderzeichen

ZeichenBedeutungBeispiel
*jeder Wert* * * * * = jede Minute
,Liste0 8,12,18 * * * = um 8, 12 und 18 Uhr
-Bereich0 9 * * 1-5 = werktags um 9 Uhr
/Schrittweite*/10 * * * * = alle 10 Minuten

Typische Stolperfallen

  • Pfade: cron hat eine minimale PATH-Variable. Befehle und Skripte immer mit vollem Pfad angeben.
  • Ausgabe: Ohne Umleitung landet die Ausgabe als Mail im Nirgendwo. Besser protokollieren: … >> /var/log/backup.log 2>&1
  • Rechte: Das Skript muss ausführbar sein (chmod +x).
  • Prüfen: Ausführungen stehen im Log: grep CRON /var/log/syslog bzw. journalctl -u cron.
# Beispiel-crontab: werktags 02:30 Backup, Ausgabe ins Log 30 2 * * 1-5 /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Alternative: Moderne Systeme können auch systemd-Timer nutzen – mit besserem Logging und der Option, verpasste Läufe nachzuholen (Persistent=true).
Linux

Bash-Scripting – Grundlagen

Aufbau eines Skripts

Kommentiertes Bash-Backup-Skript mit Variablen, Bedingung und Schleife
Abb. – Ein vollständiges kleines Backup-Skript mit allen Grundbausteinen
nano backup.sh # Skript schreiben chmod +x backup.sh # ausführbar machen ./backup.sh # starten bash -x backup.sh # Debug-Modus: zeigt jeden Befehl vor der Ausführung

Variablen & Parameter

NAME="Server01" # zuweisen – KEINE Leerzeichen um das = echo "Host: $NAME" # verwenden, immer in "Anführungszeichen" HEUTE=$(date +%F) # Ausgabe eines Befehls speichern → 2026-10-22 echo "$0" # Name des Skripts echo "$1 $2" # erster und zweiter Parameter: ./skript.sh a b echo "$#" # Anzahl der Parameter echo "$?" # Rückgabewert des letzten Befehls (0 = OK)

Bedingungen

if [ -f /etc/nginx/nginx.conf ]; then echo "nginx ist installiert" elif [ -d /etc/apache2 ]; then echo "Apache gefunden" else echo "kein Webserver" fi
TestBedeutungTestBedeutung
-f dateiDatei existiert"$a" = "$b"Texte gleich
-d ordnerVerzeichnis existiert"$a" != "$b"Texte ungleich
-z "$x"Variable ist leer$a -eq $bZahlen gleich
! …Verneinung$a -gt $bgrößer als (-lt kleiner)

Schleifen

# for: über eine Liste for host in 10.0.0.1 10.0.0.2 10.0.0.3; do ping -c1 -W1 "$host" >/dev/null && echo "$host erreichbar" || echo "$host DOWN" done # while: Datei Zeile für Zeile lesen while read -r benutzer; do sudo useradd -m "$benutzer" done < neue_benutzer.txt

Funktionen

log() { echo "$(date '+%F %T') $1" >> /var/log/mein-skript.log } log "Skript gestartet"
Gute Gewohnheiten: set -euo pipefail an den Anfang (bricht bei Fehlern ab), Variablen immer in Anführungszeichen, Kommentare mit # schreiben und Skripte mit ShellCheck prüfen.