/var/log/secure 로그로 /etc/hosts.deny 에 자동 등록시키는 스크립트

리눅스/Security|2015. 1. 26. 17:58
반응형

10분간의 로그 중 20회 이상 Fail Password를 발생시킨 아이피를 차단한다.

php 스크립트로 작성.

동작원리
1. /var/log/secure 파일에서 10분전의 로그 추출.
2. 아이피 별로 갯수 통계
3. 한 아이피에서 20회 이상 sshd로 비밀번호가 틀렸다면 /etc/hosts.deny에 "ALL : 아이피"의 형태로 저장
4. xinetd 데몬 재시작
5. 등록한 아이피 목록을 메일 주소로 발송

실행
./secure_analysis.sh sshd

crontab 등록
*/10 * * * * /경로명/secure_analysis.sh sshd

소스
#!/usr/local/php/bin/php
<?
//개요
// secure log를 분석해서 sshd로 불법적인 접속을 시도하는 IP를 /etc/hosts.deny에 등록하는 작업을 한다.
// Log Example : Jun 5 07:48:18 p1 sshd[1110]: Failed password for root from 211.114.190.196 port 52944 ssh2
// 추출 명령어 : grep "Jun 7 09" secure | grep "sshd" | grep "Failed password" | awk -F "from" '{print $2}' | awk '{print $1}'
// 지정된 입력값을 입력하지 않으면 실행하지 않는다.
 
if ($argc > 1) {
        $RECEIVE_EMAIL = "withsky@withsky.co.kr";
        $Hostname = trim(exec("hostname"));
        $Date = date("Y-m-d H:i:s");
        // 10분전 분을 구한다.
        $TenAgo = substr(date("i",mktime(date("H"), date("i")-10, 0, date("m"), date("d"), date("Y"))), 0, 1);
        if (!file_exists("/var/log/sshd_log")) {
                exec("mkdir -p /var/log/sshd_log");
        }
        if (!file_exists("/var/log/sshd_log/secure_analysis.log")) {
                exec("touch /var/log/sshd_log/secure_analysis.log");
        }
        // 날짜에 따라서 검색어의 공백처리가 틀린 관계로...
        $DayLength = strlen(date("j"));
        if ($DayLength == 2) {
                $now = date("M j H:");
        } else {
                $now = date("M j H:");
        }
        if ($argv[1] == "sshd") {
                exec("grep "$now$TenAgo" /var/log/secure | grep "sshd" | grep "Failed password" | awk -F "from" '{print $1}' > /var/log/sshd_log/secure_log_".$argv[1]);
        }
        $Fail_IP_File = file("/var/log/sshd_log/secure_log_".$argv[1]);
        for ($i = 0; $i < count($Fail_IP_File); $i++) {
                $Fail_IP_File[$i] = trim($Fail_IP_File[$i]);
        }
        $Fail_Statistics = array_count_values($Fail_IP_File);
        exec("echo "" > /var/log/sshd_log/denyIP.list_".$argv[1]);
        while (list ($Ip, $Count) = each ($Fail_Statistics)) {
                // 여기의 20을 수정하여 등록을 조절 할 수 있다.
                if ($Count > 20) {
                        $Now_Time = date("Y년 m월 d일 H시 i분 s초");
                        exec("echo "#Regist $Now_Time" >> /etc/hosts.deny");
                        exec("echo "ALL : $Ip" >> /etc/hosts.deny");
                        $Restart_Xinetd = 1;
                        exec("echo "$Now_Time | $Ip | $Count 회" >> /var/log/sshd_log/denyIP.list_".$argv[1]);
                }
                exec("echo "$Datet$Ipt$Count" >> /var/log/sshd_log/secure_analysis.log");
        }
        if ($Restart_Xinetd) {
                exec("killall -HUP xinetd");
                exec("cat "/var/log/sshd_log/denyIP.list_".$argv[1]."" | mail -s "$Hostname Deny IP LIST - $Date " $RECEIVE_EMAIL");
        }
} else {
        echo("Missing Argument... Confirm Execute...n");
}
?>

 

 

[출처] 밍구's life (http://blog.withsky.co.kr/152)

반응형

댓글()