hostapd、/dev/random、/dev/urandom


  在使用hostapd做軟ap時,出現了random熵不夠的問題,導致節點連接不上這個ap。

  下面先解釋一下/dev/random和/dev/urandom

先讓我們從一個工程中遇到的實際問題開始,先上log:

E/hostapd (  100): random: Cannot readfrom /dev/random: Try again

I/hostapd (  100): random: Only 0/20bytes of strong random data available from /dev/random

I/hostapd (  100): random: Not enoughentropy pool available for secure operations

I/hostapd (  100): WPA: Note[   22.722265] RTL871X: set group key to hw: alg:2(WEP40-1 WEP104-5TKIP-2 AES-4) keyid:1

nough entropy in random pool to proceed -reject first 4-way handshake


以上是hostapd在接受一個wifi終端的接入鑒權時的一段log,該段log顯示,在開始四步握手鑒權時,需要獲取隨機數,而此時/dev/random卻未能夠提供足夠的隨機數熵(entropy),導致鑒權不能正常進行。

那為什么/dev/random不能提供足夠的隨機數呢,為了解析這個,得從他們的根源分析起。

 

/dev/random和/dev/urandom是unix系統提供的產生隨機數的設備,很多應用都需要使用random設備提供的隨機數,比如ssh keys, SSL keys, TCP/IP sequence numbers等等

而random設備的random pool是從基於中斷的IRQS里面取值,IRQS跟一些特殊的硬件綁定,基於這些硬件的interrupts將會提供給random設備。

 

以下模擬一個從/dev/random取值但是/dev/random取不到足夠值的情況,這時候取值的進程將會等待,直到得到足夠的random 值。

 

rubbitxiao@szmce15:~$ time dd if=/dev/random of=1.dmp bs=1024k count=100 &
[1] 25398

這時dd的進程將會hang住等待足夠的random值

rubbitxiao@szmce15:~$ ps
  PID TTY          TIME CMD
24315 pts/11   00:00:00 bash
25398 pts/11   00:00:00 bash
25399 pts/11   00:00:00 dd
25400 pts/11   00:00:00 ps


用strace跟蹤dd進程在做什么

rubbitxiao@szmce15:~$ sudo strace -p 25399
[sudo] password for rubbitxiao: 
Process 25399 attached - interrupt to quit
read(0, "\256Yi\314\266\351\1\366", 1048576) = 8
write(1, "\256Yi\314\266\351\1\366", 8) = 8
read(0, "wYyV\264\362K\23", 1048576)    = 8
write(1, "wYyV\264\362K\23", 8)         = 8
read(0, "Cm\220>uy\260\376", 1048576)   = 8
write(1, "Cm\220>uy\260\376", 8)        = 8
read(0, "\365\217\302yk\177\234\244", 1048576) = 8
write(1, "\365\217\302yk\177\234\244", 8) = 8
read(0, "\24,\226l\216\203E\322", 1048576) = 8
write(1, "\24,\226l\216\203E\322", 8)   = 8
read(0, "t\273\27\237\r\243\2164", 1048576) = 8
write(1, "t\273\27\237\r\243\2164", 8)  = 8
read(0, "\232x\n \337M\313/", 1048576)  = 8
write(1, "\232x\n \337M\313/", 8)       = 8
read(0, "\227\251\212\264o\30~\327", 1048576) = 8
write(1, "\227\251\212\264o\30~\327", 8) = 8
read(0, "y\21\20\213cAS\260", 1048576)  = 8
write(1, "y\21\20\213cAS\260", 8)       = 8
read(0, "p\355\356\303\36\35\350\206\323", 1048576) = 9
write(1, "p\355\356\303\36\35\350\206\323", 9) = 9
read(0, "&\1b\32\262L\3\33\10", 1048576) = 9
write(1, "&\1b\32\262L\3\33\10", 9)     = 9
read(0, "O\30\372\374\t-7\36", 1048576) = 8
write(1, "O\30\372\374\t-7\36", 8)      = 8
read(0, "]\277\22\364\260\217\254>", 1048576) = 8
write(1, "]\277\22\364\260\217\254>", 8) = 8
read(0, "R,\0227\307\300\275}", 1048576) = 8
write(1, "R,\0227\307\300\275}", 8)     = 8
read(0, "p^\356V&7\223w\271", 1048576)  = 9
write(1, "p^\356V&7\223w\271", 9)       = 9
read(0, "t\267\325_\7\227\303\313", 1048576) = 8
write(1, "t\267\325_\7\227\303\313", 8) = 8
read(0, "\216DA_\340\211\ts", 1048576)  = 8
write(1, "\216DA_\340\211\ts", 8)       = 8
read(0, "jl\366D\1\25o\315<", 1048576)  = 9
write(1, "jl\366D\1\25o\315<", 9)       = 9
read(0, "\375\266\253\36\234\255I\n", 1048576) = 8
write(1, "\375\266\253\36\234\255I\n", 8) = 8
read(0, "h\216j\3046\315>{", 1048576)   = 8
write(1, "h\216j\3046\315>{", 8)        = 8
read(0, "\270\267\33S\314\354= ", 1048576) = 8
write(1, "\270\267\33S\314\354= ", 8)   = 8
read(0, ");\361\356\363\316_\242", 1048576) = 8

...  ...

write(1, "V\261\373h\267\0104+", 8)     = 8
read(0, "\4\327\335S\304\24\243\362", 1048576) = 8
write(1, "\4\327\335S\304\24\243\362", 8) = 8
read(0, "0\0b\27\363\\\217\"", 1048576) = 8
write(1, "0\0b\27\363\\\217\"", 8)      = 8
close(0)                                = 0
close(1)                                = 0
write(2, "0+100 records in\n0+100 records o"..., 350+100 records in
0+100 records out
) = 35
write(2, "807 bytes (807 B) copied", 24807 bytes (807 B) copied) = 24
write(2, ", 1407.68 s, 0.0 kB/s\n", 22, 1407.68 s, 0.0 kB/s
) = 22
close(2)                                = 0
exit_group(0)                           = ?
Process 25399 detached


real    23m27.695s
user    0m0.012s
sys     0m0.000s
[1]+  Done                    time dd if=/dev/random of=1.dmp bs=1024k count=100

 

以上可以看出,從/dev/random讀取(100*1024K個)隨機數,由於中間會阻塞(dd hang),所以總計花了23分鍾27秒才完成。為什么會花費這么長的時間,因為它的隨機數的提供是依賴與外部中斷事件的,如果沒有足夠多中斷事件,就會阻塞,其實為了加速/dev/random提供隨機數的速度,你可以通過操作設備的外設,讓其產生大量的中斷(如網絡傳輸數據,按鍵,移動鼠標等)。

 

是否有足夠的熵來用於產生隨機數,可以通過如下命令來查看:

cat /proc/sys/kernel/random/entropy_avail

rubbitxiao@szmce15:~$ cat /proc/sys/kernel/random/entropy_avail                                                                    
277

 

接下來我們看/dev/urandom,從它那里取同樣多的隨機數,

rubbitxiao@szmce15:~$ 
rubbitxiao@szmce15:~$ time dd if=/dev/urandom of=1.dmp bs=1024k count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 6.38387 s, 16.4 MB/s


real    0m6.385s
user    0m0.000s
sys     0m6.364s
rubbitxiao@szmce15:~$ 

卻只需要花費6.385秒,同樣的機器上,/dev/urandom不受interrupts的限制,即使沒有足夠的interrupt它也能通過 random number generator產生足夠的輸出值,所以它不會導致dd hang

至此可以看出/dev/urandom與/dev/random的區別,前者不受外部中斷的影響,照樣可以產生隨機數,而后者則受系統外部中斷的影響,所以如果取較多隨機數,可能會導致應用會hang住。在我們開篇的那個log,就是屬於這個問題。

 

還遇見了這個問題,log如下

Configuration file: /etc/hostapd/hostapd.conf
Using interface wlp4s0 with hwaddr 3c:33:00:f6:67:2b and ssid "Codz"
random: Cannot read from /dev/random: Resource temporarily unavailable
random: Only 0/20 bytes of strong random data available from /dev/random
random: Not enough entropy pool available for secure operations
WPA: Not enough entropy in random pool for secure operations - update keys later when the first station connects
wlp4s0: interface state UNINITIALIZED->ENABLED
wlp4s0: AP-ENABLED

總得來說都是random出了問題,最終的解決方法是:
mv /dev/random /dev/random.orig
ln -s /dev/urandom /dev/random
使用urandom產生隨機數

本文摘錄了https://blog.csdn.net/xiaojsj111/article/details/24366127的一些內容
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM