啓動SSHD服務遭遇【PRNGis not seeded】

今天有一臺服務器重啓後發現使用ssh無法登陸,於是從控制檯登陸後發現果然是服務器的sshd服務沒有隨機啓動,本以爲手工啓動一下就OK了,結果發現啓動的時候報錯了,進程起來然後提示【PRNGis not seeded】後就直接退出了,google了一下發現是缺失了兩個生成隨機數的文件/dev/random和/dev/urandom。而sshd服務啓動時openssl會調用RAND_add()或RAND_seed()函數產生隨機數,因此設備缺失後直接導致opensll調用使用,最終就是sshd服務無法啓動。

然後就是按照晚上所說的,使用mknod命令創建那兩個設備:

mknod /dev/random c 1 8
mknod /dev/urandom c 1 9

本以爲這樣問題就搞定了,但是我有再一次錯了,創建完這兩個設備以後再次啓動sshd服務,還是依然無法啓動,於是使用管理員三大法寶之一---重啓服務器大笑

奇蹟出現了,發現再次重啓完服務器後問題就自動解決了,sshd也可以正常隨機啓動了。

但是要注意一個問題就是,你會發現此時設備/dev/random和/dev/urandom的主從設備號變了,不是手工創建時指定的1,8和1,9了,而是:

[transdb@root]# ls -l /dev/*rand*
crw-r--r--    1 root     system       34,  0 Nov 28 09:34 /dev/random
crw-r--r--    1 root     system       34,  1 Nov 28 09:34 /dev/urandom

這說明了其實這些設備是由服務器啓動時自動生成的,而最開始之所以沒有自動產生導致sshd無法自啓動,可能是由於其他操作(如,最先重啓之前我在系統安裝了rsct.basic、rsct.compat.basic、rsct.compat.client軟件包,又在大量讀寫文件系統時進行文件系統收縮,還導致了文件系統的超級塊受污染,以及對文件系統做了fsck等等一系列的操作,我不知道是否和這些操作有關,也許吧)導致的系統沒有自動產生,再次重啓嘗試也許就OK了。


【網摘:擴展閱讀之關於mknod命令】

mknod 命令
用途
創建特殊文件。
語法
只能由 root 用戶或系統組成員運行
mknod Name { b | c } Major Minor
創建 FIFO(已命名的管道)
mknod Name { p }
描述
mknod 命令建立一個目錄項和一個特殊文件的對應索引節點。第一個參數是 Name 項設備的名稱。選擇一個描述性的設備名稱。mknod 命令有兩種形式,它們有不同的標誌。
mknod 命令的第一種形式只能由 root 用戶或系統組成員執行。在第一種形式中,使用了b 或 c 標誌。b 標誌表示這個特殊文件是面向塊的設備(磁盤、軟盤或磁帶)。c 標誌表示這個特殊文件是面向字符的設備(其它設備)。
第一種形式的最後兩個參數是指定主設備的數目,它幫助操作系統查找設備驅動程序代碼,和指定次設備的數目,也就是單元驅動器或行號,它們是十進制或八進制的。一個設備的主要和次要編號由該設備的配置方法分配,它們保存在 ODM 中的 CuDvDr 類裏。在這個對象類中定義了主要和次要編號以確保整個系統設備定義的一致性,這是很重要的。
在 mknod 命令的第二種形式中,使用了 p 標誌來創建 FIFO(已命名的管道)。
標誌
b    表示特殊文件是面向塊的設備(磁盤、軟盤或磁帶)。
c    表示特殊文件是面向字符的設備(其它設備)。
p    創建 FIFO(已命名的管道)。
示例
要創建一個新軟盤驅動器的特殊文件,輸入:
mknod /dev/fd2  b 1 2
這創建了 /dev/fd2 特殊文件,它是一個特殊塊文件,主設備號爲 1,次設備號爲 2。
文件
/usr/sbin/mknod    包含 mknod 命令。
相關信息
mknod 子例程。

【網摘:擴展閱讀之關於主從設備號】

主次設備號
定義  主設備號被系統用來確定驅動程式(設備類型:如USB設備,硬盤設備),次設備號被驅動程式用來確定具體的設備。
查看主、次設備號
  字符設備驅動的特殊文件,可以通過ls-l輸出的第一列中的“c”標明。/dev下還有塊設備,但它們是“b”來識別;儘管如下介紹的某些內容也適用於塊設備,但我們這章只關注字符設備。
  如果你執行ls-l命令,在設備文件條目中的最新修改日期前你會看到二個數(用逗號分隔),這個位置通常顯示文件長度。這二個數就是相應設備的主設備號和次設備號。下面的列表給出了我使用的系統上的一些設備。它們的主設備號是10,7,1和4,而次設備號是0,3,5,64,5和129。
  crw-rw-rw- 1 root root 1, 3 Feb23 1999 null
  crw------- 1 root root 10, 1 Feb23 1999 psaux
  crw------- 1 rubini tty 4, 1 Aug16 22:22 tty1
  crw-rw-rw- 1 root dialout 4, 64 Jun30 11:19 ttyS0
  crw-rw-rw- 1 root dialout 4, 65 Aug16 00:00 ttyS1
  crw------- 1 root sys 7, 1 Feb23 1999 vcs1
  crw------- 1 root sys 7, 129 Feb 23 1999 vcsa1
  crw-rw-rw- 1 root root 1, 5 Feb23 1999 zero
  主設備號識別設備對應的驅動程序。例如,/dev/null和/dev/zero都由驅動程序1管理,而所有的虛擬控制檯和串口終端都由驅動程序4管理,同樣,vcs1和 vcsa1由驅動程序7管理。當設備打開(open)時,內核利用主設備號分派執行相應的驅動程序。
  次設備號只由相應的設備驅動程序使用;內核的其他部分不使用它,僅將它傳遞給驅動程序。所以一個驅動程序管理若干個設備並不爲奇(如上面的例子所示),次序號提供了一種區分它們的方法。 儘管2.4版本的內核引入了一種新的特性(可選):設備文件系統,devfs。如果使用了這種文件系統,那設備文件將變得簡單,但也很原來有很大的不同。另一方面,這新的文件系統帶來了一些用戶可見的不兼容特性。
應用
  當沒有使用devfs時,向系統增加一個驅動程序意味着要賦值它一個主設備號。這一賦值過程應該在驅動程序(模塊)的初始化過程中完成,它調用如下函數,這個函數定義在<linux/fs.h>:
  int register_chrdev(unsigned intmajor, const char *name, struct file_operations *fops);
  返回值提示成功或者失敗。返回一個負值,表示出錯;返回零或正值,表示成功。參數major是所請求的主設備號,name是你的設備的名字,它將在/proc/devices中出現,fops是一個指向函數隊列的指針,利用它完成對設備函數的調用。
  主設備號是一個用來索引靜態字符設備組的整數,“動態分配主設備號”將在本章的稍後部分中介紹怎樣選擇一個主設備號。2.0內核支持128個設備驅動,而2.2和2.4內核支持256個(保留數值0和255爲將來使用)。而次版本號(8位字節的數)並沒有傳遞給register_chrdev函數,因爲次版本號是驅動程序自己使用的。開發團隊爲了增加內核可能支持的設備數量而帶來了很大的壓力,在開發樹2.5版本內核的目標中,設備號至少是16位的。
  一旦設備驅動程序註冊到內核表中,它的操作都與分配的主設備號匹配,何時在字符設備文件上操作都與它的主設備號相關聯,內核都會通過file_operations結構體查找並調用相應的驅動程序中的函數。爲了這個原因,傳遞給register_chrdev的指針應該是指向驅動程序中的全局結構體,而不是一個局部的一個模塊初始化函數。
  接下來的問題就是如何給程序一個名字以被它們用來請求你的設備驅動程序。這個名字必須插入到/dev目錄中,並與你的驅動程序的主設備號和次設備號相連。
  在文件系統上創建一個設備節點的命令是mknod,而且你必須是超級用戶才能操作。除了要創建的節點名字外,該命令還帶三個參數。例如,命令:
  mknod /dev/scull0 c 254 0
  創建一個字符設備(c),主設備號是254,次設備號是0。由於歷史原因,次設備號應該在0-255範圍內,有時它們存儲在一個字節中。存在很多原因擴展可使用的次設備號的範圍,但就現在而言,仍然有8位限制。
  請注意:如果一旦用mknod生成了一個特別的設備文件,它就永遠存在了硬盤上,除非你明白的刪除了它。你可以通過執行命令"rm"命令來刪除例子中的設備。
  rm /dev/scull0
動態分配主設備號
  某些主設備號已經靜態地指派給了大部分常見設備。在內核源代碼樹的Documentation/device.txt文件中可以找到這些設備的列表。由於許多編號已經分配了,爲新設備選擇一個唯一的編號是很困難的——可配置的設備要比主設備號多得多。
  所幸,可以對主設備號進行動態分配。如果調用register_chrdev時將major設爲0,則該函數會自動選擇一個空閒的號碼並返回作爲該設備的主設備號。返回的主設備號總是正值,而返回負值時表明出錯。注意如下兩種情況的細微差別:若調用者請求一個動態的主設備號時函數register_chrdev返回值爲所分配的主設備號,而當成功地註冊到一個預先定義的主設備號時(即不採用動態分配而採用靜態指派方式),函數返回值爲0而非主設備號。
  對於private dirvers,強烈建議使用動態分配的方法來得到主設備號。相反,如果你的設備普遍應用在大多數場合甚至要被包含在官方的內核樹中,你就需要指派一個主設備號作爲專用。
  動態分配的缺點是:由於分配給你的主設備號不能保證總是一樣的,因而你無法用mknod命令事先創建設備節點(即設備文件)(可在加載模塊時用腳本自動創建)。這意味着你將不能使用Chapter 11中介紹的關於“按需載入模塊(loading-on-demandof your driver)”的先進特性。對於用於一般用途的驅動程序,這不是什麼問題,因爲一旦分配了設備號,你就可以從/proc/devices讀取相關的設備號信息。
  爲了加載一個用動態分配來得到主設備號的驅動程序,對insmod的調用需要被替換爲一個簡單的腳本,這個腳本先調用insmod,再讀/proc/devices以得到主設備號,並創建設備文件。
實例
  下面這個腳本,scull_load,是scull發行中的一部分。使用以模塊形式發行的驅動程序的用戶可以從系統的rc.local文件中調用這個腳本,或者在需要模塊時手工調用。rc.local可在/etc/rc.d/下找到。(中文版中還提到一種方法:使用kerneld。)
  #!/bin/sh
  module=”scull”
  device =”scull”
  mode =”664”
  #invoke insmod with all
  arguments we were passed
  #and use a pathname, as
  newer modutils don’t look in. by default
  /sbin/insmod –f ./$module.o
  $* || exit
  #remove stale nodes
  rm –f /dev/$(device)[0-3]
  major=’awk “
  [url=file://///$2==/]\\$2==\[/url]
  ”$module\” {print
  [url=file://///$1]\\$1[/url]
  }” /proc/devices’
  mknod /dev/${device}0 c
  $major 0
  mknod /dev/${device}1 c
  $major 1
  mknod /dev/${device}2 c
  $major 2
  mknod /dev/${device}3 c
  $major 3
  #give appropriate group/permissions, and change the group.
  #Not all distributions have staff; some have “wheel” instead.
  group=”staff”
  grep ‘^staff:’ /etc/group
  > /dev/null || group=’wheel’
  chgrp $group
  /dev/${device}[0-3]
  chmod $mode
  /dev/${device}[0-3]
  只要重新定義腳本中的變量並對mknod命令行進行修正該腳本同樣可以用於其驅動程序。
  讀者可能對最後幾行迷惑不解:爲什麼要改變設備的組(group)和訪問權限(mode)呢?原因是該腳本只能由超級用戶運行,因而新建的設備文件自然屬於root。默認權限位只允許root對其有寫訪問權限,而其他用戶只有讀權限。通常設備文件需要不同的訪問策略,比如只對某一組用戶開放訪問權限,因而需要改變某些情況下的訪問權限。





發佈了91 篇原創文章 · 獲贊 2 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章