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) {
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2024-07-05 09:25:44 +08:00
|
|
|
|
|
|
|
if (t)
|
|
|
|
free(t);
|
2024-05-27 16:05:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|