RAND_bytes mislykkedes i OpenVPN: biblioteksfejl eller manglende node
En RAND_bytes-fejl kan betyde en afvist entropikilde eller en node skjult af en jail. Læs fejlkøen og procesvisningen, før du opretter enheder.
RAND_bytes() failed er en udtalelse om én lokal primitiv, ikke om kontoen, den foruddelte nøgle eller den eksterne port. To meget forskellige fejl frembringer samme linje og efterlader forskellige spor. Den ene er en kryptografisk backend, der nægter at udsende bytes; den anden er en proces, der ikke kan nå den entropikilde, som dens kode blev bygget til. At skelne dem kræver én læsning af fejlkøen og ét blik på den indespærrede proces' egen filsystemvisning, og den kontrol hører til før noget oprettes under /dev.
Hvad returværdien skelner
Den dokumenterede kontrakt skelner tre udfald, ikke to: 1 for succes, -1 når den indlæste RAND-metode ikke understøtter anmodningen, og 0 for andre fejl, mens forklaringen overlades til fejlkøen. RAND_bytes-referencen tilføjer et punkt, der er let at overse: standardgeneratoren initialiseres fra styresystemet på understøttede platforme, og når den initialisering fejler, forbliver den i en fejltilstand i stedet for at levere forudsigelige bytes.
Kun ét af de tal beskriver miljøet. Et -1 er et spørgsmål om build, provider eller funktionalitet, fordi koden bad om noget, som den aktive implementering ikke tilbyder. Et 0 med en klage over initialisering er et miljøspørgsmål, fordi generatoren slet ikke kunne skaffe entropi. Tallet alene siger aldrig hvilket, og funktionsnavnet gør det heller ikke.
Hvornår en skjult enhedsnode er den egentlige årsag
En indskrænket tjeneste ser et andet træ end det shell, du skriver i. Chroot-fængsler, containerbilleder og hærdede unitfiler præsenterer rutinemæssigt en /dev med færre noder end værtens. Hvis den fejlende implementering åbner /dev/urandom via stinavnet, er den forskel nok til at bryde opstarten, mens værten selv ser helt sund ud. En enhed, der findes uden for fængslet, beviser intet om, hvad den indespærrede proces må åbne.
Ikke enhver tilfældig grænseflade har dog brug for en sti. Linux-systemkaldet getrandom accepterer hverken filnavn eller fildeskriptor, og dets manualside bemærker, at denne egenskab netop er nyttig, hvor en chroot skjuler enhedsstier.
Så forklaringen om den manglende node er en hypotese om én gren af koden, ikke en regel om tilfældige tal generelt. Den holder, når beviserne nævner en sti, og den er gæt, når beviserne nævner noget andet.
Læs fejlkøen, derefter procesvisningen
Den hurtigste måde at afgøre spørgsmålet er at læse, hvad biblioteket allerede har registreret, og derefter se direkte på visningen i fængslet. Begynd med det OpenSSL-build, som tjenesten faktisk indlæste, fordi providerstakke adskiller sig mellem hovedversioner og mellem distributioner. Spørg derefter systemd, hvilken proces der kører, og hvilke begrænsninger der gælder for den. Først når begge fakta ligger på bordet, er det værd at liste de noder, som processen kan se.
openssl version -a
systemctl show openvpn-server@lab -p MainPID -p PrivateDevices -p DevicePolicy
pid=$(systemctl show -p MainPID --value openvpn-server@lab)
sudo ls -l /proc/"$pid"/root/dev/urandom /proc/"$pid"/root/dev/random
Kør disse aflæsninger mod den samme proces, ikke mod det shell, der tilfældigvis er åbent. At sammenligne værtens /dev med en urelateret proces' visning er måden, hvorpå den forkerte afhængighed bliver repareret to gange.
Tilføj først afhængigheden, når du kan navngive den
Når beviserne faktisk nævner en sti, er reparationen lille: gør netop den ene sti tilgængelig inde i fængslet, og lad alt andet være. Et bind-mount af den enkelte node er som regel nok, og mknod med nodens standard major- og minortal producerer samme resultat på installationer, hvor montering ikke er en mulighed. At udvide sandkassen, give adgang til hver tegnenhed eller slå PrivateDevices fra bytter en målrettet rettelse for en permanent sikkerhedsregression.
En entropi-dæmon er ikke en erstatning for den reparation. Pakker som haveged ændrer, hvordan kernelpuljen fodres; de kan ikke skabe et stinavn, som en indespærret proces har lov til at åbne. At installere en kan få en sundhedsgraf til at se bedre ud, mens open-kaldet stadig fejler. Hold de to problemer adskilt, ellers bliver den næste fejl igen tilskrevet det forkerte lag.
Kontroller generatoren og tunnelen hver for sig
En genstart er den eneste test, der genbruger den samme konfiguration, den samme unitfil og den samme indespærring, som frembragte fejlen. Kør den, og læs derefter de nyeste journalposter i stedet for en stikprøve fra en tidligere opstart.
sudo systemctl restart openvpn-server@lab
sudo journalctl -u openvpn-server@lab --since -5min --no-pager | grep -iE 'rand|entropy|Initialization Sequence'
Se efter to adskilte ting i det output: beskeden om tilfældigkilden, der forsvinder, og tunnelen, der når sin sædvanlige opstartsmilepæl. En generator, der virker igen, fjerner én lokal fejl og siger intet om serveridentitet, legitimationsoplysninger eller routing. Test det med samme klientkonfiguration, som fejlede før, så resultatet er sammenligneligt og ikke blot bedre.