OpenBSD Administration Cheat Sheet

OpenBSD 7.x (7.5 – 7.9) · amd64 / arm64
Keine Treffer – Suchbegriff anpassen.

💻System- & Hardware-Informationen

uname -aAlles: OS, Hostname, Release, Build-Kennung, Architektur
uname -rRelease, z. B. 7.9 – bei -current mit angehängtem Datum im Kernel
uname -m / uname -pMaschinen-Architektur (amd64) / Prozessor-Architektur
machine / archArchitektur kurz ausgeben (machine ist Alias von arch)
sysctl kern.versionVollständige Kernel-Kennung inkl. Build-Datum und Compiler
sysctl kern.osrelease kern.osversionRelease und Kernel-Buildnummer
sysctl hw.vendor hw.product hw.serialnoHersteller, Modell und Seriennummer (aus SMBIOS)
sysctl hw.modelCPU-Modellbezeichnung
sysctl hw.ncpu hw.ncpuonline hw.ncpufoundGenutzte / online / gefundene CPUs (SMT-Cores zählen mit)
sysctl hw.cpuspeed hw.setperfAktueller Takt in MHz / Performance-Sollwert in Prozent
sysctl hw.physmem hw.usermemPhysischer bzw. für Userland nutzbarer Speicher in Byte
sysctl hw.disknamesAlle Platten samt DUID – wichtig für /etc/fstab
sysctl hw.sensorsTemperaturen, Lüfter, Spannungen, RAID-Status der Treiber
sysctl kern.boottimeZeitpunkt des letzten Bootvorgangs
sysctl -a | lessAlle Kernel-Variablen (rund 1000 Einträge)
sysctl -n kern.hostnameNur den Wert ausgeben (gut für Skripte)
hostname / hostname -sFQDN / nur Kurzname; dauerhaft in /etc/myname
dmesgAktueller Kernel-Ringpuffer (Hardware-Erkennung, Fehler)
dmesg -sConsole-Message-Buffer – zeigt auch rc-Startmeldungen (nur root)
cat /var/run/dmesg.bootKopie des dmesg direkt nach dem Boot – die verlässliche Quelle
dmesg | grep -i cpu0CPU-Features und Mitigations der ersten CPU
uptime; w; dateLaufzeit und Load / angemeldete User / Systemzeit
apm -v / apm -lPower-Status ausführlich / nur Akkustand (benötigt apmd)
apm -A / apm -H / apm -LFrequenzregelung: automatisch / high / low
pcidump -vPCI-Geräte mit Vendor-/Device-IDs ausführlich auflisten
usbdevs -vAngeschlossene USB-Geräte
Praxis: Ist-Zustand vor jedem Change sichern: dmesg > /root/dmesg_$(date +%F).txt, sysctl -a > /root/sysctl_$(date +%F).txt, disklabel sd0 > /root/label.sd0. Der dmesg-Ringpuffer ist klein – nach längerer Laufzeit ist /var/run/dmesg.boot die einzige komplette Boot-Ausgabe.
Dauerhafte sysctl-Werte: Alles, was per sysctl kern.x=y gesetzt wird, ist nach dem Reboot weg. Dauerhaft gehört es als kern.x=y in /etc/sysctl.conf (Syntax: eine Zuweisung pro Zeile, ohne sysctl davor).

⏻Boot, Bootloader & Kernel

boot(8)-Prompt (boot>)

bootStandardkernel /bsd starten (passiert nach Timeout automatisch)
boot -sSingle-User-Mode – nur / read-only, Rettungsmodus
boot -cKernel-Konfigurations-Editor UKC starten (Geräte an/abschalten)
boot -aBeim Start nach dem Root-Device fragen
boot bsd.rdRAM-Disk-Kernel – Installer, Upgrade und Reparatur-Shell
boot hd0a:/bsd.spBestimmten Kernel von bestimmter Partition booten
boot -dDirekt in den Kernel-Debugger ddb(4) fallen
machine diskinfoVom Bootloader gesehene Platten anzeigen
machine memorySpeicherkarte des BIOS/UEFI anzeigen
set tty com0Konsole auf serielle Schnittstelle umlenken
stty com0 115200Baudrate der seriellen Konsole setzen
set timeout 10Wartezeit am Boot-Prompt in Sekunden
ls /Wurzelverzeichnis auflisten – prüfen welche Kernel vorhanden sind

Bootloader & Kernel im laufenden System

/etc/boot.confDauerhafte Bootloader-Kommandos (z. B. set tty com0)
installboot -v sd0Bootstrap-Code und Bootloader auf die Platte schreiben
installboot -n -v sd0Trockenlauf – zeigt nur, was geschrieben würde
config -e /bsdUKC im laufenden System öffnen (Änderung in neue Datei schreiben)
config -e -f /bsdUKC-Änderung direkt in den Kernel /bsd zurückschreiben
find / disable / enable / changeUKC-Kommandos; quit = schreiben, exit = verwerfen
/bsd · /bsd.mp · /bsd.sp · /bsd.rdAktiver Kernel · Multiprozessor · Einzelprozessor · RAM-Disk
/obsdVorheriger Kernel (Backup durch KARL-Relinking)
/usr/libexec/reorder_kernelKARL: Kernel neu linken (läuft automatisch bei jedem Boot)
ls -l /usr/share/relink/kernel/Objekte für das Relinking; muss vorhanden und beschreibbar sein
sysctl kern.securelevelAktueller Securelevel (Normalbetrieb: 1)
sysctl kern.osrevisionKernel-Revision der laufenden Version

Herunterfahren & Neustart

rebootSofortiger Neustart
halt -pHerunterfahren und ausschalten (Poweroff)
shutdown -hp nowSauber herunterfahren und ausschalten, mit wall-Meldung
shutdown -r +10 "Wartung"Reboot in 10 Minuten mit Meldung an alle User
shutdown -h nowAnhalten ohne Ausschalten (System bleibt am Prompt)
/etc/rc.shutdownEigene Kommandos, die vor dem Herunterfahren laufen
Kein Modulkonzept: OpenBSD kennt keine ladbaren Kernel-Module – es gibt kein kldload, modprobe oder /etc/modules. Geräte werden über UKC (boot -c / config -e) ein- und ausgeschaltet oder erfordern einen eigenen Kernel-Build.
KARL: Bei jedem Boot wird aus den Objekten in /usr/share/relink ein neuer, zufällig gelinkter Kernel gebaut. Dadurch unterscheidet sich /bsd nach jedem Reboot – Checksummen-Vergleiche des Kernels sind deshalb sinnlos.

⚙Init, rcctl & Dienste

rcctl – das zentrale Werkzeug

rcctl ls allAlle bekannten Dienste und Services
rcctl ls on / offAktivierte / deaktivierte Dienste
rcctl ls started / stoppedLaufende / nicht laufende Dienste
rcctl ls failedAktiviert, läuft aber nicht – erster Blick bei Störungen
rcctl ls rogueDeaktiviert, läuft aber trotzdem
rcctl enable httpdDienst aktivieren (Alias für set httpd status on)
rcctl disable httpdDienst deaktivieren, Variablen werden entfernt
rcctl start / stop / restart httpdDienst starten / stoppen / neu starten
rcctl reload httpdKonfiguration neu einlesen (sendet SIGHUP)
rcctl check httpdLäuft der Dienst? Exit-Code 0 = ja
rcctl configtest httpdKonfiguration prüfen, falls das rc.d-Skript es unterstützt
rcctl -d start httpdDebug-Modus – zeigt, warum der Start scheitert
rcctl -f start httpdStart erzwingen, auch wenn der Dienst deaktiviert ist
rcctl get httpdAlle Variablen eines Dienstes im rc.conf-Format
rcctl getdef httpd flagsWerkseinstellung der Flags anzeigen
rcctl get all | lessKomplette Dienstkonfiguration des Systems dokumentieren
rcctl set httpd flags -s 5Startparameter setzen (leeres Argument = Default)
rcctl set httpd status onLangform von rcctl enable
rcctl set ntpd user _ntpAusführenden User ändern
rcctl set httpd timeout 60Timeout für rc.d-Aktionen erhöhen (Default 30 s)
rcctl set httpd rtable 1Dienst in einer anderen Routing-Tabelle starten
rcctl set httpd logger daemon.infoAusgaben des Dienstes an syslogd weiterleiten
rcctl order unbound dhcpdStartreihenfolge in pkg_scripts festlegen

Dateien & rc-Struktur

/etc/rc.confDefaults der Basis-Dienste – niemals editieren
/etc/rc.conf.localEigene Abweichungen; wird von rcctl gepflegt
/etc/rc.localEigene Kommandos am Ende des Bootvorgangs
/etc/rc.securelevelKommandos, die vor dem Anheben des Securelevel laufen müssen
/etc/rc.firsttimeWird einmalig beim nächsten Boot ausgeführt, danach gelöscht
/etc/rc.shutdownKommandos beim Herunterfahren
/etc/rc.d/Kontrollskripte aller Dienste (Basis und Pakete)
/etc/rc.d/httpd -f restartrc.d-Skript direkt aufrufen, Start erzwingen
pkg_scripts="unbound nginx"Reihenfolge der Paket-Dienste in rc.conf.local
ln -s /etc/rc.d/snmpd /etc/rc.d/snmpd6Zweite Instanz eines Dienstes: Symlink anlegen und konfigurieren
Goldene Regel: rc.conf.local nicht mit dem Editor anfassen, sondern immer rcctl nutzen. Das vermeidet Tippfehler in Variablennamen (ein falsch geschriebenes httpd_flags wird still ignoriert) und hält pkg_scripts konsistent.
Service vs. Daemon: Manche Einträge sind reine Services ohne Prozess (z. B. pf, ipsec, library_aslr). Bei ihnen greifen nur enable/disable, nicht start/stop.

📦Pakete, Ports & Updates

Spiegel & Grundkonfiguration

cat /etc/installurlMirror-URL für pkg_add, syspatch, sysupgrade, fw_update
echo https://cdn.openbsd.org/pub/OpenBSD > /etc/installurlOffiziellen CDN-Mirror setzen (eine Zeile, ohne Slash am Ende)
export PKG_PATH=/mnt/packages/Alternative Paketquelle für eine Sitzung (z. B. lokaler Spiegel)
/etc/pkg.confDauerhafte Optionen für die pkg-Werkzeuge (installpath u. a.)

Binärpakete

pkg_add nginxPaket samt Abhängigkeiten installieren
pkg_add -v nginxAusführlich – zeigt Quelle, Signaturprüfung und Dateien
pkg_add -n nginxTrockenlauf, nichts wird installiert
pkg_add -uAlle installierten Pakete auf den passenden Release-Stand bringen
pkg_add -u -v nginxNur ein Paket aktualisieren
pkg_add -Dsnap -uPaketupdate gegen Snapshots (nur auf -current sinnvoll)
pkg_delete nginxPaket entfernen
pkg_delete -aAutomatisch installierte, nicht mehr benötigte Abhängigkeiten löschen
pkg_delete -n -aVorher anzeigen, was -a aufräumen würde
pkg_infoAlle installierten Pakete mit Kurzbeschreibung
pkg_info -mNur bewusst installierte Pakete (ohne mitgezogene Abhängigkeiten)
pkg_info -Q postgresVerfügbare Pakete im Repository suchen
pkg_info nginxDetails eines installierten Pakets
pkg_info -L nginxAlle Dateien, die das Paket mitbringt
pkg_info -E /usr/local/bin/rsyncWelches Paket besitzt diese Datei?
pkg_info -R nginxWer hängt von diesem Paket ab
pkg_info -f nginxPacking-List mit @-Kommandos (readme, rcscript …)
pkg_checkInstallierte Pakete gegen die Datenbank prüfen (fehlende Dateien)
pkg_info -mz > /root/pkglistPaketliste versionsneutral sichern
pkg_add -l /root/pkglistPaketliste auf einem neuen System wieder einspielen

Patches, Firmware & Release-Upgrade

syspatch -cVerfügbare, noch nicht installierte Patches auflisten (cron-taugllich)
syspatch -lBereits installierte Patches auflisten
syspatchAlle fehlenden Binärpatches holen, prüfen und installieren
syspatch -rDen zuletzt installierten Patch zurückrollen
syspatch -RAlle Patches zurückrollen
ls /var/syspatch/Rollback-Archive und signierte Diffs der Patches
fw_updateFehlende Firmware für erkannte Geräte nachladen
fw_update -aFirmware aller unterstützten Treiber installieren
fw_update -d intelFirmware-Paket wieder entfernen
sysupgradeAuf das nächste Release hochziehen – lädt, prüft und rebootet
sysupgrade -nNur herunterladen und /bsd.upgrade anlegen, kein Reboot
sysupgrade -sAuf den aktuellen Snapshot (-current) wechseln
sysupgrade -R 7.9Auf eine bestimmte Release-Version aktualisieren
sysupgrade -kHeruntergeladene Sets in /home/_sysupgrade behalten
sysmergeNach dem Upgrade Konfigurationsdateien in /etc abgleichen
signify -Vp /etc/signify/openbsd-79-base.pub -x SHA256.sig -m /dev/nullSignatur einer Set-Liste manuell prüfen

Ports-Tree (nur wenn nötig)

cd /usr && cvs -qd anoncvs@anoncvs.fr.openbsd.org:/cvs checkout -rOPENBSD_7_9 -P portsPorts-Tree passend zum Release auschecken
cd /usr/ports && cvs -q up -Pd -rOPENBSD_7_9Vorhandenen Ports-Tree aktualisieren
cd /usr/ports/www/nginx && make install cleanPort bauen und installieren, Arbeitsverzeichnis aufräumen
make search key=nginxIm Ports-Tree nach Stichwort suchen
make show=FLAVORS && make show=RUN_DEPENDSVarianten und Laufzeitabhängigkeiten eines Ports anzeigen
make package && make deinstallEigenes Paket erzeugen / Port wieder entfernen
make clean=dependsAuch die Build-Verzeichnisse der Abhängigkeiten aufräumen
syspatch nur für -release: syspatch funktioniert ausschließlich auf offiziellen Releases. Auf -current/Snapshots ist der Weg sysupgrade -s gefolgt von pkg_add -u.
Pakete passen zum Release: Pakete werden pro Release gebaut. Nach sysupgrade immer pkg_add -u laufen lassen, sonst laufen Binaries gegen alte Bibliotheken. Umgekehrt niemals Pakete eines neueren Releases auf ein älteres System installieren.
# Release-Upgrade Schritt für Schritt
syspatch                      # erst auf den letzten Patchstand des alten Release
pkg_add -u
sysctl kern.version           # Ausgangsstand dokumentieren
pkg_info -mz > /root/pkglist  # Paketliste sichern
sysupgrade -n                 # laedt Sets, prueft Signatur, legt /bsd.upgrade an
reboot                        # Bootloader waehlt /bsd.upgrade, Upgrade laeuft unbeaufsichtigt
# ---- nach dem Reboot ----
sysmerge                      # /etc abgleichen
pkg_add -u                    # Pakete auf das neue Release ziehen
fw_update                     # Firmware nachziehen
syspatch                      # Patches des neuen Release
rcctl ls failed               # kaputte Dienste finden
dmesg | tail -40

💽Disks, Partitionen & Labels

sysctl hw.disknamesAlle Platten mit DUID, z. B. sd0:2f4a1b…,cd0:
dmesg | grep -E '^(sd|wd|nvme)'Erkannte Platten mit Größe, Modell und Anschluss
disklabel sd1Label anzeigen: DUID, Geometrie, Partitionen a–p
disklabel -p g sd1Größenangaben in Gigabyte statt Sektoren
disklabel -E sd1Interaktiver Label-Editor (p, a, d, m, w, q)
disklabel -A sd1Automatisch ein sinnvolles Standard-Layout berechnen
disklabel -r sd1Label direkt vom Datenträger lesen, nicht aus dem Kernel
disklabel sd0 > /root/label.sd0Label sichern – Pflicht vor jeder Partitionierung
disklabel -R sd1 /root/label.sd1Gesichertes Label zurückschreiben
fdisk sd1MBR/GPT-Partitionstabelle anzeigen
fdisk -e sd1Interaktiver fdisk-Editor (p, e, edit, w, q)
fdisk -iy sd1MBR neu initialisieren, ganze Platte als OpenBSD-Partition
fdisk -gy -b 960 sd1GPT anlegen mit 960 Sektoren EFI-Systempartition (UEFI-Boot)
newfs /dev/rsd1aFFS auf der Raw-Partition anlegen (immer r-Device nutzen!)
newfs -O 2 /dev/rsd1aFFS2 erzwingen (nötig für Partitionen > 1 TB)
newfs -i 4096 /dev/rsd1aMehr Inodes (Bytes pro Inode senken) für viele kleine Dateien
growfs -y /dev/rsd1aFilesystem auf die volle Partitionsgröße ausdehnen (nur ungemountet)
installboot -v sd1Bootblocks auf eine neue Systemplatte schreiben
dd if=/dev/zero of=/dev/rsd1c bs=1m count=1Erstes Megabyte löschen (alte Label-/RAID-Reste entfernen)
dd if=/dev/rsd0c of=/mnt/sd0.img bs=1m status=progressRohabbild der ganzen Platte ziehen
scan_ffs sd1Verlorene FFS-Partitionen auf einer Platte suchen
Partitionsbuchstaben: a = Root bzw. erste Datenpartition, b = Swap, c = die ganze Platte (nie formatieren!), ab d freie Verwendung. Das Raw-Device /dev/rsd1a ist für newfs, fsck und dd zuständig, /dev/sd1a für mount.
DUIDs statt sdX: Die Nummerierung sd0, sd1 hängt an der Erkennungsreihenfolge und kann sich beim Umstecken oder nach einem Firmware-Update ändern. In /etc/fstab deshalb immer die DUID aus sysctl hw.disknames bzw. disklabel sd1 verwenden: 2f4a1b9c8d7e6f50.a /data ffs rw 1 2.
# Neue Platte einbinden - kompletter Ablauf
dmesg | tail                        # neue Platte finden -> sd2, 4T
fdisk -iy sd2                       # MBR neu, ganze Platte OpenBSD  (UEFI: fdisk -gy -b 960 sd2)
disklabel -E sd2
  > a a                             # Partition a anlegen
  offset: [64]                      # Vorschlag uebernehmen
  size:   [7814037104] *            # "*" = Rest der Platte
  FS type: [4.2BSD]
  > p g                             # kontrollieren
  > w
  > q
newfs -O 2 /dev/rsd2a               # FFS2 wegen Groesse > 1 TB
disklabel sd2 | grep duid           # DUID notieren
install -d /data
# /etc/fstab ergaenzen:
# 2f4a1b9c8d7e6f50.a /data ffs rw,nodev,nosuid,softdep 1 2
mount /data && df -h /data
disklabel sd2 > /root/label.sd2     # Label sichern

📁Filesysteme & Mounts

mountAlle gemounteten Filesysteme mit Optionen
mount -aAlle Einträge aus /etc/fstab mounten
mount /dataEinzelnen fstab-Eintrag mounten
mount /dev/sd1a /mntDevice direkt mounten
mount -u -o ro /Bereits gemountetes FS umschalten (-u = update)
mount -o rw,noatime,softdep,nodev,nosuid /dataTypische Optionen für Datenpartitionen
umount /dataAushängen; umount -f erzwingt
fuser -c /dataWer benutzt das Filesystem (PIDs)
fuser -ck /dataAlle Zugriffe beenden, dann aushängen
df -hBelegung menschenlesbar
df -i /varInode-Auslastung (voll trotz freiem Platz?)
du -shx /var/*Größen, ohne Mount-Grenzen zu überschreiten
du -sk /var/* | sort -rn | head -20Die 20 größten Verzeichnisse
fsck -pPreen-Modus: alle fstab-FS prüfen, nur harmlose Reparaturen
fsck_ffs -y /dev/rsd1aVollprüfung mit automatischem „yes“ (nur ungemountet!)
tunefs -p /dev/rsd1aAktuelle FS-Parameter anzeigen
tunefs -o space /dev/rsd1aOptimierung auf Platz statt Geschwindigkeit
tunefs -m 5 /dev/rsd1aReservierten Anteil für root von 5 % setzen

mount_*-Helfer

mount_ffs /dev/sd1a /mntFFS/FFS2 – das Standard-Dateisystem
mount_mfs -s 1G swap /tmpSpeicherbasiertes FS (Memory File System) für /tmp
mount_nfs -o ro,intr srv:/export /mntNFS-Share einbinden
mount_cd9660 /dev/cd0c /mntCD/DVD bzw. gemountetes ISO
mount_msdos /dev/sd2i /mntFAT/FAT32-Datenträger (USB-Stick)
mount_ext2fs /dev/sd2d /mntext2/ext3 lesen (kein ext4)
mount_udf /dev/cd0c /mntUDF-Medien
mount_ffs -o noperm /dev/sd2d /mntRechte auf dem Fremd-FS ignorieren (Datenrettung)

Quotas

quotacheck -aQuota-Datenbanken prüfen/erzeugen
quotaon -a / quotaoff -aQuotas ein-/ausschalten (fstab-Option userquota)
edquota benutzerLimits eines Users bearbeiten
repquota -aQuota-Report über alle Filesysteme
quota -v benutzerAktuelle Nutzung und Limits anzeigen
Kein ZFS, kein LVM: OpenBSD hat weder ZFS noch einen Logical Volume Manager. Flexibilität entsteht über softraid (Concat/RAID) und sorgfältige Planung der Partitionsgrößen. Snapshots gibt es nicht – dafür dump/tar.
wxallowed: Manche Pakete (Chromium, Java, Mono) brauchen Speicherseiten, die gleichzeitig schreib- und ausführbar sind. Dann die Partition mit /usr/local in /etc/fstab um die Option wxallowed erweitern – und nur diese.
Volles Filesystem, du zeigt wenig? Meist hält ein Prozess eine gelöschte Datei offen. Mit fstat | grep /var den Prozess finden und neu starten.

🗃softraid, Verschlüsselung & vnd

bioctl softraid0Alle softraid-Volumes des Controllers anzeigen
bioctl sd3Status eines Volumes: Online / Degraded / Rebuild
bioctl -h -v sd3Ausführlich mit lesbaren Größenangaben
bioctl -c 1 -l /dev/sd1a,/dev/sd2a softraid0RAID 1 (Mirror) aus zwei Chunks anlegen
bioctl -c 0 -l /dev/sd1a,/dev/sd2a softraid0RAID 0 (Striping)
bioctl -c 5 -l /dev/sd1a,/dev/sd2a,/dev/sd3a softraid0RAID 5, mindestens drei Chunks
bioctl -c c -l /dev/sd1a,/dev/sd2a softraid0CONCAT – Chunks aneinanderhängen
bioctl -c C -l /dev/sd1a softraid0CRYPTO – verschlüsseltes Volume, genau ein Chunk
bioctl -c 1C -l /dev/sd1a,/dev/sd2a softraid0RAID 1 + CRYPTO: gespiegelt und verschlüsselt
bioctl -C force -c 1 -l … softraid0Anlegen erzwingen, wenn Metadatenreste stören
bioctl -C noauto -c 1 -l … softraid0Volume beim Boot nicht automatisch zusammensetzen
bioctl -P sd3Passphrase eines CRYPTO-Volumes ändern
bioctl -p /etc/sr.pass -c C -l /dev/sd1a softraid0Passphrase aus Datei (muss root:0600 sein)
bioctl -k /dev/sd4a -c C -l /dev/sd1a softraid0Keydisk statt Passphrase verwenden
bioctl -r auto -c C -l /dev/sd1a softraid0KDF-Runden automatisch nach Systemleistung wählen
bioctl -O /dev/sd1a sd3Chunk künstlich offline setzen (Ausfall simulieren/vorbereiten)
bioctl -R /dev/sd2a sd3Rebuild mit neuem Chunk starten
bioctl -d sd3Volume abkoppeln (vorher aushängen!)
bioctl -c C -l /dev/sd1a softraid0Nach dem Boot dasselbe Kommando = Volume entsperren
bioctl -q sd0Hersteller, Produkt, Revision und Seriennummer einer Platte
bioctl -v nvme0Auch für Hardware-Controller nutzbar (Status, Enclosure)

vnd – Datei als Blockdevice

vnconfig vnd0 /home/images/disk.imgImage-Datei an ein vnd-Device binden
vnconfig -lAlle vnd-Devices mit Zuordnung anzeigen
vnconfig -u vnd0Bindung wieder auflösen
vnconfig -k vnd0 /home/crypt.imgImage verschlüsselt einbinden (fragt nach Passphrase)
mount /dev/vnd0a /mntPartition im Image mounten (nach disklabel/newfs)
Chunk-Vorbereitung: Jeder Chunk braucht eine Partition mit dem FS-Type RAID. Im disklabel -E-Editor bei der Frage nach dem FS-Typ also RAID eintragen – nicht 4.2BSD. Sonst wird das Volume nicht erkannt.
Passphrase-Volumes und Boot: Ein CRYPTO-Volume wird beim Boot nicht automatisch entsperrt. Filesysteme darauf gehören mit noauto in die /etc/fstab, sonst hängt der Bootvorgang im Fehler.
# softraid RAID1 (Mirror) aus zwei neuen Platten
dmesg | grep -E '^(sd|wd)'          # -> sd1 und sd2, gleich gross
for d in sd1 sd2; do
  dd if=/dev/zero of=/dev/r${d}c bs=1m count=1   # alte Metadaten loeschen
  fdisk -iy $d
done
disklabel -E sd1                    # Partition a ueber die ganze Platte,
  > a a                             #   FS type: RAID
  > w
  > q
disklabel -E sd2                    # identisch anlegen
bioctl -c 1 -l /dev/sd1a,/dev/sd2a softraid0
dmesg | tail -3                     # -> "sd3 at scsibus3 ... SR RAID 1"
dd if=/dev/zero of=/dev/rsd3c bs=1m count=1
fdisk -iy sd3
disklabel -E sd3                    # Partition a, FS type 4.2BSD
newfs /dev/rsd3a
bioctl sd3                          # Status: Online
disklabel sd3 | grep duid           # DUID fuer /etc/fstab
# Ausfalltest / Rebuild:
bioctl -O /dev/sd2a sd3             # Chunk offline -> Volume "Degraded"
bioctl -R /dev/sd2a sd3             # Rebuild starten
bioctl sd3                          # Fortschritt in Prozent beobachten

📈Swap

swapctl -lAlle Swap-Devices mit Größe, Nutzung und Priorität
swapctl -lkAusgabe in Kilobyte (-lm Megabyte, -lh lesbar)
swapctl -sKurze Zusammenfassung: total / used / available
pstat -sAlternative Swap-Übersicht aus dem Kernel
swapctl -a /dev/sd1bSwap-Partition sofort aktivieren
swapctl -a -p 1 /dev/sd1bMit Priorität 1 aktivieren (höhere Zahl = später genutzt)
swapctl -d /dev/sd1bSwap-Device deaktivieren (Inhalt wird zurückgelagert)
swapctl -AAlle Swap-Einträge aus /etc/fstab aktivieren
/dev/sd0b none swap sw 0 0Klassischer fstab-Eintrag für die Swap-Partition
2f4a1b9c8d7e6f50.b none swap sw 0 0Dasselbe mit DUID – die empfohlene Schreibweise
sysctl vm.swapencrypt.enableSwap-Verschlüsselung abfragen (1 = aktiv, Standard)
sysctl vm.swapencrypt.enable=1Einschalten; dauerhaft in /etc/sysctl.conf
vmstat 1 | awk '{print $3,$4}'Spalten pi/po beobachten – echtes Paging?
Faustregel: Partition b der Systemplatte ist der Standard-Swap. Anhaltende Werte in pi/po bedeuten RAM-Mangel – mehr Swap verschiebt das Problem nur. Für einen Kernel-Crashdump muss der Swap mindestens so groß wie der physische Speicher sein.
Verschlüsselter Swap: ist auf OpenBSD standardmäßig aktiv – ausgelagerte Seiten landen niemals im Klartext auf der Platte. Nicht abschalten; der Performance-Verlust ist minimal.

🖥Prozesse, Jobs, cron & Limits

ps auxwAlle Prozesse mit CPU-/Speicheranteil, breite Ausgabe
ps auxwwKommandozeilen nicht abschneiden
ps -axlLangformat mit PPID, Nice-Wert und Wait-Channel
ps -ax -O rss,vszZusätzliche Spalten anhängen (-O statt -o behält Defaults)
ps -axo pid,ppid,user,pcpu,rss,commandEigene Spaltenauswahl
ps -U wwwNur Prozesse eines Users
ps -axo pid,rss,command | sort -k2 -rn | headSpeicherhungrigste Prozesse
pgrep -lf nginxPIDs samt Kommandozeile suchen
pkill -HUP -x syslogdSignal an exakt passenden Prozessnamen senden
kill -TERM 1234 / kill -KILL 1234Sauber beenden / hart abschießen
kill -lAlle Signalnamen auflisten
nice -n 10 cmdMit niedrigerer Priorität starten
renice -n 5 -p 1234Priorität nachträglich ändern
timeout 30 cmdKommando nach 30 s abbrechen (-k 5 danach SIGKILL)
nohup cmd > /tmp/log 2>&1 &Abgekoppelt im Hintergrund starten
jobs / fg %1 / bg %1Shell-Jobverwaltung in der ksh
doas cmdKommando als root ausführen (OpenBSDs Ersatz für sudo)
doas -u _postgresql psqlAls anderer User ausführen
ktrace -f /tmp/tr -p 1234; kdump -f /tmp/trSyscalls eines hängenden Prozesses mitschneiden und lesen

Zeitsteuerung

crontab -l / -eEigene crontab anzeigen / bearbeiten
crontab -l -u wwwcrontab eines anderen Users lesen
ls /var/cron/tabs/Speicherort der crontabs – ins Backup aufnehmen
~ 3 * * * /usr/local/bin/jobOpenBSD-Spezialität: ~ = zufällige Minute (verteilt Last)
-Q * * * * cmdKein Mail-Report, kein zweiter Lauf bei Überlappung
at 22:00Einmaligen Job planen, mit Ctrl-D abschließen
atq / atrm 12Geplante at-Jobs anzeigen / löschen
/etc/daily · /etc/weekly · /etc/monthlySystempflege-Skripte – niemals editieren
/etc/daily.localEigene Ergänzungen zum täglichen Lauf
sh /etc/dailyTäglichen Lauf manuell anstoßen (Report per Mail an root)

Limits & login.conf

ulimit -aAlle Limits der aktuellen Shell
ulimit -n / -d / -sOffene Dateien / Datensegment / Stack
ulimit -n 1024Soft-Limit erhöhen (bis zum Hard-Limit der Klasse)
/etc/login.confLogin-Klassen mit openfiles, datasize, maxproc, umask
/etc/login.conf.d/Klassendefinitionen von Paketen (z. B. Datenbanken)
cap_mkdb /etc/login.confNach Änderung Datenbank neu bauen, falls login.conf.db existiert
usermod -L daemon benutzerUser einer anderen Login-Klasse zuweisen
sysctl kern.maxfiles kern.maxprocSystemweite Obergrenzen abfragen
sysctl kern.maxfiles=16384Sofort erhöhen; dauerhaft in /etc/sysctl.conf
sysctl kern.nfiles kern.nprocsAktuelle Nutzung gegen die Grenzen halten
cron-Falle: cron startet mit minimalem Environment und ohne .profile. Immer absolute Pfade verwenden und benötigte Variablen im Skript selbst setzen. PATH und MAILTO lassen sich oben in der crontab definieren.
Limits greifen beim Login: Änderungen an /etc/login.conf wirken erst bei einer neuen Session bzw. nach Neustart des Dienstes – ein rcctl restart des betroffenen Daemons ist Pflicht.

📊Performance & Monitoring

Schnellüberblick

topInteraktiv; Tasten: o=Sortierung u=User m=Modus ?=Hilfe
top -HThreads statt Prozesse anzeigen
top -CCPU-Werte pro Kern einzeln ausweisen
top -b -d 1Batch-Modus, ein Durchlauf – für Skripte und Logs
top -U wwwNur Prozesse eines Users
uptime; wLoad Average (1/5/15 min) und aktive Sitzungen

systat – die Schaltzentrale

systatStartet mit der Ansicht vmstat; Tab/n wechselt Ansichten
systat vmstatGesamtüberblick CPU, Speicher, Interrupts, Disks
systat iostatDurchsatz und Transfers pro Platte
systat ifstatDurchsatz pro Netzwerk-Interface
systat netstatOffene Verbindungen live
systat pfpf-Statistik: States, Suchen, Matches, Drops
systat queuesAuslastung der pf-Queues (Traffic-Shaping)
systat statesEinzelne pf-States mit Rate und Alter
systat rulesTrefferzähler je pf-Regel – findet toten Regelcode
systat mbufsmbuf-Cluster pro Interface (Netzwerkspeicher)
systat sensorsTemperatur- und Hardware-Sensoren live
systat pigsDie größten CPU-Verbraucher
systat uvm / pool / mallocInterna des virtuellen Speichers und der Kernel-Pools
systat -s 2 vmstatAktualisierungsintervall auf 2 Sekunden setzen

Messwerkzeuge

vmstat 1Sekundenwerte: procs, memory, page, disks, faults, cpu
vmstat 2 10Zehn Messungen im 2-Sekunden-Takt
vmstat -sKumulierte Zähler seit dem Boot
vmstat -iInterrupts pro Gerät – findet störende Hardware
vmstat -mKernel-Speicherpools und ihre Auslastung
iostat 1Disk-Statistik: tps, KB/t, MB/s je Platte
iostat -C 1Zusätzlich CPU-Zeilen ausgeben
iostat -d 2 5Nur Disk-Werte, fünf Messungen
fstatAlle offenen Dateien systemweit
fstat -p 1234 / fstat -u wwwOffene Dateien eines Prozesses / Users
fstat /var/log/messagesWer hält diese Datei offen?
netstat -mmbuf-Nutzung; „requests for memory denied“ muss 0 sein
netstat -s | lessProtokollstatistiken (Retransmits, Checksum-Fehler)
netstat -biBytes und Fehler pro Interface
sysctl kern.timecounterAktive Zeitquelle und Auswahl (hardware, choice)
sysctl hw.sensorsTemperaturen und Lüfter; rcctl enable sensorsd für Alarme
pstat -tTerminal-Statistik (hängende Sessions)
Vorgehen bei „Server ist langsam“: 1. systat vmstat – wo geht die Zeit hin (user/sys/interrupt/idle)? 2. top -C – einzelner Kern am Anschlag? 3. systat iostat – wartet das System auf Platten? 4. vmstat 1 – Spalten pi/po prüfen. 5. systat pf – State-Tabelle voll?
Load Average täuscht: Auf OpenBSD zählen auch auf I/O wartende Prozesse in die Load. Ein Load von 4 bei 4 % CPU-Nutzung bedeutet meist ein Platten- oder Netzwerkproblem, keinen Rechenengpass.

🌐Netzwerk & Interfaces

Interfaces

ifconfigAlle aktiven Interfaces mit Adressen und Status
ifconfig -AAuch Interfaces ohne Adresse anzeigen
ifconfig em0Einzelnes Interface: MAC, Media, Gruppen, Adressen
ifconfig -a inetNur IPv4-Adressen
ifconfig em0 inet 10.0.0.10/24 upAdresse temporär setzen (nach Reboot weg)
ifconfig em0 inet alias 10.0.0.11/32Zweite Adresse auf dasselbe Interface legen
ifconfig em0 inet 10.0.0.11 deleteAdresse entfernen
ifconfig em0 up / downInterface ein-/ausschalten
ifconfig em0 media / ifconfig em0 mediaoptVerfügbare Medientypen und Optionen anzeigen
ifconfig em0 media 1000baseT mediaopt full-duplexGeschwindigkeit fest setzen (Autoneg abschalten)
ifconfig em0 mtu 9000Jumbo Frames – Switch und Gegenstelle müssen mitspielen
ifconfig em0 descr "Uplink DMZ"Beschreibung setzen – erscheint in ifconfig
ifconfig em0 group internalInterface einer Gruppe zuordnen (in pf als on internal nutzbar)
ifconfig egressAutomatische Gruppe: das Interface mit der Default-Route
sh /etc/netstart em0Ein Interface aus /etc/hostname.em0 neu konfigurieren
sh /etc/netstartKomplette Netzwerkkonfiguration neu einlesen

Dauerhafte Konfiguration

/etc/hostname.em0Konfiguration je Interface, eine Anweisung pro Zeile
inet 10.0.0.10 255.255.255.0Statische IPv4-Adresse (auch inet 10.0.0.10/24 möglich)
dhcpAdresse per DHCP holen (dhcpleased übernimmt)
inet6 autoconfIPv6 per SLAAC (slaacd übernimmt)
/etc/mynameHostname des Systems (FQDN, eine Zeile)
/etc/mygateDefault-Gateway, je eine Zeile für IPv4 und IPv6
/etc/resolv.confNameserver; wird von resolvd gepflegt
rcctl enable unwindLokaler validierender DNS-Resolver mit DNSSEC
rcctl enable dhcpleased slaacdDHCP- und SLAAC-Clients aktivieren
/etc/hostsStatische Namensauflösung

Routing & Diagnose

route -n showRouting-Tabelle numerisch
route -n show -inetNur IPv4-Routen
route -n get 8.8.8.8Welche Route würde greifen?
route add default 10.0.0.1Default-Route setzen (temporär)
route delete defaultDefault-Route entfernen
route add -net 192.168.5.0/24 10.0.0.254Statische Netzroute
route -T 1 exec cmdKommando in einer anderen Routing-Tabelle ausführen
netstat -rnRouting-Tabelle mit Flags und Interface
netstat -anAlle Sockets, numerisch
netstat -na -f inet -p tcpNur TCP/IPv4 – welche Ports lauschen?
netstat -inInterface-Übersicht mit Paketzählern
arp -a / arp -d 10.0.0.5ARP-Cache anzeigen / Eintrag löschen
ndp -aIPv6-Neighbor-Cache
ping -c 3 10.0.0.1Drei Pakete senden (ohne -c läuft es endlos)
ping6 -c 3 fe80::1%em0Link-lokale IPv6-Adresse mit Interface-Scope testen
traceroute -n host / traceroute6 -n hostPfad verfolgen
ftp -o /tmp/f https://example.com/fileDownload mit dem Basis-Werkzeug (kein curl nötig)
nc -z -v host 22Port-Test ohne Datenverkehr
tcpdump -n -i em0Mitlesen ohne Namensauflösung
tcpdump -nvvi em0 port 53Sehr ausführlich, gefiltert auf DNS
tcpdump -n -w /tmp/dump.pcap -i em0 host 10.0.0.5Mitschnitt in Datei (später mit -r lesen)

Virtuelle Interfaces

ifconfig vlan10 parent em0 vnetid 10 inet 10.10.0.1/24 upVLAN-Interface anlegen (dauerhaft: /etc/hostname.vlan10)
ifconfig trunk0 trunkproto lacp trunkport em0 trunkport em1 upLink Aggregation mit LACP
ifconfig trunk0 trunkproto failover trunkport em0 trunkport em1Aktiv/Passiv-Bündel ohne Switch-Konfiguration
ifconfig carp0 vhid 1 carpdev em0 pass geheim 10.0.0.1/24 upRedundante virtuelle IP (Failover-Cluster)
ifconfig carp0 advskew 100Backup-Knoten kennzeichnen (höherer Wert = niedrigere Priorität)
ifconfig bridge0 add em1 add em2 upLayer-2-Bridge zwischen zwei Interfaces
ifconfig bridge0 addrGelernte MAC-Adressen der Bridge
ifconfig vether0 / ifconfig tap0Virtuelle Interfaces für Bridges bzw. VMs
sysctl net.inet.ip.forwarding=1IPv4-Routing einschalten (dauerhaft in /etc/sysctl.conf)
sysctl net.inet6.ip6.forwarding=1Dasselbe für IPv6
hostname.if-Syntax: Jede Zeile ist das, was hinter ifconfig em0 stehen würde. Typische Dateien: inet 10.0.0.10 255.255.255.0 für statisch, nur das Wort dhcp für DHCP, inet6 autoconf für IPv6. Kommentare mit #, mehrere Zeilen werden der Reihe nach abgearbeitet. Zum Testen sh /etc/netstart em0 – kein Reboot nötig.
Kein ip-Kommando: OpenBSD hat kein ip addr, kein nmcli und kein NetworkManager. Alles läuft über ifconfig, route und die /etc/hostname.if-Dateien.
resolv.conf wird überschrieben: resolvd pflegt /etc/resolv.conf aus den Daten von dhcpleased, slaacd und unwind. Feste Nameserver deshalb per nameserver-Zeile setzen und beachten, dass unwind sich als 127.0.0.1 davorschiebt.

🔥pf – Packet Filter

Regelwerk laden & prüfen

pfctl -nf /etc/pf.confNur prüfen (parse), nichts laden – immer zuerst!
pfctl -vnf /etc/pf.confPrüfen und die expandierten Regeln anzeigen
pfctl -f /etc/pf.confRegelwerk laden (States bleiben erhalten)
pfctl -e / pfctl -dpf einschalten / ausschalten
rcctl enable pfpf beim Boot aktivieren (Service ohne Prozess)
pfctl -siStatuszeile, Zähler, State-Tabelle, Counters
pfctl -srGeladene Filterregeln
pfctl -vvsrRegeln mit Regelnummer, Paket- und Byte-Zählern
pfctl -snGeladene NAT-/Translation-Regeln
pfctl -ssAktuelle State-Tabelle
pfctl -ss | wc -lAnzahl States – gegen set limit states halten
pfctl -sqQueues (Traffic-Shaping) anzeigen
pfctl -smLimits für States, Tabellen, Fragmente
pfctl -sTAlle definierten Tabellen auflisten
pfctl -sIInterfaces, die pf kennt
pfctl -sAVorhandene Anchors
pfctl -saAlles auf einmal – gute Change-Dokumentation
pfctl -a relayd/* -srRegeln in einem Anchor ansehen (hier: relayd)

Eingreifen im Betrieb

pfctl -k 10.0.0.5Alle States mit dieser Adresse löschen (Verbindung kappen)
pfctl -k 10.0.0.5 -k 10.0.0.9States eines bestimmten Adresspaares löschen
pfctl -F statesKomplette State-Tabelle leeren
pfctl -F rulesFilterregeln entfernen (Achtung: dann gilt pass all)
pfctl -F allAlles zurücksetzen – nur bewusst und lokal!
pfctl -t bruteforce -T showInhalt einer Tabelle anzeigen
pfctl -t bruteforce -T add 10.0.0.5Adresse zur Tabelle hinzufügen (sofort wirksam)
pfctl -t bruteforce -T delete 10.0.0.5Adresse aus der Tabelle entfernen
pfctl -t bruteforce -T flushTabelle leeren
pfctl -t bruteforce -T test 10.0.0.5Prüfen, ob eine Adresse enthalten ist
pfctl -t bruteforce -T expire 86400Einträge älter als 24 h entfernen (typisch per cron)
pfctl -t bruteforce -T replace -f /etc/blocklistTabelle komplett aus Datei ersetzen
pfctl -t bruteforce -T zeroZähler der Tabelleneinträge zurücksetzen
pfctl -x loudDebug-Stufe erhöhen (none, urgent, misc, loud)
pfctl -zAlle Regelzähler auf Null – vor einem Testlauf

Protokollierung

tcpdump -n -e -ttt -i pflog0Live-Blick auf alle geloggten pf-Entscheidungen
tcpdump -n -e -ttt -i pflog0 port 22Gefiltert auf einen Dienst
tcpdump -n -e -r /var/log/pflogGespeicherte pf-Logs auswerten
tcpdump -n -e -r /var/log/pflog action dropNur Blocks aus dem Log herausfiltern
block log (all) …In der Regel log setzen; (all) loggt jedes Paket, nicht nur das erste
set loginterface egressInterface, für das pf Byte-Statistiken führt
Reihenfolge ist Pflicht: Erst pfctl -nf /etc/pf.conf, dann pfctl -f /etc/pf.conf. Ein Syntaxfehler beim direkten Laden lässt pf im alten Zustand – ein logischer Fehler sperrt dich dagegen sofort aus der SSH-Sitzung aus. Bei Remote-Arbeit vorher eine Rückfalloption einplanen (siehe Workflow).
Letzte passende Regel gewinnt – außer bei quick. Regeln werden von oben nach unten ausgewertet, das letzte Match entscheidet. match-Regeln setzen Eigenschaften (nat-to, scrub, queue), ohne die Pass/Block-Entscheidung zu treffen.
# /etc/pf.conf - schlanke Server-Grundkonfiguration
ext_if = "em0"
table <bruteforce> persist
table <admins> const { 10.0.0.0/24 }

set skip on lo
set block-policy drop
set loginterface egress
match in all scrub (no-df random-id max-mss 1440)

block log all                                  # Default-Deny
block quick log from <bruteforce>
pass out quick inet keep state                 # ausgehend erlauben

pass in on egress proto tcp from <admins> to (egress) port 22 \
     keep state (max-src-conn 5, max-src-conn-rate 5/30, \
                 overload <bruteforce> flush global)
pass in on egress proto tcp to (egress) port { 80 443 }
pass in on egress inet proto icmp icmp-type echoreq

antispoof quick for { lo $ext_if }
# pf-Regelwerk sicher testen und laden (auch remote)
cp /etc/pf.conf /etc/pf.conf.bak            # Rueckfall sichern
pfctl -nf /etc/pf.conf                      # Syntax pruefen -> muss still bleiben
pfctl -vnf /etc/pf.conf | less              # expandierte Regeln lesen
# Notbremse fuer Remote-Arbeit: in 3 Minuten automatisch zurueck
( sleep 180 && pfctl -f /etc/pf.conf.bak ) &
pfctl -f /etc/pf.conf                       # neues Regelwerk laden
pfctl -si                                   # Status: Enabled?
pfctl -vvsr | head -40                      # greifen die Regeln?
tcpdump -n -e -ttt -i pflog0                # blockt etwas Unerwartetes?
pkill -f "sleep 180"                        # alles gut -> Notbremse loesen
pfctl -t bruteforce -T show                 # Blockliste kontrollieren

🔌Basisdienste im Überblick

OpenSSH

/etc/ssh/sshd_configServerkonfiguration; ssh_config ist die Client-Seite
sshd -tKonfiguration prüfen – vor jedem reload
sshd -T | grep -i permitrootEffektive Konfiguration inkl. aller Defaults ausgeben
rcctl reload sshdNeu einlesen, bestehende Sitzungen bleiben
ssh-keygen -t ed25519 -C "rene@logicalis"Modernen Schlüssel erzeugen
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubFingerprint eines Hostkeys anzeigen
ssh-copy-id -i ~/.ssh/id_ed25519.pub hostÖffentlichen Schlüssel verteilen
ssh-keyscan -t ed25519 hostHostkey für known_hosts abholen

Zeit: ntpd

/etc/ntpd.confservers, sensor *, constraints from …
ntpd -nKonfiguration prüfen
ntpctl -s allPeers, Sensoren und Synchronisationsstatus
ntpctl -s statusNur die Kurzfassung (Offset, Stratum)
rcctl set ntpd flags -sBeim Start einmal die Zeit sofort setzen

Logging: syslogd & newsyslog

/etc/syslog.confRegeln facility.level   Ziel (Tabulator als Trenner!)
*.notice;auth,authpriv.none /var/log/messagesBeispielzeile aus der Standardkonfiguration
*.* @loghost.example.comAlles zusätzlich an einen zentralen Logserver senden
rcctl set syslogd flags -uLogs anderer Hosts per UDP annehmen (unsicher, nur intern)
rcctl reload syslogdKonfiguration neu einlesen
logger -t backup -p daemon.info "Lauf beendet"Eigene Meldung ins Syslog schreiben
/etc/newsyslog.confRotation: Datei, Rechte, Anzahl, Größe, Intervall, Signal
newsyslog -nTrockenlauf – zeigt, was rotiert würde
newsyslog -FRotation erzwingen, unabhängig von Größe und Zeit

Web & Loadbalancing

/etc/httpd.confKonfiguration von httpd(8), Root ist /var/www
httpd -nKonfiguration prüfen
rcctl enable httpd && rcctl start httpdAktivieren und starten
acme-client -v example.comLet's-Encrypt-Zertifikat holen (/etc/acme-client.conf)
/etc/relayd.confReverse-Proxy und Loadbalancer
relayd -nKonfiguration prüfen
relayctl show summaryStatus aller Relays, Tables und Hosts
relayctl host disable 10.0.0.5Backend aus dem Pool nehmen (Wartung)

DNS: unbound & nsd

/var/unbound/etc/unbound.confKonfiguration des Resolvers (läuft im chroot)
unbound-checkconfKonfiguration prüfen
unbound-control status / stats_noresetStatus und Statistiken (vorher unbound-control-setup)
unbound-control reload / flush example.comNeu laden / Cache-Eintrag verwerfen
/var/nsd/etc/nsd.confAutoritativer Nameserver, Zonen unter /var/nsd/zones
nsd-checkconf /var/nsd/etc/nsd.confKonfiguration prüfen
nsd-checkzone example.com /var/nsd/zones/master/example.comZonendatei prüfen
nsd-control reload / notifyZonen neu laden / Slaves benachrichtigen

Mail & DHCP

/etc/mail/smtpd.confKonfiguration von smtpd(8)
smtpd -nKonfiguration prüfen
smtpctl show queueWarteschlange anzeigen
smtpctl schedule allAlle wartenden Mails sofort erneut ausliefern
smtpctl show statsStatistiken des Mailservers
/etc/mail/aliases && newaliasesAliase pflegen und Datenbank neu bauen (root-Mails umleiten!)
/etc/dhcpd.confDHCP-Server-Konfiguration
dhcpd -nKonfiguration prüfen
rcctl set dhcpd flags em1Interface festlegen, auf dem dhcpd lauscht
cat /var/db/dhcpd.leasesVergebene Leases nachsehen
Muster für alle Basisdienste: Konfiguration liegt flach in /etc, jeder Daemon hat einen Syntaxtest (-n bzw. -t), läuft unter eigenem _dienst-User im chroot und wird ausschließlich mit rcctl verwaltet. Reihenfolge immer: Syntaxtest → reload → Log prüfen.
root-Mail lesen: /etc/daily, syspatch und die Security-Reports schreiben an root. Ohne einen Alias in /etc/mail/aliases auf eine echte Adresse gehen diese Hinweise unter.

👥User, Gruppen & doas

adduserInteraktiv anlegen – fragt Klasse, Gruppen, Shell, Passwort ab
adduser -batch rene wheel "Rene Pfeifer" geheimNicht-interaktiv (für Skripte)
useradd -m -s /bin/ksh -G wheel reneAnlegen mit Homedir aus /etc/skel
useradd -DAktuelle Vorgaben für neue User anzeigen
usermod -G wheel,operator reneSekundäre Gruppen setzen (ersetzt die bisherige Liste!)
usermod -s /bin/sh reneShell ändern
usermod -L daemon reneLogin-Klasse aus /etc/login.conf zuweisen
usermod -l rpfeifer reneBenutzer umbenennen
userdel reneUser entfernen, Home bleibt stehen
userdel -r reneUser samt Homedirectory entfernen
vipw/etc/master.passwd sicher bearbeiten (baut die DB neu)
pwd_mkdb -p /etc/master.passwdPasswort-Datenbanken manuell neu erzeugen
chpass reneEinzelnen Datensatz im Editor ändern (Shell, Gecos, Ablauf)
passwd renePasswort setzen (bcrypt gemäß login.conf)
groupadd projektGruppe anlegen (-g für feste GID)
groupmod -n neu altGruppe umbenennen
groupdel projektGruppe löschen
/etc/groupGruppenmitgliedschaften; wheel darf su zu root
id rene / groups reneUID, GID und alle Gruppen eines Users
w / who / usersWer ist angemeldet, seit wann, von wo
last / last reneLogin-Historie aus /var/log/wtmp
lastcommAusgeführte Kommandos (nur bei aktivem Accounting)
su -lZu root wechseln mit dessen Environment (nur wheel)
grep sshd /var/log/authlog | tail -30Fehlgeschlagene Anmeldungen prüfen

doas – Rechteerweiterung

/etc/doas.confRegelwerk; existiert nach der Installation nicht und muss angelegt werden
doas -C /etc/doas.confKonfiguration auf Syntaxfehler prüfen
doas -C /etc/doas.conf pfctl -siPrüfen, ob ein bestimmtes Kommando erlaubt wäre
doas -LGemerkte Authentifizierung (persist) sofort verwerfen
doas -u _postgresql psqlAls anderer Benutzer statt root ausführen
doas -sRoot-Shell starten
permit persist keepenv :wheelTypische Regel: Gruppe wheel, Passwort wird für 5 min gemerkt
permit nopass rene cmd /sbin/pfctl args -siGenau ein Kommando ohne Passwort erlauben
deny rene cmd /bin/shExplizit verbieten (letzte passende Regel gewinnt)
doas.conf fehlt = kein doas: Ohne /etc/doas.conf funktioniert doas gar nicht. Datei anlegen, chown root:wheel, chmod 0600 und mit doas -C prüfen – bevor man sich per sshd_config den direkten Root-Login abschneidet.
Kein sudo im Basissystem: sudo ist nur ein Paket. Standard ist doas – deutlich kleiner, mit einer Konfigurationsdatei von wenigen Zeilen. In Skripten doas -n nutzen, damit kein Passwortprompt blockiert.

🔒Security-Härtung

Securelevel & unveränderliche Dateien

sysctl kern.securelevelAktuelle Stufe: -1 permissiv, 0 unsicher, 1 sicher (Standard), 2 hochsicher
sysctl kern.securelevel=2Anheben – nur nach oben möglich, Absenken nur per Reboot
/etc/rc.securelevelKommandos, die noch bei Level 0 laufen müssen
chflags schg /usr/local/bin/wichtigSystem-Immutable-Flag setzen (Datei nicht mehr änderbar)
chflags noschg dateiFlag entfernen – nur bei Securelevel 0 möglich
chflags -R schg /bin /sbinGanze Verzeichnisbäume schreibgeschützt machen
ls -lo /bin/lsGesetzte Flags anzeigen (schg, uchg, uappnd)
sysctl kern.allowkmemZugriff auf /dev/mem (sollte 0 sein)
sysctl ddb.console=0Kernel-Debugger über die Konsole sperren
sysctl ddb.panic=0Bei Panic nicht in den Debugger, sondern Dump und Reboot
/etc/sysctl.confAlle Härtungs-sysctls dauerhaft ablegen

Integrität & Reports

signify -Vp /etc/signify/openbsd-79-base.pub -x SHA256.sig -m -Signatur der offiziellen Sets prüfen
signify -C -p /etc/signify/openbsd-79-base.pub -x SHA256.sigChecksummenliste prüfen und Dateien vergleichen
ls /etc/signify/Mitgelieferte Public Keys für Basis und Pakete
sh /etc/securitySicherheits-Check manuell starten (läuft täglich automatisch)
ls /etc/mtree/Referenz-Hierarchien für Rechte und Besitzer
mtree -f /etc/mtree/special -p / | lessAbweichungen bei Rechten sicherheitsrelevanter Pfade finden
grep -A20 "insecurity" /var/log/messagesAuffälligkeiten aus dem Security-Report nachlesen
find / -xdev -type f -perm -4000 -lsAlle setuid-Dateien auflisten und mit dem Report vergleichen
find / -xdev -nouser -o -nogroupDateien ohne gültigen Besitzer (Reste alter User)

Angriffsfläche verkleinern

rcctl ls onBestandsaufnahme: welche Dienste laufen wirklich?
rcctl disable dienstAlles Unnötige abschalten – der wirksamste Einzelschritt
netstat -na -f inet -p tcp | grep LISTENOffene Ports prüfen und gegen die Dienstliste halten
PermitRootLogin noIn sshd_config: kein direkter Root-Login
PasswordAuthentication noNur Schlüssel zulassen (vorher Key testen!)
AllowGroups wheel sshusersSSH auf bestimmte Gruppen begrenzen
block log allpf-Grundsatz: Default-Deny, danach gezielt öffnen
umask 077 in /etc/login.confRestriktive Standardrechte je Login-Klasse
nodev,nosuid für Datenpartitionenfstab-Optionen: keine Devices, keine setuid-Binäries
pledge & unveil: Nahezu alle Basisdienste schränken sich selbst ein: pledge(2) begrenzt die erlaubten Syscalls, unveil(2) den sichtbaren Dateisystemausschnitt. Als Admin muss man nichts konfigurieren – aber wissen, dass ein Dienst nach einem Konfigurationsfehler mit „Abort trap“ endet, wenn er auf einen Pfad zugreift, den er sich selbst verboten hat. Dann Log lesen, nicht Rechte aufweiten.
chflags braucht Securelevel: Das schg-Flag wirkt erst ab Securelevel 1 – also im Normalbetrieb. Es lässt sich nur im Single-User-Mode (Securelevel 0) wieder entfernen. Vorsicht bei Dateien, die syspatch oder sysupgrade ersetzen wollen: das Update scheitert sonst.
Securelevel 2: Zusätzlich zu Level 1 sind Rohzugriffe auf gemountete Platten und Änderungen an der pf-Konfiguration und der Systemzeit gesperrt. Sehr wirksam für Firewalls – aber jede Regeländerung erfordert dann einen Reboot. Vorher testen, ob alle Dienste damit zurechtkommen.

📜Logs & Fehlersuche

dmesg | tail -40Neueste Kernel-Meldungen (Hardware, Treiber, Fehler)
cat /var/run/dmesg.bootVollständige Boot-Ausgabe
tail -f /var/log/messagesAllgemeines Systemlog live mitlesen
tail -f /var/log/authlogAnmeldungen, doas, su, sshd
tail -f /var/log/daemonMeldungen der Daemons (httpd, unbound, ntpd …)
/var/log/secureSicherheitsrelevante Meldungen (auth.info und höher)
/var/log/maillogsmtpd-Protokoll
/var/log/xferlogFTP-Übertragungen
/var/log/pflogBinäres pf-Log, nur mit tcpdump -r lesbar
/var/log/wtmp, /var/log/lastlogLogin-Historie für last bzw. lastlogin
zgrep -i error /var/log/messages.*.gzAuch in rotierten Logs suchen
grep -i 'panic\|error\|fail' /var/log/messages | tail -40Schnellsuche nach harten Fehlern
newsyslog -n / newsyslog -FRotation testen / erzwingen
ls -lt /var/log | headWelche Logs sind aktiv, welche stehen still?

Tiefergehende Analyse

fstat | grep /varWer hält Dateien in einem Filesystem offen?
fstat -p 1234Alle File Descriptors eines Prozesses
ktrace -f /tmp/tr -p 1234; sleep 5; ktrace -CSyscalls kurz mitschneiden, Tracing global beenden
kdump -f /tmp/tr | lessMitschnitt lesbar aufbereiten
ktrace -di -f /tmp/tr cmdKommando samt Kindprozessen von Anfang an tracen
ps -axl | awk '$3 ~ /D/'Prozesse im ununterbrechbaren I/O-Wait finden
tcpdump -n -e -ttt -i pflog0Blockt die Firewall den Dienst?
pfctl -sipf-Zähler: State-Limit erreicht? Fragmente verworfen?
savecore /var/crashCrashdump aus dem Swap in Dateien ausschreiben
ls -l /var/crash/Vorhandene Dumps (bsd.0.gz, bsd.0.core)
sysctl ddb.trigger=1Bewusst in den Kernel-Debugger springen (nur bei Analyse!)
trace / ps / show panic (in ddb)Stack, Prozessliste und Panic-Ursache im Debugger
boot dump (in ddb)Dump schreiben und neu starten
Crashdumps vorbereiten: Ein Dump braucht eine Swap-Partition, die mindestens so groß wie der physische Speicher ist, sowie /var/crash mit genug Platz. Danach sysctl ddb.panic=0, damit das System nach der Panic automatisch dumpt und rebootet statt am Debugger-Prompt zu warten.
Manpages sind die Referenz: OpenBSDs Handbuchseiten sind Teil des Systems und immer zur installierten Version passend. Vor jeder Websuche erst man 8 dienst, man 5 datei und apropos begriff – die Trefferquote ist höher als bei jedem Blogartikel. Einstieg für neue Systeme: man afterboot.

💾Backup, Migration & Installation

dump / restore – das FFS-Werkzeug

dump -0uaf /mnt/home.dump /homeVollbackup (Level 0), Datum in /etc/dumpdates vermerken
dump -1uaf /mnt/home.d1 /homeInkrementell: alles seit dem letzten niedrigeren Level
dump -0af - /home | gzip > /mnt/home.dump.gzAuf stdout dumpen und komprimieren
dump -0af - /home | ssh backup dd of=/srv/home.dumpDirekt auf einen anderen Host schreiben
dump -WWelche Filesysteme sind laut /etc/dumpdates fällig?
restore -tf /mnt/home.dumpInhaltsverzeichnis des Archivs anzeigen
restore -if /mnt/home.dumpInteraktiv einzelne Dateien auswählen (add, extract)
restore -rf /mnt/home.dumpKomplettes Filesystem in ein leeres FS zurückschreiben
restore -xf /mnt/home.dump ./pfadGezielt einen Pfad wiederherstellen

Weitere Wege

tar -czf /mnt/etc.tgz /etcKlassisches Archiv mit gzip
tar -xzpf /mnt/etc.tgz -C /Zurückspielen, Rechte erhalten
tar -cf - /etc | ssh host 'cat > /srv/etc.tar'Über SSH streamen
pax -rw -pe /home /mnt/homeVerzeichnis kopieren, alle Attribute erhalten
cpdup / rsync -aH --delete src/ dst/Spiegel-Kopien (rsync ist ein Paket, nicht Basis)
cp -Rp /etc /mnt/etc-backupSchnelle lokale Kopie mit Rechten
dd if=/dev/rsd0c of=/mnt/sd0.img bs=1mRohabbild der Systemplatte (System vorher stoppen!)
disklabel sd0 > /root/label.sd0; fdisk sd0 > /root/fdisk.sd0Partitionierung dokumentieren – klein, aber unverzichtbar
pkg_info -mz > /root/pkglistInstallierte Pakete versionsneutral sichern
tar -czf /root/etc-$(date +%F).tgz /etc /var/cron /var/wwwMinimales Konfigurations-Backup für Wiederaufbau

/altroot & unbeaufsichtigte Installation

ROOTBACKUP=1 in /etc/daily.localTägliche Sicherung der Root-Partition nach /altroot aktivieren
/dev/sd0j /altroot ffs xx 0 0Passender fstab-Eintrag: Mountoption xx, Verzeichnis muss existieren
/etc/changelistDateien, deren Änderungen der tägliche Report melden soll
/etc/daily.local /etc/weekly.local /etc/monthly.localEigene Wartungsaufgaben einhängen
/install.siteSkript, das am Ende einer Neuinstallation im Ziel-Root läuft
/upgrade.siteDasselbe für Upgrades (auch bei sysupgrade)
/auto_install.confAntwortdatei für unbeaufsichtigte Installation (autoinstall)
/auto_upgrade.confAntwortdatei für unbeaufsichtigtes Upgrade
boot bsd.rd -> "A" (autoinstall)Installer holt die Antwortdatei per DHCP/HTTP vom Server
Wiederaufbau in 20 Minuten: OpenBSD-Systeme lassen sich fast immer schneller neu installieren als reparieren. Wer /etc, /var/cron, die Labels, pkglist und die Daten hat, ist nach Neuinstallation, pkg_add -l und dem Zurückspielen von /etc wieder produktiv.
dump und laufende Systeme: dump auf ein gemountetes, aktiv beschriebenes Filesystem kann inkonsistente Archive liefern. Sauber ist ein Lauf im Single-User-Mode oder auf ein read-only gemountetes FS. Da OpenBSD keine Snapshots kennt, ist das die einzige echte Absicherung.

🧩Virtualisierung mit vmm/vmd

dmesg | grep vmmVoraussetzung prüfen: vmm0 at mainbus0 muss erscheinen
rcctl enable vmd && rcctl start vmdHypervisor-Daemon aktivieren und starten
/etc/vm.confDeklarative VM- und Switch-Definitionen
vmd -nKonfiguration prüfen
vmctl statusAlle VMs mit ID, Speicher, Zustand und Besitzer
vmctl create -s 20G /home/vm/web.qcow2Neues Disk-Image anlegen (qcow2 oder raw)
vmctl start web -m 2G -d /home/vm/web.qcow2 -i 1 -cVM starten und direkt auf die Konsole verbinden
vmctl start web -b /bsd.rd -d /home/vm/web.qcow2 -cVon bsd.rd booten, um das Gastsystem zu installieren
vmctl console webAn die serielle Konsole andocken (Verlassen mit ~.)
vmctl stop webVM sauber herunterfahren (-f erzwingt, -w wartet)
vmctl stop -aAlle VMs stoppen
vmctl pause web / vmctl unpause webVM anhalten und weiterlaufen lassen
vmctl reset allAlle VMs und Switches zurücksetzen
vmctl load /etc/vm.confKonfiguration ohne Neustart von vmd einlesen
vmctl reloadAlles zurücksetzen und /etc/vm.conf neu laden
vmctl send web > /mnt/web.dumpLaufende VM in eine Datei serialisieren
vmctl receive web < /mnt/web.dumpVM aus der Datei wiederherstellen
ifconfig tap0Host-Seite der VM-Netzwerkverbindung
/etc/hostname.veb0 bzw. bridge0tap-Interfaces mit dem physischen Netz verbinden
chown build:build /home/vm/*.qcow2Nicht-root-Besitzer, damit User ihre VMs selbst starten können
Grenzen von vmm: Nur amd64 (und arm64) mit Hardware-Virtualisierung (Intel VMX / AMD SVM). Verschachtelte Virtualisierung gibt es nicht – in einer VMware- oder KVM-Gast-Instanz läuft vmd in der Regel nicht. Als Gäste sind OpenBSD, andere BSDs und Linux vorgesehen; kein Windows, keine Grafikausgabe (nur serielle Konsole).
Dauerhaft über vm.conf: VMs, die beim Boot starten sollen, gehören nach /etc/vm.conf (mit owner, memory, disk, interface), nicht in ein rc.local-Skript. vmctl start ist für Tests und Installationen gedacht.

📂Wichtige Dateien & Verzeichnisse

Konfiguration in /etc

/etc/rc.conf.localAktivierte Dienste und ihre Flags (per rcctl pflegen)
/etc/rc.local /etc/rc.shutdown /etc/rc.securelevelEigene Kommandos beim Start, Stopp und vor Securelevel-Wechsel
/etc/hostname.em0, /etc/hostname.vlan10Netzwerkkonfiguration je Interface
/etc/myname /etc/mygate /etc/hostsHostname, Default-Gateway, statische Namen
/etc/resolv.confNameserver (wird von resolvd verwaltet)
/etc/pf.confFirewall-Regelwerk
/etc/fstabFilesysteme und Swap – mit DUIDs statt sdX
/etc/doas.confWer darf was als root ausführen
/etc/login.conf, /etc/login.conf.d/Login-Klassen, Limits, Passwort-Hashing
/etc/sysctl.confDauerhafte Kernel-Parameter
/etc/installurlMirror für Pakete, Patches und Upgrades
/etc/pkg.confOptionen der pkg-Werkzeuge
/etc/boot.confDauerhafte Bootloader-Anweisungen
/etc/syslog.conf, /etc/newsyslog.confLogziele und Logrotation
/etc/daily.local, /etc/changelistEigene Wartung, überwachte Dateien
/etc/master.passwd, /etc/groupBenutzer (nur über vipw) und Gruppen
/etc/signify/Public Keys zur Signaturprüfung von Sets und Paketen
/etc/ssh/sshd_configSSH-Server
/etc/vm.confVM-Definitionen für vmd

Daten, Logs & Systempfade

/bsd, /bsd.mp, /bsd.sp, /bsd.rd, /obsdKernel: aktiv, MP, SP, RAM-Disk, Vorgänger
/var/run/dmesg.bootBoot-Meldungen als Datei
/var/log/messages, authlog, daemon, secureDie vier wichtigsten Logdateien
/var/log/pflogpf-Log (binär, mit tcpdump -r lesen)
/var/cron/tabs/crontabs der Benutzer
/var/syspatch/Rollback-Archive installierter Patches
/var/crash/Kernel-Crashdumps
/var/www/chroot von httpd
/var/unbound/, /var/nsd/chroots der DNS-Dienste samt Konfiguration
/home/_sysupgrade/Von sysupgrade geladene Installations-Sets
/usr/local/Alles aus Paketen und Ports (Basissystem bleibt sauber)
/usr/share/relink/Objekte für das KARL-Kernel-Relinking
/usr/ports/, /usr/src/Ports-Tree und Quellcode (optional)
/dev/sd0a vs. /dev/rsd0aBlock-Device (mount) vs. Raw-Device (newfs, fsck, dd)
/altrootZiel der täglichen Root-Sicherung
Trennung Basis / Pakete: Das Basissystem liegt komplett unter /bin, /sbin, /usr/bin, /usr/sbin und wird gemeinsam als ein Ganzes entwickelt und aktualisiert. Alles aus Paketen landet unter /usr/local. Diese Trennung macht Updates vorhersagbar – und Backups von /etc plus Paketliste ausreichend.

🔧Shell, Manpages & Praxis-Workflows

Dokumentation

man 8 rcctlGezielt die Section angeben (8 = Systemverwaltung, 5 = Dateiformate)
man -k firewall / apropos pfAlle Manpages nach Stichwort durchsuchen
man -s 5 pf.confDas komplette pf-Regelsyntax-Handbuch
man afterbootCheckliste für alles, was nach einer Installation zu tun ist
man hierErklärung der gesamten Verzeichnisstruktur
man intro / man 8 introEinstieg in eine Manpage-Section
whatis rcctl / man -f rcctlEinzeilige Beschreibung eines Kommandos
man -w rcctlPfad zur Quelldatei der Manpage
/usr/share/doc/, man faqWeitere Dokumentation im System

ksh & Werkzeuge

set -o vivi-Editiermodus (Esc, dann k für History) – in ~/.profile
set -o emacsemacs-Tastenbelegung als Alternative
PS1='\u@\h:\w\$ 'Prompt mit User, Host und Pfad
~/.profile, /etc/ksh.kshrc, ENVLogin-Profil, systemweite ksh-Einstellungen, Startdatei
which cmd / whereis cmd / type cmdPfad, Manpage-Ort und Typ eines Kommandos
grep -rn "muster" /etcRekursiv mit Zeilennummern durchsuchen
sed -i.bak 's/alt/neu/g' dateiIn-place ersetzen und Backup anlegen
awk '{print $1, $5}' dateiSpalten extrahieren
for i in $(rcctl ls on); do rcctl check $i; doneAlle aktivierten Dienste durchprüfen
find /var/log -mtime -1 -type fWas hat sich im letzten Tag geändert?
script /tmp/session.logKomplette Sitzung protokollieren (Change-Nachweis)
tee -a /tmp/logAusgabe anzeigen und gleichzeitig mitschreiben
gzip -9 / bzip2 / xz / zstdKomprimieren; Sets und Pakete nutzen .tgz
install -d -o www -g www -m 0755 /var/www/htdocs/appVerzeichnis mit Besitzer und Rechten in einem Schritt
# Neuen Server aufsetzen und haerten (nach der Installation)
man afterboot                                  # Checkliste durcharbeiten
echo https://cdn.openbsd.org/pub/OpenBSD > /etc/installurl
syspatch && fw_update                          # Patch- und Firmwarestand
cat > /etc/doas.conf <<'EOF'
permit persist keepenv :wheel
EOF
chmod 0600 /etc/doas.conf && doas -C /etc/doas.conf
# --- SSH absichern (Key vorher testen!) ---
vi /etc/ssh/sshd_config    # PermitRootLogin no / PasswordAuthentication no / AllowGroups wheel
sshd -t && rcctl reload sshd
# --- Dienste reduzieren ---
rcctl ls on                                    # Bestandsaufnahme
rcctl disable smtpd                            # Beispiel: nicht gebraucht
netstat -na -f inet -p tcp | grep LISTEN       # offene Ports gegenpruefen
# --- Firewall ---
vi /etc/pf.conf                                # Default-Deny plus benoetigte Dienste
pfctl -nf /etc/pf.conf && pfctl -f /etc/pf.conf
rcctl enable pf
# --- Zeit, Logging, Mail ---
rcctl enable ntpd && rcctl start ntpd && ntpctl -s all
vi /etc/mail/aliases                           # root: admin@example.com
newaliases
echo 'ROOTBACKUP=1' >> /etc/daily.local        # /altroot-Sicherung
# --- Pakete und Doku ---
pkg_add -u
pkg_info -mz > /root/pkglist
disklabel sd0 > /root/label.sd0
sysctl -a > /root/sysctl-baseline.txt
reboot                                         # Kaltstart-Test - jetzt, nicht in 6 Monaten
Merksatz: OpenBSD ist konsequent einfach gehalten: eine Konfigurationsdatei pro Dienst, ein Werkzeug pro Aufgabe (rcctl, pfctl, bioctl, disklabel), und die Manpage ist immer aktueller als jede fremde Anleitung. Temporäre Änderungen per ifconfig, sysctl, mount oder route sind nach dem Reboot weg – dauerhaft wird es erst in /etc/hostname.if, /etc/sysctl.conf, /etc/fstab bzw. /etc/mygate.
Keine Linux- oder FreeBSD-Reflexe: Es gibt kein systemctl, service, journalctl, ip, iptables, lsblk, apt, sysrc, gpart und kein ZFS. Die Entsprechungen heißen rcctl, syslogd/tail, ifconfig, pfctl, disklabel, pkg_add und softraid.