Inhaltsverzeichnis
Auffälligkeiten bei der CPU-Auslastung
Durch Auffälligkeiten auf einer meiner OPNsense Firewalls in der Cloud bei Hetzner, habe ich eine zu hohe CPU-Auslastung durch Zufallszahlen bei OPNsense in der Version 23.1.6 entdeckt. Dabei lastet der für die Erzeugung der Zufallszahlen zuständige Systemprozess rand_harvestq einen CPU Kern komplett aus.
Eine Recherche im Internet zeigte mir, dass Ich nicht der einzige mit dem Phänomen bin. Man findet ab spätestens 2018 im Internet Quellen die von Problemen mit dem VirtIO Entropy Adapter bei FreeBSD gibt. In dem Forumsbeitrag [FreeBSD 13] High CPU Usage – rand_harvestq vom Mai 2021 wird z.B. über ähnliche Phänomene bei KVM berichtet. Es tritt immer auf, wenn der VirtIO Entropy Adapter für virtuelle Maschinen eingestellt ist. In den aktuellen Kommentaren in dem Forumsbeitrag wird dann auf den Bug 254513 verlinkt.
In diesem Bug wurde am 23.03.2021 gemeldet, dass das Problem bei einigen Servern und in der Cloud von Hetzner auftritt. Dieser wurde aber mit dem Vermerk geschlossen, dass es sich um eine Dublette von und Bug 253175 handelt, welcher bereits am 19.03.2022 gelöst wurde. Sehr komisch also, dass dies Phänomen bei mir immer noch, oder schon wieder auftritt.
Normaler Weise reicht es, den VirtIO Entropy Adapter für die virtuelle Maschine abzustellen. Leider kann man das in der Cloud von Hetzner aber nicht machen, da man keinen Zugriff auf diese Einstellungen hat.
Noch komischer ist jedoch, dass es der VirtIO Entropy Adapter einige Tage später in der virtuellen Maschine nicht mehr auftauchte. Ich Rätsel jetzt, ob das ganze ein Zufall ist und der VirtIO Entropy Adapter demnächst wieder auftaucht.
Noch bevor der Adapter verschwunden ist, habe ich einen Workaround gefunden, um das Phänomen abzustellen. Ich diesem Blogbeitrag schildere ich den Workaround im Detail. Eventuell hilft er ja dem einen oder anderen, wenn bei ihm die zu hohe CPU-Auslastung durch Zufallszahlen bei OPNsense auftaucht. Außerdem kann ich auch selber hier nachschlagen, wenn ich wieder betroffen sein sollte. Und ich befürchte, dass dies früher oder später der Fall sein wird.
Wie erkennt man die zu hohe Hohe CPU-Auslastung durch Zufallszahlen bei OPNsense?
Aufgefallen ist mir die zu hohe CPU-Auslastung durch Zufallszahlen bei OPNsense, da eine neue Firewall mit 2 CPU Kernen sofort und konstant 50% der CPU Rechenleistung verbraucht hat, obwohl diese noch nichts zu tun hatte.
Noch konkreter konnte man das Fehlverhalten sehen, wenn man top -S auf der Kommandozeile eingibt. Das -S zeigt auch die Systemprozesse an, die sonst nicht auftauchen. Die Ausgabe zeigt einem, dass die Auslastung der CPU von dem Systemprozess rand_harvestq stammt und es folglich ein Problem mit der Erzeugung der Zufallszahlen gibt.
Wie werden die Zufallszahlen bei FreeBSD erzeugt?
Mit dem Befehl sysctl kern.random bekommt man alle Kernelparameter der Teilbaums random angezeigt.
kern.random.random_sources: 'VirtIO Entropy Adapter','Intel Secure Key RNG'
Der Wert kern.random.random_sources zeigt die verwendeten Zufallsquellen an. Wie man der Ausgabe entnehmen kann, kommen für die Erzeugung der Zufallszahlen aktuell die Quellen „VirtIO Entropy Adapter"
und „Intel Secure Key RNG"
zum Einsatz. Dabei soll laut den Berichten im Internet die Quelle "VirtIO Entropy Adapter"
die zu hohe CPU-Auslastung durch Zufallszahlen bei OPNsense auslösen.
Die Maske des Kernelparameters
In FreeBSD kann man mit einer Maske einen Kernelparameter steuern. Durch dieses Konzept wird es dem Administratoren ermöglicht, bestimmte Einstellungen und Optionen im Kernel des Betriebssystems zu aktivieren oder zu deaktivieren. Somit sollte man eigentlich mit kern.random.harvest.mask die verwendeten Zufallsgeneratoren steuern können. Dies funktionierte bei mir aber leider nicht, um die zu hohe CPU-Auslastung durch Zufallszahlen bei OPNsense abzustellen.
Selbst das Ausschalten mit der Maske 0 durch die folgende Befehlszeile, funktionierte bei mir nicht. Hinterher konnte man immer noch die Konfiguration anzeigen lassen und kldstat zeigte die geladenen Kernelmodule.
# sysctl kern.random.harvest.mask=0
# sysctl kern.random.harvest
kern.random.harvest.mask_symbolic: PURE_VIRTIO,PURE_RDRAND,[UMA],[FS_ATIME],[SWI],[INTERRUPT],[NET_NG],[NET_ETHER],[NET_TUN],[MOUSE],[KEYBOARD],[ATTACH],[CACHED]
kern.random.harvest.mask_bin: 000001001000000000000000
kern.random.harvest.mask: 294912
Id Refs Address Size Name
1 66 0xffffffff80200000 215db90 kernel
2 1 0xffffffff8235e000 18338 if_lagg.ko
3 2 0xffffffff82377000 3538 if_infiniband.ko
4 1 0xffffffff8237b000 4b58 if_enc.ko
5 1 0xffffffff82380000 e4c0 if_bridge.ko
6 2 0xffffffff8238f000 7870 bridgestp.ko
7 1 0xffffffff82398000 5b9380 zfs.ko
8 1 0xffffffff82952000 e3d8 pfsync.ko
9 3 0xffffffff82961000 752b0 pf.ko
10 1 0xffffffff829d7000 ab48 opensolaris.ko
11 1 0xffffffff829e2000 3b18 pflog.ko
12 1 0xffffffff829e6000 ba48 if_gre.ko
13 1 0xffffffff829f2000 f460 carp.ko
14 1 0xffffffff82d18000 4304 virtio_console.ko
15 1 0xffffffff82d1d000 22a8 virtio_random.ko
16 1 0xffffffff82d20000 3250 ichsmb.ko
17 1 0xffffffff82d24000 2180 smbus.ko
18 1 0xffffffff82d27000 2340 uhid.ko
19 1 0xffffffff82d2a000 3380 usbhid.ko
20 1 0xffffffff82d2e000 31f8 hidbus.ko
21 1 0xffffffff82d32000 3320 wmt.ko
22 1 0xffffffff82d36000 4700 nullfs.ko
Späteres Entladen funktioniert nicht
Normaler Weise soll man die zu hohe CPU-Auslastung durch Zufallszahlen bei OPNsense abstellen können, in dem man das betroffene Kenelmodul mit kldunload entlädt. Ein „kldunload virtio_random“ auf der Kommandozeile kommt aber nicht zurück. Offensichtlich erzeugt das Phänomen nicht nur zu hohe CPU-Auslastung durch Zufallszahlen bei OPNsense, sondern läßt das Kernelmodul so heftig abstürzen, dass man dieses nicht mal mehr entladen kann. Nicht mal mehr ein Reboot des Servers funktioniert. Man muss den Server hard rebooten.
Blackliste für das Modul funktioniert leider auch nicht
Die Blacklist für Kernelmodule in FreeBSD ist eine Konfigurationsdatei, die verwendet wird, um bestimmte Kernelmodule daran zu hindern, geladen zu werden. Diese Blacklist ermöglicht es Systemadministratoren, bestimmte Module zu sperren, um potenzielle Probleme oder Sicherheitslücken zu vermeiden.
Eigentlich kann man in der Datei /boot/loader.conf bei OPNsense konfigurieren, dass ein Kernelmodul auf dieser Blacklist landet. Ich konnte jedoch weder mit der Zeile
/boot/loader.conf: virtio_random_load = "NO"
noch mit der Zeile
/boot/loader.conf: module_blacklist = virtio_random
verhindern, dass das Modul virtio_random geladen wird. Offensichtlich lädt der Kernel das Modul dennoch.
Workaround für eine temporäre Lösung
Um die zu hohe CPU-Auslastung durch Zufallszahlen bei OPNsense zu stoppen, bleiben somit nur die ganz harten Methoden. Es gibt das Verzeichnis /boot/kernel mit den Kernelmodulen. Wenn man das Modul hier einfach mal in einen anderen Ordner verschiebt, findet der Kenner das Modul beim booten nicht mehr. Dies verhindert das laden beim booten.
mkdir /boot/disabled/ && mv /boot/kernel/virtio_random.ko /boot/disabled/
Und … man glaubt es kaum … die zu hohe CPU-Auslastung durch Zufallszahlen bei OPNsense ist nach einen Neustart verschwunden.
Schreibe einen Kommentar