RAND_bytes v OpenVPN ni uspel: napaka knjižnice ali manjkajoče vozlišče
Neuspeh RAND_bytes lahko pomeni zavrnjen vir entropije ali vozlišče, skrito z ječo. Preberite čakalno vrsto napak in pogled procesa, preden ustvarite naprave.
RAND_bytes() failed je trditev o enem lokalnem primitivu, ne o računu, vnaprej deljenem ključu ali oddaljenih vratih. Dve zelo različni okvari ustvarita isto vrstico in pustita različne sledi. Ena je kriptografski backend, ki noče izdati bajtov; druga je proces, ki ne doseže vira entropije, za katerega je bila njegova koda zgrajena. Za ločitev je potrebno eno branje čakalne vrste napak in en pogled na datotečni sistem zaprtega procesa, ta pregled pa sodi pred vse, kar nastane pod /dev.
Kaj razlikuje povratna vrednost
Dokumentirana pogodba loči tri izide, ne dva: 1 za uspeh, -1 ko naložena metoda RAND ne podpira zahteve, in 0 za druge okvare, pri čemer razlaga ostane v čakalni vrsti napak. Referenca RAND_bytes doda točko, ki jo zlahka spregledamo: privzeti generator se na podprtih platformah seeda iz operacijskega sistema, in ko to sejanje spodleti, ostane v stanju napake, namesto da bi vrnil predvidljive bajte.
Samo ena od teh številk opisuje okolje. -1 je vprašanje gradnje, ponudnika ali funkcije, ker je koda zahtevala nekaj, česar aktivna izvedba ne ponuja. 0 s pritožbo zaradi sejanja je okoljsko vprašanje, ker generator sploh ni mogel dobiti entropije. Številka sama nikoli ne pove, katera od obeh, in ime funkcije prav tako ne.
Kdaj je skrito vozlišče naprave resnični vzrok
Omejena storitev vidi drugačno drevo kot lupina, v katero tipkate. Chroot ječe, slike vsebnikov in utrjene unit datoteke redno predstavljajo /dev z manj vozlišči kot gostiteljev. Če okvarjena izvedba odpira /dev/urandom po imenu poti, ta razlika zadostuje, da zlomi zagon, medtem ko je gostitelj sam videti popolnoma zdrav. Naprava, ki obstaja zunaj ječe, ne dokazuje ničesar o tem, kaj sme zaprti proces odpreti.
Vsak naključni vmesnik pa ne potrebuje poti. Sistemski klic getrandom v Linuxu ne sprejema imena datoteke niti datotečnega deskriptorja, in njegova stran s priročnikom ugotavlja, da je ta lastnost koristna prav tam, kjer chroot skriva poti naprav.
Razlaga manjkajočega vozlišča je torej hipoteza o eni veji kode, ne pravilo o naključnih številih na splošno. Drži, ko dokazi imenujejo pot, in je ugibanje, ko dokazi imenujejo kaj drugega.
Najprej preberite čakalno vrsto napak, nato pogled procesa
Najhitrejši način za razrešitev vprašanja je prebrati, kar je knjižnica že zabeležila, in nato neposredno pogledati pogled znotraj ječe. Začnite z gradnjo OpenSSL, ki jo je storitev dejansko naložila, ker se skladi ponudnikov razlikujejo med glavnimi različicami in med distribucijami. Nato vprašajte systemd, kateri proces teče in katere omejitve zanj veljajo. Šele ko sta obe dejstvi na mizi, se je vredno lotiti seznama vozlišč, ki jih ta proces vidi.
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
Te poglede izvajajte na istem procesu, ne na lupini, ki je slučajno odprta. Primerjanje gostiteljevega /dev s pogledom nepovezanega procesa je način, kako se napačna odvisnost popravi dvakrat.
Odvisnost dodajte šele, ko jo znate poimenovati
Ko dokazi res imenujejo pot, je popravilo majhno: omogočite to eno pot znotraj ječe in pustite vse ostalo pri miru. Bind mount posameznega vozlišča običajno zadostuje, in mknod s standardnimi major in minor številkami vozlišča da enak rezultat v namestitvah, kjer mount ni možnost. Razširitev peskovnika, dostop do vsake znakovne naprave ali izklop PrivateDevices zamenja ciljni popravek za trajno varnostno regresijo.
Entropijski demon ne nadomesti tega popravila. Paketi, kot je haveged, spreminjajo, kako se krmi jedrni bazen; ne morejo ustvariti poti, ki jo sme zaprti proces odpreti. Namestitev enega lahko izboljša graf zdravja, medtem ko klic open še vedno spodleti. Držite težavi ločeni, sicer bo naslednja okvara spet pripisana napačni plasti.
Preverite generator in tunel ločeno
Ponovni zagon je edini test, ki znova uporabi isto konfiguracijo, isto unit datoteko in isto izolacijo, ki so povzročili okvaro. Zaženite ga in nato berite najnovejše vnose v dnevniku, ne vzorca iz prejšnjega zagona.
sudo systemctl restart openvpn-server@lab
sudo journalctl -u openvpn-server@lab --since -5min --no-pager | grep -iE 'rand|entropy|Initialization Sequence'
V tem izpisu poiščite dve ločeni stvari: sporočilo o naključnem viru, ki izgine, in tunel, ki doseže svoj običajni zagonski mejnik. Generator, ki spet deluje, odpravi eno lokalno okvaro in ne pove ničesar o identiteti strežnika, poverilnicah ali usmerjanju. Preizkusite to z isto odjemalsko konfiguracijo, ki je prej spodletela, da bo rezultat primerljiv in ne le boljši.