diff --git a/.vscode/settings.json b/.vscode/settings.json index 91a46bb..5455103 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ "conf.h": "c", "ccronexpr.h": "c", "clamscan.h": "c", - "libiptc.h": "c" + "libiptc.h": "c", + "stdio.h": "c" } } \ No newline at end of file diff --git a/libiptc.c b/libiptc.c index 3a98df9..1ebcb95 100644 --- a/libiptc.c +++ b/libiptc.c @@ -105,7 +105,8 @@ struct ipt_entry_match *get_match(const char *sports, const char *dports, unsign return match; } -int iptc_add_rule(const char *table, const char *chain, int protocol, const char *iniface, const char *outiface, unsigned int src, unsigned int dest, const char *srcports, const char *destports, const char *target, const char *dnat_to, const int append) +int iptc_add_rule(const char *table, const char *chain, int protocol, const char *iniface, const char *outiface, \ + unsigned int src, unsigned int dest, const char *srcports, const char *destports, const char *target, const char *dnat_to, const int append) { struct xtc_handle *handle; struct ipt_entry *chain_entry; @@ -116,6 +117,10 @@ int iptc_add_rule(const char *table, const char *chain, int protocol, const char int result = 0; chain_entry = (struct ipt_entry *)calloc(1, sizeof(*chain_entry)); + if (chain_entry == NULL) { + perror("calloc failed"); + return 1; + } if (src != 0) { chain_entry->ip.src.s_addr = src; @@ -137,7 +142,8 @@ int iptc_add_rule(const char *table, const char *chain, int protocol, const char if (IPPROTO_TCP == protocol) entry_match = get_match(srcports, destports, &chain_entry->nfcache, "tcp"); - if (strcmp(target, "") == 0 || strcmp(target, IPTC_LABEL_ACCEPT) == 0 || strcmp(target, IPTC_LABEL_DROP) == 0 || strcmp(target, IPTC_LABEL_QUEUE) == 0 || strcmp(target, IPTC_LABEL_RETURN) == 0) { + if (strcmp(target, "") == 0 || strcmp(target, IPTC_LABEL_ACCEPT) == 0 || strcmp(target, IPTC_LABEL_DROP) == 0 || \ + strcmp(target, IPTC_LABEL_QUEUE) == 0 || strcmp(target, IPTC_LABEL_RETURN) == 0) { size_t size; size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int)); entry_target = (struct ipt_entry_target *)calloc(1, size); @@ -192,6 +198,7 @@ int iptc_add_rule(const char *table, const char *chain, int protocol, const char { result = iptc_insert_entry(labelit, chain_entry, 0, handle); } + if (!result) { printf("libiptc error: Can't add, %s\n", iptc_strerror(errno)); diff --git a/libiptc.h b/libiptc.h index 749a83f..6fed12d 100644 --- a/libiptc.h +++ b/libiptc.h @@ -30,6 +30,7 @@ #define IPTC_FULL_SIZE IPTC_ENTRY_SIZE + IPTC_MATCH_SIZE + IPTC_TARGET_SIZE int show_all_rule(char *ipv4); -int iptc_add_rule(const char *table, const char *chain, int protocol, const char *iniface, const char *outiface, unsigned int src, unsigned int dest, const char *srcports, const char *destports, const char *target, const char *dnat_to, const int append); +int iptc_add_rule(const char *table, const char *chain, int protocol, const char *iniface, const char *outiface, \ + unsigned int src, unsigned int dest, const char *srcports, const char *destports, const char *target, const char *dnat_to, const int append); #endif diff --git a/libiptc/iptc_delete_rule.c b/libiptc/iptc_delete_rule.c new file mode 100644 index 0000000..183dcea --- /dev/null +++ b/libiptc/iptc_delete_rule.c @@ -0,0 +1,275 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NFC_IP_SRC_PT 0x0200 +#define NFC_IP_DST_PT 0x0400 + +#ifndef IPT_MIN_ALIGN +#define IPT_MIN_ALIGN (__alignof__(struct ipt_entry)) +#endif + +#define IPT_ALIGN(s) (((s) + ((IPT_MIN_ALIGN)-1)) & ~((IPT_MIN_ALIGN)-1)) + +#define IPTC_ENTRY_SIZE XT_ALIGN(sizeof(struct ipt_entry)) +#define IPTC_MATCH_SIZE XT_ALIGN(sizeof(struct ipt_entry_match) + sizeof(struct ipt_udp)) +#define IPTC_TARGET_SIZE XT_ALIGN(sizeof(struct ipt_entry_target)) +#define IPTC_FULL_SIZE IPTC_ENTRY_SIZE + IPTC_MATCH_SIZE + IPTC_TARGET_SIZE + +#define IPTC_LABEL_ACCEPT "ACCEPT" +#define IPTC_LABEL_DROP "DROP" +#define IPTC_LABEL_QUEUE "QUEUE" +#define IPTC_LABEL_RETURN "RETURN" + +static u_int16_t parse_port(const char *port) +{ + return atoi(port); +} + +static void parse_ports(const char *portstring, u_int16_t *ports) +{ + char *buffer; + char *cp; + + buffer = strdup(portstring); + if ((cp = strchr(buffer, ':')) == NULL) + ports[0] = ports[1] = parse_port(buffer); + else { + *cp = '\0'; + cp++; + + ports[0] = buffer[0] ? parse_port(buffer) : 0; + ports[1] = cp[0] ? parse_port(cp) : 0xFFFF; + } + + free(buffer); +} + +struct ipt_entry_match *get_match(const char *sports, const char *dports, unsigned int *nfcache, const char *protocol) +{ + struct ipt_entry_match *match; + struct ipt_udp *udpinfo; + size_t size; + + size = IPT_ALIGN(sizeof(*match)) + IPT_ALIGN(sizeof(*udpinfo)); + match = (struct ipt_entry_match *)calloc(1, size); + if (!match) { + perror("calloc failed for match"); + return NULL; + } + + match->u.match_size = size; + strncpy(match->u.user.name, protocol, IPT_FUNCTION_MAXNAMELEN - 2); + match->u.user.name[IPT_FUNCTION_MAXNAMELEN - 2] = '\0'; + + udpinfo = (struct ipt_udp *)match->data; + udpinfo->spts[1] = udpinfo->dpts[1] = 0xFFFF; + + if (sports) { + *nfcache |= NFC_IP_SRC_PT; + parse_ports(sports, udpinfo->spts); + } + if (dports) { + *nfcache |= NFC_IP_DST_PT; + parse_ports(dports, udpinfo->dpts); + } + + return match; +} + +// 打印 IP 地址 +void print_ip_address(const char *label, struct in_addr addr) { + char ip_str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &addr, ip_str, sizeof(ip_str)); + printf("%s: %s\n", label, ip_str); +} + +// 打印规则详细信息 +void print_rule(const char *label, const struct ipt_entry *entry) { + printf("%s:\n", label); + print_ip_address(" src", entry->ip.src); + print_ip_address(" dst", entry->ip.dst); + printf(" proto: %u\n", entry->ip.proto); + printf(" iniface: %s\n", entry->ip.iniface); + printf(" outiface: %s\n", entry->ip.outiface); + printf(" target_offset: %u\n", entry->target_offset); + printf(" next_offset: %u\n", entry->next_offset); + printf(" counters: pkts=%llu, bytes=%llu\n", entry->counters.pcnt, entry->counters.bcnt); +} + +// 打印匹配结构详细信息 +void print_match(const char *label, const struct ipt_entry_match *match) { + printf("%s:\n", label); + printf(" match_size: %u\n", match->u.user.match_size); + printf(" name: %s\n", match->u.user.name); + printf(" revision: %u\n", match->u.user.revision); + // 如果有特定协议的数据,例如 TCP 或 UDP,可以在这里打印具体内容 + // 例如:匹配 TCP 协议时,打印源端口和目标端口 + if (strcmp(match->u.user.name, "tcp") == 0) { + struct ipt_tcp *tcpinfo = (struct ipt_tcp *)match->data; + printf(" TCP source port: %u\n", ntohs(tcpinfo->spts[0])); + printf(" TCP destination port: %u\n", ntohs(tcpinfo->dpts[0])); + } else if (strcmp(match->u.user.name, "udp") == 0) { + struct ipt_udp *udpinfo = (struct ipt_udp *)match->data; + printf(" UDP source port: %u\n", ntohs(udpinfo->spts[0])); + printf(" UDP destination port: %u\n", ntohs(udpinfo->dpts[0])); + } +} + +// 打印目标结构详细信息 +void print_target(const char *label, const struct ipt_entry_target *target) { + printf("%s:\n", label); + printf(" target_size: %u\n", target->u.user.target_size); + printf(" name: %s\n", target->u.user.name); + printf(" revision: %u\n", target->u.user.revision); +} + +int iptc_delete_rule(const char *table, const char *chain, int protocol, const char *iniface, const char *outiface, \ + unsigned int src, unsigned int dest, const char *srcports, const char *destports, const char *target) +{ + struct xtc_handle *handle = NULL; + struct ipt_entry *chain_entry = NULL; + struct ipt_entry_match *entry_match = NULL; + struct ipt_entry_target *entry_target = NULL; + ipt_chainlabel labelit; + long match_size = 0; + int result = 1; // Default to failure + + // Initialize rule entry + chain_entry = (struct ipt_entry *)calloc(1, sizeof(*chain_entry)); + if (!chain_entry) { + perror("calloc failed"); + return 1; + } + + if (src != 0) { + chain_entry->ip.src.s_addr = src; + chain_entry->ip.smsk.s_addr = 0xFFFFFFFF; + } + if (dest != 0) { + chain_entry->ip.dst.s_addr = dest; + chain_entry->ip.dmsk.s_addr = 0xFFFFFFFF; + } + + if (iniface) + strncpy(chain_entry->ip.iniface, iniface, IFNAMSIZ); + if (outiface) + strncpy(chain_entry->ip.outiface, outiface, IFNAMSIZ); + + chain_entry->ip.proto = protocol; + if (IPPROTO_UDP == protocol) + entry_match = get_match(srcports, destports, &chain_entry->nfcache, "udp"); + if (IPPROTO_TCP == protocol) + entry_match = get_match(srcports, destports, &chain_entry->nfcache, "tcp"); + + print_match("entry_match", entry_match); + + if (strcmp(target, "") == 0 || strcmp(target, IPTC_LABEL_ACCEPT) == 0 || strcmp(target, IPTC_LABEL_DROP) == 0 || strcmp(target, IPTC_LABEL_QUEUE) == 0 || strcmp(target, IPTC_LABEL_RETURN) == 0) { + size_t size; + size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int)); + entry_target = (struct ipt_entry_target *)calloc(1, size); + if (!entry_target) { + perror("calloc failed for target"); + goto cleanup; + } + entry_target->u.user.target_size = size; + strncpy(entry_target->u.user.name, target, XT_EXTENSION_MAXNAMELEN); + entry_target->u.user.name[XT_EXTENSION_MAXNAMELEN - 1] = '\0'; + } + match_size = entry_match ? entry_match->u.match_size : 0; + print_target("entry_target", entry_target); + + + struct ipt_entry *tmp_ipt = chain_entry; + chain_entry = (struct ipt_entry *)realloc(chain_entry, sizeof(*chain_entry) + match_size + entry_target->u.target_size); + if (!chain_entry) { + free(tmp_ipt); + free(entry_target); + if (entry_match) free(entry_match); + perror("realloc failed"); + return 1; + } + + memcpy(chain_entry->elems + match_size, entry_target, entry_target->u.target_size); + chain_entry->target_offset = sizeof(*chain_entry) + match_size; + chain_entry->next_offset = sizeof(*chain_entry) + match_size + entry_target->u.target_size; + if (entry_match) { + memcpy(chain_entry->elems, entry_match, match_size); + } + + handle = iptc_init(table); + if (!handle) { + fprintf(stderr, "libiptc error: Can't initialize table %s, %s\n", table, iptc_strerror(errno)); + goto cleanup; + } + + strncpy(labelit, chain, sizeof(ipt_chainlabel)); + labelit[sizeof(ipt_chainlabel) - 1] = '\0'; + if (0 == iptc_is_chain(labelit, handle)) { + fprintf(stderr, "libiptc error: Chain %s does not exist!\n", labelit); + goto cleanup; + } + + // 打印 chain_entry 详细信息 + print_rule("Chain entry", chain_entry); + + // Find and delete the matching rule + const struct ipt_entry *entry; + unsigned int rule_num = 0; + for (entry = iptc_first_rule(labelit, handle); entry; (entry = iptc_next_rule(entry, handle), ++rule_num)) + { + + if (entry->ip.proto == chain_entry->ip.proto && + entry->ip.src.s_addr == chain_entry->ip.src.s_addr && + entry->ip.dst.s_addr == chain_entry->ip.dst.s_addr && + strncmp(entry->ip.iniface, chain_entry->ip.iniface, IFNAMSIZ) == 0 && + strncmp(entry->ip.outiface, chain_entry->ip.outiface, IFNAMSIZ) == 0) + { + // 打印当前 entry 详细信息 + print_rule("Current entry", entry); + + printf("Matching rule found. Deleting rule number: %u\n", rule_num); + + // 删除规则 + if (!iptc_delete_num_entry(labelit, rule_num, handle)) { + fprintf(stderr, "libiptc error: Can't delete entry, %s\n", iptc_strerror(errno)); + iptc_free(handle); + return result; + } + + // 提交更改 + if (!iptc_commit(handle)) { + fprintf(stderr, "libiptc error: Commit error, %s\n", iptc_strerror(errno)); + } else { + printf("Rule deleted successfully\n"); + result = 0; + break; + } + } + } + +cleanup: + if (entry_match) free(entry_match); + if (entry_target) free(entry_target); + if (chain_entry) free(chain_entry); + if (handle) iptc_free(handle); + + return result; +} + +int main(int argc, char *argv[]) { + // Test deleting rule + unsigned int srcIp; + inet_pton(AF_INET, argv[1], &srcIp); + + int result = iptc_delete_rule("filter", "INPUT", IPPROTO_TCP, NULL, NULL, srcIp, 0, NULL, NULL, IPTC_LABEL_DROP); + + return result; +} diff --git a/nginx.c b/nginx.c index f87d50a..eb687b8 100644 --- a/nginx.c +++ b/nginx.c @@ -1,7 +1,6 @@ #include "nginx.h" - #define EVENT_SIZE (sizeof(struct inotify_event)) #define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16)) #define INITIAL_BUFFER_SIZE 8192 @@ -13,20 +12,30 @@ void nginx_iptc(char *ip) iptc_add_rule("filter", "INPUT", IPPROTO_TCP, NULL, NULL, srcIp, 0, NULL, NULL, "DROP", NULL, 1); } -int IP_location(char *string, conf *config) { +int IP_location(char *string, conf *config) +{ char *area = NULL; char *xdb_path = "ip2region.xdb"; char *p = strchr(string, ' '); char IP[64]; memset(IP, 0, 64); + char *t = _time(); + char nginx_region_list[WHITELIST_IP_NUM][WHITELIST_IP_NUM] = { { 0 }, { 0 } }; + char NGINX_REGION_LIST_COPY[config->NGINX_REGION_LIST_LEN + 1]; + + memset(NGINX_REGION_LIST_COPY, 0, config->NGINX_REGION_LIST_LEN + 1); + memcpy(NGINX_REGION_LIST_COPY, config->NGINX_REGION_LIST, config->NGINX_REGION_LIST_LEN); // 复制配置字符串,split_string()会改变原数据 + + split_string(NGINX_REGION_LIST_COPY, " ", nginx_region_list); + + // IP 地理位置获取 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) { @@ -34,28 +43,36 @@ int IP_location(char *string, conf *config) { return -1; } } - area = ip2region(xdb_path, IP); if (area == NULL) { printf("ip2region解析地域错误\n"); return -1; } - printf("IP地址:%s, %s\n", IP, area); - printf("%s, %s\n", config->NGINX_LOG_FILE, config->NGINX_REGION_LIST); + my_printf("IP地址:%s, %s\n", IP, area); + //printf("%s, %s\n", config->NGINX_LOG_FILE, config->NGINX_REGION_LIST); + if (config->NGINX == 1) // 开启Nginx防御 + { + if (isregion(area, nginx_region_list) == 1) { // 返回1表示在白名单列表 + printf(RED "%s Nginx Ip Address: %s, 属于地域白名单: %s\n" COLOR_NONE, t, IP, area); + } else { + my_printf(RED "%s Nginx 封禁 Ip Address: %s, 地址: %s!!!\n" COLOR_NONE, t, IP, area); + nginx_iptc(IP); + } + } return 0; } -int nginx_read_log(const char *filename, conf *p) { +int nginx_read_log(const char *filename, conf *p) +{ int fd = open(p->NGINX_LOG_FILE, O_RDONLY); if (fd == -1) { perror("open"); - + return -1; } - // Move to the end of the file if (lseek(fd, 0, SEEK_END) == -1) { perror("lseek"); @@ -96,7 +113,6 @@ int nginx_read_log(const char *filename, conf *p) { close(fd); return -1; } - // Initial dynamic buffer allocation size_t buffer_size = INITIAL_BUFFER_SIZE; char *read_buf = alloca(buffer_size); @@ -116,7 +132,7 @@ int nginx_read_log(const char *filename, conf *p) { } for (int i = 0; i < length;) { - struct inotify_event *event = (struct inotify_event *) &buffer[i]; + 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) { diff --git a/rhost.c b/rhost.c index 94bfa5d..28de681 100644 --- a/rhost.c +++ b/rhost.c @@ -28,18 +28,17 @@ static int cronAllocations = 0; static int cronTotalAllocations = 0; static int maxAlloc = 0; -void* cron_malloc(size_t n) +void *cron_malloc(size_t n) { cronAllocations++; cronTotalAllocations++; - if (cronAllocations > maxAlloc) - { + if (cronAllocations > maxAlloc) { maxAlloc = cronAllocations; } return malloc(n); } -void cron_free(void* p) +void cron_free(void *p) { cronAllocations--; free(p); @@ -47,6 +46,47 @@ void cron_free(void* p) #endif // CRON END + + + + +// 自定义 printf 函数 +void my_printf(const char *format, ...) { + va_list args; + va_start(args, format); + + // 打印到控制台 + vprintf(format, args); + va_end(args); // 结束对变参列表的处理 + + // 重新启动变参列表 + va_start(args, format); + + // 打开日志文件(追加模式) + FILE *log_file = fopen(LOG_FILE, "a"); + if (log_file != NULL) { + // 获取当前时间 + time_t now = time(NULL); + struct tm local_time; + localtime_r(&now, &local_time); + char time_str[20]; // YYYY-MM-DD HH:MM:SS 格式 + strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &local_time); + + // 打印时间戳到日志文件 + fprintf(log_file, "[%s] ", time_str); + + // 打印内容到日志文件 + vfprintf(log_file, format, args); + + // 关闭日志文件 + fclose(log_file); + } else { + perror("Unable to open log file"); + } + + va_end(args); // 结束对变参列表的处理 +} + // 存储公网IP char *public_ip; @@ -698,6 +738,8 @@ BLOCKED: if (conf->IS_BLOCKED == 1) { // libiptc 库插入规则 // iptables -t filter -A INPUT -p tcp -m tcp -s 47.110.180.35 -j DROP + + // libiptc 库删除规则 // 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); @@ -843,7 +885,6 @@ int update_freshclam(int argc, char *argv[]) system("mkdir -p /etc/clamav/"); system("cp freshclam.conf /etc/clamav/"); } - // 打印clamav参数 for (int i = 0; i < fre_argc; i++) { printf("%s %d\n", fre_argv[i], i); @@ -1068,119 +1109,113 @@ goto_daemon: exit(0); } - if (-1 == (nice(-20))) // 进程优先级 + // 进程优先级 + if (-1 == (nice(-20))) perror("nice"); - pid_t pid; - // 创建一个新进程 - 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)); - 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; - timep = time(NULL); - 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; - - //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("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) { - //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); - - pid_t pid; - pid = fork(); - if (pid < 0) { - printf("fork error.\n"); - return -1; - } else if (pid == 0) // child process - { - int r = 0; - int virus_files = -1; - - // 扫描病毒前,更新病毒库 - update_freshclam(argc, argv); - - r = _clamscan(head_argc, head_argvs); - 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); - } - } - - // 磁盘告警 - 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"); - } - } - - _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(60); // 跳过这一分钟 - } - } - } - - rule(conf); - sleep(conf->TIME); - } - } else { - // 父进程 - printf("The parent process processes Nginx logs!!!"); - while(1) + // 处理Nginx + pid_t pid = fork(); // 创建子进程 + if (pid == 0) { + printf("The parent process processes Nginx logs!!!\n"); + while (1) { nginx_read_log(conf->NGINX_LOG_FILE, conf); - sleep(1); } } + + while (1) + { + // 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; + timep = time(NULL); + 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; + + //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("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) { + //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); + + pid_t pid; + pid = fork(); + if (pid < 0) { + printf("fork error.\n"); + return -1; + } else if (pid == 0) // child process + { + int r = 0; + int virus_files = -1; + + // 扫描病毒前,更新病毒库 + update_freshclam(argc, argv); + + r = _clamscan(head_argc, head_argvs); + 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); + } + } + + // 磁盘告警 + 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"); + } + } + + _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(60); // 跳过这一分钟 + } + } + } + + rule(conf); + sleep(conf->TIME); + } } else { - ; + ; } free(t); diff --git a/rhost.conf b/rhost.conf index 21635cd..25d8af3 100644 --- a/rhost.conf +++ b/rhost.conf @@ -3,7 +3,7 @@ global { DAEMON = "off"; // on开启后台运行,off不开启(弃用) TIME = "10"; // 睡眠时间(大于等于1,单位秒) - + PUBLIC_IP = "http://inet-ip.info"; // 获取公网IP diff --git a/rhost.h b/rhost.h index 9fbd773..6949254 100644 --- a/rhost.h +++ b/rhost.h @@ -14,10 +14,12 @@ #include #include #include +#include #include "conf.h" + typedef struct now_next_time { int now_year; @@ -70,11 +72,14 @@ typedef struct now_next_time #define QQMAIL_Virus "gomail -r %s -s \"System Virus Infected\" -t \"%s\"" #define QQMAIL_DISK_USE "gomail -r %s -s \"System Disk Use\" -t \"%s\"" +#define LOG_FILE "nginx.log" extern void read_conf(char *filename, conf * configure); extern void free_conf(conf * conf); extern void ptintf_conf(conf * conf); +extern void my_printf(const char *format, ...); +extern char *_time(); extern int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM]); #endif