RAND_bytes gagal dalam OpenVPN: ralat pustaka atau nod yang hilang
Kegagalan RAND_bytes boleh bermakna sumber entropi yang ditolak atau nod yang disembunyikan oleh jail. Baca baris gilir ralat dan paparan proses sebelum mencipta peranti.
RAND_bytes() failed ialah kenyataan tentang satu primitif tempatan, bukan tentang akaun, kunci yang dikongsi terlebih dahulu atau port jauh. Dua kegagalan yang sangat berbeza menghasilkan baris yang sama dan meninggalkan bukti yang berbeza. Satu ialah backend kriptografi yang enggan mengeluarkan bait; satu lagi ialah proses yang tidak sampai ke sumber entropi yang menjadi asas kodnya dibina. Memisahkan kedua-duanya memerlukan satu bacaan baris gilir ralat dan satu pandangan pada paparan sistem fail proses yang dikurung, dan semakan itu perlu dilakukan sebelum apa-apa dicipta di bawah /dev.
Apa yang dibezakan nilai pulangan
Kontrak yang didokumenkan membezakan tiga hasil, bukan dua: 1 untuk kejayaan, -1 apabila kaedah RAND yang dimuatkan tidak menyokong permintaan, dan 0 untuk kegagalan lain, dengan penjelasan ditinggalkan dalam baris gilir ralat. Rujukan RAND_bytes menambah satu perkara yang mudah terlepas pandang: penjana lalai mengambil benih daripada sistem pengendalian pada platform yang disokong, dan apabila pembenihan itu gagal, ia kekal dalam keadaan ralat dan bukannya memulangkan bait yang boleh diramal.
Hanya satu daripada nombor itu menggambarkan persekitaran. -1 ialah persoalan binaan, penyedia atau ciri, kerana kod meminta sesuatu yang tidak ditawarkan oleh pelaksanaan aktif. 0 dengan aduan pembenihan ialah persoalan persekitaran, kerana penjana langsung tidak dapat memperoleh entropi. Nombor itu sendiri tidak pernah mengatakan yang mana, dan nama fungsi itu juga tidak.
Bila nod peranti tersembunyi menjadi punca sebenar
Perkhidmatan terbatas melihat pokok yang berbeza daripada shell tempat anda menaip. Penjara chroot, imej kontena dan fail unit yang dikeraskan lazimnya menyediakan /dev yang mengandungi lebih sedikit nod daripada milik hos. Jika pelaksanaan yang gagal membuka /dev/urandom mengikut nama laluan, perbezaan itu cukup untuk merosakkan permulaan sementara hos sendiri kelihatan sangat sihat. Peranti yang wujud di luar penjara tidak membuktikan apa-apa tentang apa yang boleh dibuka oleh proses yang dikurung.
Bukan setiap antara muka rawak memerlukan laluan, bagaimanapun. Panggilan sistem getrandom dalam Linux tidak menerima nama fail mahupun deskriptor fail, dan halaman manualnya menyatakan bahawa sifat ini berguna tepat di tempat chroot menyembunyikan laluan peranti.
Jadi penjelasan nod yang hilang ialah hipotesis tentang satu cabang kod, bukan peraturan tentang nombor rawak secara umum. Ia bertahan apabila bukti menyebut laluan, dan ia ialah tekaan apabila bukti menyebut sesuatu yang lain.
Baca baris gilir ralat, kemudian paparan proses
Cara terpantas untuk menyelesaikan persoalan ialah membaca apa yang telah direkodkan oleh pustaka, kemudian melihat terus paparan di dalam penjara. Mulakan dengan binaan OpenSSL yang benar-benar dimuatkan oleh perkhidmatan, kerana tindanan penyedia berbeza antara versi utama dan antara pengedaran. Kemudian tanya systemd proses mana yang berjalan dan sekatan apa yang terpakai kepadanya. Hanya selepas kedua-dua fakta berada di atas meja barulah senarai nod yang boleh dilihat oleh proses itu berbaloi.
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
Jalankan bacaan itu terhadap proses yang sama, bukan terhadap shell yang kebetulan terbuka. Membandingkan /dev hos dengan paparan proses yang tidak berkaitan ialah cara pergantungan yang salah dibaiki dua kali.
Tambah pergantungan hanya selepas anda boleh menamakannya
Apabila bukti memang menyebut laluan, pembaikan itu kecil: sediakan satu laluan itu di dalam penjara dan biarkan yang lain. Bind mount bagi satu nod biasanya memadai, dan mknod dengan nombor major dan minor standard nod menghasilkan hasil yang sama pada pemasangan di mana mount bukan pilihan. Meluaskan sandbox, memberi akses kepada setiap peranti aksara atau mematikan PrivateDevices menukar pembaikan bersasar dengan regresi keselamatan kekal.
Daemon entropi bukan pengganti pembaikan itu. Pakej seperti haveged mengubah cara kolam kernel diberi makan; ia tidak boleh mencipta nama laluan yang dibenarkan untuk dibuka oleh proses yang dikurung. Memasangnya boleh membuat graf kesihatan kelihatan lebih baik sementara panggilan buka masih gagal. Jaga kedua-dua masalah itu berasingan, jika tidak kegagalan seterusnya akan dikaitkan semula dengan lapisan yang salah.
Sahkan penjana dan terowong secara berasingan
Mula semula ialah satu-satunya ujian yang menggunakan semula konfigurasi, fail unit dan kurungan yang sama yang menghasilkan kegagalan itu. Jalankannya, kemudian baca entri jurnal terbaharu dan bukannya sampel daripada permulaan terdahulu.
sudo systemctl restart openvpn-server@lab
sudo journalctl -u openvpn-server@lab --since -5min --no-pager | grep -iE 'rand|entropy|Initialization Sequence'
Cari dua perkara berasingan dalam output itu: mesej tentang sumber rawak yang hilang, dan terowong yang mencapai pencapaian permulaan biasa. Penjana yang berfungsi semula menghilangkan satu kegagalan tempatan dan tidak mengatakan apa-apa tentang identiti pelayan, kelayakan atau penghalaan. Uji perkara itu dengan konfigurasi klien yang sama yang gagal sebelum ini, supaya hasilnya setanding dan bukan sekadar lebih baik.