故障現象:
獲得中軟Linux3.1服務版以及隨後獲得升級補丁光盤在聯想萬全服務器進行安裝,在安裝至分區界面發生“設備無法找到”的錯誤提示,安裝程序異常退出安裝進程。
在安裝過程中擊鍵[Ctrl]+[Alt]+F3查看安裝進程日志以及[Ctrl]+[Alt]+[F4]查看系統相關消息,獲得信息為無法尋找正確設備ID號。
分析:
中軟3.1版本自帶的AIC-78xx並不能很好的支持的SCSI硬盤的驅動。安裝程序在引導時無法在initrd所解壓的程序模塊尋找到正確的驅動與設備ID相對應,因此需要修改升級安裝光盤驅動程序,采用磁盤方式預先加載SCSI AIC78XX驅動。
解決辦法:
從官方站點獲取Adaptec AIC-78xx的SCSI驅動,並在RH7.2系統環境制作與中軟3.1內核(2.4.18)一致的SCSI驅動。
從官方站點(ftp://updates.redhat.com/7.2/en/os/i386)下載新版本的BOOT內核程序,使用NEW_BOOT_KERNEL_RPM和NEW_BOOT_KERNEL_VERSION環境變量定義驅動盤所采用的內核版本。
eXPort NEW_BOOT_KERNEL_RPM=”Kernel-BOOT-2.4.18-24.7.x.i386.rpm”
export NEW_BOOT_KERNEL_VERSION=”2.4.8-24.7.xBOOT”
臨時性安裝BOOT內核程序,由於只需要修改BOOT內核模塊,因此在驅動盤制作完畢,需要刪除此程序
rpm –ivh $NEW_BOOT_KERNEL_RPM
創建制作驅動模塊目錄
mkdir /tmp/bootdisk
cd /tmp/bootdisk
拷貝RH7.2光盤bootnet.img文件至/tmp/bootdisk目錄,並掛載img文件於對應目錄
mkdir /tmp/bootdisk/bootnet_image
mkdir /tmp/bootdisk/initrd_image
mount –o loop /tmp/bootdisk/bootnet.img /tmp/bootdisk/bootnet_image
cp /tmp/bootdisk/bootnet_image/initrd.img /tmp/bootdisk/initrd.gz
gunzip /tmp/bootdisk/initrd.gz
mv /tmp/bootdisk/initrd /tmp/bootdisk/initrd.img
mount –o loop /tmp/bootdisk/initrd.img /tmp/bootdisk/initrd_image
創建臨時initrd映像文件用於升級和增加驅動模塊。最後一個命令用於創建一個BOOT目錄,其包含了initrd內部所有模塊的列表。
mkdir /tmp/bootdisk/initrd_tmp
cp –a /tmp/bootdisk/initrd_image/* /tmp/bootdisk/initrd_tmp/
cd /tmp/bootdisk/initrd_tmp
zcat modules/modules.cgz cpio -ivd
由於BOOT內核需要升級,所以驅動模塊也需要升級。假如版本不一致,驅動模塊將不能被裝載。下面多個語句將在initrd_tmp目錄創建包含升級模塊的新BOOT目錄。首先創建一個模塊文件列表,使用文件列表找出新版本驅動模塊,並把其添加到initrd_tmp的BOOT目錄中。
mkdir /tmp/bootdisk/initrd_mtp/$NEW_BOOT_KERNEL_VERSION
cd /tmp/bootdisk/initrd_tmp
OldBootVersion=`zcat modules/modules.cgz cpio –t head –l awk –F / ‘{print $1}’`
ModuleList=`ls $OldBootVersion`
cd /lib/modules/$NEW_BOOT_KERNEL_VERSION/kernel
for ModuleName in $ModuleList do NewModuleName=`find . -name $ModuleName`
cp $NewModuleName /tmp/bootdisk/initrd_tmp/$NEW_BOOT_KERNEL_VERSION/
$ModuleName
done
增加新SCSI驅動模塊
cp /lib/modules/$NEW_BOOT_KERNEL_VERSION/kernel/drivers/scsi/aic7xxx/aic78xx.o
/tmp/bootdisk/initrd_tmp/$NEW_BOOT_KERNEL_VERSION
創建新module.cgz以包含所有升級和增加的模塊
cd /tmp/bootdisk/initrd_tmp/
find $NEW_BOOT_KERNEL_VERSION cpio -ov -H crc gzip -c9 > \
/tmp/bootdisk/initrd_tmp/modules/modules.cgz
cd /tmp/bootdisk
rm -rf /tmp/bootdisk/initrd_tmp/*BOOT
為新增加的SCSI驅動模塊定義依賴關系
echo "aic78xx: scsi_aic78xx" >> /tmp/bootdisk/initrd_tmp/modules/modules.dep
為新增驅動模塊定義模塊信息
/tmp/bootdisk/initrd_tmp/modules/module-info :
aic78xx
sisc
“””” "Adaptec SCSI aic-78xx"
在/odules/pcitable為增加的設備驅動制作記錄,可使內核根據設備號尋找正確的驅動。可使用stage2文件的記錄進行增加。(使用TAB鍵代替空格)
cp /tmp/bootdisk/initrd_image/modules/pcitable /tmp/bootdisk/pcitable
grep "\"aic78xx\"" /tmp/bootdisk/stage2_image/modules/pcitable >>
/tmp/bootdisk/pcitable
排序pcitable文件並寫入initrd映像文件
sort /tmp/bootdisk/pcitable > /tmp/bootdisk/initrd_tmp/modules/pcitable
創建新版initrd映像文件。必須為initrd映像文件預留足夠空間以便在運行期間能成功裝載驅動。這是initrd在引導期間解壓所需要的文件系統空間。
INITRD_SIZE=`du -k -s /tmp/bootdisk/initrd_tmp awk '{print $1}'`
let "NEW_INITRD_SIZE=$INITRD_SIZE + 1000"
mkdir /tmp/bootdisk/initrd_new_image
dd if=/dev/zero bs=1k count=$NEW_INITRD_SIZE of=/tmp/bootdisk/initrd_new.img
echo "y" mke2fs /tmp/bootdisk/initrd_new.img > /dev/null
mount -o loop /tmp/bootdisk/initrd_new.img /tmp/bootdisk/initrd_new_image
cp -a /tmp/bootdisk/initrd_tmp/* /tmp/bootdisk/initrd_new_image/
sync
umount /tmp/bootdisk/initrd_new_image
umount /tmp/bootdisk/initrd_image
壓縮initrd映像文件和新版本內核至bootnet映像文件中。
gzip -9 /tmp/bootdisk/initrd_new.img
cp /tmp/bootdisk/initrd_new.img.gz /tmp/bootdisk/bootnet_image/initrd.img
cp /boot/vmlinuz-$NEW_BOOT_KERNEL_VERSION /tmp/bootdisk/bootnet_image/
vmlinuz
拷貝映像至磁盤
dd if=/tmp/bootdisk/bootnet.img of=/dev/fd0
刪除引導文件
rpm –e
通過安裝新驅動模塊,解決安裝故障。
遺留問題:
系統只能安裝於一塊硬盤,當加載多塊硬盤,仍舊提示“設備無法找到”錯誤信息,原因不明,有待進一步查明。
小結:
通過研究Linux引導過程機制,對Linux引導裝載驅動有深入了解,並掌握如何定制驅動程序,並在引導時裝載,實現相關設備的驅動。通過制作initrd映像文件掌握驅動加載所必須的模塊依賴文件modelue.dep和模塊設備文件pcitable。
在定制bootnet.img文件,需要考慮給initrd解壓時所必須預留的文件系統空間,而不是磁盤本身的空間。如果bootnet.img本身容量已經超過磁盤容量限制,則必須考慮刪除不必要的驅動模塊以減小映像文件的大小。
此外,對制作的bootnet.img必須采用D9高壓縮比率,可增加可用資源。
LVS組件安裝
故障現象:
安裝ipvsadm套件遇到需要Glibc2.3版才可支持組件安裝,否則無法順利安裝。中軟3.1自帶Glibc版本為2.2.3,下載新版 glibc-2.3 RPM包進行強行安裝,結果系統出現不穩定,使用RPM進行軟件安裝,系統出現故障性提示:“Cannot handle file ‘libc.so.6’ with TLS data”,軟件無法正常安裝。
分析:
使用GLIBC的RPM軟件強制進行軟件升級,導致RPM本身依賴關系遭到破壞。這是著名的Catch-22問題,即Glibc與RPM軟件包是彼此相互依賴。因此必須對RPM本身進行升級。然而升級Glibc造成系統無法正常運行RPM,因此使用RPM包無法進行升級。經過查閱紅帽官房站點,得知與RPM一同安裝的工具rpm2cpio可以析取rpm包中內容。使用ldconfig配置鏈接路徑,並重新建構rpm數據庫就可升級RPM包,解決 Glibc升級問題。
解決:
獲得RPM升級相關軟件包
rpm-4.2-0.68.i386.rpm
rpm-build-4.2-0.68.i386.rpm
rpm-devel-4.2-0.68.i386.rpm
rpm-python-4.2-0.68.i386.rpm
elfutils-0.76-2.i386.rpm
elfutils-devel-0.76-2.i386.rpm
elfutils-libelf-0.76-2.i386.rpm
popt-1.8-0.68.i386.rpm
redhat-rpm-config-8.0.20-1.noarch.rpm
使用rpm2cpio工具析取rpm包內容,使用ldconfig配置鏈接時動態庫路徑,並重新編譯rpm數據庫
cd /
sudo rpm2cpio ~/rpmdir/rpm-* ~/rpmdir/elfutils-* sudo cpio -ivd
sudo rm -f /var/lib/rpm/__db.00*
sudo ldconfig
cd ~/rpmdir
sudo rpm -Uvh *.rpm
sudo rpm -rebuilddb
遺留問題:
升級RPM包本身會影響操作系統某些軟件的正常運行,其遭到破壞的依賴關系可以使用軟件升級的辦法進行解決。然而某些軟件本身只支持 Glibc2.2,因此升級Glibc2.3版本會導致依賴於Glibc2.2的軟件無法運行,系統將遺留垃圾軟件。解決辦法有待進一步研究。
小結:
通過對系統關鍵性組件包,諸如Glibc和RPM的升級,了解系統對軟件安裝和維護的基礎結構。關於RPM升級時必須考慮elf文件包的升級,因為elf格式為所有unix的文件基准格式、軟件包安裝/升級和維護的文件都必須遵守ELF規范。
此外,使用rpm2cpio對rpm文件內容進行提取後,必須使用ldconfig命令指定編譯鏈接時的動態庫路徑,才能成功實現RPM安裝。
入侵監測系統配置
故障現象:
單點snort入侵監測系統,接入百兆交換機後大約每間隔2小時,傳感器就發生系統崩潰。檢查系統日志,發現報警日志數量巨大,日志迅速占據硬盤大量空間。
分析:
整個網絡只提供WEB訪問服務和FTP訪問服務,snort入侵檢測系統默認配置較多無關入侵規則,導致日志中出現大量誤報信息,諸如遠程認證登錄,數據庫遠程訪問等數據導致日志數量增長迅速;此外,入侵監測系統采用華為SB2026交換機,采用端口鏡像方式使交換機所有數據流均復制到監聽端口,導致交換機達到負載承受臨界點,鏡像端口數據交換過量,整個網絡資源無法正常使用。
解決:
根據網絡使使用的具體服務,使用Webmin管理界面定義所監測的入侵規則只包含HTTP和FTP的相關規則,關閉其他入侵規則,提高入侵監測系統判別能力,降低誤報信息。
減少交換機鏡像方式所監測的端口數,只對重要服務器進行端口數據鏡像拷貝,緩解交換機數據交換所承載的負荷,提高網絡資源利用率。
遺留問題:
暫無
小結:
通過研究Linux下snort的運行機理與入侵監測規則過濾結構,掌握開源snort下特定入侵規則編寫和動態防御,了解真實網絡環境中入侵監測系統所存在的缺陷和特定的補修方法。
安全策略配置
故障現象:
Linux服務器正常訪問一段時間後系統運行速度逐漸下降,某些主機使用安全工具進行安全掃描後無法正常訪問服務器。服務器重新啟動後使用安全掃描的主機仍然無法正常訪問。
分析:
查看iptables防火牆列表規則,發現被拒絕訪問主機列表龐大,被拒絕主機永久存在列表規則之中,不會自動刪除,導致系統運行效率降低,並使安全監測主機在發生安全檢測掃描行為之後無法正常訪問系統。
自動防御進程portsentry監測異常數據訪問行為,並與防火牆連動,對發送異常數據流進行隔離,因此iptables列表隔離主機數目隨時間呈線形增長,系統運行效率將逐步降低。
解決:
修改portsentry配置文件KILL_ROUTE參數
KILL_ROUTE="/usr/local/bin/iptables -I INPUT -s $TARGET$ -j DROP"
為:
KILL_ROUTE="/usr/local/bin/ip_chk $TARGET$"
ip_chk程序如下:
// ip_chk.c
#include
#include
#include
#include
#include
#include
#include
#define IP_LIST_FILE "/tmp/.iplist"
#define IP_DROP_TIMEOUT 2000
#define SEM_ID 250
int line_count(FILE *file){
int line_count = 0;
char ch;
fseek(file, SEEK_SET, 0);
do{
ch = fgetc(file);
if(ch = '\n'){
line_count =+1;
}
}while(ch = !EOF)
return line_count;
}
boolean is_repeat(char *ip_addr, long fpos_offset, long lpos_offset, File* file){
char buf[15];
char ch;
fseek(file, SEEK_SET, 0);
do{
ch = fgetc(file);
}while(ftell(file < fpos_offset))
for(int i = 0; i <= (lpos_offset-fpos_offset); i++){
if((buf = fgetc(file)) == " ")
break;
}
if(strcmp(buf, ip_addr)
return true
else
return false;
}
void update(boolean need_update, File* file, char* ip_addr){
int i = 0;
int count;
int flg;
char buf[4];
string new_content;
char new_buf[50];
time_t t;
if(need_update){
do{
fgetc(file);
}while(ch != " ");
flg = (int)ftell(file) + 1;
do{
buf = fgetc(file);
i++;
}while(ch != "\n");
buf[++i] = 'P';
count = (int)buf + 1;
buf = (string)count;
i = 0;
fseek(file, 0, flg);
while(buf != 'P'){
fputc(buf, file);
i++;
}
}else{
fseek(file, 0, SEEK_END);
t = time(NULL);
new_content = ip_addr + " " + (string)t + " " + "1" + "\n";
new_buf = new_content;
i = 0;
do{
fputc(new_buf, file);
i++;
}while(new_buf != '\n');
}
}
void iptables(char *ip_drop){
string cmdstr = "iptables -I INPUT -s "+ip_drop+" -j DROP";
system(cmdstr);
}
void ip_chk(int sem_set_id, char *ip_target, char *file_name){
FILE* file;
strUCt sembuf sem_op;
char buf[50];
int i = 0;
int count;
char ch;
long f_offset, l_offset;
int action = false;
sem_op.sem_num = 0;
sem_op.sem_op = -1;
sem_op.sem_flg = 0;
semop(sem_set_id, &semop, 1);
file = fopen(file_name, "awr");
if(!file){
fprintf(stderr, "fail to open this file!\n");
return 1;
}
count = line_count(file);
l_offset = fseek(file, SEEK_SET, 0);
for(int i = 1; i <= count; i++){
do{
ch = fgetc(file);
if(ch = '\n'){
if(i == 1){
f_offset = l_offset;
}
else{
f_offset = l_offset + 1;
}
l_offset = ftell(file);
break;
}
}while(ch = !EOF)
if(is_repeat(ip_target, f_offset, l_offset, file)){
update(action, file);
action = true;
break;
}
}
if(!action){
update(action, file);
iptables(ip_target);
action = true;
}
fclose(file);
sem_op.sem_num = 0;
sem_op.sem_op = 1;
sem_op.sem_flg = 0;
semop(sem_set_id, &sem_op, 1);
}
int main(int argc, char **argv){
int sem_set_id;
union semun sem_val;
char *ip_arg;
if(argc < 2){
perror("Usage: ip_chk ");
exit(1);
}
ip_arg = argv[1];
sem_set_id = semget(SEM_ID, 1, IPC_CREAT 0600);
if(sem_set_id == -1){
perror("main: semget");
exit(1);
}
sem_val.val = 1;
rc = semctl(sem_set_id, 0, SETVAL, sem_val);
if(rc == -1){
perror("main: semctl");
exit(1);
}
ip_chk(sem_set_id, ip_arg, IP_LIST_FILE);
return 0;
}
遺留問題:
腳本程序還存在諸如如何判斷惡意計算機IP的永久性封鎖、如何維護拒絕表,如何與tcp wrapper實現連動等功能,善待完善。
小結:
掌握hostsentry主機入侵防御軟件的配置及管理方法,並使用c編程開發適合自身網絡情況的主機入侵防御程序。
遠程監管配置
故障現象:
利用XDMCP協議配置NC遠程服務監管多台Linux服務器,NC連接X服務器總提示連接失敗。使用Linux操作系統進行加密隧道的XDMCP連接,系統提示無法連接。
查看日志記錄,相關錯誤信息如下:“Fwd X11 connection from LinuxN refused by tcp_wrappers”。通過修改tcp_wrappers的host.deny以及host.allow文件內容,NC主機仍然無法連接X服務器。
使用Linux主機進行連接,屏幕顯示錯誤信息如下:
xlib: Connection refused (error 111): unable to connect to X server
xlib: No such process (error 3): Server error
分析:
經對整個遠程監管體系的網絡數據包跟蹤和分析,發現SSH安全加密協商會話正常,加密的安全隧道確實已經在NC主機和Linux服務器之間建立連接。但NC主機和Linux服務器所使用的XDMCP協商會話由於加密隧道而無法觀察。
檢查NC主機及Linux服務器的ssh2_config配置文件,NC主機已經啟用“ForwardX11”參數項,使X客戶端請求程序能實現轉發;Linux服務器啟用“AllowX11Forwarding”參數項,允許服務器的X應用程序請求轉發。查閱ssh2參考手冊,發現2.3版本以上的OpenSSH軟件集成X服務安全性擴展。這將導致ssh2協議通知X服務器客戶端程序默認情況是不受信任的,所以NC主機的X客戶端程序運行失敗。
解決:
針對X11的加密轉發故障的解決策略是啟用ssh2_config文件的TrustX11Applications參數項,指定X服務器承認 X11客戶端程序的可信度;在NC主機X啟動腳本加入“+X”啟動參數,以信任方式啟動X11連接轉發,成功實現NC與Linux服務器基於SSH加密隧道的XDMCP的遠程監管。
遺留問題:
暫無
小結:
研究加密方式下XDMCP協議轉發X請求,使NC以SSH方式通過網絡對分散多點的Linux主機進行管理,實現集中式Linux服務管理。
Signal 11”現象
故障現象:
Linux服務器使用“xhost +”與“export DISPLAY=(your local host IP):0.0”命令分別開放X服務主機的訪問,並設置DISPLAY環境變量,使客戶端通過無須加密的XDMCP進行連接,可以出現遠程Linux服務登錄認證圖形截面。但是遠程監管的Linux服務器在一段時候自動斷開與之連接的客戶端。服務器日志文件出現:“Signal 11”錯誤信息記錄。
分析:
“Signal 11”錯誤意味著程序訪問一個為經分配的內存區域。一般情況是由於某些軟件缺陷和硬件故障造成的。由於所安裝的X服務軟件包無任何程序缺陷,因此X服務器出現“Signal 11”錯誤而導致崩潰的起因很可能是Linux服務器硬件故障所引起。使用硬件診斷程序檢測服務器,測試結果顯示正常。
經過反復檢測,發現快速鼠標移動將引發X服務器“Signal 11”錯誤,由於X服務需要采集諸如鼠標移動各種硬件輸入操作事件,當發生鼠標滾輪迅速移動諸類事件,網絡重復發送大量移動操作導致X服務器對各種X客戶端程序的繁重處理無法負擔,導致X服務器崩潰。
解決:
針對“Signal 11”的解決策略是在NC主機系統使用mouseconfig配置鼠標特性,關閉滾輪特性,並降低鼠標靈敏度,徹底解決X服務崩潰故障。
分析:
“Signal 11”錯誤意味著程序訪問一個為經分配的內存區域。一般情況是由於某些軟件缺陷和硬件故障造成的。由於所安裝的X服務軟件包無任何程序缺陷,因此X服務器出現“Signal 11”錯誤而導致崩潰的起因很可能是Linux服務器硬件故障所引起。使用硬件診斷程序檢測服務器,測試結果顯示正常。
經過反復檢測,發現快速鼠標移動將引發X服務器“Signal 11”錯誤,由於X服務需要采集諸如鼠標移動各種硬件輸入操作事件,當發生鼠標滾輪迅速移動諸類事件,網絡重復發送大量移動操作導致X服務器對各種X客戶端程序的繁重處理無法負擔,導致X服務器崩潰。
解決:
針對“Signal 11”的解決策略是在NC主機系統使用mouseconfig配置鼠標特性,關閉滾輪特性,並降低鼠標靈敏度,徹底解決X服務崩潰故障。