RAND_bytes() failed tek bir yerel ilkel hakkında bir ifadedir; hesap, önceden paylaşılan anahtar veya uzak bağlantı noktası hakkında değildir. Çok farklı iki arıza aynı satırı üretir ve farklı izler bırakır. Biri bayt vermeyi reddeden bir kriptografik arka uçtur; diğeri, kodunun kullanmak üzere inşa edildiği entropi kaynağına ulaşamayan bir süreçtir. Bunları ayırmak bir hata kuyruğu okuması ve hapishaneye kapatılmış sürecin dosya sistemi görünümüne bir bakış gerektirir ve bu kontrol /dev altında herhangi bir şey oluşturulmadan önce yapılmalıdır.

Dönüş değerinin ayırt ettikleri

Belgelenen sözleşme iki değil üç sonucu ayırır: başarı için 1, yüklenen RAND yöntemi isteği desteklemediğinde -1 ve diğer arızalar için 0; açıklama hata kuyruğunda bırakılır. RAND_bytes başvurusu kolayca atlanan bir nokta ekler: varsayılan üretici desteklenen platformlarda işletim sisteminden tohum alır ve bu tohumlama başarısız olduğunda öngörülebilir baytlar döndürmek yerine hata durumunda kalır.

Bu sayılardan yalnızca biri ortamı tanımlar. -1, derleme, sağlayıcı veya özellik sorusudur, çünkü kod etkin uygulamanın sunmadığı bir şey istemiştir. Tohumlama şikâyetiyle gelen 0 ise ortam sorusudur, çünkü üretici hiç entropi elde edememiştir. Sayı tek başına hangisi olduğunu asla söylemez, işlev adı da söylemez.

Gizli aygıt düğümü gerçek neden olduğunda

Kısıtlanmış bir hizmet, yazdığınız kabuktan farklı bir ağaç görür. Chroot hapishaneleri, konteyner imajları ve sertleştirilmiş birim dosyaları düzenli olarak ana makinedekinden daha az düğüm içeren bir /dev sunar. Arızalı uygulama /dev/urandom dosyasını yol adıyla açıyorsa bu fark, ana makine tamamen sağlıklı görünürken başlatmayı bozmaya yeter. Hapishanenin dışında var olan bir aygıt, kapatılmış sürecin neyi açmasına izin verildiği konusunda hiçbir şey kanıtlamaz.

Ancak her rastgele arayüz bir yola ihtiyaç duymaz. Linux'un getrandom sistem çağrısı ne bir dosya adı ne de bir dosya tanımlayıcısı kabul eder ve kılavuz sayfası, bu özelliğin tam olarak bir chroot'un aygıt yollarını gizlediği yerde yararlı olduğunu belirtir.

Dolayısıyla eksik düğüm açıklaması kodun bir dalına ilişkin bir hipotezdir, rastgele sayılar hakkında genel bir kural değildir. Kanıtlar bir yol adlandırdığında geçerlidir ve kanıtlar başka bir şey adlandırdığında bir tahmindir.

Önce hata kuyruğunu, sonra süreç görünümünü okuyun

Soruyu çözmenin en hızlı yolu, kitaplığın hâlihazırda kaydettiklerini okumak ve ardından hapishanenin içindeki görünüme doğrudan bakmaktır. Hizmetin gerçekte yüklediği OpenSSL derlemesiyle başlayın, çünkü sağlayıcı yığınları ana sürümler ve dağıtımlar arasında farklıdır. Ardından systemd'ye hangi sürecin çalıştığını ve hangi kısıtlamaların geçerli olduğunu sorun. Ancak her iki olgu da masadayken o sürecin görebildiği düğümleri listelemeye değer.

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

Bu okumaları aynı süreç üzerinde yapın, açık kalan kabuk üzerinde değil. Ana makinenin /dev değerini ilgisiz bir sürecin görünümüyle karşılaştırmak, yanlış bağımlılığın iki kez onarıldığı yoldur.

Bağımlılığı ancak adlandırabildiğinizde ekleyin

Kanıtlar gerçekten bir yol adlandırdığında onarım küçüktür: o tek yolu hapishanenin içinde kullanılabilir kılın ve geri kalan her şeye dokunmayın. Tek düğümün bind bağlaması genellikle yeterlidir ve mknod düğümün standart major ve minor numaralarıyla bağlamanın seçenek olmadığı kurulumlarda aynı sonucu verir. Korumalı alanı genişletmek, her karakter aygıtına erişim vermek veya PrivateDevices seçeneğini kapatmak hedefli bir düzeltmeyi kalıcı bir güvenlik gerilemesiyle değiştirir.

Bir entropi arka plan programı bu onarımın yerini tutmaz. haveged gibi paketler çekirdek havuzunun nasıl beslediğini değiştirir; kapatılmış bir sürecin açmasına izin verilen bir yol oluşturamazlar. Birini kurmak, açma çağrısı hâlâ başarısızken sağlık grafiğini daha iyi gösterebilir. İki sorunu ayrı tutun, yoksa bir sonraki arıza yine yanlış katmana atfedilir.

Üreticiyi ve tüneli ayrı ayrı doğrulayın

Yeniden başlatma, arızayı üreten aynı yapılandırmayı, aynı birim dosyasını ve aynı yalıtımı yeniden kullanan tek testtir. Çalıştırın ve ardından önceki bir başlatmadan alınan örnek yerine günlüğün en yeni girdilerini okuyun.

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

O çıktıda iki ayrı şey arayın: rastgele kaynakla ilgili mesajın kaybolması ve tünelin olağan başlatma kilometre taşına ulaşması. Yeniden çalışan bir üretici yerel bir arızayı ortadan kaldırır ve sunucu kimliği, kimlik bilgileri veya yönlendirme hakkında hiçbir şey söylemez. Bunu daha önce başarısız olan aynı istemci yapılandırmasıyla test edin, sonuç yalnızca daha iyi değil karşılaştırılabilir olsun.

İlgili makaleler