So ermitteln Sie, welche Prozesse wie viel Entropie aus /dev/urandom verwenden

So ermitteln Sie, welche Prozesse wie viel Entropie aus /dev/urandom verwenden

Doing fuser -v /dev/urandomsagt mir, welche Prozesse derzeit /dev/urandomgeöffnet sind, aber nur das. Gibt es eine Möglichkeit, etwas darüber zu bestimmen, wie viel Entropie jeder einzelne im Laufe der Zeit verbraucht? Es könnte zum Beispiel sein, dass ein Prozess etwa 1 Bit Entropie pro Minute verbraucht, während ein anderer etwa 8 Bits pro Sekunde verbraucht; ich hätte gerne eine Möglichkeit, das festzustellen.

Antwort1

Die kurze Antwort ist 0, da keine Entropie verbraucht wird.

Da ist einhäufiges Missverständnisdass Entropie verbraucht wird – dass jedes Mal, wenn Sie ein zufälliges Bit lesen, der Zufallsquelle etwas Entropie entzogen wird. Das ist falsch.Sie „verbrauchen“ keine Entropie. Ja,die Linux-Dokumentation ist falsch.

Während des Lebenszyklus eines Linux-Systems gibt es zwei Phasen:

  1. Anfangs ist nicht genug Entropie vorhanden. /dev/randomwird blockiert, bis es denkt, dass es genug Entropie angesammelt hat; /dev/urandomstellt dann problemlos Daten mit niedriger Entropie bereit.
  2. Nach einer Weile ist im Pool des Zufallsgenerators genügend Entropie vorhanden. /dev/randomweist ab und zu eine falsche Rate von „Entropie-Leck“ zu und blockiert; /dev/urandomliefert fröhlich Zufallsdaten in Kryptoqualität.

FreeBSD macht es richtig: Unter FreeBSD blockiert /dev/random(oder /dev/urandom, was dasselbe ist), wenn nicht genügend Entropie vorhanden ist, und wenn dies der Fall ist, spuckt es weiterhin zufällige Daten aus. Unter Linux ist weder /dev/randomnoch /dev/urandomdas Nützliche.

Verwenden Sie in der Praxis /dev/urandomund stellen Sie bei der Bereitstellung Ihres Systems sicher, dass der Entropiepool gespeist wird (durch Festplatten-, Netzwerk- und Mausaktivität, durch eine Hardwarequelle, durch einen externen Rechner usw.).

Sie könnten zwar versuchen, zu ermitteln, wie viele Bytes von gelesen werden /dev/urandom, aber das ist völlig sinnlos. Das Lesen von /dev/urandomerschöpft den Entropiepool nicht. Jeder Verbraucher verbraucht 0 Bit Entropie pro beliebiger Zeiteinheit.

Antwort2

Obwohl dies nicht automatisiert ist, können Sie ein Tool wie strace verwenden, um auf Lesevorgänge von den mit urandom verknüpften Dateideskriptoren zu achten. Sehen Sie dann, wie viele Daten über einen bestimmten Zeitraum gelesen werden, um die Leserate zu ermitteln.

Antwort3

Wenn Sie nicht wissen (oder keinen Verdacht haben), welcher Prozess unter Linux für die Erschöpfung von entropy_available verantwortlich ist, können Sie das Problem auf verschiedene Weise angehen.

Wie bereits erwähnt, können Sie strace verwenden. Dies ist hervorragend geeignet, um nützliche Einblicke in die Prozesse zu erhalten, die Sie sich ansehen möchten.

Mit auditd können Sie prüfen, welche Prozesseoffen/dev/random oder /dev/urandom, aber das sagt Ihnen nicht, wie viele Daten gelesen werden (um Protokollierungsprobleme zu vermeiden). Hier sind einige Befehle, um die Regeln aufzulisten und dann zwei Überwachungen hinzuzufügen

auditctl -l
auditctl -w /dev/random
auditctl -w /dev/urandom
auditctl -l

Melden Sie sich jetzt per SSH bei der Box an (oder tun Sie etwas anderes, von dem Sie wissen, dass es zum Öffnen von /dev/urandom oder Ähnlichem führen sollte, z. B. dd).

ausearch -ts aktuell | aureport -f

In meinem Fall sehe ich ungefähr Folgendes:

[root@metrics-d02 vagrant]# ausearch -ts recent | aureport -f

File Report
===============================================
# date time file syscall success exe auid event
===============================================
1. 07/01/20 01:13:36 /dev/urandom 2 yes /usr/bin/dd 1000 6383
2. 07/01/20 01:16:43 /dev/urandom 2 yes /usr/sbin/sshd -1 6389
3. 07/01/20 01:16:43 /dev/urandom 2 yes /usr/sbin/sshd -1 6388
4. 07/01/20 01:16:43 /dev/urandom 2 yes /usr/sbin/sshd -1 6390
5. 07/01/20 01:16:44 /dev/urandom 2 yes /usr/sbin/sshd 1000 6408

Deaktivieren Sie diese Uhren

auditctl -W /dev/random
auditctl -W /dev/urandom

Bedenken Sie jedoch, dass hierdurch nur Daten für Systemaufrufe erfasst werden, bei denen es sich nicht um Lese-/Schreibaufrufe usw. handelt. Wenn also etwas bereits geöffnet ist, sehen Sie nicht, dass es gelesen wird.

Allerdings fiel mir (unter Verwendung von Prometheus und node_exporter) auf, dass ich immer noch ein Sägezahnmuster sah, wobei die VM (CentOS 7 ohne etwas zum Sammeln von Entropie) einen Anstieg von entropy_available auf fast 200 meldete und danach wieder auf 0 zurückfiel.

Bietet lsof (oder fuser, wenn Sie das bevorzugen) etwas?

[root@metrics-d02 vagrant]# lsof /dev/random /dev/urandom
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd 2184 chrony    3r   CHR    1,9      0t0 5339 /dev/urandom
tuned   2525   root    5r   CHR    1,9      0t0 5339 /dev/urandom

Beachten Sie jedoch die Haupt- und Nebennummern der Zeichengeräte. Testen Sie auf andere Weise … (Ich bin nicht sicher, ob dies nützlich wäre, denke nur an Dinge wie Docker, das auf dieser VM nicht läuft.)

[root@metrics-d02 vagrant]# ls -l /dev/*random
crw-rw-rw-. 1 root root 1, 8 Dec 19 01:24 /dev/random
crw-rw-rw-. 1 root root 1, 9 Dec 19 01:24 /dev/urandom

[root@metrics-d02 vagrant]# lsof | grep '1,[89]'
chronyd    2184           chrony    3r      CHR                1,9      0t0       5339 /dev/urandom
tuned      2525             root    5r      CHR                1,9      0t0       5339 /dev/urandom
gmain      2525  2714       root    5r      CHR                1,9      0t0       5339 /dev/urandom
tuned      2525  2715       root    5r      CHR                1,9      0t0       5339 /dev/urandom
tuned      2525  2717       root    5r      CHR                1,9      0t0       5339 /dev/urandom
tuned      2525  2754       root    5r      CHR                1,9      0t0       5339 /dev/urandom

Okay, wir haben also zwei Prozesse, chronyd und tuned. Lass uns strace verwenden. lsof hat uns mitgeteilt, dass chrony /dev/urandom zum Lesen mit dem Datei-Deskriptor 3 geöffnet hat.

[root@metrics-d02 vagrant]# strace -p 2184 -f
strace: Process 2184 attached
select(6, [1 2 5], NULL, NULL, {98, 516224}
.... (I'm waiting)

Chronyd wartet also auf eine Aktivität mit einem Timeout von 98 Sekunden ab dem Start dieses Systemaufrufs.

Während ich warte, sollte ich darauf hinweisen, dass meine Aktivität auf dem System wahrscheinlich zu einer Erhöhung der Kernel-Schätzung der verfügbaren Zufallsbits führt. (verfügbare_Entropie) … lehnen Sie sich also zurück und beobachten Sie einfach das Prometheus-Diagramm …

Prometheus-Diagramm, das node_entropy_available_bits im Zeitverlauf mit Beschreibungen zeigt

Wir können dies auch mit „tuned“ wiederholen ... (diesmal fügen wir einige Zeitstempel und einen Grep-Filter nur für den Dateideskriptor 5 hinzu (die Leseaufrufe usw. hätten dies als erstes Argument)

[root@metrics-d02 vagrant]# strace -p 2525 -f -tt -T 2>&1 | grep '(5,'

Red Hat hat einen Blog, der weiter diskutiertCSPRNG (Kryptographisch sicherer Pseudozufallszahlengenerator). Es werden einige andere Möglichkeiten erläutert, wie Prozesse auf Zufallszahlen zugreifen können:

  • getrandom() Systemaufruf <-- empfohlen für RHEL7.4+, hohe Qualität ohne Blockierung nach Initialisierung des Entropiepools
  • /dev/random <-- wird leicht blockiert
  • /dev/urandom <-- Problem bei Verwendung vor Initialisierung des Pools. Wird „niemals blockieren“; sollte das sein, was die meisten Anwendungen verwenden sollten.
  • AT_RANDOM <-- setzt 16 zufällige Bytes einmalig zur Ausführungszeit

Obwohl AT_RANDOM nicht nützlich ist, ist es bei jedem Prozess vorhanden, sodass allein das Starten eines Prozesses zumindest ein wenig Zeit in Anspruch nehmen sollte.

Sie werden jetzt erkennen, dass das, was ich oben mit lsof gezeigt habe, nicht ausreicht, da es die Verwendung von getrandom() nicht offenbart. Da getrandom() jedoch ein Systemaufruf ist, sollten wir die Verwendung mit auditctl offenbaren können.

[root@metrics-d02 vagrant]# auditctl -a exit,always -F arch=b64 -S getrandom
[root@metrics-d02 vagrant]# auditctl -l
-a always,exit -F arch=b64 -S getrandom
[root@metrics-d02 vagrant]# tail -F -n0 /var/log/audit/audit.log 
... (now we wait)

Mir war langweilig und ich habe mich per SSH mit der Box verbunden und eine Menge interessantes, cooles Zeug gesehen, aber kein getrandom(), was aber keine Überraschung sein sollte, da wir es vorher bei der Verwendung der /dev/urandom-API gesehen haben.

Wenn wir also versuchen, die Vertiefungen im Diagramm zu erklären, wird /dev/*random nicht geöffnet, und nichts, das es geöffnet hat, verwendet es derzeit, und nichts scheint getrandom() aufzurufen ... Gibt es sonst noch etwas, das Daten aus dem [Pool hinter /dev/random] verbrauchen würde? Was ist mit dem Kernel? Betrachten Sie Funktionen wie Address Space Layout Randomisation (ASLR):

https://access.redhat.com/solutions/44460 [erfordert Abonnement]

[root@metrics-d02 vagrant]# cat /proc/sys/kernel/randomize_va_space 
2

'2' bedeutet hier, dass zusätzlich zur zufälligen Auswahl, wo Dinge wie mmap und Stack (usw.) geladen werden, auch die zufällige Auswahl des Heaps aktiviert wird. Was passiert, wenn wir das ausschalten?

[root@metrics-d02 vagrant]# echo 0 > /proc/sys/kernel/randomize_va_space
[root@metrics-d02 vagrant]# cat /proc/sys/kernel/randomize_va_space 
0

(Antwort: dasselbe ... vielleicht kann das jemand anders näher erläutern)

Der Kernel ist auch der Ort, an dem AT_RANDOM gesetzt wird. Hier ist ein einfaches Beispiel, bei dem Sie strace verwenden können, um zu beobachten, dass es nicht /dev/*random oder getrandom() aufruft.

[vagrant@metrics-d02 ~]$ cat at_random.c 
#include <stdio.h>
#include <stdint.h>
#include <sys/auxv.h>

#define AT_RANDOM_LEN 16

int main(int argc, char *argv[])
{
    uintptr_t at_random;
    int i;

    at_random = getauxval(AT_RANDOM);

    for (i=0; i<AT_RANDOM_LEN; i++) {
        printf("%02x", ((uint8_t *)at_random)[i]);
    }
    printf("\n");

    /* show that it's a one-time thing */

    for (i=0; i<AT_RANDOM_LEN; i++) {
        printf("%02x", ((uint8_t *)at_random)[i]);
    }
    printf("\n");
}
[vagrant@metrics-d02 ~]$ make at_random
cc     at_random.c   -o at_random
[vagrant@metrics-d02 ~]$ ./at_random 
255f8d5711b9aecf9b5724aa53bc968b
255f8d5711b9aecf9b5724aa53bc968b
[vagrant@metrics-d02 ~]$ ./at_random 
ef4b25faf9f435b3a879a17d0f5c1a62
ef4b25faf9f435b3a879a17d0f5c1a62

Hoffe, das ist hilfreich.

In der Praxis würde ich mir zunächst Java-Workloads ansehen, da ich dort normalerweise am meisten davon betroffen bin. Siehehttps://blogs.oracle.com/luzmestre/warum-dauert-der-start-meines-weblogic-servers-so-langezum Beispiel.

verwandte Informationen