FreeBSD Administration Cheat Sheet

FreeBSD 13 / 14 · ZFS · pf · Jails · bhyve
Keine Treffer – Suchbegriff anpassen.

💻System-Informationen

uname -a / uname -KUVollständige Kennung / Kernel- und Userland-Version als Zahl (z. B. 1401000)
freebsd-version -kruInstallierter Kernel (k), laufender Kernel (r), Userland (u) – wichtig nach Patches
sysctl hw.model hw.ncpu hw.physmemCPU-Modell, CPU-Anzahl, physischer Speicher in Byte
sysctl -a | lessAlle Kernel-Variablen (mehrere tausend Einträge)
dmesg | less bzw. cat /var/run/dmesg.bootAktuelle Kernel-Meldungen / Meldungen vom letzten Boot
pciconf -lvPCI-Geräte mit Klartext-Beschreibung und Treiber
devinfo -rvGerätebaum mit belegten Ressourcen (IRQ, I/O)
kenvKernel-Environment (vom Loader gesetzte Variablen)
uptime / wLaufzeit und Load Average / angemeldete Benutzer
hostname / sysrc hostnameAktueller Hostname / dauerhaft in rc.conf hinterlegter Wert
df -h / df -hT ufs,zfsBelegung aller Dateisysteme / gefiltert nach Typ
swapinfo -hSwap-Geräte und Auslastung
sysctl kern.boottimeExakter Zeitpunkt des letzten Systemstarts
sysctl machdep.hyperv_featuresHyper-V-Erkennung; für VMware siehe kenv smbios.system.product
kenv smbios.system.maker smbios.system.productHersteller und Modell – erkennt auch VMware/KVM/VirtualBox
ntpq -p / chronyc sourcesZeitsynchronisation prüfen (je nach eingesetztem Dienst)
Vor jedem Change dokumentieren: freebsd-version -kru; uname -a; zpool status; df -h; ifconfig -a; pkg -vv | head – in eine Datei umlenken und im Ticket ablegen.

⏻Boot & Loader

shutdown -r now / rebootSauberer Neustart (shutdown benachrichtigt Benutzer)
shutdown -p now / poweroffHerunterfahren und ausschalten
shutdown -r +10 "Wartung"Neustart in 10 Minuten mit Meldung an alle Sitzungen
shutdown nowIn den Single-User-Modus wechseln (ohne Reboot)
/boot/loader.confDauerhafte Loader-Einstellungen: Module, Tunables, autoboot_delay
/boot/loader.conf.localLokale Ergänzungen – wird bei Updates nicht überschrieben
boot -s (im Loader-Prompt)Single-User booten, z. B. für Root-Passwort-Reset
unload / load kernel.old / bootAlten Kernel starten, wenn der neue nicht bootet
set kern.geom.label.disk_ident.enable=0Beispiel: Loader-Variable interaktiv setzen (Prompt OK)
nextboot -k kernel.oldEinmalig mit anderem Kernel booten – danach wieder Standard
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0Bootcode für GPT+ZFS neu schreiben (BIOS-Boot)
efibootmgr -vUEFI-Booteinträge anzeigen (FreeBSD 13+)
sysctl vfs.root.mountfromWoher wurde die Root gemountet – hilft bei Boot-Problemen

Root-Passwort zurücksetzen

Im Loader-Menü Option 2 (Single User) wählen
Enter bei "Enter full pathname of shell..."
zfs:   zfs mount -a
ufs:   mount -u /  &&  mount -a -t ufs
passwd root
exit                                   # bootet weiter in den Mehrbenutzerbetrieb
Achtung: Single-User-Zugang setzt physischen bzw. Konsolen-Zugriff voraus. Wer das verhindern will, setzt in /etc/ttys die Konsole auf insecure – dann verlangt Single-User das Root-Passwort.

⚙Dienste, rc.d & sysrc

service -eAlle aktivierten Dienste in Startreihenfolge
service -lAlle verfügbaren rc-Skripte (auch nicht aktivierte)
service sshd statusStatus eines Dienstes inkl. PID
service nginx start | stop | restartDienst starten / stoppen / neu starten
service nginx reloadKonfiguration neu einlesen ohne Verbindungsabbruch
service nginx onestartDienst starten, obwohl er in rc.conf nicht aktiviert ist
sysrc nginx_enable=YESDienst dauerhaft aktivieren (schreibt sauber in /etc/rc.conf)
sysrc -x nginx_enableEintrag wieder aus rc.conf entfernen
sysrc -aAlle aktuell gesetzten rc-Variablen anzeigen
sysrc ifconfig_em0="inet 10.0.0.5/24"Typisches Beispiel: Netzwerkkonfiguration dauerhaft setzen
sysrc -f /etc/rc.conf.local key=valueIn eine andere rc-Datei schreiben
/etc/rc.conf · /etc/rc.conf.d/<dienst>Zentrale Konfiguration bzw. pro Dienst getrennte Dateien
/etc/defaults/rc.confVorgabewerte – nur lesen, nie ändern
/usr/local/etc/rc.d/rc-Skripte aus Paketen (Basis-System liegt in /etc/rc.d/)
service sshd rcvarZeigt, welche rc-Variable den Dienst steuert und ihren Wert
/etc/rc.localEigene Startbefehle am Ende des Bootvorgangs
Merksatz: sysrc statt Editor. Es prüft die Syntax, legt fehlende Einträge an und ändert bestehende, ohne die Datei zu zerstören.

📦Paketverwaltung (pkg)

pkg update / pkg update -fPaketkatalog aktualisieren / erzwungen neu laden
pkg search nginxVerfügbare Pakete suchen
pkg install nginxPaket samt Abhängigkeiten installieren
pkg install -y -r FreeBSD nginxOhne Rückfrage aus einem bestimmten Repository installieren
pkg info / pkg info -x nginxInstallierte Pakete / gefiltert per Muster
pkg info -l nginxAlle Dateien eines Pakets auflisten
pkg which /usr/local/sbin/nginxZu welchem Paket gehört diese Datei?
pkg upgrade / pkg upgrade -nAlle Pakete aktualisieren / erst nur anzeigen (Trockenlauf)
pkg delete nginx / pkg autoremovePaket entfernen / verwaiste Abhängigkeiten aufräumen
pkg lock nginx / pkg unlock nginxPaket gegen Updates sperren / wieder freigeben
pkg check -d / pkg check -sFehlende Abhängigkeiten / veränderte Prüfsummen finden
pkg audit -FInstallierte Pakete gegen bekannte Sicherheitslücken prüfen
pkg clean -aPaket-Cache unter /var/cache/pkg leeren
pkg query "%n-%v %sh" | sortName, Version und Größe aller Pakete – gut für Inventar
pkg rquery "%n %v" nginxVersion im Repository abfragen, ohne zu installieren
pkg annotate -S nginx note "Prod-Webserver"Eigene Notiz an ein Paket hängen
/usr/local/etc/pkg/repos/*.confEigene oder interne Repositories definieren
pkg -o ASSUME_ALWAYS_YES=yes install …Nicht-interaktiv, z. B. in Skripten
Wichtig: Pakete stammen aus dem Zweig quarterly (Vorgabe, stabiler) oder latest. Umstellen in /usr/local/etc/pkg/repos/FreeBSD.conf – danach pkg update -f && pkg upgrade. Nicht mitten in einem Cluster mischen.

🔧Ports & System-Updates

freebsd-update fetch installSicherheits-Patches für Basis-System holen und einspielen
freebsd-update -r 14.1-RELEASE upgradeMajor-/Minor-Upgrade vorbereiten
freebsd-update install (nach Reboot erneut)Beim Upgrade dreimal nötig: Kernel, Reboot, Userland, Reboot
freebsd-update rollbackLetztes Update zurücknehmen
freebsd-update cronZeitversetzt Updates herunterladen (nicht installieren)
git clone https://git.FreeBSD.org/ports.git /usr/portsPorts-Baum beziehen (früher portsnap)
cd /usr/ports/www/nginx && make configBuild-Optionen im Menü wählen
make install cleanPort übersetzen, installieren, Bauverzeichnis aufräumen
make deinstall / make reinstallPort entfernen / neu installieren
make showconfig / make rmconfigGewählte Optionen anzeigen / zurücksetzen
make search name=nginxIm Ports-Baum suchen
/usr/ports/UPDATINGUnbedingt vor größeren Updates lesen – Sonderfälle stehen hier
/usr/src/UPDATINGGleiches für das Basis-System bei Quell-Updates
poudriere bulk -j 141amd64 -p default -f pkglistEigene Paket-Builds im Bulk (saubere Jail-Umgebung)
etcupdate / mergemaster -UiKonfigurationsdateien unter /etc nach Quell-Update abgleichen
Nie mischen: Entweder Pakete (pkg) oder selbst gebaute Ports. Wer beides mischt, bekommt früher oder später Bibliotheks-Konflikte. Für eigene Optionen ist poudriere der saubere Weg – es liefert wieder normale Pakete.

🧩Kernel, Module & sysctl

kldstat / kldstat -vGeladene Kernel-Module / mit allen enthaltenen Treibern
kldload if_laggModul sofort laden
kldunload if_laggModul entladen (nur wenn nicht in Benutzung)
if_lagg_load="YES" in /boot/loader.confModul dauerhaft beim Boot laden
sysctl vfs.zfs.arc_maxWert einer Kernel-Variable lesen
sysctl kern.ipc.somaxconn=4096Wert zur Laufzeit setzen (bis zum nächsten Reboot)
/etc/sysctl.confDauerhafte sysctl-Werte (nur zur Laufzeit änderbare Variablen)
sysctl -d kern.maxfilesKurzbeschreibung einer Variable anzeigen
sysctl -a | grep -i zfs.arcGezielt nach Variablen suchen
cd /usr/src && make buildkernel KERNCONF=MYKERNEigenen Kernel übersetzen
make installkernel KERNCONF=MYKERNKernel installieren – alter landet als /boot/kernel.old
make buildworld && make installworldUserland aus Quellen bauen und installieren
/usr/src/sys/amd64/conf/GENERICVorlage für eigene Kernel-Konfigurationen
sysctl security.bsd.see_other_uids=0Härtung: Benutzer sehen nur eigene Prozesse
Unterschied merken: loader.conf setzt Variablen, die nur beim Boot wirken (Tunables, sysctl -T zeigt sie). sysctl.conf setzt Variablen, die zur Laufzeit änderbar sind. Wenn sysctl mit read only abbricht, gehört der Wert in die loader.conf.

🔧Geräte & Datenträger

camcontrol devlistAlle SCSI-/SATA-/SAS-Geräte mit Modell und Seriennummer
camcontrol rescan allBus neu abtasten – neue LUNs sichtbar machen
camcontrol reprobe da3Nach Größenänderung einer LUN die neue Kapazität übernehmen
camcontrol identify ada0ATA-Identifikation (Firmware, Features, Rotationsrate)
geom disk listAlle Platten mit Größe, Sektorgröße und Beschreibung
gpart show / gpart show -lPartitionstabellen / mit Labels
geom label status / glabel statusVergebene GEOM-Labels und zugeordnete Geräte
gmultipath status / gmultipath listMultipath-Zustand bei SAN-Anbindung
gmultipath label -v MPATH1 /dev/da4 /dev/da5Zwei Pfade zu einem Multipath-Gerät zusammenfassen
smartctl -a /dev/ada0SMART-Werte auslesen (Paket smartmontools)
usbconfig / usbconfig show_ifdrvUSB-Geräte / mit zugeordnetem Treiber
devctl list / devctl disable da3Geräte-Zustand anzeigen / Gerät im Kernel deaktivieren
diskinfo -v /dev/ada0Sektorgröße, Kapazität, Geometrie
diskinfo -t /dev/ada0Kurzer Durchsatz- und Zugriffszeit-Test
/etc/devd.conf · /usr/local/etc/devd/Regeln für Geräte-Ereignisse (Hotplug-Aktionen)
Gerätenamen: ada* = ATA/SATA, da* = SCSI/SAS/USB-Massenspeicher, nda*/nvd* = NVMe, vtbd* = VirtIO-Block. Namen können sich beim Boot verschieben – deshalb in /etc/fstab besser Labels (/dev/gpt/…, /dev/ufs/…) verwenden.

💾Partitionierung (gpart)

gpart show ada0Partitionsschema und freie Bereiche
gpart create -s gpt ada1Neue GPT-Partitionstabelle anlegen
gpart add -t freebsd-ufs -a 1m -l data1 ada1UFS-Partition über den restlichen Platz, ausgerichtet, mit Label
gpart add -t freebsd-swap -s 8G -l swap1 ada1Swap-Partition fester Größe
gpart add -t freebsd-zfs -l zdisk1 ada1Partition für ZFS (empfohlen statt ganzer Platte bei Boot-Pools)
gpart delete -i 3 ada1Partition mit Index 3 entfernen
gpart destroy -F ada1Gesamte Partitionstabelle löschen (erzwungen)
gpart resize -i 3 -s 200G ada1Partition vergrößern (Platz dahinter muss frei sein)
gpart recover ada0Beschädigte GPT-Sicherungskopie wiederherstellen
gpart backup ada0 > /root/ada0.gptPartitionslayout sichern
gpart restore -F ada1 < /root/ada0.gptLayout auf eine zweite Platte übertragen (Spiegel-Vorbereitung)
gpart modify -i 1 -l boot1 ada0Label einer bestehenden Partition ändern
gpart set -a bootme -i 1 ada0Boot-Flag setzen (MBR/GPT je nach Schema)
Ausrichtung nicht vergessen: -a 1m bei jedem gpart add verhindert schlechte Performance auf SSDs und SAN-LUNs mit 4K-Sektoren.

🗃ZFS – Pools

zpool list / zpool list -vAlle Pools mit Kapazität / aufgeschlüsselt nach vdev
zpool status / zpool status -xVollständiger Zustand / nur Pools mit Problemen
zpool create tank mirror da1 da2Gespiegelten Pool anlegen
zpool create tank raidz2 da1 da2 da3 da4 da5RAIDZ2 (zwei Platten dürfen ausfallen)
zpool add tank mirror da6 da7Pool um ein weiteres vdev erweitern (nicht rückgängig zu machen)
zpool attach tank da1 da3Platte an bestehende hängen – macht aus Einzelplatte einen Spiegel
zpool detach tank da3Platte aus einem Spiegel lösen
zpool replace tank da3 da8Defekte Platte ersetzen (Resilver startet automatisch)
zpool offline / online tank da3Platte gezielt aus dem Betrieb nehmen / zurückholen
zpool scrub tank / zpool scrub -s tankKonsistenzprüfung starten / abbrechen
zpool clear tankFehlerzähler nach behobenem Problem zurücksetzen
zpool iostat -v 5I/O pro vdev im 5-Sekunden-Takt
zpool history tankAlle jemals ausgeführten Änderungen am Pool
zpool import / zpool import tankImportierbare Pools anzeigen / Pool einbinden
zpool import -f -R /mnt tankFremden Pool erzwungen unter alternativem Wurzelpfad importieren
zpool export tankPool sauber freigeben (vor Umzug auf anderen Server)
zpool upgrade -v / zpool upgrade tankVerfügbare Features / Pool auf neue Feature-Flags heben
zpool set autoexpand=on tankNach LUN-Vergrößerung automatisch mitwachsen
zpool add tank log mirror da9 da10Separates ZIL (SLOG) anlegen – nur bei synchronen Schreiblasten sinnvoll
zpool add tank cache da11L2ARC-Cache-Gerät hinzufügen
Kein Undo: zpool add fügt ein neues vdev hinzu und lässt sich nicht rückgängig machen. Wer versehentlich zpool add tank da3 statt zpool attach tippt, hat einen Pool ohne Redundanz. Immer erst zpool add -n (Trockenlauf) ausführen.

📁ZFS – Dateisysteme & Snapshots

zfs list / zfs list -t all -r tankDateisysteme / inkl. Snapshots und Volumes rekursiv
zfs create tank/dataNeues Dateisystem anlegen (mountet sofort)
zfs create -o mountpoint=/srv/app tank/appMit abweichendem Mountpoint anlegen
zfs create -V 20G tank/vol1Blockgerät (zvol) anlegen – z. B. für bhyve oder iSCSI
zfs destroy tank/data / zfs destroy -r tank/dataEntfernen / mitsamt Kindern und Snapshots
zfs get all tank/dataAlle Eigenschaften mit Quelle (local, inherited, default)
zfs set quota=100G tank/dataHarte Obergrenze inkl. Kinder und Snapshots
zfs set refquota=100G tank/dataObergrenze nur für die Nutzdaten (ohne Snapshots)
zfs set reservation=50G tank/dataPlatz fest reservieren
zfs set compression=lz4 tankKompression aktivieren – praktisch immer sinnvoll
zfs set atime=off tankZugriffszeiten abschalten, spart Schreib-I/O
zfs set recordsize=16k tank/dbBlockgröße an Datenbank anpassen
zfs snapshot tank/data@2026-08-18Snapshot erstellen (sofort, kostet zunächst keinen Platz)
zfs snapshot -r tank@vor-updateRekursiv über alle Kind-Dateisysteme
zfs rollback -r tank/data@2026-08-18Auf Snapshot zurücksetzen (neuere Snapshots werden verworfen)
zfs clone tank/data@snap tank/data-testBeschreibbare Kopie ohne Platzverbrauch
zfs diff tank/data@snap tank/dataWas hat sich seit dem Snapshot geändert?
zfs send tank/data@snap | zfs recv backup/dataVollständige Replikation
zfs send -i @alt tank/data@neu | ssh bkp zfs recv -F backup/dataInkrementell über SSH auf zweiten Server
zfs hold keep tank/data@snapSnapshot gegen versehentliches Löschen schützen
zfs mount -a / zfs unmount tank/dataAlle ZFS-Dateisysteme einhängen / eines aushängen
zfs list -o space -r tankPlatzverbrauch getrennt nach Daten, Snapshots und Kindern
Snapshots direkt lesen: unter /tank/data/.zfs/snapshot/<name>/ liegt der alte Stand read-only bereit – einzelne Dateien lassen sich einfach zurückkopieren, ohne Rollback. Sichtbar machen mit zfs set snapdir=visible tank/data.

📂UFS & Mounts

newfs -U -L data /dev/gpt/data1UFS2 mit Soft-Updates und Label anlegen
newfs -U -j /dev/gpt/data1Zusätzlich mit Journaling (SU+J) – schnellerer Check nach Absturz
tunefs -p /dev/gpt/data1Aktuelle Dateisystem-Parameter anzeigen
tunefs -n enable /dev/gpt/data1Soft-Updates nachträglich aktivieren (nur ungemountet)
mount / mount -pEingehängte Dateisysteme / im fstab-Format ausgeben
mount /dev/gpt/data1 /dataManuell einhängen
mount -o ro,noatime /dev/gpt/data1 /dataNur lesend, ohne Zugriffszeiten
mount -u -o rw /Root im laufenden Betrieb von read-only auf beschreibbar umstellen
umount /data / umount -f /dataAushängen / erzwingen
fstat -f /data / fuser -c /dataWer blockiert das Aushängen?
fsck -t ufs -y /dev/gpt/data1Dateisystem prüfen und automatisch reparieren
fsck -y -t ufs / (Single User)Root-Dateisystem prüfen – nur ungemountet oder read-only
growfs /dev/gpt/data1UFS auf die neue Partitionsgröße ausdehnen
df -i /dataInode-Belegung – Dateisystem kann trotz freiem Platz voll sein
du -h -d1 /var | sort -hGrößte Unterverzeichnisse finden
mdconfig -a -t vnode -f image.iso && mount -t cd9660 /dev/md0 /mntISO-Datei als Gerät einbinden
mdconfig -d -u 0Speicher-Gerät wieder freigeben
mount -t tmpfs -o size=2G tmpfs /tmpTemporäres Dateisystem im RAM
/etc/fstabDauerhafte Mounts – Felder: Gerät, Mountpoint, Typ, Optionen, Dump, Pass
Reihenfolge in fstab beachten: Die letzte Spalte (Pass) steuert die fsck-Reihenfolge: 1 für Root, 2 für alle anderen, 0 für überspringen. ZFS-Dateisysteme gehören nicht in die fstab.

🔄Swap & Speicher

swapinfo -h / swapctl -lSwap-Geräte, Größe und Auslastung
swapon /dev/gpt/swap1Swap-Partition aktivieren
swapoff /dev/gpt/swap1Deaktivieren – RAM muss den Inhalt aufnehmen können
swapon -a / swapoff -aAlle Einträge aus /etc/fstab aktivieren / deaktivieren
/dev/gpt/swap1 none swap sw 0 0Typischer fstab-Eintrag für Swap
zfs create -V 16G -o org.freebsd:swap=on tank/swapSwap auf ZFS-Volume (Checksummen und Cache besser abschalten)
zfs set primarycache=metadata secondarycache=none tank/swapEmpfohlene Einstellungen für Swap-zvol
mdconfig -a -t swap -s 4G && swapon /dev/md1Not-Swap zur Laufzeit anlegen
top -o resProzesse nach tatsächlichem Speicherverbrauch sortieren
vmstat -s | head -20Kumulierte Speicher- und Paging-Statistik
sysctl vm.stats.vm.v_free_count vm.stats.vm.v_page_countFreie und gesamte Speicherseiten
sysctl vfs.zfs.arc_max=8589934592ARC begrenzen (hier 8 GB) – dauerhaft in /boot/loader.conf
sysctl kstat.zfs.misc.arcstats.sizeAktuelle ARC-Größe
dumpon /dev/gpt/swap1 · savecore -vCrash-Dump-Gerät setzen / Dump nach Reboot sichern
ARC ist kein Leck: ZFS belegt scheinbar den gesamten freien RAM. Das ist der ARC-Cache, er wird bei Bedarf freigegeben. Erst wenn Anwendungen tatsächlich warten müssen, lohnt eine Begrenzung über vfs.zfs.arc_max.

⚙Prozesse & Jobs

ps auxwwAlle Prozesse mit vollständiger Kommandozeile
ps -axo pid,ppid,jid,%cpu,%mem,rss,state,commandEigene Spaltenauswahl inkl. Jail-ID
pgrep -lf nginx / pkill -f nginxProzesse per Muster finden / beenden
kill -TERM 1234 / kill -9 1234Sauber beenden / hart abschießen (letztes Mittel)
kill -HUP 1234Konfiguration neu einlesen (bei vielen Diensten üblich)
procstat -a -f | lessAlle offenen Dateideskriptoren systemweit
procstat -k 1234Kernel-Stack eines hängenden Prozesses
fstat -p 1234 / fstat -u wwwOffene Dateien eines Prozesses / eines Benutzers
truss -f -p 1234Systemaufrufe live mitschneiden (inkl. Kindprozesse)
ktrace -p 1234 && kdump | lessKernel-Trace aufzeichnen und auswerten
renice -n 10 -p 1234Priorität senken
idprio 20 befehl / rtprio 5 befehlNur bei Leerlauf laufen lassen / Echtzeit-Priorität
cpuset -l 0-3 -p 1234Prozess an bestimmte CPUs binden
limits -a / login.confAktuelle Grenzwerte / dauerhafte Klassen-Limits
crontab -l -u www / crontab -eCron-Jobs eines Benutzers anzeigen / bearbeiten
/etc/crontab · /etc/cron.d/ · periodic.confSystem-Cron und die täglichen periodic-Läufe
service <dienst> status; pgrep -q <dienst>; echo $?Skriptfreundliche Zustandsprüfung
Hängender Prozess: Zustand D in ps bedeutet ununterbrechbares Warten auf I/O – kill -9 hilft dort nicht. Erst procstat -k ansehen, dann die Ursache im Storage suchen.

📈Performance-Analyse

top -aSHProzesse mit Argumenten, System-Threads und pro Thread aufgeschlüsselt
top -m ioSortierung nach I/O statt CPU
vmstat 5CPU, Paging, Interrupts im Intervall – erste Zeile ist Durchschnitt seit Boot
iostat -x 5Erweiterte Gerätestatistik mit Auslastung und Wartezeiten
gstat -p / gstat -f 'da'GEOM-Ebene live – das beste Werkzeug für Platten-Engpässe
systat -vmstat 1Kompakte Gesamtübersicht auf einem Bildschirm
systat -iostat 1 / systat -ifstat 1Platten- bzw. Netzwerkdurchsatz
netstat -i 1 / netstat -w 1 -hPaket- bzw. Byte-Raten pro Sekunde
netstat -mmbuf-Verbrauch – Engpass bei hoher Netzlast
pmcstat -T -w 2Hardware-Performance-Counter, zeigt heiße Funktionen
dtrace -n 'syscall:::entry { @[execname] = count(); }'Welcher Prozess macht die meisten Systemaufrufe?
dtrace -n 'io:::start { @[args[2]->fi_pathname] = count(); }'Welche Dateien erzeugen die meiste I/O?
zpool iostat -vl 5ZFS-Latenzen pro vdev – trennt Storage- von Anwendungsproblemen
sysctl kstat.zfs.misc.arcstats | grep -E 'hits|misses'ARC-Trefferquote beurteilen
sysctl -a | grep -i temperatureCPU-Temperaturen (Modul coretemp bzw. amdtemp laden)
sysctl dev.cpu.0.freq dev.cpu.0.freq_levelsAktuelle Taktrate und mögliche Stufen
service powerd onestart; sysrc powerd_enable=YESTaktsteuerung – auf Servern oft besser auf hiadaptive setzen
Vorgehen bei "Server ist langsam": top (CPU oder Speicher?) → gstat (Platte am Limit?) → netstat -w 1 (Netz?) → zpool iostat -vl (einzelne Platte auffällig?). Erst wenn diese vier unauffällig sind, lohnt sich DTrace.

🌐Netzwerk

ifconfig -a / ifconfig em0Alle Schnittstellen / eine bestimmte
ifconfig em0 inet 10.0.0.5/24IP-Adresse zur Laufzeit setzen
ifconfig em0 inet 10.0.0.6/24 aliasZweite Adresse auf derselben Schnittstelle
ifconfig em0 up / downSchnittstelle aktivieren / deaktivieren
ifconfig em0 mtu 9000Jumbo Frames setzen (Switch muss mitspielen)
sysrc ifconfig_em0="inet 10.0.0.5/24"Dauerhafte Konfiguration
sysrc ifconfig_em0="DHCP" / defaultrouter="10.0.0.1"DHCP bzw. Standard-Gateway dauerhaft
sysrc ifconfig_em0_alias0="inet 10.0.0.6/32"Dauerhafte zusätzliche Adresse
netstat -rn / netstat -rn -f inet6Routing-Tabelle IPv4 / IPv6
route add -net 192.168.9.0/24 10.0.0.254Statische Route zur Laufzeit
sysrc static_routes="db" route_db="-net 192.168.9.0/24 10.0.0.254"Statische Route dauerhaft
netstat -an -p tcp | grep LISTENLauschende TCP-Ports
sockstat -4 -l / sockstat -46 -lOffene Ports mit Prozess und Benutzer – sehr praktisch
arp -an / ndp -anARP- bzw. IPv6-Nachbar-Tabelle
ping -c4 host / ping6 -c4 hostErreichbarkeit prüfen
traceroute host / traceroute6 hostPfad verfolgen
tcpdump -ni em0 port 443 -w /tmp/t.pcapMitschnitt für spätere Auswertung
ifconfig lagg0 create laggproto lacp laggport em0 laggport em1Link-Aggregation (LACP) einrichten
ifconfig vlan10 create vlan 10 vlandev em0VLAN-Schnittstelle anlegen
ifconfig bridge0 create addm em0 addm tap0 upBridge für Jails oder bhyve
ifconfig em0 media / ifconfig em0 -mAktuelle Verbindung / alle unterstützten Medientypen
sysctl net.inet.ip.forwarding=1Routing aktivieren (dauerhaft: sysrc gateway_enable=YES)
Nach jeder Änderung: service netif restart lädt die Schnittstellen aus rc.conf neu – bei Fernzugriff riskant. Sicherer: service netif restart && service routing restart in einem tmux-Fenster starten oder vorher einen shutdown -r +5 als Rettungsanker setzen.

🔒Firewall (pf & ipfw)

sysrc pf_enable=YES pflog_enable=YESpf und Protokollierung dauerhaft aktivieren
service pf start | stop | reloadFirewall starten / stoppen / Regeln neu laden
pfctl -nf /etc/pf.confRegelwerk nur prüfen, nicht laden – immer zuerst!
pfctl -f /etc/pf.confRegeln laden
pfctl -sr / pfctl -sn / pfctl -saFilterregeln / NAT-Regeln / alles anzeigen
pfctl -ssAktuelle Zustandstabelle (Verbindungen)
pfctl -si / pfctl -vsiStatistik: passiert, blockiert, Zustandszähler
pfctl -sr -vRegeln mit Trefferzählern – zeigt tote Regeln
pfctl -t badhosts -T show / -T add 1.2.3.4Tabelle anzeigen / Adresse ergänzen
pfctl -k 10.0.0.9Alle Zustände einer Adresse verwerfen
pfctl -d / pfctl -eFirewall aus- / einschalten
tcpdump -n -e -ttt -i pflog0Blockierte Pakete live mitlesen
sysrc firewall_enable=YES firewall_type=workstationAlternative: ipfw mit vorgefertigtem Regelsatz
ipfw list / ipfw -a listipfw-Regeln / mit Zählern
ipfw add 100 allow tcp from any to me 22Einzelne ipfw-Regel ergänzen

Minimales pf.conf-Gerüst

ext_if = "em0"
table <badhosts> persist

set skip on lo0
scrub in all

block drop in log all
pass out quick keep state

pass in on $ext_if proto tcp to ($ext_if) port 22 \
     keep state (max-src-conn-rate 5/60, overload <badhosts> flush global)
pass in on $ext_if proto tcp to ($ext_if) port {80, 443} keep state
pass in on $ext_if inet proto icmp icmp-type echoreq keep state
Sperr dich nicht aus: Vor pfctl -f immer pfctl -nf /etc/pf.conf prüfen und bei Fernwartung einen Notfall-Job setzen: echo "pfctl -d" | at now + 5 minutes. Nach erfolgreichem Test den Job mit atrm entfernen.

📡Netzwerkdienste

sysrc sshd_enable=YES; service sshd reloadSSH aktivieren / Konfiguration neu laden
/etc/ssh/sshd_config · sshd -tSSH-Konfiguration / Syntaxprüfung vor dem Reload
sysrc nfs_server_enable=YES rpcbind_enable=YES mountd_enable=YESNFS-Server aktivieren
/etc/exports · service mountd reloadFreigaben definieren / neu einlesen
showmount -e localhostExportierte Verzeichnisse prüfen
mount -t nfs -o nfsv4 srv:/export /mntNFS-Freigabe einhängen
nfsstat -c / nfsstat -sNFS-Statistik Client- bzw. Serverseite
sysrc ntpd_enable=YES ntpd_sync_on_start=YESZeitdienst aktivieren, beim Start große Abweichung korrigieren
ntpq -pn / ntpdate -q zeitserverSynchronisationsstatus / Abweichung testen
/etc/resolv.conf · /etc/hosts · /etc/nsswitch.confNamensauflösung: DNS, lokale Einträge, Reihenfolge
drill example.com / host -t MX example.comDNS-Abfragen (drill ist im Basis-System, dig aus Paket)
sysrc local_unbound_enable=YES; service local_unbound setupLokalen DNS-Resolver einrichten
sysrc syslogd_flags="-ss"syslogd ohne Netzwerk-Ports betreiben (Härtung)
sysrc sendmail_enable=NONESendmail vollständig abschalten, wenn kein Mail benötigt wird
ctladm portlist / ctld (iSCSI-Target)iSCSI-Ziele bereitstellen, Konfiguration in /etc/ctl.conf
iscsictl -Aa / iscsictl -LiSCSI-Initiator verbinden / Sitzungen anzeigen
Dienst prüfen in drei Schritten: service <name> status (läuft er?) → sockstat -4 -l | grep <port> (lauscht er?) → tail -50 /var/log/messages (was sagt er?).

👤Benutzer, Gruppen & Rechte

adduserInteraktiv anlegen – fragt alles Notwendige ab
pw useradd max -c "Max Muster" -m -s /bin/sh -G wheelNicht-interaktiv mit Homeverzeichnis und Gruppe
pw usermod max -G wheel,operatorZusatzgruppen setzen (ersetzt die bisherigen!)
pw groupmod wheel -m maxBenutzer einer Gruppe hinzufügen, ohne andere zu verlieren
pw userdel max -rBenutzer samt Homeverzeichnis entfernen
pw usershow max / pw groupshow wheelEintrag anzeigen
pw lock max / pw unlock maxKonto sperren / entsperren
passwd max / chpass maxPasswort ändern / Feld im Benutzereintrag bearbeiten
id max / groups maxUID, GID und Gruppenmitgliedschaften
/etc/master.passwd · /etc/passwd · /etc/groupBenutzerdatenbank – nur über pw oder vipw ändern
pwd_mkdb -p /etc/master.passwdDatenbank nach manueller Änderung neu erzeugen
/etc/login.conf · cap_mkdb /etc/login.confLogin-Klassen mit Limits – nach Änderung neu erzeugen
su - / sudo -i (Paket sudo)Root werden – su setzt Mitgliedschaft in wheel voraus
visudo · /usr/local/etc/sudoerssudo-Rechte sicher bearbeiten
chmod 640 datei / chmod -R g+rX verzRechte setzen / rekursiv mit Verzeichnis-Ausführrecht
chown max:staff datei / chflags schg dateiEigentümer ändern / Datei unveränderbar machen (System-Flag)
ls -lo datei / chflags noschg dateiFlags anzeigen / Unveränderbarkeit aufheben
setfacl -m u:max:rwx datei / getfacl dateiACLs setzen / anzeigen (UFS mit acls, ZFS mit NFSv4-ACLs)
last / lastlogin / wAnmeldehistorie / letzte Anmeldung je Benutzer / aktive Sitzungen
schg-Flag beachten: Bei kern.securelevel >= 1 lässt sich schg im laufenden Betrieb nicht mehr entfernen – das geht dann nur im Single-User-Modus. Vor dem Setzen von securelevel also gut überlegen.

🏗Jails

jls / jls -vLaufende Jails mit ID, IP und Pfad
jexec 1 /bin/sh bzw. jexec web01 /bin/shShell in einer Jail öffnen
service jail start web01 / stop web01Einzelne Jail starten / stoppen
sysrc jail_enable=YES jail_list="web01 db01"Jails beim Boot automatisch starten
/etc/jail.conf · /etc/jail.conf.d/web01.confZentrale bzw. getrennte Jail-Definitionen
bsdinstall jail /jails/web01Basis-System in ein Jail-Verzeichnis installieren
zfs create -o mountpoint=/jails/web01 tank/jails/web01Eigenes Dataset pro Jail – erlaubt Snapshots und Klone
jail -c -f /etc/jail.conf web01Jail direkt aus der Konfiguration starten
jail -r web01Jail sauber beenden
ps -ax -o jid,pid,command | grep -v ' 0 'Alle Prozesse, die in Jails laufen
pkg -j web01 install nginxPaket vom Host aus in einer Jail installieren
freebsd-update -b /jails/web01 fetch installJail-Userland patchen
sysctl security.jail.param | lessAlle möglichen Jail-Parameter
iocage / bastille (Pakete)Komfortable Jail-Verwaltung mit ZFS-Integration

Beispiel /etc/jail.conf

exec.start  = "/bin/sh /etc/rc";
exec.stop   = "/bin/sh /etc/rc.shutdown";
exec.clean;
mount.devfs;
host.hostname = "$name.example.local";
path          = "/jails/$name";

web01 {
    ip4.addr = "em0|10.0.0.11/24";
    allow.raw_sockets = 0;
}
db01 {
    ip4.addr = "em0|10.0.0.12/24";
    allow.sysvipc = 1;
}
Vor Jail-Updates: zfs snapshot tank/jails/web01@vor-update – ein Rollback dauert dann Sekunden statt einer Neuinstallation.

🖥bhyve & Virtualisierung

sysrc vmm_load=YES (bzw. /boot/loader.conf)Hypervisor-Modul beim Boot laden
kldload vmm nmdm if_bridge if_tapBenötigte Module zur Laufzeit laden
sysctl hw.vmm.create / bhyvectl --get-stats --vm=vm1Zustand und Statistik einer VM
bhyvectl --destroy --vm=vm1VM-Instanz im Kernel aufräumen (nach hartem Abbruch nötig)
ls /dev/vmm/Alle aktuell existierenden VM-Instanzen
vm list / vm info vm1 (Paket vm-bhyve)Komfortable Verwaltung – empfohlen statt Handarbeit
vm create -t linux-zvol -s 40G vm1Neue VM aus Vorlage anlegen
vm install vm1 debian.iso / vm start vm1Installation starten / VM hochfahren
vm console vm1Auf die serielle Konsole schalten (~~. zum Verlassen)
vm stop vm1 / vm poweroff vm1Sauber herunterfahren / hart ausschalten
vm switch create public && vm switch add public em0Virtuellen Switch (Bridge) anlegen
cu -l /dev/nmdm0BDirekter Zugriff auf die Nullmodem-Konsole einer VM
zfs create -V 40G tank/vms/vm1zvol als VM-Datenträger – schneller als Image-Datei
sysctl hw.vmm.vmx.initialized / kldstat -m vmmPrüfen, ob der Hypervisor bereit ist
Voraussetzung: bhyve braucht Intel VT-x mit EPT bzw. AMD-V mit RVI. Prüfen mit sysctl hw.vmm.vmx.cap.unrestricted_guest (Intel). Bei aktiviertem BIOS-Schutz muss die Virtualisierung dort erst freigeschaltet werden.

💾Backup & Wiederherstellung

dump -0auLf /backup/root.dump /Vollsicherung eines UFS-Dateisystems (-L = Snapshot im laufenden Betrieb)
dump -1auLf /backup/root.inc /Inkrementell seit der letzten Sicherung niedrigerer Stufe
restore -rf /backup/root.dumpKomplett zurückspielen (in leeres Dateisystem)
restore -if /backup/root.dumpInteraktiv einzelne Dateien auswählen (add, extract)
restore -tf /backup/root.dump | lessInhalt anzeigen ohne zurückzuspielen
zfs send -R tank@voll | zfs recv -F backup/tankKompletter Pool inkl. aller Snapshots und Eigenschaften
zfs send -Ri @alt tank@neu | ssh bkp "zfs recv -F backup/tank"Inkrementelle Replikation auf zweiten Server
zfs send tank/data@snap | zstd | ssh bkp "cat > /bkp/data.zfs.zst"Als komprimierte Datei ablegen
tar -czf /backup/etc.tgz -C / etc usr/local/etcKonfiguration schnell sichern
rsync -aHAX --delete /srv/ bkp:/srv/Dateiabgleich mit Hardlinks, ACLs und erweiterten Attributen
gpart backup ada0 > /backup/ada0.gptPartitionslayout mitsichern – oft vergessen
pkg query "%n" > /backup/pkglist.txtPaketliste für schnellen Wiederaufbau
pkg install -y $(cat /backup/pkglist.txt)Pakete auf einem neuen System wiederherstellen
dd if=/dev/ada0 of=/backup/mbr.bin bs=512 count=1Bootsektor sichern (nur MBR-Systeme)
bectl list / bectl create vor-updateBoot-Environments auf ZFS – ganzes System als Snapshot
bectl activate vor-update && rebootZum alten Systemstand zurückkehren
bectl destroy alt-beNicht mehr benötigtes Boot-Environment entfernen
Bestes Sicherheitsnetz vor Updates: bectl create vor-update auf ZFS-Root. Geht beim Patchen etwas schief, bringt bectl activate plus Reboot das System in Minuten zurück – ohne Restore aus dem Backup.

📜Logs & Fehlersuche

tail -f /var/log/messagesWichtigstes System-Log live verfolgen
/var/log/messages · security · auth.log · cronSystem, Firewall-Zusammenfassung, Anmeldungen, Cron
/var/log/dmesg.today · /var/run/dmesg.bootKernel-Meldungen des Tages / vom letzten Boot
/etc/syslog.conf · /usr/local/etc/syslog.d/Regeln, welche Meldung wohin geschrieben wird
service syslogd reloadNach Änderung an syslog.conf nötig
logger -t test -p daemon.notice "Testmeldung"Eigene Meldung erzeugen – prüft die Konfiguration
/etc/newsyslog.conf · newsyslog -nvRotation konfigurieren / Trockenlauf zur Kontrolle
/etc/periodic.conf · periodic dailyTägliche Prüfberichte konfigurieren / manuell ausführen
grep -i error /var/log/messages | tail -50Schneller Blick auf Fehler
dmesg | grep -iE 'error|fail|timeout'Hardware-Probleme im Kernel-Log
zpool status -v; zpool events -v | tailZFS-Fehler und Ereignisprotokoll
smartctl -l error /dev/ada0Fehlerprotokoll der Platte selbst
devctl / devd -d (im Vordergrund)Geräte-Ereignisse zur Fehlersuche mitlesen
sysctl kern.corefile / ls /var/crashWohin gehen Core-Dumps / Kernel-Abstürze
kgdb /boot/kernel/kernel /var/crash/vmcore.0Kernel-Dump analysieren
Nach jedem Absturz prüfen: ls -l /var/crash/. Damit überhaupt ein Dump entsteht, muss dumpdev="AUTO" in /etc/rc.conf gesetzt und der Swap groß genug sein.

📄Wichtige Dateien & Pfade

/etc/rc.conf · /etc/rc.conf.localZentrale Systemkonfiguration – Dienste, Netz, Hostname
/etc/defaults/rc.confAlle Vorgabewerte mit Kommentaren – beste Referenz
/boot/loader.conf · /boot/loader.conf.localModule und Tunables für den Bootvorgang
/etc/sysctl.confKernel-Variablen, die zur Laufzeit gesetzt werden
/etc/fstabDauerhafte Mounts und Swap
/etc/pf.conf · /etc/ipfw.rulesFirewall-Regelwerke
/etc/jail.conf · /etc/jail.conf.d/Jail-Definitionen
/etc/exports · /etc/ctl.confNFS-Freigaben / iSCSI-Ziele
/etc/periodic.conf · /etc/newsyslog.confTägliche Berichte / Log-Rotation
/etc/login.conf · /etc/login.accessRessourcen-Limits je Klasse / Zugangsregeln
/etc/ttysKonsolen und deren Sicherheitsstufe (secure/insecure)
/usr/local/etc/Konfiguration aller aus Paketen installierten Programme
/usr/local/etc/rc.d/Start-Skripte der Pakete
/var/db/pkg/ · /var/cache/pkg/Paketdatenbank / heruntergeladene Pakete
/etc/mail/mailer.confWelcher MTA wird verwendet (sendmail, dma, postfix)
/usr/share/examples/Beispielkonfigurationen für fast alles im Basis-System
/etc/motd.template · /etc/issueBegrüßungstexte nach bzw. vor der Anmeldung
Handbuch nutzen: FreeBSD hat die beste Dokumentation aller UNIX-Derivate. man rc.conf, man 5 pf.conf, man jail und man 7 hier (Verzeichnisstruktur) beantworten die meisten Fragen sofort.

🛠Praxis-Workflows

Neue SAN-LUN in ZFS-Pool aufnehmen

camcontrol rescan all                       # Bus neu abtasten
camcontrol devlist                          # neue da-Nummer merken
gpart create -s gpt da6
gpart add -t freebsd-zfs -a 1m -l zdisk6 da6
zpool add -n tank mirror gpt/zdisk6 gpt/zdisk7   # TROCKENLAUF pruefen!
zpool add    tank mirror gpt/zdisk6 gpt/zdisk7
zpool status tank                           # neues vdev online?
zpool list                                  # Kapazitaet gewachsen?

Defekte Platte im Spiegel ersetzen

zpool status -v tank                        # welche Platte ist DEGRADED?
zpool offline tank gpt/zdisk3               # falls noch nicht ausgefallen
camcontrol devlist                          # Seriennummer der Platte notieren
# --- Platte physisch tauschen ---
camcontrol rescan all
gpart backup ada0 | gpart restore -F da3    # Layout uebernehmen
zpool replace tank gpt/zdisk3 gpt/zdisk3neu
zpool status 5                              # Resilver-Fortschritt beobachten
zpool clear tank                            # Zaehler nach Abschluss zuruecksetzen

LUN vergrößert – Platz nutzbar machen

camcontrol reprobe da5                      # neue Groesse uebernehmen
gpart recover da5                           # GPT-Backup ans neue Ende schieben
gpart resize -i 1 da5                       # Partition auf Maximum ausdehnen
zpool set autoexpand=on tank
zpool online -e tank gpt/zdisk5             # Pool waechst mit
zpool list                                  # Kontrolle
# UFS stattdessen:  growfs /dev/gpt/data1

Dateisystem voll – systematisch vorgehen

df -h                                       # welches Dateisystem?
zfs list -o space -r tank                   # USEDSNAP hoch? -> Snapshots
du -h -d1 /var | sort -h | tail             # groesste Verzeichnisse
fstat | awk '$NF ~ /^[0-9]+$/' | head       # geloeschte, offene Dateien
zfs list -t snapshot -o name,used -S used | head
zfs destroy tank/data@alter-snap            # gezielt aufraeumen
# Notfall: zfs set refreservation=none tank/data  schafft Luft

Sicheres Patchen eines Produktionsservers

freebsd-version -kru; pkg -vv | grep url    # Ausgangslage dokumentieren
bectl create vor-patch-$(date +%F)          # Rueckfallpunkt (ZFS-Root)
zfs snapshot -r tank@vor-patch              # zusaetzlich Daten sichern
freebsd-update fetch install                # Basis-System
pkg update && pkg upgrade -n                # erst Trockenlauf ansehen
pkg upgrade
shutdown -r +5 "Patch-Reboot"
# nach dem Reboot:
freebsd-version -kru; service -e; zpool status -x; sockstat -4 -l

Dienst startet nicht – Fehlersuche

service nginx status                        # laeuft er ueberhaupt?
service nginx rcvar                         # ist er in rc.conf aktiviert?
sh -x /usr/local/etc/rc.d/nginx start       # Startskript mit Ablaufprotokoll
tail -100 /var/log/messages                 # was meldet das System?
nginx -t                                    # Konfiguration syntaktisch pruefen
sockstat -4 -l | grep :80                   # belegt jemand anderes den Port?
pfctl -sr -v | grep 80                      # blockiert die Firewall?