#include "rule.h" static int Handle_IP(conf *conf, char *ip) { char whitelist_ip[WHITELIST_IP_NUM][WHITELIST_IP_NUM] = { { 0 }, { 0 } }; char region_list[WHITELIST_IP_NUM][WHITELIST_IP_NUM] = { { 0 }, { 0 } }; char REGION_LIST_COPY[conf->REGION_LIST_LEN + 1]; char IPV4_WHITE_LIST_COPY[conf->IPV4_WHITE_LIST_LEN + 1]; char *t = _time(); memset(REGION_LIST_COPY, 0, sizeof(REGION_LIST_COPY)); memset(IPV4_WHITE_LIST_COPY, 0, sizeof(IPV4_WHITE_LIST_COPY)); memcpy(REGION_LIST_COPY, conf->REGION_LIST, strlen(conf->REGION_LIST)); memcpy(IPV4_WHITE_LIST_COPY, conf->IPV4_WHITE_LIST, strlen(conf->IPV4_WHITE_LIST)); split_string(IPV4_WHITE_LIST_COPY, " ", whitelist_ip); split_string(REGION_LIST_COPY, " ", region_list); // IP白名单 if (conf->IPV4_RESTRICTION == 1) { if (whitelist(ip, whitelist_ip) == 1) { printf("%s 白名单IPV4:%s\n", t, ip); return 3; } } if (show_all_rule(ip) != 0) // 不在防火墙规则表里 { char *area = NULL; char *xdb_path = "ip2region.xdb"; if (conf->REGION == 1) { if (conf->IP2REGION == 1) { //printf("%s Use ip2region !!!\n", t); if (access(xdb_path, F_OK) == -1) { xdb_path = "ip2region/ip2region.xdb"; if (access(xdb_path, F_OK) == -1) { printf("%s ip2region.xdb DOESN'T EXIST!\n", t); } } area = ip2region(xdb_path, ip); if (area == NULL) { printf("%s ip2region解析地域错误\n", t); goto BLOCKED; } } if (isregion(area, region_list) == 1) { printf(RED "%s SSH Ip Address: %s, 地域白名单: %s\n" COLOR_NONE, t, ip, area); return 3; } } printf(RED "%s 攻击者IP地址:%s, %s\n" COLOR_NONE, t, ip, area); BLOCKED: if (conf->IS_BLOCKED == 1) { unsigned int srcIp; inet_pton(AF_INET, ip, &srcIp); iptc_add_rule("filter", "INPUT", IPPROTO_TCP, NULL, NULL, srcIp, 0, NULL, NULL, "DROP", NULL, 1); } if (area != NULL) { free(area); } } return 0; } void extract_rhost_ip(conf *conf, const char *line) { char *rhost_start = strstr(line, RHOST_KEY); if (rhost_start) { rhost_start += strlen(RHOST_KEY); // 移动到rhost=后的字符 char *rhost_end = strpbrk(rhost_start, " \n"); if (rhost_end) { char ip[64]; strncpy(ip, rhost_start, rhost_end - rhost_start); ip[rhost_end - rhost_start] = '\0'; Handle_IP(conf, ip); } else { ; } } } int rule_(conf *conf, char *LOG_FILE) { FILE *file; char buffer[BUFFER_SIZE]; off_t last_size = 0; struct stat file_stat; // 打开日志文件 file = fopen(LOG_FILE, "r"); if (file == NULL) { perror("无法打开日志文件"); return EXIT_FAILURE; } // 获取文件初始大小 fseek(file, 0, SEEK_END); last_size = ftell(file); while (1) { // 检查文件是否被轮转 if (stat(LOG_FILE, &file_stat) == -1) { perror("无法获取文件状态"); fclose(file); return EXIT_FAILURE; } // 如果文件大小小于上次读取的位置,说明文件被轮转了 if (file_stat.st_size < last_size) { fclose(file); file = fopen(LOG_FILE, "r"); if (file == NULL) { perror("无法重新打开日志文件"); return EXIT_FAILURE; } last_size = 0; } // 移动到上次读取的位置 fseek(file, last_size, SEEK_SET); // 逐行读取新增的日志内容 while (fgets(buffer, sizeof(buffer), file) != NULL) { extract_rhost_ip(conf, buffer); } // 记录当前文件大小 last_size = ftell(file); // 暂停一段时间然后继续检查文件变化 sleep(1); } // 关闭文件 fclose(file); return EXIT_SUCCESS; }