Error de RAND_bytes a OpenVPN: error de biblioteca o node absent
Una errada de RAND_bytes pot significar una font d’entropia rebutjada o un node amagat per una gàbia. Llegeix la cua d’errors i la vista del procés abans de crear dispositius.
RAND_bytes() failed és una afirmació sobre una primitiva local, no sobre el compte, la clau prèviament compartida o el port remot. Dues fallades molt diferents produeixen aquesta mateixa línia i deixen proves diferents. Una és un rerefons criptogràfic que es nega a emetre bytes; l’altra és un procés que no arriba a la font d’entropia per a la qual es va compilar el seu codi. Separar-les exigeix una lectura de la cua d’errors i una mirada a la vista del sistema de fitxers del mateix procés engabiat, i aquesta comprovació va abans de crear res sota /dev.
Què distingeix el valor de retorn
El contracte documentat separa tres resultats, no dos: 1 per a l’èxit, -1 quan el mètode RAND carregat no admet la petició i 0 per a la resta de fallades, amb l’explicació reservada a la cua d’errors. La referència de RAND_bytes afegeix un punt fàcil de passar per alt: el generador per defecte s’inicialitza des del sistema operatiu a les plataformes suportades, i quan aquesta inicialització falla es queda en un estat d’error en lloc de tornar bytes previsibles.
Només un d’aquests nombres descriu l’entorn. Un -1 és una qüestió de compilació, de proveïdor o de funcionalitat, perquè el codi va demanar una cosa que la implementació activa no ofereix. Un 0 amb una queixa d’inicialització és una qüestió d’entorn, perquè el generador no va poder obtenir entropia de cap manera. El nombre per si sol mai no diu quin dels dos, i el nom de la funció tampoc.
Quan un node de dispositiu amagat és la causa real
Un servei confinat veu un arbre diferent del de l’intèrpret on escriviu. Les gàbies chroot, les imatges de contenidor i les unitats endurides presenten habitualment un /dev amb menys nodes que el de l’amfitrió. Si la implementació que falla obre /dev/urandom pel camí, aquesta diferència n’hi ha prou per trencar l’arrencada mentre l’amfitrió sembla perfectament sa. Un dispositiu que existeix fora de la gàbia no demostra res sobre què pot obrir el procés engabiat.
No tota interfície aleatòria necessita un camí, però. La crida de sistema getrandom de Linux no accepta cap nom de fitxer ni cap descriptor de fitxer, i la seva pàgina de manual assenyala que aquesta propietat és útil precisament on un chroot amaga els camins dels dispositius.
Així, l’explicació del node absent és una hipòtesi sobre una branca del codi, no una regla sobre els nombres aleatoris en general. Es manté quan les proves nomenen un camí, i és conjectura quan les proves nomenen una altra cosa.
Llegeix la cua d’errors i després la vista del procés
La manera més ràpida de resoldre la qüestió és llegir què ha registrat ja la biblioteca i després mirar directament la vista engabiada. Comença per la compilació d’OpenSSL que el servei va carregar realment, perquè les piles de proveïdors difereixen entre versions majors i entre distribucions. Pregunta després a systemd quin procés s’executa i quines restriccions se li apliquen. Només quan tots dos fets són sobre la taula val la pena llistar els nodes que aquest procés pot veure.
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
Executa aquestes lectures contra el mateix procés, no contra l’intèrpret que passi a estar obert. Comparar el /dev de l’amfitrió amb la vista d’un procés aliè és com la dependència equivocada es repara dues vegades.
Afegeix la dependència només quan la puguis nomenar
Quan les proves sí que nomenen un camí, la reparació és petita: fes que aquest únic camí estigui disponible dins de la gàbia i no toquis res més. Una muntura bind del node únic sol ser suficient, i mknod amb els números major i minor estàndard del node produeix el mateix resultat en instal·lacions on la muntura no és una opció. Eixamplar la caixa de sorra, concedir accés a tots els dispositius de caràcters o desactivar PrivateDevices canvia una correcció puntual per una regressió de seguretat permanent.
Un dimoni d’entropia no substitueix aquesta reparació. Paquets com haveged canvien com s’alimenta el pool del nucli; no poden crear un camí que un procés engabiat tingui permès d’obrir. Instal·lar-ne un pot fer que un gràfic de salut sembli millor mentre la crida d’obertura continua fallant. Mantén els dos problemes separats, o la propera fallada s’atribuirà una altra vegada a la capa equivocada.
Verifica el generador i el túnel per separat
Un reinici és l’única prova que reutilitza la mateixa configuració, el mateix fitxer d’unitat i el mateix confinament que van produir la fallada. Executa’l i després llegeix les entrades més recents del registre en lloc d’una mostra d’una arrencada anterior.
sudo systemctl restart openvpn-server@lab
sudo journalctl -u openvpn-server@lab --since -5min --no-pager | grep -iE 'rand|entropy|Initialization Sequence'
Busca dues coses separades en aquesta sortida: el missatge de la font aleatòria que desapareix i el túnel que assoleix la seva fita habitual d’arrencada. Un generador que torna a funcionar elimina una fallada local i no diu res sobre la identitat del servidor, les credencials o l’encaminament. Prova-ho amb la mateixa configuració de client que fallava abans, perquè el resultat sigui comparable i no només millor.