添加Nginx日志文件
This commit is contained in:
parent
778c9d5fff
commit
00567557ba
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -5,6 +5,7 @@
|
|||||||
"conf.h": "c",
|
"conf.h": "c",
|
||||||
"ccronexpr.h": "c",
|
"ccronexpr.h": "c",
|
||||||
"clamscan.h": "c",
|
"clamscan.h": "c",
|
||||||
"libiptc.h": "c"
|
"libiptc.h": "c",
|
||||||
|
"stdio.h": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
11
libiptc.c
11
libiptc.c
@ -105,7 +105,8 @@ struct ipt_entry_match *get_match(const char *sports, const char *dports, unsign
|
|||||||
return match;
|
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 xtc_handle *handle;
|
||||||
struct ipt_entry *chain_entry;
|
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;
|
int result = 0;
|
||||||
|
|
||||||
chain_entry = (struct ipt_entry *)calloc(1, sizeof(*chain_entry));
|
chain_entry = (struct ipt_entry *)calloc(1, sizeof(*chain_entry));
|
||||||
|
if (chain_entry == NULL) {
|
||||||
|
perror("calloc failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (src != 0) {
|
if (src != 0) {
|
||||||
chain_entry->ip.src.s_addr = src;
|
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)
|
if (IPPROTO_TCP == protocol)
|
||||||
entry_match = get_match(srcports, destports, &chain_entry->nfcache, "tcp");
|
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_t size;
|
||||||
size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));
|
size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));
|
||||||
entry_target = (struct ipt_entry_target *)calloc(1, size);
|
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);
|
result = iptc_insert_entry(labelit, chain_entry, 0, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
printf("libiptc error: Can't add, %s\n", iptc_strerror(errno));
|
printf("libiptc error: Can't add, %s\n", iptc_strerror(errno));
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#define IPTC_FULL_SIZE IPTC_ENTRY_SIZE + IPTC_MATCH_SIZE + IPTC_TARGET_SIZE
|
#define IPTC_FULL_SIZE IPTC_ENTRY_SIZE + IPTC_MATCH_SIZE + IPTC_TARGET_SIZE
|
||||||
|
|
||||||
int show_all_rule(char *ipv4);
|
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
|
#endif
|
||||||
|
275
libiptc/iptc_delete_rule.c
Normal file
275
libiptc/iptc_delete_rule.c
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <libiptc/libiptc.h>
|
||||||
|
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
38
nginx.c
38
nginx.c
@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
#include "nginx.h"
|
#include "nginx.h"
|
||||||
|
|
||||||
|
|
||||||
#define EVENT_SIZE (sizeof(struct inotify_event))
|
#define EVENT_SIZE (sizeof(struct inotify_event))
|
||||||
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
|
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
|
||||||
#define INITIAL_BUFFER_SIZE 8192
|
#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);
|
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 *area = NULL;
|
||||||
char *xdb_path = "ip2region.xdb";
|
char *xdb_path = "ip2region.xdb";
|
||||||
char *p = strchr(string, ' ');
|
char *p = strchr(string, ' ');
|
||||||
char IP[64];
|
char IP[64];
|
||||||
memset(IP, 0, 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) {
|
if ((p - string) > 0) {
|
||||||
memmove(IP, string, p - string);
|
memmove(IP, string, p - string);
|
||||||
} else {
|
} else {
|
||||||
printf("Invalid IP string format.\n");
|
printf("Invalid IP string format.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access(xdb_path, F_OK) == -1) { // 判断 ip2region 地址定位库是否存在
|
if (access(xdb_path, F_OK) == -1) { // 判断 ip2region 地址定位库是否存在
|
||||||
xdb_path = "ip2region/ip2region.xdb";
|
xdb_path = "ip2region/ip2region.xdb";
|
||||||
if (access(xdb_path, F_OK) == -1) {
|
if (access(xdb_path, F_OK) == -1) {
|
||||||
@ -34,28 +43,36 @@ int IP_location(char *string, conf *config) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
area = ip2region(xdb_path, IP);
|
area = ip2region(xdb_path, IP);
|
||||||
if (area == NULL) {
|
if (area == NULL) {
|
||||||
printf("ip2region解析地域错误\n");
|
printf("ip2region解析地域错误\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("IP地址:%s, %s\n", IP, area);
|
my_printf("IP地址:%s, %s\n", IP, area);
|
||||||
printf("%s, %s\n", config->NGINX_LOG_FILE, config->NGINX_REGION_LIST);
|
//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;
|
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);
|
int fd = open(p->NGINX_LOG_FILE, O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
perror("open");
|
perror("open");
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move to the end of the file
|
// Move to the end of the file
|
||||||
if (lseek(fd, 0, SEEK_END) == -1) {
|
if (lseek(fd, 0, SEEK_END) == -1) {
|
||||||
perror("lseek");
|
perror("lseek");
|
||||||
@ -96,7 +113,6 @@ int nginx_read_log(const char *filename, conf *p) {
|
|||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial dynamic buffer allocation
|
// Initial dynamic buffer allocation
|
||||||
size_t buffer_size = INITIAL_BUFFER_SIZE;
|
size_t buffer_size = INITIAL_BUFFER_SIZE;
|
||||||
char *read_buf = alloca(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;) {
|
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) {
|
if (event->mask & IN_MODIFY) {
|
||||||
int bytes_read;
|
int bytes_read;
|
||||||
while ((bytes_read = read(fd, read_buf, buffer_size - 1)) > 0) {
|
while ((bytes_read = read(fd, read_buf, buffer_size - 1)) > 0) {
|
||||||
|
253
rhost.c
253
rhost.c
@ -28,18 +28,17 @@
|
|||||||
static int cronAllocations = 0;
|
static int cronAllocations = 0;
|
||||||
static int cronTotalAllocations = 0;
|
static int cronTotalAllocations = 0;
|
||||||
static int maxAlloc = 0;
|
static int maxAlloc = 0;
|
||||||
void* cron_malloc(size_t n)
|
void *cron_malloc(size_t n)
|
||||||
{
|
{
|
||||||
cronAllocations++;
|
cronAllocations++;
|
||||||
cronTotalAllocations++;
|
cronTotalAllocations++;
|
||||||
if (cronAllocations > maxAlloc)
|
if (cronAllocations > maxAlloc) {
|
||||||
{
|
|
||||||
maxAlloc = cronAllocations;
|
maxAlloc = cronAllocations;
|
||||||
}
|
}
|
||||||
return malloc(n);
|
return malloc(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cron_free(void* p)
|
void cron_free(void *p)
|
||||||
{
|
{
|
||||||
cronAllocations--;
|
cronAllocations--;
|
||||||
free(p);
|
free(p);
|
||||||
@ -47,6 +46,47 @@ void cron_free(void* p)
|
|||||||
#endif
|
#endif
|
||||||
// CRON END
|
// 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
|
// 存储公网IP
|
||||||
char *public_ip;
|
char *public_ip;
|
||||||
|
|
||||||
@ -698,6 +738,8 @@ BLOCKED:
|
|||||||
if (conf->IS_BLOCKED == 1) {
|
if (conf->IS_BLOCKED == 1) {
|
||||||
// libiptc 库插入规则
|
// libiptc 库插入规则
|
||||||
// iptables -t filter -A INPUT -p tcp -m tcp -s 47.110.180.35 -j DROP
|
// 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
|
// iptables -t filter -D INPUT -p tcp -m tcp -s 47.110.180.35 -j DROP
|
||||||
unsigned int srcIp;
|
unsigned int srcIp;
|
||||||
inet_pton(AF_INET, buffer, &srcIp);
|
inet_pton(AF_INET, buffer, &srcIp);
|
||||||
@ -843,7 +885,6 @@ int update_freshclam(int argc, char *argv[])
|
|||||||
system("mkdir -p /etc/clamav/");
|
system("mkdir -p /etc/clamav/");
|
||||||
system("cp freshclam.conf /etc/clamav/");
|
system("cp freshclam.conf /etc/clamav/");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打印clamav参数
|
// 打印clamav参数
|
||||||
for (int i = 0; i < fre_argc; i++) {
|
for (int i = 0; i < fre_argc; i++) {
|
||||||
printf("%s %d\n", fre_argv[i], i);
|
printf("%s %d\n", fre_argv[i], i);
|
||||||
@ -1068,119 +1109,113 @@ goto_daemon:
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-1 == (nice(-20))) // 进程优先级
|
// 进程优先级
|
||||||
|
if (-1 == (nice(-20)))
|
||||||
perror("nice");
|
perror("nice");
|
||||||
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
// 创建一个新进程
|
// 处理Nginx
|
||||||
pid = fork();
|
pid_t pid = fork(); // 创建子进程
|
||||||
|
if (pid == 0) {
|
||||||
if (pid < 0) {
|
printf("The parent process processes Nginx logs!!!\n");
|
||||||
// fork 失败
|
while (1)
|
||||||
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_read_log(conf->NGINX_LOG_FILE, conf);
|
nginx_read_log(conf->NGINX_LOG_FILE, conf);
|
||||||
|
|
||||||
sleep(1);
|
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 {
|
} else {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(t);
|
free(t);
|
||||||
|
@ -3,7 +3,7 @@ global {
|
|||||||
DAEMON = "off"; // on开启后台运行,off不开启(弃用)
|
DAEMON = "off"; // on开启后台运行,off不开启(弃用)
|
||||||
TIME = "10"; // 睡眠时间(大于等于1,单位秒)
|
TIME = "10"; // 睡眠时间(大于等于1,单位秒)
|
||||||
|
|
||||||
|
|
||||||
PUBLIC_IP = "http://inet-ip.info"; // 获取公网IP
|
PUBLIC_IP = "http://inet-ip.info"; // 获取公网IP
|
||||||
|
|
||||||
|
|
||||||
|
5
rhost.h
5
rhost.h
@ -14,10 +14,12 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct now_next_time
|
typedef struct now_next_time
|
||||||
{
|
{
|
||||||
int now_year;
|
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_Virus "gomail -r %s -s \"System Virus Infected\" -t \"%s\""
|
||||||
#define QQMAIL_DISK_USE "gomail -r %s -s \"System Disk Use\" -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 read_conf(char *filename, conf * configure);
|
||||||
extern void free_conf(conf * conf);
|
extern void free_conf(conf * conf);
|
||||||
extern void ptintf_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]);
|
extern int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user