Linux隨機數nonblocking pool快速初始化

在計算節點nova-compute運行裁剪Linux虛機提供OpenVPN服務端出現無法連接成功的情況,對Linux隨機數進行初步的瞭解以定位分析問題原因

1994 年,美國軟件工程師 Theodore Y. Ts'o 第一次在 Linux 內核中實現了隨機數發生器,使用 SHA-1 散列算法而非密碼,提高了密碼強度。

Linux 內核採用熵來描述數據的隨機性,熵(entropy)是描述系統混亂無序程度的物理量,一個系統的熵越大則說明該系統的有序性越差,即不確定性越大。內核維護了一個熵池用來收集來自設備驅動程序和其它來源的環境噪音。理論上,熵池中的數據是完全隨機的,可以實現產生真隨機數序列。爲跟蹤熵池中數據的隨機性,內核在將數據加入池的時候將估算數據的隨機性,這個過程稱作熵估算。熵估算值描述池中包含的隨機數位數,其值越大表示池中數據的隨機性越好。內核中隨機數發生器 PRNG 爲一個字符設備 random,代碼實現在drivers/char/random.c,該設備實現了一系列接口函數用於獲取系統環境的噪聲數據,並加入熵池。系統環境的噪聲數據包括設備兩次中斷間的間隔,輸入設備的操作時間間隔,連續磁盤操作的時間間隔等。對應的接口包括:

voidadd_device_randomness(const void *buf, unsigned int size);

函數用於獲取系統網絡設備環境的噪聲數據

voidadd_input_randomness(unsigned int type, unsigned int code,

                                     unsignedint value);

函數用於獲取系統輸入環境的噪聲數據

voidadd_interrupt_randomness(int irq, int irq_flags);

函數用於獲取系統中斷環境的噪聲數據

voidadd_disk_randomness(struct gendisk *disk);

函數用於獲取系統磁盤環境的噪聲數據

 

內核提供了 1 個的接口來供其他內核模塊使用

 

void get_random_bytes(void *buf, intnbytes);

該接口會返回指定字節數的隨機數。random 設備了提供了 2 個字符設備供用戶態進程使用——/dev/random /dev/urandom

·        /dev/random 適用於對隨機數質量要求比較高的請求,在熵池中數據不足時,讀取 dev/random 設備時會返回小於熵池噪聲總數的隨機字節。/dev/random 可生成高隨機性的公鑰或一次性密碼本。若熵池空了,對/dev/random 的讀操作將會被阻塞,直到收集到了足夠的環境噪聲爲止。這樣的設計使得/dev/random 是真正的隨機數發生器,提供了最大可能的隨機數據熵。

·        /dev/urandom,非阻塞的隨機數發生器,它會重複使用熵池中的數據以產生僞隨機數據。這表示對/dev/urandom 的讀取操作不會產生阻塞,但其輸出的熵可能小於/dev/random 的。它可以作爲生成較低強度密碼的僞隨機數生成器,對大多數應用來說,隨機性是可以接受的。

奇怪的問題:

在計算節點nova-compute運行裁剪Linux虛機提供OpenVPN服務端,在對虛機無任何操作的情況,發現OpenVPN客戶端長時間無法連接成功。

直到出現random: nonblocking pool is initializedOpenVPN客戶端正常連接成功。初步分析與nonblocking pool初始化有關。



問題解決:

如何加速Linux隨機數nonblocking pool初始化,解決在對虛機無任何操作的情況下OpenVPN客戶端長時間無法連接的內核補丁:


https://patchwork.kernel.org/patch/6781261/

重新編譯內核驗證Linux隨機數nonblocking pool2s左右完成初始化, 網絡初始完成OpenVPN客戶端正常連接。

後續關於Linux隨機數獲取系統環境的噪聲數據原理與實現有待分析




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章