denyhosts/rule.c

148 lines
4.2 KiB
C
Raw Normal View History

2024-05-27 16:05:31 +08:00
#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) {
2024-05-28 11:08:55 +08:00
//printf("%s Use ip2region !!!\n", t);
2024-05-27 16:05:31 +08:00
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) {
2024-05-28 11:08:55 +08:00
printf(RED "%s SSH Ip Address: %s, 地域白名单: %s\n" COLOR_NONE, t, ip, area);
2024-05-27 16:05:31 +08:00
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;
}