2022-07-07 16:52:24 +08:00
# include "conf.h"
# include "rhost.h"
# include "libiptc.h"
2022-10-22 18:41:00 +08:00
# include "libclamav.h"
# include "clamscan.h"
2022-06-26 19:49:00 +08:00
2022-10-25 23:07:47 +08:00
# include "ccronexpr.h"
2022-06-26 19:49:00 +08:00
// 存储公网IP
2022-10-08 14:28:05 +08:00
char * public_ip ;
2022-06-26 19:49:00 +08:00
2022-10-28 21:53:48 +08:00
struct MemoryStruct
{
2022-10-08 14:28:05 +08:00
char * memory ;
size_t size ;
} ;
static size_t WriteMemoryCallback ( void * contents , size_t size , size_t nmemb , void * userp )
2022-06-26 19:49:00 +08:00
{
2022-10-08 14:28:05 +08:00
size_t realsize = size * nmemb ;
struct MemoryStruct * mem = ( struct MemoryStruct * ) userp ;
// 注意这里根据每次被调用获得的数据重新动态分配缓存区的大小
char * ptr = realloc ( mem - > memory , mem - > size + realsize + 1 ) ;
2022-10-28 21:53:48 +08:00
if ( ptr = = NULL )
{
2022-10-08 14:28:05 +08:00
/* 内存不足! */
printf ( " not enough memory (realloc returned NULL) \n " ) ;
return 0 ;
2022-06-26 19:49:00 +08:00
}
2022-10-08 14:28:05 +08:00
mem - > memory = ptr ;
memcpy ( & ( mem - > memory [ mem - > size ] ) , contents , realsize ) ;
mem - > size + = realsize ;
mem - > memory [ mem - > size ] = 0 ;
return realsize ;
2022-06-26 19:49:00 +08:00
}
// 获取公网IP
2022-10-08 14:28:05 +08:00
static char * GET_PUBLIC_IP ( char * URL )
2022-06-26 19:49:00 +08:00
{
2022-10-08 14:28:05 +08:00
CURL * curl_handle ;
CURLcode res ;
2022-06-26 19:49:00 +08:00
2022-10-08 14:28:05 +08:00
struct MemoryStruct chunk ;
2022-06-26 19:49:00 +08:00
2022-10-08 14:28:05 +08:00
chunk . memory = malloc ( 1 ) ; /* 将根据上述再分配的需要增长 */
chunk . size = 0 ; /* 此时没有数据 */
curl_global_init ( CURL_GLOBAL_ALL ) ;
/* 初始化curl会话 */
curl_handle = curl_easy_init ( ) ;
/* 指定要获取的URL */
curl_easy_setopt ( curl_handle , CURLOPT_URL , URL ) ;
/* 将所有数据发送到此函数 */
//对于同一次阻塞的curl_easy_perform而言, 在写完获取的数据之前, 会多次调用 WriteMemoryCallback
curl_easy_setopt ( curl_handle , CURLOPT_WRITEFUNCTION , WriteMemoryCallback ) ;
2022-10-22 18:41:00 +08:00
/* 将"chunk"结构传递给回调函数 */
2022-10-08 14:28:05 +08:00
curl_easy_setopt ( curl_handle , CURLOPT_WRITEDATA , ( void * ) & chunk ) ;
curl_easy_setopt ( curl_handle , CURLOPT_USERAGENT , " libcurl-agent/1.0 " ) ;
//对于同一次阻塞的curl_easy_perform而言, 在写完获取的数据之前, 会多次调用 WriteMemoryCallback
res = curl_easy_perform ( curl_handle ) ;
2022-10-28 21:53:48 +08:00
if ( res ! = CURLE_OK )
{
2022-10-08 14:28:05 +08:00
fprintf ( stderr , " curl_easy_perform() failed: %s \n " , curl_easy_strerror ( res ) ) ;
2022-10-28 21:53:48 +08:00
}
else
{
2022-10-08 14:28:05 +08:00
//printf("%lu bytes retrieved\n", (unsigned long)chunk.size);
//printf("%s", chunk.memory);
;
2022-06-26 19:49:00 +08:00
}
2022-10-08 14:28:05 +08:00
curl_easy_cleanup ( curl_handle ) ;
curl_global_cleanup ( ) ;
2022-06-26 19:49:00 +08:00
2022-10-08 14:28:05 +08:00
return chunk . memory ;
2022-06-26 19:49:00 +08:00
}
2022-10-08 14:28:05 +08:00
// 检测系统
int check_system ( )
2022-06-26 19:49:00 +08:00
{
2022-10-28 21:53:48 +08:00
if ( 0 = = access ( " /etc/debian_version " , F_OK ) )
{
2022-10-08 14:28:05 +08:00
return DEBISN_SYSTEM ;
2022-11-14 16:07:49 +08:00
}
else if ( 0 = = access ( " /etc/centos-release " , F_OK ) )
2022-10-28 21:53:48 +08:00
{
2022-10-08 14:28:05 +08:00
return CENTOS_SYSTEM ;
2022-06-26 19:49:00 +08:00
}
2022-10-08 14:28:05 +08:00
return UNKNOWN_SYSTEM ;
2022-06-26 19:49:00 +08:00
}
// 钉钉告警
2022-10-08 14:28:05 +08:00
int dingding_warning ( char * illegal_ip , char * public_ip , conf * conf )
2022-06-26 19:49:00 +08:00
{
2022-07-07 16:52:24 +08:00
FILE * fp ;
2022-10-08 14:28:05 +08:00
char temp [ 64 ] ;
char jsonObj [ BUFFER ] ;
memset ( jsonObj , 0 , BUFFER ) ;
memset ( temp , 0 , 64 ) ;
strcpy ( temp , public_ip ) ;
temp [ strlen ( public_ip ) - 1 ] = ' \0 ' ;
2022-10-28 21:53:48 +08:00
if ( ( fp = fopen ( " libcurl.log " , " wt+ " ) ) = = NULL )
{
2022-07-07 16:52:24 +08:00
return 1 ;
}
2022-10-08 14:28:05 +08:00
2022-06-26 19:49:00 +08:00
CURL * curl ;
CURLcode res ;
curl_global_init ( CURL_GLOBAL_ALL ) ;
curl = curl_easy_init ( ) ;
2022-10-28 21:53:48 +08:00
if ( curl = = NULL )
{
2022-06-26 19:49:00 +08:00
return 1 ;
}
2022-10-22 18:41:00 +08:00
# define JSIN "{ \
2022-06-26 19:49:00 +08:00
\ " msgtype \" : \" text \" , \
\ " text \" : { \
2022-10-08 14:28:05 +08:00
\ " content \" : \" Alert @%s 服务器地址:%s, 封禁非法入侵主机:%s \" \
2022-06-26 19:49:00 +08:00
} , \
\ " at \" : { \
2022-10-08 14:28:05 +08:00
\ " atMobiles \" : [ \" %s \" ], \
2022-06-26 19:49:00 +08:00
\ " isAtAll \" : false \
} \
2022-10-08 14:28:05 +08:00
} "
2022-06-26 19:49:00 +08:00
2022-10-08 14:28:05 +08:00
sprintf ( jsonObj , JSIN , conf - > PHONE , temp , illegal_ip , conf - > PHONE ) ;
printf ( " %s \n " , jsonObj ) ;
2022-06-26 19:49:00 +08:00
struct curl_slist * headers = NULL ;
headers = curl_slist_append ( headers , " Accept: application/json " ) ;
headers = curl_slist_append ( headers , " Content-Type: application/json " ) ;
headers = curl_slist_append ( headers , " charset: utf-8 " ) ;
2022-07-07 16:52:24 +08:00
curl_easy_setopt ( curl , CURLOPT_URL , conf - > DING_WEBHOOK ) ;
2022-06-26 19:49:00 +08:00
curl_easy_setopt ( curl , CURLOPT_SSL_VERIFYPEER , 0 ) ;
curl_easy_setopt ( curl , CURLOPT_SSL_VERIFYHOST , 0 ) ;
curl_easy_setopt ( curl , CURLOPT_POST , 1 ) ;
curl_easy_setopt ( curl , CURLOPT_HTTPHEADER , headers ) ;
curl_easy_setopt ( curl , CURLOPT_POSTFIELDS , jsonObj ) ;
curl_easy_setopt ( curl , CURLOPT_USERAGENT , " libcurl/0.1 " ) ;
2022-07-07 16:52:24 +08:00
curl_easy_setopt ( curl , CURLOPT_WRITEDATA , fp ) ;
2022-10-08 14:28:05 +08:00
2022-06-26 19:49:00 +08:00
res = curl_easy_perform ( curl ) ;
curl_easy_cleanup ( curl ) ;
curl_global_cleanup ( ) ;
2022-07-07 16:52:24 +08:00
fclose ( fp ) ;
2022-10-08 14:28:05 +08:00
2022-06-26 19:49:00 +08:00
return res ;
}
// 邮件告警
2022-10-08 14:28:05 +08:00
int mail_warning ( char * illegal_ip , char * public_ip , conf * conf )
2022-06-26 19:49:00 +08:00
{
FILE * fp = NULL ;
char buff [ BUFFER ] ;
2022-10-08 14:28:05 +08:00
char text [ BUFFER ] ;
char temp [ 64 ] ;
2022-06-26 19:49:00 +08:00
memset ( buff , 0 , BUFFER ) ;
2022-10-08 14:28:05 +08:00
memset ( text , 0 , BUFFER ) ;
memset ( temp , 0 , 64 ) ;
2022-06-26 19:49:00 +08:00
2022-10-08 14:28:05 +08:00
strcpy ( temp , public_ip ) ;
temp [ strlen ( public_ip ) - 1 ] = ' \0 ' ;
sprintf ( text , " echo \" 主机:%s, 禁止%s访问 \" | mail -s \" System ban IP \" %s " , temp , illegal_ip , conf - > RECV_MAIL ) ;
2022-06-26 19:49:00 +08:00
2022-10-28 21:53:48 +08:00
if ( NULL = = ( fp = popen ( text , " r " ) ) )
{
2022-06-26 19:49:00 +08:00
perror ( " popen text " ) ;
}
2022-10-28 21:53:48 +08:00
while ( fgets ( buff , BUFFER , fp ) ! = NULL )
{
2022-06-26 19:49:00 +08:00
buff [ strlen ( buff ) - 1 ] = ' \0 ' ;
}
if ( NULL ! = fp )
pclose ( fp ) ;
return 0 ;
}
// 第三方邮箱告警
2022-10-08 14:28:05 +08:00
int QQ_mail_warning ( char * illegal_ip , char * public_ip , conf * conf )
2022-06-26 19:49:00 +08:00
{
2022-10-28 21:53:48 +08:00
char string [ BUFFER + ( sizeof ( QQMAIL ) ) + 1 ] ;
2022-10-08 14:28:05 +08:00
char text [ BUFFER ] ;
char temp [ 32 ] ;
2022-10-28 21:53:48 +08:00
memset ( string , 0 , BUFFER + ( sizeof ( QQMAIL ) ) + 1 ) ;
2022-10-08 14:28:05 +08:00
memset ( text , 0 , BUFFER ) ;
memset ( temp , 0 , 32 ) ;
strcpy ( temp , public_ip ) ;
temp [ strlen ( public_ip ) - 1 ] = ' \0 ' ;
sprintf ( text , " 主机:%s, 禁止%s访问 " , temp , illegal_ip ) ;
sprintf ( string , QQMAIL , conf - > RECV_MAIL , text ) ;
return system ( string ) ;
2022-06-26 19:49:00 +08:00
}
2022-11-29 13:32:29 +08:00
// 第三方邮箱告警, 感染病毒邮件提醒
int QQ_mail_warning_Virus_files ( char * local_ip , int Virus_number , conf * conf )
{
char * command ;
char * text ;
char temp [ 32 ] ;
command = ( char * ) alloca ( BUFFER + ( sizeof ( QQMAIL ) ) + 1 ) ;
text = ( char * ) alloca ( BUFFER ) ;
memset ( command , 0 , BUFFER + ( sizeof ( QQMAIL ) ) + 1 ) ;
memset ( text , 0 , BUFFER ) ;
memset ( temp , 0 , 32 ) ;
2022-12-01 10:47:15 +08:00
strcpy ( temp , local_ip ) ;
temp [ strlen ( local_ip ) - 1 ] = ' \0 ' ;
2022-11-29 13:32:29 +08:00
sprintf ( text , " Host:%s, Infected files: %d, Please handle! " , temp , Virus_number ) ;
2022-12-01 10:47:15 +08:00
sprintf ( command , QQMAIL_Virus , conf - > RECV_MAIL , text ) ;
return system ( command ) ;
}
// 第三方邮箱告警, 磁盘使用率
int QQ_mail_warning_Disk_Use ( char * local_ip , int disk_use , conf * conf )
{
char * command ;
char * text ;
char temp [ 32 ] ;
command = ( char * ) alloca ( BUFFER + ( sizeof ( QQMAIL ) ) + 1 ) ;
text = ( char * ) alloca ( BUFFER ) ;
memset ( command , 0 , BUFFER + ( sizeof ( QQMAIL ) ) + 1 ) ;
memset ( text , 0 , BUFFER ) ;
memset ( temp , 0 , 32 ) ;
strcpy ( temp , local_ip ) ;
temp [ strlen ( local_ip ) - 1 ] = ' \0 ' ;
sprintf ( text , " Host:%s, Disk usage reaches threshold!, Please handle! " , temp ) ;
sprintf ( command , QQMAIL_DISK_USE , conf - > RECV_MAIL , text ) ;
2022-11-29 13:32:29 +08:00
return system ( command ) ;
}
2022-10-10 17:52:00 +08:00
// IP段白名单对比
int whitelist ( char * client_ip , char ( * whitelist_ip ) [ WHITELIST_IP_NUM ] )
{
int i ;
2022-10-28 21:53:48 +08:00
for ( i = 1 ; i < WHITELIST_IP_NUM - 1 ; i + + )
{
if ( strcmp ( whitelist_ip [ i ] , " \0 " ) = = 0 ) // 如果字符串为空就跳出循环
{
2022-10-10 17:52:00 +08:00
break ;
}
2022-10-28 21:53:48 +08:00
if ( ( strncmp ( client_ip , whitelist_ip [ i ] , strlen ( whitelist_ip [ i ] ) ) ) = = 0 ) // 对比client_ip长度,
{
2022-10-10 17:52:00 +08:00
return 1 ;
}
}
return 0 ;
}
2022-10-13 18:01:06 +08:00
// 地域段白名单对比
int isregion ( char * str , char ( * region_list ) [ WHITELIST_IP_NUM ] )
{
int i ;
char * p ;
2022-10-28 21:53:48 +08:00
for ( i = 1 ; i < WHITELIST_IP_NUM - 1 ; i + + )
{
if ( strcmp ( region_list [ i ] , " \0 " ) = = 0 ) // 如果字符串为空就跳出循环
{
2022-10-13 18:01:06 +08:00
break ;
}
// 在str中查找region_list[i]
2022-10-22 18:41:00 +08:00
p = strstr ( str , region_list [ i ] ) ;
2022-10-28 21:53:48 +08:00
if ( p ! = NULL )
{
2022-10-13 18:01:06 +08:00
return 1 ;
}
}
return 0 ;
}
// 去除空格
2022-10-10 17:52:00 +08:00
char * remove_space ( const char * str )
{
2022-10-28 21:53:48 +08:00
unsigned int i = 0 , j = 0 ;
2022-10-22 18:41:00 +08:00
unsigned int uLen = strlen ( str ) ;
2022-10-28 21:53:48 +08:00
char * strRet ;
2022-10-22 18:41:00 +08:00
2022-10-28 21:53:48 +08:00
if ( 0 = = uLen )
{
2022-10-22 18:41:00 +08:00
return ' \0 ' ;
}
2022-11-14 16:07:49 +08:00
strRet = ( char * ) malloc ( uLen + 2 ) ;
memset ( strRet , 0 , uLen + 2 ) ;
2022-10-22 18:41:00 +08:00
2022-11-14 16:07:49 +08:00
for ( i = 0 ; i < uLen ; i + + )
2022-10-28 21:53:48 +08:00
{
if ( str [ i ] ! = ' ' )
{
2022-10-22 18:41:00 +08:00
strRet [ j + + ] = str [ i ] ;
}
}
strRet [ j ] = ' \0 ' ;
return strRet ;
2022-10-10 17:52:00 +08:00
}
2022-12-01 10:47:15 +08:00
int disk_waring ( int threshold )
{
FILE * fp = NULL ;
char buffer [ 1024 ] ;
char command [ 1024 ] ;
int is = 0 ;
# define DF "for u in `df -mh | grep -E -e \".:.\" -e \"^ / dev\" | awk '{print $5}' | sed 's|%%||g'`; do if test \"$u\" -ge %d; then echo \"$u\"; fi done"
memset ( buffer , 0 , 1024 ) ;
memset ( command , 0 , 1024 ) ;
sprintf ( command , DF , threshold ) ;
//printf("%s\n", command);
fp = popen ( command , " r " ) ;
while ( fgets ( buffer , 1024 , fp ) ! = NULL )
{
printf ( " %s " , buffer ) ;
is = 1 ;
break ;
}
pclose ( fp ) ;
return is ;
}
2022-06-26 19:49:00 +08:00
// 封禁非法IP
2022-10-08 14:28:05 +08:00
int rule ( conf * conf )
2019-09-24 08:53:00 +08:00
{
2022-10-10 17:52:00 +08:00
char whitelist_ip [ WHITELIST_IP_NUM ] [ WHITELIST_IP_NUM ] = { { 0 } , { 0 } } ;
2022-10-13 18:01:06 +08:00
char region_list [ WHITELIST_IP_NUM ] [ WHITELIST_IP_NUM ] = { { 0 } , { 0 } } ;
2022-10-22 18:41:00 +08:00
2022-11-25 18:35:33 +08:00
char p_two [ 2 ] , * command , * splice_command , * temp , buffer [ BUFFER ] , awk [ BUFFER ] ;
2022-10-10 17:52:00 +08:00
FILE * fp , * fc ;
2019-09-24 08:53:00 +08:00
time_t timep ;
2021-07-11 10:10:55 +08:00
struct tm * tp ;
2022-11-25 18:35:33 +08:00
long int ip_length = 1 ;
2022-10-22 18:41:00 +08:00
2022-10-28 21:53:48 +08:00
2022-10-10 17:52:00 +08:00
fp = NULL ;
fc = NULL ;
2022-10-28 21:53:48 +08:00
timep = time ( NULL ) ;
2021-07-11 10:10:55 +08:00
tp = localtime ( & timep ) ;
memset ( buffer , 0 , BUFFER ) ;
memset ( awk , 0 , BUFFER ) ;
2022-11-25 18:35:33 +08:00
memset ( p_two , 0 , 2 ) ;
2022-06-26 19:49:00 +08:00
2022-10-28 21:53:48 +08:00
2022-10-22 18:41:00 +08:00
if ( DEBISN_SYSTEM = = check_system ( ) ) // Debian 系统规则
2022-06-26 19:49:00 +08:00
{
2022-10-28 21:53:48 +08:00
if ( tp - > tm_mday > = 10 )
{
if ( ( fp = popen ( GE_10 , " r " ) ) = = NULL )
{
2022-06-26 19:49:00 +08:00
perror ( " GE_10 " ) ;
2022-11-25 18:35:33 +08:00
return - 1 ;
2022-06-26 19:49:00 +08:00
}
2022-10-28 21:53:48 +08:00
}
else
{
if ( ( fp = popen ( LE_10 , " r " ) ) = = NULL )
{
2022-06-26 19:49:00 +08:00
perror ( " LE_10 " ) ;
2022-11-25 18:35:33 +08:00
return - 1 ;
2022-06-26 19:49:00 +08:00
}
2019-09-24 08:53:00 +08:00
}
2022-10-28 21:53:48 +08:00
}
else if ( CENTOS_SYSTEM = = check_system ( ) ) // Centos 7系统规则
2022-06-26 19:49:00 +08:00
{
2022-10-28 21:53:48 +08:00
if ( tp - > tm_mday > = 10 )
{
if ( ( fp = popen ( CENTOS_GE_10 , " r " ) ) = = NULL )
{
2022-06-26 19:49:00 +08:00
perror ( " CENTOS_GE_10 " ) ;
2022-11-25 18:35:33 +08:00
return - 1 ;
2022-06-26 19:49:00 +08:00
}
2022-10-28 21:53:48 +08:00
}
else
{
if ( ( fp = popen ( CENTOS_LE_10 , " r " ) ) = = NULL )
{
2022-06-26 19:49:00 +08:00
perror ( " CENTOS_LE_10 " ) ;
2022-11-25 18:35:33 +08:00
return - 1 ;
2022-06-26 19:49:00 +08:00
}
2019-09-24 08:53:00 +08:00
}
2022-06-26 19:49:00 +08:00
2022-10-28 21:53:48 +08:00
}
else
{
2022-06-26 19:49:00 +08:00
return UNKNOWN_SYSTEM ;
2019-09-24 08:53:00 +08:00
}
2022-06-26 19:49:00 +08:00
2022-10-28 21:53:48 +08:00
2022-11-25 18:35:33 +08:00
splice_command = ( char * ) malloc ( ip_length ) ;
if ( splice_command = = NULL ) {
free ( splice_command ) ;
return - 1 ;
}
memset ( splice_command , 0 , ip_length ) ;
2022-10-28 21:53:48 +08:00
while ( fgets ( buffer , BUFFER , fp ) ! = NULL )
{
2022-11-25 18:35:33 +08:00
char * new_splice_command ;
2019-09-24 08:53:00 +08:00
temp = strstr ( buffer , " rhost " ) ;
sscanf ( temp , " rhost=%s " , temp ) ;
2022-11-25 18:35:33 +08:00
if ( atoi ( strncpy ( p_two , temp , 1 ) ) > 0 )
2022-10-28 21:53:48 +08:00
{
2022-11-25 18:35:33 +08:00
ip_length + = strlen ( temp ) + 1 ;
new_splice_command = ( char * ) realloc ( splice_command , ip_length + 32 ) ;
if ( new_splice_command = = NULL ) {
free ( splice_command ) ;
return - 1 ;
}
splice_command = new_splice_command ;
2021-07-11 10:10:55 +08:00
strcat ( splice_command , temp ) ;
strcat ( splice_command , " \n " ) ;
}
}
2022-10-28 21:53:48 +08:00
printf ( " %s " , splice_command ) ; // 打印所有非法IP
2022-11-25 18:35:33 +08:00
//printf("%ld\n", ip_length);
command = ( char * ) malloc ( ip_length + BUFFER ) ;
if ( command = = NULL ) {
free ( command ) ;
return - 1 ;
}
memset ( command , 0 , ip_length + BUFFER ) ;
2022-06-26 19:49:00 +08:00
2022-10-22 18:41:00 +08:00
sprintf ( awk , AWK , conf - > REFUSE_NUMBER ) ; // 拼接命令
2021-07-11 10:10:55 +08:00
strcpy ( command , " echo \" " ) ;
strcat ( command , splice_command ) ;
strcat ( command , " \" " ) ;
strcat ( command , awk ) ;
2022-06-26 19:49:00 +08:00
2022-11-25 18:35:33 +08:00
2022-10-28 21:53:48 +08:00
if ( ( fc = popen ( command , " r " ) ) = = NULL ) // 执行命令
2022-06-26 19:49:00 +08:00
{
perror ( " popen command " ) ;
2022-11-25 18:35:33 +08:00
return - 1 ;
2021-07-11 10:10:55 +08:00
}
2022-11-25 18:35:33 +08:00
if ( splice_command ! = NULL ) {
free ( splice_command ) ;
}
if ( command ! = NULL ) {
free ( command ) ;
}
2022-06-26 19:49:00 +08:00
2022-10-28 21:53:48 +08:00
while ( fgets ( buffer , BUFFER , fc ) ! = NULL ) // 执行命令后, 为空时就不会
2022-06-26 19:49:00 +08:00
{
2022-10-22 18:41:00 +08:00
buffer [ strlen ( buffer ) - 1 ] = ' \0 ' ; // 去除回车
2022-10-10 17:52:00 +08:00
split_string ( conf - > IPV4_WHITE_LIST , " " , whitelist_ip ) ;
2022-10-13 18:01:06 +08:00
split_string ( conf - > REGION_LIST , " " , region_list ) ;
2022-10-22 18:41:00 +08:00
2022-10-28 21:53:48 +08:00
if ( conf - > IPV4_RESTRICTION = = 1 ) // 是否启用白名单
{
if ( whitelist ( buffer , whitelist_ip ) = = 1 )
{
2022-10-13 18:01:06 +08:00
printf ( " 白名单IPV4:%s \n " , buffer ) ;
2022-10-10 17:52:00 +08:00
continue ;
}
}
2022-06-26 19:49:00 +08:00
2022-10-28 21:53:48 +08:00
if ( 0 ! = show_all_rule ( buffer ) ) // libiptc库判断否存在规则
2022-06-26 19:49:00 +08:00
{
2022-10-10 17:52:00 +08:00
char * location = NULL ;
char * location_json = NULL ;
char iplocation [ BUFFER ] ;
2022-10-22 18:41:00 +08:00
char URL [ BUFFER + 70 ] ;
2022-10-28 21:53:48 +08:00
char temp [ BUFFER ] ;
char * p ;
char * p1 ;
2022-10-22 18:41:00 +08:00
memset ( URL , 0 , BUFFER + 70 ) ;
2022-10-25 23:07:47 +08:00
//sprintf(URL, "http://opendata.baidu.com/api.php?query=%s&co=&resource_id=6006&oe=utf8", buffer);
sprintf ( URL , conf - > REGION_URL , buffer ) ;
2022-10-28 21:53:48 +08:00
//printf("%s\n", URL);
2022-10-22 18:41:00 +08:00
2022-10-10 17:52:00 +08:00
location_json = GET_PUBLIC_IP ( URL ) ;
2022-11-25 18:35:33 +08:00
2022-10-28 21:53:48 +08:00
if ( NULL = = location_json )
{
2022-10-10 17:52:00 +08:00
printf ( " 获取IP位置错误! \n " ) ;
2022-10-13 18:01:06 +08:00
goto BLOCKED ;
2022-10-28 21:53:48 +08:00
}
else
{
p = strstr ( location_json , " \" location \" " ) ;
2022-11-25 18:35:33 +08:00
if ( p = = NULL ) {
printf ( " 解析IP位置错误! \n " ) ;
goto BLOCKED ;
}
2022-10-28 21:53:48 +08:00
p1 = strstr ( p , " \" , " ) ;
2022-11-25 18:35:33 +08:00
if ( p1 = = NULL ) {
printf ( " 解析IP位置错误! \n " ) ;
goto BLOCKED ;
}
2022-10-13 18:01:06 +08:00
memset ( temp , 0 , BUFFER ) ;
2022-10-22 18:41:00 +08:00
memcpy ( temp , p + 12 , p1 - p - 12 ) ;
2022-10-10 17:52:00 +08:00
location = remove_space ( temp ) ;
}
2022-10-22 18:41:00 +08:00
2022-10-10 17:52:00 +08:00
memset ( iplocation , 0 , BUFFER ) ;
strcpy ( iplocation , buffer ) ;
strcat ( iplocation , " ( " ) ;
strcat ( iplocation , location ) ;
strcat ( iplocation , " ) " ) ;
2022-10-28 21:53:48 +08:00
2022-11-14 16:07:49 +08:00
printf ( " %s \n " , iplocation ) ;
2022-10-13 18:01:06 +08:00
// 地域白名单
2022-10-28 21:53:48 +08:00
if ( conf - > REGION = = 1 )
{
if ( isregion ( iplocation , region_list ) = = 1 )
{
2022-10-13 18:01:06 +08:00
printf ( " 地域白名单: %s \n " , iplocation ) ;
continue ;
}
2022-10-22 18:41:00 +08:00
}
2022-10-10 17:52:00 +08:00
2022-10-22 18:41:00 +08:00
if ( conf - > IS_DING_WEBHOOK = = 1 ) // 钉钉告警
2022-10-10 17:52:00 +08:00
{
dingding_warning ( iplocation , public_ip , conf ) ;
2022-06-26 19:49:00 +08:00
sleep ( 3 ) ;
}
2022-10-08 14:28:05 +08:00
2022-10-28 21:53:48 +08:00
if ( conf - > IS_MAIL = = 1 ) // 邮件告警
2022-06-26 19:49:00 +08:00
{
2022-10-10 17:52:00 +08:00
mail_warning ( iplocation , public_ip , conf ) ;
2022-06-26 19:49:00 +08:00
sleep ( 3 ) ;
}
2022-10-08 14:28:05 +08:00
2022-10-28 21:53:48 +08:00
if ( conf - > IS_QQMAIL = = 1 ) // 邮件告警
2022-06-26 19:49:00 +08:00
{
2022-10-10 17:52:00 +08:00
QQ_mail_warning ( iplocation , public_ip , conf ) ;
2022-06-26 19:49:00 +08:00
sleep ( 3 ) ;
}
2022-10-08 14:28:05 +08:00
2022-10-28 21:53:48 +08:00
2022-10-13 18:01:06 +08:00
BLOCKED :
2022-10-10 17:52:00 +08:00
// 是否封禁攻击IP
2022-10-28 21:53:48 +08:00
if ( conf - > IS_BLOCKED = = 1 )
{
2022-10-10 17:52:00 +08:00
// libiptc 库插入规则 iptables -t filter -A INPUT -p tcp -m tcp -s xxxx -j DROP
unsigned int srcIp ;
inet_pton ( AF_INET , buffer , & srcIp ) ;
iptc_add_rule ( " filter " , " INPUT " , IPPROTO_TCP , NULL , NULL , srcIp , 0 , NULL , NULL , " DROP " , NULL , 1 ) ;
}
2022-11-25 18:35:33 +08:00
if ( location ! = NULL )
free ( location ) ;
if ( location_json ! = NULL )
free ( location_json ) ;
2021-07-11 10:10:55 +08:00
}
2019-09-24 08:53:00 +08:00
}
2022-06-26 19:49:00 +08:00
if ( fp ! = NULL )
pclose ( fp ) ;
if ( fc ! = NULL )
pclose ( fc ) ;
return 0 ;
}
static void sig_child ( int signo )
{
pid_t pid ;
int stat ;
// 处理僵尸进程
while ( ( pid = waitpid ( - 1 , & stat , WNOHANG ) ) > 0 ) ;
2022-10-08 14:28:05 +08:00
2022-06-26 19:49:00 +08:00
return ;
}
2022-10-08 14:28:05 +08:00
static int get_executable_path ( char * processdir , char * processname , int len )
{
char * filename ;
2022-10-28 21:53:48 +08:00
2022-10-08 14:28:05 +08:00
if ( readlink ( " /proc/self/exe " , processdir , len ) < = 0 )
return - 1 ;
filename = strrchr ( processdir , ' / ' ) ;
if ( filename = = NULL )
return - 1 ;
+ + filename ;
strcpy ( processname , filename ) ;
* filename = ' \0 ' ;
return ( int ) ( filename - processdir ) ;
}
2022-10-22 18:41:00 +08:00
// 处理参数
int process_argv ( int argc , char * argv [ ] , char * * argvs )
{
argvs [ 0 ] = argv [ 0 ] ;
2022-10-28 21:53:48 +08:00
int i ;
2022-11-14 16:07:49 +08:00
int j ;
2022-10-28 21:53:48 +08:00
for ( i = 0 ; i < = argc - 1 ; i + + )
{
if ( i = = 1 )
{
2022-11-14 16:07:49 +08:00
for ( j = i ; j < = argc - 2 ; j + + )
2022-10-28 21:53:48 +08:00
{
2022-10-22 18:41:00 +08:00
argvs [ j ] = argv [ j + 1 ] ;
}
}
}
return 0 ;
}
2022-10-25 23:07:47 +08:00
int _crontab ( struct tm * * calnext , char * string )
{
const char * err = NULL ;
time_t cur ;
time_t datenext ;
time ( & cur ) ;
cron_expr parsed ;
cron_parse_expr ( string , & parsed , & err ) ;
datenext = cron_next ( & parsed , cur ) ;
* calnext = localtime ( & datenext ) ;
assert ( * calnext ) ;
return 0 ;
}
2022-11-29 13:32:29 +08:00
static int get_clamav_log ( char * file )
{
FILE * fp = NULL ;
char buffer [ BUFFER ] , * temp = NULL , * command = NULL ;
command = ( char * ) alloca ( BUFFER ) ;
memset ( buffer , 0 , BUFFER ) ;
memset ( command , 0 , BUFFER ) ;
memcpy ( command , " tail -n 12 " , 11 ) ;
strcat ( command , file ) ;
fp = popen ( command , " r " ) ;
if ( fp = = NULL ) {
perror ( " popen " ) ;
return - 1 ;
}
while ( fgets ( buffer , BUFFER , fp ) ! = NULL )
{
//printf("%s", buffer);
temp = strstr ( buffer , " Infected " ) ;
if ( temp )
sscanf ( temp , " Infected files: %s " , temp ) ;
if ( temp ! = NULL )
{
//printf("%s\n", temp);
break ;
}
}
pclose ( fp ) ;
if ( temp ! = NULL ) {
printf ( " %d \n " , atoi ( temp ) ) ;
return atoi ( temp ) ;
}
else
{
return - 1 ;
}
return 0 ;
}
2022-11-23 13:15:49 +08:00
int update_freshclam ( int argc , char * argv [ ] )
2022-06-26 19:49:00 +08:00
{
2022-11-23 13:15:49 +08:00
if ( DEBISN_SYSTEM = = check_system ( ) | | CENTOS_SYSTEM = = check_system ( ) ) {
char * * fre_argv ;
int fre_argc = 0 ;
char * fre_argvss [ ARGS_NUM ] = { NULL } ;
2022-11-04 19:37:03 +08:00
2022-11-23 13:15:49 +08:00
fre_argvss [ 0 ] = argv [ 0 ] ;
fre_argvss [ 1 ] = " --user=root " ;
fre_argvss [ 2 ] = " --quiet " ;
fre_argvss [ 3 ] = " --no-warnings " ;
fre_argv = & ( fre_argvss [ 0 ] ) ;
fre_argc = 2 ;
2022-11-04 19:37:03 +08:00
// freshclam配置文件
if ( access ( " /etc/clamav/freshclam.conf " , F_OK ) = = - 1 ) {
system ( " mkdir -p /etc/clamav/ " ) ;
system ( " cp freshclam.conf /etc/clamav/ " ) ;
}
2022-11-23 13:15:49 +08:00
// 打印clamav参数
for ( int i = 0 ; i < fre_argc ; i + + )
{
printf ( " %s %d \n " , fre_argv [ i ] , i ) ;
}
pid_t pid ;
pid = fork ( ) ;
if ( pid < 0 ) {
printf ( " fork error. \n " ) ;
return - 1 ;
}
else if ( pid = = 0 ) // child process
{
int r = 0 ;
r = _freshclam ( fre_argc , fre_argv ) ;
_exit ( r ) ;
}
else
{
int status = 0 ;
wait ( & status ) ; // wait the end of child process
if ( WIFEXITED ( status ) )
{
;
printf ( " child process return %d \n " , WEXITSTATUS ( status ) ) ;
}
sleep ( 3 ) ;
return 0 ;
}
2022-11-04 19:37:03 +08:00
}
2022-11-23 13:15:49 +08:00
return - 1 ;
}
2022-11-19 19:30:56 +08:00
2022-12-01 10:47:15 +08:00
2022-12-08 17:13:32 +08:00
static char help_information ( void )
{
static const char name [ ] = " Rhost " ;
static const char subject [ ] = " Reject host&scan for viruses " ;
static const struct {
const char * email ;
} author = {
" AIXIAO@AIXIAO.ME " ,
} ;
static const char usage [ ] = " Usage: [-?h] [-d] " ;
static const char * s_help [ ] = {
" " ,
" Options: " ,
" -d : Background running " ,
" -? -h --help : help information " ,
" The configuration file needs to be in the same directory as the executable file! " ,
" " ,
" " ,
0
} ;
fprintf ( stderr , " %s %s \n " , name , subject ) ;
fprintf ( stderr , " Author: %s \n " , author . email ) ;
fprintf ( stderr , " %s \n " , usage ) ;
int l ;
for ( l = 0 ; s_help [ l ] ; l + + ) {
fprintf ( stderr , " %s \n " , s_help [ l ] ) ;
}
BUILD ( " Compile、link. \n " ) ;
return 0 ;
}
2022-11-23 13:15:49 +08:00
int main ( int argc , char * argv [ ] , char * * env )
{
2022-12-08 17:13:32 +08:00
2022-10-22 18:41:00 +08:00
signal ( SIGCHLD , sig_child ) ; // 创建捕捉子进程退出信号
2022-11-23 13:15:49 +08:00
2022-12-08 17:13:32 +08:00
2022-10-28 21:53:48 +08:00
int pid ;
2022-11-14 16:07:49 +08:00
int i ;
2022-11-19 19:30:56 +08:00
char move [ BUFFER ] ;
2022-10-28 21:53:48 +08:00
// 读取配置
2022-10-08 14:28:05 +08:00
char path [ BUFFER ] = { 0 } ;
char executable_filename [ BUFFER ] = { 0 } ;
( void ) get_executable_path ( path , executable_filename , sizeof ( path ) ) ;
strcat ( executable_filename , " .conf " ) ;
strcat ( path , executable_filename ) ;
2022-12-08 17:13:32 +08:00
if ( NULL ! = argv [ 1 ] ) {
if ( 0 = = strcmp ( argv [ 1 ] , " -v " ) | | 0 = = strcmp ( argv [ 1 ] , " --version " ) | | 0 = = strcmp ( argv [ 1 ] , " -h " ) | | 0 = = strcmp ( argv [ 1 ] , " --help " ) | | 0 = = strcmp ( argv [ 1 ] , " -? " ) )
{
help_information ( ) ;
exit ( 0 ) ;
}
}
2022-11-19 19:30:56 +08:00
if ( 1 = = access ( path , F_OK ) )
{
printf ( " 配置文件不存在! \n " ) ;
}
2022-07-07 16:52:24 +08:00
conf * conf = ( struct CONF * ) malloc ( sizeof ( struct CONF ) ) ;
2022-10-08 14:28:05 +08:00
read_conf ( path , conf ) ;
2022-07-07 16:52:24 +08:00
//ptintf_conf(conf);
2022-10-28 21:53:48 +08:00
2022-12-08 17:13:32 +08:00
// 更新病毒库
update_freshclam ( argc , argv ) ;
2022-11-19 19:30:56 +08:00
// 创建移除目录
if ( conf - > CLAMAV_ARG )
{
char temp [ BUFFER ] ;
char * p , * p1 ;
memset ( temp , 0 , BUFFER ) ;
memset ( move , 0 , BUFFER ) ;
p = strstr ( conf - > CLAMAV_ARG , " --move= " ) ;
if ( p ! = NULL )
{
p1 = strstr ( p , " " ) ;
if ( ( p1 - p ) > 7 )
{
memcpy ( temp , p , p1 - p ) ;
p = strstr ( temp , " = " ) ;
strcpy ( move , " mkdir -p " ) ;
strcat ( move , p + 1 ) ;
//printf("%s %ld \n", move, strlen(move));
system ( move ) ;
}
}
}
2022-11-23 13:15:49 +08:00
2022-10-28 21:53:48 +08:00
// 处理clamav参数
char * * head_argvs ;
int head_argc = 0 ;
char * argvs [ ARGS_NUM ] = { NULL } ;
char args [ ARGS_NUM ] [ WHITELIST_IP_NUM ] = { { 0 } , { 0 } } ;
//printf("%d\n", argc);
if ( argc > 3 ) // 手动输入参数(如果手动输入参数个数大于3个, 则使用用户输入的参数)
{
process_argv ( argc , argv , & ( argvs [ 0 ] ) ) ;
head_argvs = & ( argvs [ 0 ] ) ; // head_argvs指向argvs[0]
head_argc = argc - 1 ; // 改变argc数
}
else // 读取配置文件参数
{
argvs [ 0 ] = argv [ 0 ] ;
split_string ( conf - > CLAMAV_ARG , " " , args ) ;
2022-11-14 16:07:49 +08:00
for ( i = 1 ; i < ARGS_NUM ; i + + )
2022-10-28 21:53:48 +08:00
{
if ( args [ i ] [ 0 ] = = ' \0 ' )
{
continue ;
}
else
{
argvs [ i ] = strdup ( args [ i ] ) ;
head_argc + + ;
}
}
head_argvs = & ( argvs [ 0 ] ) ;
head_argc + = 1 ;
}
2022-11-23 13:15:49 +08:00
/*
2022-10-28 21:53:48 +08:00
// 打印clamav参数
for ( int i = 0 ; i < head_argc ; i + + )
{
printf ( " %s %d \n " , head_argvs [ i ] , i ) ;
}
2022-11-23 13:15:49 +08:00
_clamscan ( head_argc , head_argvs ) ;
*/
2022-10-28 21:53:48 +08:00
2022-10-25 23:07:47 +08:00
now_next_time * t = ( now_next_time * ) malloc ( sizeof ( struct now_next_time ) ) ;
memset ( t , 0 , sizeof ( struct now_next_time ) ) ;
2022-10-10 17:52:00 +08:00
// 获取公网IP
2022-10-08 14:28:05 +08:00
public_ip = GET_PUBLIC_IP ( conf - > PUBLIC_IP ) ;
//printf("%s", public_ip);
2022-06-26 19:49:00 +08:00
2022-10-10 17:52:00 +08:00
2022-10-28 21:53:48 +08:00
if ( 0 = = strcmp ( conf - > DAEMON , " on " ) )
{
2022-07-07 16:52:24 +08:00
goto goto_daemon ;
}
2022-06-26 19:49:00 +08:00
2022-10-28 21:53:48 +08:00
if ( argv [ 1 ] ! = NULL & & 0 = = strcmp ( argv [ 1 ] , " -d " ) )
{
2022-07-07 16:52:24 +08:00
goto_daemon :
2022-10-28 21:53:48 +08:00
/*
2022-06-26 19:49:00 +08:00
if ( daemon ( 1 , 1 ) ) // 守护进程
{
perror ( " daemon " ) ;
return - 1 ;
}
2022-10-28 21:53:48 +08:00
*/
2022-06-26 19:49:00 +08:00
2022-10-28 21:53:48 +08:00
// 守护进程
if ( ( pid = fork ( ) ) < 0 ) {
return 0 ;
} else if ( 0 ! = pid ) {
2022-11-14 16:07:49 +08:00
for ( i = 1 ; i < head_argc ; i + + )
2022-10-28 21:53:48 +08:00
{
if ( head_argvs [ i ] )
free ( head_argvs [ i ] ) ;
}
free ( t ) ;
free_conf ( conf ) ;
free ( conf ) ;
free ( public_ip ) ;
exit ( 0 ) ;
}
if ( setsid ( ) < 0 ) {
return 0 ;
}
signal ( SIGHUP , SIG_IGN ) ;
if ( ( pid = fork ( ) ) < 0 ) {
return 0 ;
} else if ( 0 ! = pid ) {
2022-11-14 16:07:49 +08:00
for ( i = 1 ; i < head_argc ; i + + )
2022-10-28 21:53:48 +08:00
{
if ( head_argvs [ i ] )
free ( head_argvs [ i ] ) ;
}
free ( t ) ;
free_conf ( conf ) ;
free ( conf ) ;
free ( public_ip ) ;
exit ( 0 ) ;
}
while ( 1 )
{
2022-10-25 23:07:47 +08:00
// Cron
struct tm * calnext ; //取得Cron规则时间
calnext = ( struct tm * ) malloc ( sizeof ( struct tm ) ) ;
memset ( calnext , 0 , sizeof ( struct tm ) ) ;
_crontab ( & calnext , conf - > CLAMAV_TIME ) ;
t - > next_year = 1900 + calnext - > tm_year ;
t - > next_mon = 1 + calnext - > tm_mon ;
t - > next_day = calnext - > tm_mday ;
t - > next_hour = calnext - > tm_hour ;
t - > next_min = calnext - > tm_min ;
t - > next_sec = calnext - > tm_sec ;
// 取得现在时间
time_t timep ;
struct tm * p ;
2022-10-28 21:53:48 +08:00
timep = time ( NULL ) ;
2022-10-25 23:07:47 +08:00
p = localtime ( & timep ) ;
t - > now_year = 1900 + p - > tm_year ;
t - > now_mon = 1 + p - > tm_mon ;
t - > now_day = p - > tm_mday ;
t - > now_hour = p - > tm_hour ;
t - > now_min = p - > tm_min ;
t - > now_sec = p - > tm_sec ;
2022-10-22 18:41:00 +08:00
// Clamav call
2022-10-25 23:07:47 +08:00
if ( 1 = = conf - > CLAMAV )
2022-10-22 18:41:00 +08:00
{
2022-10-25 23:07:47 +08:00
if ( t - > now_year = = t - > next_year & & t - > now_mon = = t - > next_mon & & t - > now_day = = t - > next_day & & t - > now_hour = = t - > next_hour & & t - > now_min = = t - > next_min )
{
//printf("%d%d%d %d:%d:%d\n", t->now_year, t->now_mon, t->now_day, t->now_hour, t->now_min, t->now_sec);
//printf("%d%d%d %d:%d:%d\n", t->next_year, t->next_mon, t->next_day, t->next_hour, t->next_min, t->next_sec);
2022-10-22 18:41:00 +08:00
pid_t pid ;
pid = fork ( ) ;
if ( pid < 0 ) {
printf ( " fork error. \n " ) ;
return - 1 ;
2022-10-28 21:53:48 +08:00
}
else if ( pid = = 0 ) // child process
{
2022-10-22 18:41:00 +08:00
int r = 0 ;
2022-11-29 13:32:29 +08:00
int virus_files = - 1 ;
2022-10-22 18:41:00 +08:00
r = _clamscan ( head_argc , head_argvs ) ;
2022-11-29 13:32:29 +08:00
virus_files = get_clamav_log ( " clamscan.log " ) ;
if ( virus_files > 0 ) {
if ( conf - > IS_QQMAIL = = 1 )
{
QQ_mail_warning_Virus_files ( public_ip , virus_files , conf ) ;
sleep ( 3 ) ;
}
}
2022-12-01 10:47:15 +08:00
// 磁盘告警
if ( 1 = = conf - > IS_DISK )
{
if ( disk_waring ( conf - > DISK_USE ) = = 1 )
{
printf ( " Disk usage reaches threshold!, Please handle! \n " ) ;
if ( conf - > IS_QQMAIL = = 1 )
{
QQ_mail_warning_Disk_Use ( public_ip , 0 , conf ) ;
sleep ( 3 ) ;
}
}
else
{
printf ( " Disk usage does not reach threshold! \n " ) ;
}
}
2022-10-22 18:41:00 +08:00
_exit ( r ) ;
2022-10-28 21:53:48 +08:00
}
else
{
2022-10-22 18:41:00 +08:00
int status = 0 ;
2022-10-28 21:53:48 +08:00
wait ( & status ) ; // wait the end of child process
if ( WIFEXITED ( status ) )
{
2022-10-22 18:41:00 +08:00
;
2022-10-25 23:07:47 +08:00
//printf("child process return %d\n", WEXITSTATUS(status));
2022-10-22 18:41:00 +08:00
}
2022-10-25 23:07:47 +08:00
2022-10-28 21:53:48 +08:00
sleep ( 60 ) ; // 跳过这一分钟
2022-10-22 18:41:00 +08:00
}
}
}
2022-10-25 23:07:47 +08:00
2022-06-26 19:49:00 +08:00
2022-10-22 18:41:00 +08:00
rule ( conf ) ;
2022-07-07 16:52:24 +08:00
sleep ( conf - > TIME ) ;
2022-06-26 19:49:00 +08:00
}
2022-10-28 21:53:48 +08:00
}
else
{
2022-12-01 10:47:15 +08:00
2022-07-07 16:52:24 +08:00
rule ( conf ) ;
2022-06-26 19:49:00 +08:00
}
2022-10-25 23:07:47 +08:00
free ( t ) ;
2022-07-07 16:52:24 +08:00
free_conf ( conf ) ;
free ( conf ) ;
2022-10-08 14:28:05 +08:00
free ( public_ip ) ;
2022-11-14 16:07:49 +08:00
for ( i = 1 ; i < head_argc ; i + + )
2022-10-28 21:53:48 +08:00
{
//printf("%s %d\n", head_argvs[i], i);
if ( head_argvs [ i ] )
free ( head_argvs [ i ] ) ;
}
2019-09-24 08:53:00 +08:00
return 0 ;
}