增加IP白名单,增加显示封禁IP地域

This commit is contained in:
aixiao 2022-10-10 17:52:00 +08:00
parent 15b093d3f6
commit 706299cd4c
7 changed files with 217 additions and 49 deletions

View File

@ -42,17 +42,30 @@ update-alternatives --set ebtables /usr/sbin/ebtables-legacy
配置文件
global {
DAEMON = "off"; // on开启后台运行off不开启
TIME = "60"; // 睡眠时间单位秒大于等于1
TIME = "10"; // 睡眠时间
REFUSE_NUMBER = 5; // 拒绝攻击次数大于等于1
IS_MAIL = 0; // 开启邮件告警0关闭1开启
PUBLIC_IP = "http://inet-ip.info"; // 获取公网IP
IS_DING_WEBHOOK = 1; // 开启叮叮告警0关闭1开启
IPV4_RESTRICTION = 1; // 是否启用百名单
IPV4_WHITE_LIST = "1.193.37.156 117.158.215.217"; // IP白名单
IS_BLOCKED = 1; // 是否封禁攻击IP
REFUSE_NUMBER = 5; // 拒绝攻击次数
IS_MAIL = 0; // 开启邮件告警
IS_DING_WEBHOOK = 1; // 开启叮叮告警
PHONE = "15565979082"; // @的人手机号
DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=7f069c672cb878987aa6772cca336740eece4ce36bde12b51b45e9f440e0565a"; // 钉钉WEBHOOK
IS_QQMAIL = 0; // 开启QQ邮箱告警0关闭1开启
RECV_MAIL = "1605227279"; // 接收者QQ
IS_QQMAIL = 0; // 开启QQ邮箱告警
RECV_MAIL = "1605227279@qq.com"; // 接收者QQ
}
```

35
conf.c
View File

@ -91,6 +91,12 @@ static void parse_global_module(char *content, conf * conf)
conf->TIME = atoi(val_begin);
}
if (strcasecmp(var, "IS_BLOCKED") == 0) {
val_begin_len = val_end - val_begin;
conf->IS_BLOCKED = atoi(val_begin);
}
if (strcasecmp(var, "REFUSE_NUMBER") == 0) {
val_begin_len = val_end - val_begin;
@ -150,6 +156,19 @@ static void parse_global_module(char *content, conf * conf)
if (copy_new_mem(val_begin, val_begin_len, &conf->PUBLIC_IP) != 0)
return;
}
if (strcasecmp(var, "IPV4_RESTRICTION") == 0) {
val_begin_len = val_end - val_begin;
conf->IPV4_RESTRICTION = atoi(val_begin);
}
if (strcasecmp(var, "IPV4_WHITE_LIST") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->IPV4_WHITE_LIST) != 0)
return;
}
content = strchr(lineEnd + 1, '\n');
}
@ -226,6 +245,8 @@ void free_conf(conf * conf)
free(conf->RECV_MAIL);
if (conf->PUBLIC_IP)
free(conf->PUBLIC_IP);
if (conf->IPV4_WHITE_LIST)
free(conf->IPV4_WHITE_LIST);
return;
}
@ -251,4 +272,18 @@ void ptintf_conf(conf * conf)
printf("%s\n", conf->RECV_MAIL);
if (conf->PUBLIC_IP)
printf("%s\n", conf->PUBLIC_IP);
if (conf->IPV4_WHITE_LIST)
printf("%s\n", conf->IPV4_WHITE_LIST);
}
void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM])
{
int i = 0;
char *result = NULL;
result = strtok(string, delims);
while (result != NULL) {
i++;
strcpy(whitelist_ip[i], result);
result = strtok(NULL, delims);
}
}

8
conf.h
View File

@ -7,15 +7,22 @@
#include <stddef.h>
#include <string.h>
#define WHITELIST_IP_NUM 1024
typedef struct CONF {
char *DAEMON;
int TIME;
int IS_BLOCKED;
int REFUSE_NUMBER;
// 获取公网IP Url地址
char *PUBLIC_IP;
// IPV4 白名单
int IPV4_RESTRICTION;
char *IPV4_WHITE_LIST;
int IS_MAIL;
int IS_DING_WEBHOOK;
@ -31,5 +38,6 @@ typedef struct CONF {
void read_conf(char *filename, conf * configure);
void free_conf(conf * conf);
void ptintf_conf(conf * conf);
void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM]);
#endif

View File

@ -176,10 +176,16 @@ int iptc_add_rule(const char *table, const char *chain, int protocol, const char
free(entry_match);
return 1;
}
if (append)
{
result = iptc_append_entry(labelit, chain_entry, handle);
}
else
{
result = iptc_insert_entry(labelit, chain_entry, 0, handle);
}
if (!result) {
printf("libiptc error: Can't add, %s\n", iptc_strerror(errno));
free(chain_entry);
@ -188,6 +194,7 @@ int iptc_add_rule(const char *table, const char *chain, int protocol, const char
free(entry_match);
return 1;
}
result = iptc_commit(handle);
if (!result) {
printf("libiptc error: Commit error, %s\n", iptc_strerror(errno));

173
rhost.c
View File

@ -196,28 +196,71 @@ int QQ_mail_warning(char *illegal_ip, char *public_ip, conf * conf)
return system(string);
}
// IP段白名单对比
int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM])
{
int i;
for (i = 1; i < WHITELIST_IP_NUM - 1; i++) {
if (strcmp(whitelist_ip[i], "\0") == 0) { // 如果字符串为空就跳出循环
break;
}
if ((strncmp(client_ip, whitelist_ip[i], strlen(whitelist_ip[i]))) == 0) { // 对比client_ip长度,
return 1;
}
}
return 0;
}
char *remove_space(const char *str)
{
unsigned int uLen = strlen(str);
if(0 == uLen)
{
return '\0';
}
char *strRet = (char *)malloc(uLen + 1);
memset(strRet, 0, uLen+1);
unsigned int i = 0, j = 0;
for(i=0; i<uLen+1; i++)
{
if(str[i] != ' ')
{
strRet[j++] = str[i];
}
}
strRet[j] = '\0';
return strRet;
}
// 封禁非法IP
int rule(conf * conf)
{
FILE *fp, *fc;
//char p[2], splice_command[LONG_BUFFER], command[LONG_BUFFER], *temp, buffer[BUFFER], awk[BUFFER], iptables[BUFFER + (sizeof(IPTABLES))], iptables_check[BUFFER + (sizeof(IPTABLES_CHECK))];
int i;
char whitelist_ip[WHITELIST_IP_NUM][WHITELIST_IP_NUM] = { { 0 }, { 0 } };
char p[2], splice_command[LONG_BUFFER], command[LONG_BUFFER], *temp, buffer[BUFFER], awk[BUFFER];
FILE *fp, *fc;
time_t timep;
struct tm *tp;
i=0;
fp = NULL;
fc = NULL;
time(&timep);
tp = localtime(&timep);
memset(splice_command, 0, LONG_BUFFER);
memset(command, 0, LONG_BUFFER);
memset(buffer, 0, BUFFER);
memset(awk, 0, BUFFER);
//memset(iptables, 0, BUFFER+(sizeof(IPTABLES)));
//memset(iptables_check, 0, BUFFER+(sizeof(IPTABLES_CHECK)));
fp = NULL;
fc = NULL;
if (DEBISN_SYSTEM == check_system()) // Debian 系统规则
if (DEBISN_SYSTEM == check_system()) // Debian 系统规则
{
if (tp->tm_mday >= 10) {
if ((fp = popen(GE_10, "r")) == NULL) {
@ -230,7 +273,7 @@ int rule(conf * conf)
return 1;
}
}
} else if (CENTOS_SYSTEM == check_system()) // Centos 7系统规则
} else if (CENTOS_SYSTEM == check_system()) // Centos 7系统规则
{
if (tp->tm_mday >= 10) {
if ((fp = popen(CENTOS_GE_10, "r")) == NULL) {
@ -256,62 +299,111 @@ int rule(conf * conf)
strcat(splice_command, "\n");
}
}
printf("%s", splice_command); // 打印所有非法IP
printf("%s", splice_command); // 打印所有非法IP
// 拼接命令
sprintf(awk, AWK, conf->REFUSE_NUMBER);
sprintf(awk, AWK, conf->REFUSE_NUMBER); // 拼接命令
strcpy(command, "echo \"");
strcat(command, splice_command);
strcat(command, "\"");
strcat(command, awk);
if ((fp = popen(command, "r")) == NULL) // 执行命令
if ((fp = popen(command, "r")) == NULL) // 执行命令
{
perror("popen command");
return 1;
}
while (fgets(buffer, BUFFER, fp) != NULL) // 执行命令后, 为空时就不会
while (fgets(buffer, BUFFER, fp) != NULL) // 执行命令后, 为空时就不会
{
buffer[strlen(buffer) - 1] = '\0'; // 去除回车
split_string(conf->IPV4_WHITE_LIST, " ", whitelist_ip);
for (i = 1; i <= WHITELIST_IP_NUM - 1; i++) {
if (*whitelist_ip[i] != '\0') ;
//printf("%s\n", whitelist_ip[i]);
}
if (conf->IPV4_RESTRICTION == 1) { // 是否启用百名单
if (whitelist(buffer, whitelist_ip) == 1) {
;
//printf("白名单IPV4:%s\n", buffer);
continue;
}
}
buffer[strlen(buffer) - 1] = '\0'; // 去除回车
//sprintf(iptables, IPTABLES, buffer);
//sprintf(iptables_check, IPTABLES_CHECK, buffer);
//if (0 != system(iptables_check)) // 调用iptables命令判断是否存在规则, 不存在时再添加规则
if (0 != show_all_rule(buffer)) // libiptc库判断
if (0 != show_all_rule(buffer)) // libiptc库判断否存在规则
{
if (conf->IS_DING_WEBHOOK == 1) // 钉钉告警
char *location = NULL;
char *location_json = NULL;
char iplocation[BUFFER];
char URL[BUFFER+70];
memset(URL, 0, BUFFER+70);
sprintf(URL, "http://opendata.baidu.com/api.php?query=%s&co=&resource_id=6006&oe=utf8", buffer);
location_json = GET_PUBLIC_IP(URL);
if (NULL == location_json)
{
dingding_warning(buffer, public_ip, conf);
printf("获取IP位置错误!\n");
}
else
{
//printf("%s\n", location_json);
char temp[BUFFER];
memset(temp, 0, BUFFER);
char *p = strstr(location_json, "\"location\"");
char *p1 = strstr(p, "\",");
memcpy(temp, p+12, p1-p-12);
location = remove_space(temp);
}
memset(iplocation, 0, BUFFER);
strcpy(iplocation, buffer);
strcat(iplocation, "(");
strcat(iplocation, location);
strcat(iplocation, ")");
//printf("%s\n", iplocation);
if (conf->IS_DING_WEBHOOK == 1) // 钉钉告警
{
dingding_warning(iplocation, public_ip, conf);
sleep(3);
}
if (conf->IS_MAIL == 1) // 邮件告警
if (conf->IS_MAIL == 1) // 邮件告警
{
mail_warning(buffer, public_ip, conf);
mail_warning(iplocation, public_ip, conf);
sleep(3);
}
if (conf->IS_QQMAIL == 1) // 邮件告警
if (conf->IS_QQMAIL == 1) // 邮件告警
{
QQ_mail_warning(buffer, public_ip, conf);
QQ_mail_warning(iplocation, public_ip, conf);
sleep(3);
}
/*
// 调用命令下发规则
if ((fc = popen(iptables, "r")) == NULL) {
perror("popen iptables");
return 1;
}
*/
// libiptc 库插入规则 iptables -t filter -A INPUT -p tcp -s xxxx -j DROP
unsigned int srcIp;
inet_pton(AF_INET, buffer, &srcIp);
iptc_add_rule("filter", "INPUT", IPPROTO_TCP, NULL, NULL, srcIp, 0, NULL, NULL, "DROP", NULL, 1);
// 是否封禁攻击IP
if (conf->IS_BLOCKED == 1) {
// libiptc 库插入规则 iptables -t filter -A INPUT -p tcp -m tcp -s xxxx -j DROP
unsigned int srcIp;
inet_pton(AF_INET, buffer, &srcIp);
iptc_add_rule("filter", "INPUT", IPPROTO_TCP, NULL, NULL, srcIp, 0, NULL, NULL, "DROP", NULL, 1);
}
free(location);
free(location_json);
}
}
@ -362,13 +454,16 @@ int main(int argc, char *argv[], char **env)
conf *conf = (struct CONF *)malloc(sizeof(struct CONF));
read_conf(path, conf);
//ptintf_conf(conf);
// 新版本获取公网IP
// 获取公网IP
public_ip = GET_PUBLIC_IP(conf->PUBLIC_IP);
//printf("%s", public_ip);
signal(SIGCHLD, sig_child); // 创建捕捉子进程退出信号
if (0 == strcmp(conf->DAEMON, "on")) {
goto goto_daemon;
}

View File

@ -1,17 +1,27 @@
global {
DAEMON = "off"; // on开启后台运行off不开启
TIME = "60"; // 睡眠时间
TIME = "10"; // 睡眠时间
PUBLIC_IP = "http://inet-ip.info"; // 获取公网IP
REFUSE_NUMBER = 3; // 拒绝攻击次数
IPV4_RESTRICTION = 1; // 是否启用百名单
IPV4_WHITE_LIST = "1.193.37.156 117.158.215.217"; // IP白名单
IS_BLOCKED = 1; // 是否封禁攻击IP
REFUSE_NUMBER = 5; // 拒绝攻击次数
IS_MAIL = 0; // 开启邮件告警
IS_DING_WEBHOOK = 1; // 开启叮叮告警
PHONE = "15565979082"; // @的人手机号
DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=7f069c672cb878987aa6772cca336740eece4ce36bde12b51b45e9f440e0565a"; // 钉钉WEBHOOK
IS_QQMAIL = 0; // 开启QQ邮箱告警
RECV_MAIL = "1605227279@qq.com"; // 接收者QQ
}

View File

@ -20,6 +20,8 @@
#define BUFFER 1024
#define LONG_BUFFER 1024*100
#define WHITELIST_IP_NUM 1024
#define AWK " | awk -v num=%d '{a[$1]+=1;} END {for(i in a){if (a[i] >= num) {print i;}}}' "
#define GE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\").$(LC_ALL=\"C\" date \"+%d\")\" /var/log/auth.log | grep failure | grep rhost"
#define LE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\")..$(LC_ALL=\"C\" date | awk '{print $3}')\" /var/log/auth.log | grep failure | grep rhost"
@ -27,8 +29,6 @@
#define CENTOS_GE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\").$(LC_ALL=\"C\" date \"+%d\")\" /var/log/secure | grep failure | grep rhost"
#define CENTOS_LE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\")..$(LC_ALL=\"C\" date | awk '{print $3}')\" /var/log/secure | grep failure | grep rhost"
#define IPTABLES "`which iptables` -t filter -I INPUT -s %s -j DROP"
#define IPTABLES_CHECK "`which iptables` -t filter -C INPUT -s %s -j DROP 2> /dev/null"
#define QQMAIL "email -r %s -s \"System ban IP\" -t \"%s\""