RAND_bytes() failed је тврдња о једном локалном примитиву, не о налогу, унапред подељеном кључу или удаљеном порту. Две веома различите грешке стварају исти ред и остављају различите трагове. Једна је криптографски бекенд који одбија да испоручи бајтове; друга је процес који не достиже извор ентропије за који је његов код изграђен. Раздвојити их захтева једно читање реда грешака и један поглед на датотечни систем затвореног процеса, а та провера припада пре свега што настане под /dev.

Шта повратна вредност разликује

Документовани уговор разликује три исхода, не два: 1 за успех, -1 када учитана метода RAND не подржава захтев, и 0 за остале грешке, при чему објашњење остаје у реду грешака. Референца RAND_bytes додаје тачку коју је лако превидети: подразумевани генератор сеје семе из оперативног система на подржаним платформама, а када то сејање не успе, остаје у стању грешке уместо да врати предвидиве бајтове.

Само један од тих бројева описује окружење. -1 је питање градње, пружаоца или функције, јер је код тражио нешто што активна имплементација не нуди. 0 са притужбом на сејање је питање окружења, јер генератор уопште није могао да добије ентропију. Број сам по себи никада не каже који, а ни име функције.

Када је скривени чвор уређаја прави узрок

Ограничена услуга види друго стабло од љуске у коју куцате. Chroot затвори, слике контејнера и очврснуте unit датотеке редовно приказују /dev са мање чворова од оног на хосту. Ако имплементација која не успева отвара /dev/urandom по путањи, та разлика је довољна да сломи покретање док сам хост изгледа потпуно здраво. Уређај који постоји изван затвора не доказује ништа о томе шта затворени процес сме да отвори.

Нема свако насумично сучеље потребу за путањом, ипак. Системски позив getrandom у Linux-у не прихвата ни име датотеке ни датотечни дескриптор, а његова страница приручника напомиње да је то својство корисно управо онде где chroot скрива путање уређаја.

Дакле, објашњење чвора који недостаје је хипотеза о једној грани кода, а не правило о насумичним бројевима уопште. Држи када докази именују путању, а нагађање је када докази именују нешто друго.

Прво прочитајте ред грешака, затим приказ процеса

Најбржи начин да разјасните питање јесте да прочитате шта је библиотека већ забележила, а затим директно погледате приказ унутар затвора. Почните са градњом OpenSSL-а коју је услуга стварно учитала, јер се стекови пружалаца разликују између главних верзија и између дистрибуција. Затим питајте systemd који процес ради и која се ограничења на њега примењују. Тек када су обе чињенице на столу, вреди пописати чворове које тај процес може да види.

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

Изводите та читања на истом процесу, не на љусци која се случајно налази отворена. Поређење /dev хоста са приказом неповезаног процеса је начин на који се погрешна зависност поправи двапут.

Додајте зависност тек када можете да је именујете

Када докази заиста именују путању, поправка је мала: учините ту једну путању доступном унутар затвора и оставите све остало на миру. Bind mount појединачног чвора обично је довољан, а mknod са стандардним major и minor бројевима чвора даје исти резултат у инсталацијама где mount није опција. Проширење песковника, давање приступа сваком знаковном уређају или искључивање PrivateDevices мења циљану исправку за трајну безбедносну регресију.

Ентропијски демон није замена за ту поправку. Пакети попут haveged мењају како се храни језгрени базен; не могу да створе путању коју затворени процес сме да отвори. Инсталација једног може да побољша график здравља док позив open и даље не успева. Држите та два проблема одвојено, иначе ће следећи неуспех опет бити приписан погрешном слоју.

Проверите генератор и тунел одвојено

Поновно покретање је једини тест који поново користи исту конфигурацију, исту unit датотеку и исту изолацију које су проузроковале неуспех. Покрените га, а затим читајте најновије записе у дневнику уместо узорка из ранијег покретања.

sudo systemctl restart openvpn-server@lab
sudo journalctl -u openvpn-server@lab --since -5min --no-pager | grep -iE 'rand|entropy|Initialization Sequence'

У том излазу тражите две одвојене ствари: поруку о насумичном извору која нестаје и тунел који достиже своју уобичајену покретачку прекретницу. Генератор који поново ради уклања један локални неуспех и не говори ништа о идентитету сервера, акредитивима или рутирању. Тестирајте то истом клијентском конфигурацијом која раније није успела, како би резултат био упоредив, а не само бољи.

Повезани чланци