denyhosts/nginx.c

157 lines
4.4 KiB
C
Raw Normal View History

2024-05-21 15:28:20 +08:00
2024-05-21 09:08:14 +08:00
#include "nginx.h"
2024-05-21 15:28:20 +08:00
2024-05-21 09:08:14 +08:00
#define EVENT_SIZE (sizeof(struct inotify_event))
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
#define INITIAL_BUFFER_SIZE 8192
2024-05-21 15:28:20 +08:00
void nginx_iptc(char *ip)
{
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);
}
2024-05-22 11:36:50 +08:00
int IP_location(char *string, conf *config)
{
2024-05-21 09:08:14 +08:00
char *area = NULL;
char *xdb_path = "ip2region.xdb";
char *p = strchr(string, ' ');
char IP[64];
memset(IP, 0, 64);
2024-05-22 11:36:50 +08:00
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 地理位置获取
2024-05-21 09:08:14 +08:00
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;
}
2024-05-22 11:36:50 +08:00
my_printf("IP地址:%s, %s\n", IP, area);
//printf("%s, %s\n", config->NGINX_LOG_FILE, config->NGINX_REGION_LIST);
2024-05-21 15:28:20 +08:00
2024-05-22 11:36:50 +08:00
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);
}
}
2024-05-21 09:08:14 +08:00
return 0;
}
2024-05-22 11:36:50 +08:00
int nginx_read_log(const char *filename, conf *p)
{
2024-05-21 15:28:20 +08:00
int fd = open(p->NGINX_LOG_FILE, O_RDONLY);
2024-05-21 09:08:14 +08:00
if (fd == -1) {
perror("open");
2024-05-22 11:36:50 +08:00
2024-05-21 15:28:20 +08:00
return -1;
2024-05-21 09:08:14 +08:00
}
// Move to the end of the file
if (lseek(fd, 0, SEEK_END) == -1) {
perror("lseek");
close(fd);
2024-05-21 15:28:20 +08:00
return -1;
2024-05-21 09:08:14 +08:00
}
int inotify_fd = inotify_init();
if (inotify_fd < 0) {
perror("inotify_init");
close(fd);
2024-05-21 15:28:20 +08:00
return -1;
2024-05-21 09:08:14 +08:00
}
2024-05-21 15:28:20 +08:00
int wd = inotify_add_watch(inotify_fd, p->NGINX_LOG_FILE, IN_MODIFY);
2024-05-21 09:08:14 +08:00
if (wd == -1) {
perror("inotify_add_watch");
close(inotify_fd);
close(fd);
2024-05-21 15:28:20 +08:00
return -1;
2024-05-21 09:08:14 +08:00
}
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);
2024-05-21 15:28:20 +08:00
return -1;
2024-05-21 09:08:14 +08:00
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
perror("fcntl F_SETFL");
inotify_rm_watch(inotify_fd, wd);
close(inotify_fd);
close(fd);
2024-05-21 15:28:20 +08:00
return -1;
2024-05-21 09:08:14 +08:00
}
// 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);
2024-05-21 15:28:20 +08:00
return -1;
2024-05-21 09:08:14 +08:00
}
while (1) {
int length = read(inotify_fd, buffer, EVENT_BUF_LEN);
if (length < 0) {
perror("read");
break;
}
for (int i = 0; i < length;) {
2024-05-22 11:36:50 +08:00
struct inotify_event *event = (struct inotify_event *)&buffer[i];
2024-05-21 09:08:14 +08:00
if (event->mask & IN_MODIFY) {
int bytes_read;
while ((bytes_read = read(fd, read_buf, buffer_size - 1)) > 0) {
read_buf[bytes_read] = '\0';
2024-05-21 15:28:20 +08:00
IP_location(read_buf, p);
2024-05-21 09:08:14 +08:00
}
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);
2024-05-21 15:28:20 +08:00
return 0;
2024-05-21 09:08:14 +08:00
}