#版權宣告: 歡迎鳥哥與各位大大轉載,但此篇文章若用在商業用途,必須事先告知本人,謝謝! #E-mail : solman@pchome.com.tw #作者:duba 2006/3/17 前言: 系統管理最困擾的問題就是系統被人入侵,每天觀察主機log,你就會發現很多來路不明的ip,不停 測試主機的系統帳號,包括:ssh,ftp,http等主要的services,當然,除了http以外,ssh,ftp通常不對外開放, 若不得已需要開放,也只開放某幾個ip使用主機的特定服務,可以當你的業務需要,你必須到處遊走,遷移工 作也就是你的ip並不固定的時候,防火牆也就沒法鎖住外部的ip,這時候該怎麼辦? 我們先畫個簡單的示意圖: 情況一 主機(sshd) <---> 防火牆 <------61.63.66.88 (192.16.0.88) 情況二 主機(sshd) <---> 防火牆 <-----所有外部ip都可能使用ssh services 當情況一的時候,是不會有入侵問題,系統處於全安狀態,除非內部有內奸,一般情況下是安全的 但當情況二時候,sshd 服務就處於對任何ip提供服務的情況下,因此任何人都可以來使用這個服務,惡意 就會不停的測試可以簽入的系統帳號,實在不勝其擾,怎樣發現這些惡意行為呢?很簡單,我們檢查log檔, /var/log/messages,可以檢查出以下信息: sshd[16433]: Failed password for illegal user guest from 66.232.8.37 port 40892 ssh2 或是 sshd[16511]: Illegal user admin from 66.232.8.37 所以就可以知道這樣的管理方式是有危險性的,根據鳥哥提供的logwatch去分析log檔提供管理者更 進一步的分析訊息,我們可以利用分析出來的訊息去ban掉惡意ip,怎麼做呢? 首先: 1, 安裝logwatch-7.2.1 , 安裝方法不在贅述,請參考鳥哥的文章 2, 安裝Tcp_wrapper(inetd) , 後來的改進版本xinetd直接內建在Mandrake與redhat中,所以不用另外安裝 3, 修改logwatch中的ssh script增加過濾ip與append bad ip 到/etc/hosts.deny檔中 4, 將logwatch放入排班程式按照預定時間執行 1, 安裝好logwatch後,要設定/etc/logwatch/conf/logwatch.conf檔 #設定logwatch結果寄到哪個信箱 MailTo = admin@aaa.com # Default person to mail reports from. Can be a local account or a # complete email address. MailFrom = admin@aaa.com # 分析複雜程度由Low到High , 越低所花時間越少, 在此必須設定為High , 否則會抓不到最後一筆比對ip # The default detail level for the report. # This can either be Low, Med, High or a number. # Low = 0 # Med = 5 # High = 10 Detail = High #根據log檔的日期,來分析,可以往前推一天Yesterday,或是All對整個所有的log檔做分析比對 #當然All所花的時間是最多的,建議設定成Today即可 # The default time range for the report... # The current choices are All, Today, Yesterday Range = Today #預設掃描的所有的services參數為All,所花的時間是最多,為了節省時間,可以把不需要分析的 #services一一設定上去節省執行時間 # The 'Service' option expects either the name of a filter # (in /usr/share/logwatch/scripts/services/*) or 'All'. # The default service(s) to report on. This should be left as All for # most people. Service = -audit Service = -cisco Service = -http Service = -samba Service = -postfix Service = -secure Service = -pam Service = -pam_pwdb 2, 設定/etc/xinetd.d下的services檔 , 找到你要讓xinetd控管的服務,比如:ssh default: off # description: sshd server, xinetd version. \ # Don't run the standalone version if you run \ # this. service ssh { disable = no #此處設定為no,restart xinetd即可 socket_type = stream wait = no user = root server = /usr/sbin/sshd server_args = -i log_on_success += DURATION USERID log_on_failure += USERID nice = 10 } 接著執行/etc/rc.d/init.d/xinetd restart 或是reload重新讀取組態即可 3, 修改logwatch的ssh script檔 , logwatch ssd預設安裝在/usr/local/logwatch/scripts/services #開啟sshd檔案到394行,加入 #add code 把bad ip從hosts.deny檔讀出,並去除#,:,A~z,空白與倒退字元 open (HOSTFILE,"/etc/hosts.deny") || die $!; @hosts = grep {!/^#/} ; close (HOSTFILE); #chomp @hosts; foreach $Host (@hosts) { $Host =~ tr/a-z/ /; $Host =~ tr/:/ /; #delete whitespace and backspace $Host =~s/[\s\r]//g; push @BadIP, $Host; #add end if (keys %BadLogins) { print "\nFailed logins from:\n"; foreach my $ip (sort SortIP keys %BadLogins) { my $i =0; #add code: 把取出的@Badip陣列一筆筆讀出$bip與sshd過濾出的$ip一筆筆比對 #若比對結果no match($t=0)則把該ip寫入hosts.deny檔 foreach my $bip (@BadIP ){ if($ip eq $bip){ print "This IP $ip is match in /etc/hosts.deny!"; $i++; } } if ($i == 0){ print "This IP $ip is no match in /etc/hosts.deny!"; open (HOSTFILE,">>/etc/hosts.deny") || die $!; print HOSTFILE "#".localtime(time)."\n"; print HOSTFILE "sshd:"."\t"."$ip"."\t".":"."\t"."deny\n"; close (HOSTFILE); } #add end #因為惡意ip有可能重複出現在log中的兩段過濾規則,所以必須存檔後,在取出,以免重複紀錄 #開啟sshd檔到448行 #add code 把bad ip從hosts.deny檔讀出,並去除#,:,A~z,空白與倒退字元 open (HOSTFILE,"/etc/hosts.deny") || die $!; @hosts = grep {!/^#/} ; close (HOSTFILE); chomp @hosts; foreach $Host (@hosts) { $Host =~ tr/a-z/ /; $Host =~ tr/:/ /; #delete ":", whitespace and backspace $Host =~s/[\s\r]//g; push @BadIP, $Host; # print $Host."\n"; } #add end #再根據"Illegal user"做比對 if (keys %IllegalUsers) { print "\nIllegal users from(DUBA): \n"; foreach my $ip (sort SortIP keys %IllegalUsers) { #add code: 把取出的@Badip陣列一筆筆讀出$bip與sshd過濾出的$ip一筆筆比對 #若比對結果no match($t=0)則把該ip寫入hosts.deny檔 foreach my $bip (@BadIP ){ if($ip eq $bip){ print "This IP $ip is match in /etc/hosts.deny!"; #測試訊息,可以刪除 $t++; } } if ($t == 0){ print "This IP $ip is no match in /etc/hosts.deny!"; open (HOSTFILE,">>/etc/hosts.deny") || die $!; print HOSTFILE "#".localtime(time)."\n"; print HOSTFILE "sshd:"."\t"."$ip"."\t".":"."\t"."deny\n"; close (HOSTFILE); } #add end #修改好後,先執行logwatch看看顯示信息是否正常,在比對/var/log/messages的bad ip 是否正確的 #append 到/etc/hosts.deny , 如果正確無誤,在執行下一步 4, 將logwatch放入排班程式按照預定時間執行: 只需要修改/etc/crontab檔案加入 30 * * * * root (/etc/rc.d/init.d/xinetd restart)|/usr/sbin/logwatch 每個小時執行一次,你可以依照你實際需要去修改logwatch執行次數 經過以上簡單的步驟以後,就把logwatch的功能進一步強化了,讓logwatch+TCP warpper具備智慧型的 簡易防火牆功能喔! 你可以自行依照上面範例,去修改自己想要自動化的services , 比如ftp等,自己 做練習! #需要完整版本的請到我的MSN 部落格回應留下Email索取 #http://spaces.msn.com/vrhost/?_c02_owner=1 logwatch-7.2.1 (/etc/rc.d/init.d/xinetd restart)|/usr/sbin/logwatch #add by duba 2006 3/7 open (HOSTFILE,"/etc/hosts.deny") || die $!; @hosts = grep {!/^#/} ; #去除有"#"之行 close (HOSTFILE); #chomp @hosts; foreach $Host (@hosts) { $Host =~ tr/a-z/ /; #去除任文英文字母 $Host =~ tr/:/ /; #去除:號 #delete whitespace and backspace $Host =~s/[\s\r]//g; push @BadIP, $Host; #print $Host."\n"; } #add end by duba foreach my $ip (sort SortIP keys %IllegalUsers) { my $t = 0; #add by duba 2006/3/7 foreach my $bip (@BadIP ){ #取出~log/messages中的bad ip if($ip eq $bip){ #與hosts.deny 中的ip比對 print "This IP $ip is match in /etc/hosts.deny!"; $t++; } } if ($t == 0){ # 為0表示沒重複的ip,在寫入hots.deny檔中 print "This IP $ip is no match in /etc/hosts.deny!"; open (HOSTFILE,">>/etc/hosts.deny") || die $!; print HOSTFILE "#".localtime(time)."\n"; print HOSTFILE "sshd:"."\t"."$ip"."\t".":"."\t"."deny\n"; close (HOSTFILE); } #add end .............. .......... ..... }