修改获取公网IP方法,优化配置打印
修改: Makefile 修改: README.md 修改: conf.c 修改: conf.h 修改: denyhosts.sh 修改: libiptc.c 修改: libiptc.h 修改: rhost.c 修改: rhost.conf 修改: rhost.h
This commit is contained in:
parent
a7ff1174c0
commit
9421d1f1eb
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
||||
CROSS_COMPILE ?=
|
||||
CC := $(CROSS_COMPILE)gcc
|
||||
CFLAGS += -O2 -g -Wall
|
||||
CFLAGS += -Os -g -Wall
|
||||
LIB += -lcurl -lip4tc
|
||||
OBG = rhost
|
||||
|
||||
|
12
README.md
12
README.md
@ -3,8 +3,16 @@ ssh防止暴力破解,适用Debian 8、9、11 Centos 7
|
||||
支持钉钉告警和邮件告警
|
||||
支持第三方QQ邮箱告警
|
||||
支持一次运行检测、后台运行检测
|
||||
|
||||
```
|
||||
Debian系统请安装libcurl库和libiptc库
|
||||
Centos 7系统请安装libcurl库和iptables-devel库,yum install iptables-devel libcurl-devel
|
||||
apt install libip4tc-dev libcurl4-openssl-dev (或者libcurl4-gnutls-dev)
|
||||
```
|
||||
|
||||
```
|
||||
Centos 7系统请安装libcurl库和iptables-devel库
|
||||
yum install iptables-devel libcurl-devel
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
@ -45,8 +53,6 @@ global {
|
||||
DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=7f069c672cb878987aa6772cca336740eece4ce36bde12b51b45e9f440e0565a"; // 钉钉WEBHOOK
|
||||
|
||||
IS_QQMAIL = 0; // 开启QQ邮箱告警(0关闭,1开启)
|
||||
SEND_QQ = "1605227279"; // 发送者QQ
|
||||
QQMAIL_KEY = "caczsjchvyibiabe"; // 发送者QQ密钥
|
||||
RECV_MAIL = "1605227279"; // 接收者QQ
|
||||
}
|
||||
```
|
||||
|
76
conf.c
76
conf.c
@ -81,7 +81,7 @@ static void parse_global_module(char *content, conf * conf)
|
||||
while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) {
|
||||
if (strcasecmp(var, "DAEMON") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
|
||||
|
||||
if (copy_new_mem(val_begin, val_begin_len, &conf->DAEMON) != 0)
|
||||
return;
|
||||
}
|
||||
@ -89,61 +89,67 @@ static void parse_global_module(char *content, conf * conf)
|
||||
if (strcasecmp(var, "TIME") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
conf->TIME = atoi(val_begin);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (strcasecmp(var, "REFUSE_NUMBER") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
conf->REFUSE_NUMBER = atoi(val_begin);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (strcasecmp(var, "IS_MAIL") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
conf->IS_MAIL = atoi(val_begin);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (strcasecmp(var, "IS_DING_WEBHOOK") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
conf->IS_DING_WEBHOOK = atoi(val_begin);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (strcasecmp(var, "PHONE") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
if (copy_new_mem(val_begin, val_begin_len, &conf->PHONE) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (strcasecmp(var, "DING_WEBHOOK") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
if (copy_new_mem(val_begin, val_begin_len, &conf->DING_WEBHOOK) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (strcasecmp(var, "IS_QQMAIL") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
conf->IS_QQMAIL = atoi(val_begin);
|
||||
}
|
||||
|
||||
|
||||
if (strcasecmp(var, "SEND_QQ") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
if (copy_new_mem(val_begin, val_begin_len, &conf->SEND_QQ) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (strcasecmp(var, "QQMAIL_KEY") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
if (copy_new_mem(val_begin, val_begin_len, &conf->QQMAIL_KEY) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (strcasecmp(var, "RECV_MAIL") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
if (copy_new_mem(val_begin, val_begin_len, &conf->RECV_MAIL) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(var, "PUBLIC_IP") == 0) {
|
||||
val_begin_len = val_end - val_begin;
|
||||
if (copy_new_mem(val_begin, val_begin_len, &conf->PUBLIC_IP) != 0)
|
||||
return;
|
||||
}
|
||||
|
||||
content = strchr(lineEnd + 1, '\n');
|
||||
}
|
||||
@ -206,27 +212,43 @@ void read_conf(char *filename, conf * configure)
|
||||
|
||||
void free_conf(conf * conf)
|
||||
{
|
||||
free(conf->DAEMON);
|
||||
free(conf->PHONE);
|
||||
free(conf->DING_WEBHOOK);
|
||||
free(conf->SEND_QQ);
|
||||
free(conf->QQMAIL_KEY);
|
||||
free(conf->RECV_MAIL);
|
||||
if (conf->DAEMON)
|
||||
free(conf->DAEMON);
|
||||
if (conf->PHONE)
|
||||
free(conf->PHONE);
|
||||
if (conf->DING_WEBHOOK)
|
||||
free(conf->DING_WEBHOOK);
|
||||
if (conf->SEND_QQ)
|
||||
free(conf->SEND_QQ);
|
||||
if (conf->QQMAIL_KEY)
|
||||
free(conf->QQMAIL_KEY);
|
||||
if (conf->RECV_MAIL)
|
||||
free(conf->RECV_MAIL);
|
||||
if (conf->PUBLIC_IP)
|
||||
free(conf->PUBLIC_IP);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ptintf_conf(conf *conf)
|
||||
void ptintf_conf(conf * conf)
|
||||
{
|
||||
printf("%s\n", conf->DAEMON);
|
||||
if (conf->DAEMON)
|
||||
printf("%s\n", conf->DAEMON);
|
||||
printf("%d\n", conf->TIME);
|
||||
printf("%d\n", conf->REFUSE_NUMBER);
|
||||
printf("%d\n", conf->IS_MAIL);
|
||||
printf("%d\n", conf->IS_DING_WEBHOOK);
|
||||
printf("%s\n", conf->PHONE);
|
||||
printf("%s\n", conf->DING_WEBHOOK);
|
||||
if (conf->PHONE)
|
||||
printf("%s\n", conf->PHONE);
|
||||
if (conf->DING_WEBHOOK)
|
||||
printf("%s\n", conf->DING_WEBHOOK);
|
||||
printf("%d\n", conf->IS_QQMAIL);
|
||||
printf("%s\n", conf->SEND_QQ);
|
||||
printf("%s\n", conf->QQMAIL_KEY);
|
||||
printf("%s\n", conf->RECV_MAIL);
|
||||
if (conf->SEND_QQ)
|
||||
printf("%s\n", conf->SEND_QQ);
|
||||
if (conf->QQMAIL_KEY)
|
||||
printf("%s\n", conf->QQMAIL_KEY);
|
||||
if (conf->RECV_MAIL)
|
||||
printf("%s\n", conf->RECV_MAIL);
|
||||
if (conf->PUBLIC_IP)
|
||||
printf("%s\n", conf->PUBLIC_IP);
|
||||
}
|
||||
|
15
conf.h
15
conf.h
@ -10,23 +10,26 @@
|
||||
typedef struct CONF {
|
||||
char *DAEMON;
|
||||
int TIME;
|
||||
|
||||
|
||||
int REFUSE_NUMBER;
|
||||
|
||||
// 获取公网IP Url地址
|
||||
char *PUBLIC_IP;
|
||||
|
||||
int IS_MAIL;
|
||||
|
||||
|
||||
int IS_DING_WEBHOOK;
|
||||
char *PHONE;
|
||||
char *DING_WEBHOOK;
|
||||
|
||||
|
||||
int IS_QQMAIL;
|
||||
char *SEND_QQ;
|
||||
char *QQMAIL_KEY;
|
||||
char *RECV_MAIL;
|
||||
} conf;
|
||||
|
||||
void read_conf(char *filename, conf *configure);
|
||||
void read_conf(char *filename, conf * configure);
|
||||
void free_conf(conf * conf);
|
||||
void ptintf_conf(conf *conf);
|
||||
void ptintf_conf(conf * conf);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -9,7 +9,7 @@
|
||||
source /etc/profile
|
||||
|
||||
function init() {
|
||||
SEND_MAIL=0
|
||||
SEND_MAIL=1
|
||||
PWD_PATH="/root";
|
||||
TIME=`date +"%Y%m%d%H%M"`;
|
||||
LOG_FILE="${PWD_PATH}/${TIME}.log";
|
||||
@ -28,7 +28,7 @@ function run()
|
||||
free -hl &>> ${LOG_FILE}
|
||||
|
||||
echo "System process:" &>> ${LOG_FILE}
|
||||
ps -auxwwjf &>> ${LOG_FILE}
|
||||
ps -auxwwf &>> ${LOG_FILE}
|
||||
|
||||
echo "Network Connections" &>> ${LOG_FILE}
|
||||
netstat -tnulp &>> ${LOG_FILE}
|
||||
|
39
libiptc.c
39
libiptc.c
@ -2,7 +2,7 @@
|
||||
|
||||
int x_get_rule(const char *chain, struct xtc_handle *handle, char *ipv4)
|
||||
{
|
||||
int r=1;
|
||||
int r = 1;
|
||||
const struct ipt_entry *entry;
|
||||
struct ipt_entry_match *entry_match;
|
||||
|
||||
@ -10,14 +10,13 @@ int x_get_rule(const char *chain, struct xtc_handle *handle, char *ipv4)
|
||||
const char *t = iptc_get_target(entry, handle);
|
||||
entry_match = (struct ipt_entry_match *)entry->elems;
|
||||
//printf("u.user.name: %s\n", entry_match->u.user.name);
|
||||
char addr[33];
|
||||
memset(addr, 0, 33);
|
||||
inet_ntop(AF_INET, &(entry->ip.dst), addr, sizeof(addr));
|
||||
char addr[64];
|
||||
memset(addr, 0, 64);
|
||||
inet_ntop(AF_INET, &(entry->ip.src), addr, sizeof(addr));
|
||||
//printf("%s\n", addr);
|
||||
//printf("%s\n", t);
|
||||
if (0 == strcmp(ipv4, addr) && 0 == strcmp(t, "DROP") && 0 == strcmp(entry_match->u.user.name, "tcp"))
|
||||
{
|
||||
r=0;
|
||||
if (0 == strcmp(ipv4, addr) && 0 == strcmp(t, "DROP") && 0 == strcmp(entry_match->u.user.name, "tcp")) {
|
||||
r = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -28,25 +27,24 @@ int x_get_rule(const char *chain, struct xtc_handle *handle, char *ipv4)
|
||||
|
||||
int show_all_rule(char *ipv4)
|
||||
{
|
||||
int r=0;
|
||||
int r = 0;
|
||||
struct xtc_handle *handle;
|
||||
const char *chain = NULL;
|
||||
struct ipt_counters counter;
|
||||
|
||||
|
||||
handle = iptc_init("filter");
|
||||
|
||||
for (chain = iptc_first_chain(handle); chain; chain = iptc_next_chain(handle))
|
||||
{
|
||||
for (chain = iptc_first_chain(handle); chain; chain = iptc_next_chain(handle)) {
|
||||
if (chain != NULL && handle != NULL) {
|
||||
iptc_get_policy(chain, &counter, handle);
|
||||
}
|
||||
|
||||
r = x_get_rule(chain, handle, ipv4);
|
||||
if (r==0){
|
||||
if (r == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -70,6 +68,7 @@ static void parse_ports(const char *portstring, u_int16_t * ports)
|
||||
ports[0] = buffer[0] ? parse_port(buffer) : 0;
|
||||
ports[1] = cp[0] ? parse_port(cp) : 0xFFFF;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
@ -82,7 +81,7 @@ struct ipt_entry_match *get_match(const char *sports, const char *dports, unsign
|
||||
size = IPT_ALIGN(sizeof(*match)) + IPT_ALIGN(sizeof(*udpinfo));
|
||||
match = (struct ipt_entry_match *)calloc(1, size);
|
||||
match->u.match_size = size;
|
||||
strncpy(match->u.user.name, protocol, IPT_FUNCTION_MAXNAMELEN-2);
|
||||
strncpy(match->u.user.name, protocol, IPT_FUNCTION_MAXNAMELEN - 2);
|
||||
|
||||
udpinfo = (struct ipt_udp *)match->data;
|
||||
udpinfo->spts[1] = udpinfo->dpts[1] = 0xFFFF;
|
||||
@ -99,8 +98,7 @@ struct ipt_entry_match *get_match(const char *sports, const char *dports, unsign
|
||||
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 ipt_entry *chain_entry;
|
||||
@ -137,7 +135,7 @@ int iptc_add_rule(const char *table, const char *chain, int protocol, const char
|
||||
size = IPT_ALIGN(sizeof(struct ipt_entry_target)) + IPT_ALIGN(sizeof(int));
|
||||
entry_target = (struct ipt_entry_target *)calloc(1, size);
|
||||
entry_target->u.user.target_size = size;
|
||||
strncpy(entry_target->u.user.name, target, IPT_FUNCTION_MAXNAMELEN);
|
||||
strncpy(entry_target->u.user.name, target, XT_EXTENSION_MAXNAMELEN);
|
||||
}
|
||||
if (entry_match) {
|
||||
match_size = entry_match->u.match_size;
|
||||
@ -149,14 +147,14 @@ int iptc_add_rule(const char *table, const char *chain, int protocol, const char
|
||||
if (chain_entry == NULL) {
|
||||
free(tmp_ipt);
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
printf("libiptc error: Can't initialize table %s, %s\n", table, iptc_strerror(errno));
|
||||
@ -200,11 +198,10 @@ int iptc_add_rule(const char *table, const char *chain, int protocol, const char
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (entry_match)
|
||||
free(entry_match);
|
||||
free(entry_target);
|
||||
free(chain_entry);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
/* Dest port. */
|
||||
#define NFC_IP_DST_PT 0x0400
|
||||
|
||||
|
||||
#ifndef IPT_MIN_ALIGN
|
||||
#define IPT_MIN_ALIGN (__alignof__(struct ipt_entry))
|
||||
#endif
|
||||
@ -30,9 +29,7 @@
|
||||
#define IPTC_TARGET_SIZE XT_ALIGN(sizeof(struct ipt_entry_target))
|
||||
#define IPTC_FULL_SIZE IPTC_ENTRY_SIZE + IPTC_MATCH_SIZE + IPTC_TARGET_SIZE
|
||||
|
||||
|
||||
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
|
||||
|
310
rhost.c
310
rhost.c
@ -1,11 +1,76 @@
|
||||
|
||||
#include "conf.h"
|
||||
#include "rhost.h"
|
||||
#include "libiptc.h"
|
||||
|
||||
|
||||
// 存储公网IP
|
||||
char public_ip[BUFFER];
|
||||
char *public_ip;
|
||||
|
||||
struct MemoryStruct {
|
||||
char *memory;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
|
||||
|
||||
// 注意这里根据每次被调用获得的数据重新动态分配缓存区的大小
|
||||
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
|
||||
if (ptr == NULL) {
|
||||
/* 内存不足! */
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem->memory = ptr;
|
||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
// 获取公网IP
|
||||
static char *GET_PUBLIC_IP(char *URL)
|
||||
{
|
||||
CURL *curl_handle;
|
||||
CURLcode res;
|
||||
|
||||
struct MemoryStruct chunk;
|
||||
|
||||
chunk.memory = malloc(1); /* 将根据上述再分配的需要增长 */
|
||||
chunk.size = 0; /* 此时没有数据 */
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* 初始化curl会话 */
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
/* 指定要获取的URL */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, URL);
|
||||
/* 将所有数据发送到此函数 */
|
||||
//对于同一次阻塞的curl_easy_perform而言,在写完获取的数据之前,会多次调用 WriteMemoryCallback
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
|
||||
/* 将“chunk”结构传递给回调函数 */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
|
||||
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
|
||||
//对于同一次阻塞的curl_easy_perform而言,在写完获取的数据之前,会多次调用 WriteMemoryCallback
|
||||
res = curl_easy_perform(curl_handle);
|
||||
|
||||
if (res != CURLE_OK) {
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
|
||||
} else {
|
||||
//printf("%lu bytes retrieved\n", (unsigned long)chunk.size);
|
||||
//printf("%s", chunk.memory);
|
||||
;
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl_handle);
|
||||
curl_global_cleanup();
|
||||
|
||||
return chunk.memory;
|
||||
}
|
||||
|
||||
// 检测系统
|
||||
int check_system()
|
||||
@ -19,74 +84,22 @@ int check_system()
|
||||
return UNKNOWN_SYSTEM;
|
||||
}
|
||||
|
||||
// 获取公网IP
|
||||
char *get_public_ip(char *ip)
|
||||
{
|
||||
FILE *fp;
|
||||
char buff[BUFFER];
|
||||
|
||||
memset(buff, 0, BUFFER);
|
||||
if (NULL == (fp = popen("curl members.3322.org/dyndns/getip --silent", "r"))) {
|
||||
perror("popen curl");
|
||||
}
|
||||
|
||||
while (fgets(buff, BUFFER, fp) != NULL) {
|
||||
buff[strlen(buff) - 1] = '\0';
|
||||
}
|
||||
|
||||
if (NULL != fp)
|
||||
pclose(fp);
|
||||
|
||||
return strcpy(ip, buff);
|
||||
}
|
||||
|
||||
// 替换字符串
|
||||
int strReplaceAll(char *str, char *sub, char *replace)
|
||||
{
|
||||
if (NULL == str || NULL == sub || NULL == replace) {
|
||||
printf("strReplaceAll\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *p = NULL;
|
||||
char *t = NULL;
|
||||
char *q = NULL;
|
||||
char *dst = NULL;
|
||||
char *src = NULL;
|
||||
|
||||
int str_len = strlen(str);
|
||||
int sub_len = strlen(sub);
|
||||
int replace_len = strlen(replace);
|
||||
|
||||
p = str;
|
||||
while ('\0' != *p) {
|
||||
t = str + str_len;
|
||||
q = strstr(str, sub);
|
||||
if (NULL == q) // 没有子串了直接返回
|
||||
break;
|
||||
|
||||
src = q + sub_len; // 源头, 原有sub后的一个字符
|
||||
dst = q + replace_len; // 目的,放完replace后的一个字符
|
||||
memcpy(dst, src, t - src); // 原有字符串后移,放出空间
|
||||
memcpy(q, replace, replace_len); // 将replace字符拷贝进来
|
||||
str_len = str_len + replace_len - sub_len;
|
||||
|
||||
p = q + replace_len; // p 下一轮replace后的一个字符
|
||||
}
|
||||
|
||||
str[str_len] = '\0'; // 通过'\0'表示结尾
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 钉钉告警
|
||||
int dingding_warning(char *illegal_ip, char *public_ip, conf *conf)
|
||||
int dingding_warning(char *illegal_ip, char *public_ip, conf * conf)
|
||||
{
|
||||
FILE *fp;
|
||||
if ((fp = fopen("libcurl_ding.log", "wt+")) == NULL){
|
||||
char temp[64];
|
||||
char jsonObj[BUFFER];
|
||||
|
||||
memset(jsonObj, 0, BUFFER);
|
||||
memset(temp, 0, 64);
|
||||
strcpy(temp, public_ip);
|
||||
temp[strlen(public_ip) - 1] = '\0';
|
||||
|
||||
if ((fp = fopen("libcurl_ding.log", "wt+")) == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
@ -95,22 +108,20 @@ int dingding_warning(char *illegal_ip, char *public_ip, conf *conf)
|
||||
if (curl == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
char jsonObj[BUFFER] = "{ \
|
||||
|
||||
#define JSIN "{ \
|
||||
\"msgtype\": \"text\", \
|
||||
\"text\": { \
|
||||
\"content\": \"Alert @PHONE 主机PUBLIC 非法主机IP被封禁! Warning!\" \
|
||||
\"content\": \"Alert @%s 服务器地址:%s,封禁非法入侵主机:%s\" \
|
||||
}, \
|
||||
\"at\": { \
|
||||
\"atMobiles\": [\"PHONE\"], \
|
||||
\"atMobiles\": [\"%s\"], \
|
||||
\"isAtAll\": false \
|
||||
} \
|
||||
}";
|
||||
}"
|
||||
|
||||
strReplaceAll(jsonObj, "IP", illegal_ip);
|
||||
strReplaceAll(jsonObj, "PHONE", conf->PHONE);
|
||||
strReplaceAll(jsonObj, "PUBLIC", public_ip);
|
||||
//printf("%s\n", jsonObj);
|
||||
sprintf(jsonObj, JSIN, conf->PHONE, temp, illegal_ip, conf->PHONE);
|
||||
printf("%s\n", jsonObj);
|
||||
|
||||
struct curl_slist *headers = NULL;
|
||||
headers = curl_slist_append(headers, "Accept: application/json");
|
||||
@ -125,28 +136,31 @@ int dingding_warning(char *illegal_ip, char *public_ip, conf *conf)
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonObj);
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl/0.1");
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
fclose(fp);
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// 邮件告警
|
||||
int mail_warning(char *illegal_ip, char *public_ip)
|
||||
int mail_warning(char *illegal_ip, char *public_ip, conf * conf)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
char buff[BUFFER];
|
||||
char text[BUFFER] = "echo \"主机:HOST, 禁止IP访问!\" |";
|
||||
char text[BUFFER];
|
||||
char temp[64];
|
||||
|
||||
memset(buff, 0, BUFFER);
|
||||
strReplaceAll(text, "IP", illegal_ip);
|
||||
strReplaceAll(text, "HOST", public_ip);
|
||||
memset(text, 0, BUFFER);
|
||||
memset(temp, 0, 64);
|
||||
|
||||
strcat(text, " mail -s \"System ban IP\" 1605227279@qq.com");
|
||||
strcpy(temp, public_ip);
|
||||
temp[strlen(public_ip) - 1] = '\0';
|
||||
sprintf(text, "echo \"主机:%s, 禁止%s访问\" | mail -s \"System ban IP\" %s", temp, illegal_ip, conf->RECV_MAIL);
|
||||
|
||||
if (NULL == (fp = popen(text, "r"))) {
|
||||
perror("popen text");
|
||||
@ -163,29 +177,30 @@ int mail_warning(char *illegal_ip, char *public_ip)
|
||||
}
|
||||
|
||||
// 第三方邮箱告警
|
||||
int QQ_mail_warning(char *illegal_ip, char *public_ip, conf *conf)
|
||||
int QQ_mail_warning(char *illegal_ip, char *public_ip, conf * conf)
|
||||
{
|
||||
|
||||
char string[BUFFER+(sizeof(QQMAIL))];
|
||||
char text[BUFFER] = "主机:HOST, 禁止IP访问";
|
||||
|
||||
strReplaceAll(text, "IP", illegal_ip);
|
||||
strReplaceAll(text, "HOST", public_ip);
|
||||
|
||||
memset(string, 0, BUFFER+(sizeof(QQMAIL)));
|
||||
|
||||
sprintf(string, QQMAIL, conf->SEND_QQ, conf->QQMAIL_KEY, conf->RECV_MAIL, text);
|
||||
|
||||
system(string);
|
||||
|
||||
return 0;
|
||||
char string[BUFFER + (sizeof(QQMAIL))];
|
||||
char text[BUFFER];
|
||||
char temp[32];
|
||||
|
||||
memset(string, 0, BUFFER + (sizeof(QQMAIL)));
|
||||
memset(text, 0, BUFFER);
|
||||
memset(temp, 0, 32);
|
||||
|
||||
strcpy(temp, public_ip);
|
||||
temp[strlen(public_ip) - 1] = '\0';
|
||||
|
||||
sprintf(text, "主机:%s, 禁止%s访问", temp, illegal_ip);
|
||||
sprintf(string, QQMAIL, conf->RECV_MAIL, text);
|
||||
|
||||
return system(string);
|
||||
}
|
||||
|
||||
// 封禁非法IP
|
||||
int rule(conf *conf)
|
||||
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))];
|
||||
char p[2], splice_command[LONG_BUFFER], command[LONG_BUFFER], *temp, buffer[BUFFER], awk[BUFFER];
|
||||
|
||||
@ -241,7 +256,7 @@ int rule(conf *conf)
|
||||
strcat(splice_command, "\n");
|
||||
}
|
||||
}
|
||||
printf("%s", splice_command); // 打印所有非法IP
|
||||
printf("%s", splice_command); // 打印所有非法IP
|
||||
|
||||
// 拼接命令
|
||||
sprintf(awk, AWK, conf->REFUSE_NUMBER);
|
||||
@ -250,54 +265,53 @@ int rule(conf *conf)
|
||||
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'; // 去除回车
|
||||
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) // 钉钉告警
|
||||
if (conf->IS_DING_WEBHOOK == 1) // 钉钉告警
|
||||
{
|
||||
dingding_warning(buffer, public_ip, conf);
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
if (conf->IS_MAIL == 1) // 邮件告警
|
||||
|
||||
if (conf->IS_MAIL == 1) // 邮件告警
|
||||
{
|
||||
mail_warning(buffer, public_ip);
|
||||
mail_warning(buffer, public_ip, conf);
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
if (conf->IS_QQMAIL == 1) // 邮件告警
|
||||
|
||||
if (conf->IS_QQMAIL == 1) // 邮件告警
|
||||
{
|
||||
QQ_mail_warning(buffer, public_ip, conf);
|
||||
sleep(3);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// 调用命令下发规则
|
||||
if ((fc = popen(iptables, "r")) == NULL) {
|
||||
perror("popen iptables");
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
|
||||
// 调用命令下发规则
|
||||
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 destIp;
|
||||
inet_pton(AF_INET, buffer, &destIp);
|
||||
iptc_add_rule("filter", "INPUT", IPPROTO_TCP, NULL, NULL, 0, destIp, NULL, NULL, "DROP", NULL, 1);
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -317,28 +331,49 @@ static void sig_child(int signo)
|
||||
int stat;
|
||||
// 处理僵尸进程
|
||||
while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) ;
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int get_executable_path(char *processdir, char *processname, int len)
|
||||
{
|
||||
char *filename;
|
||||
if (readlink("/proc/self/exe", processdir, len) <= 0)
|
||||
return -1;
|
||||
filename = strrchr(processdir, '/');
|
||||
if (filename == NULL)
|
||||
return -1;
|
||||
++filename;
|
||||
strcpy(processname, filename);
|
||||
*filename = '\0';
|
||||
return (int)(filename - processdir);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[], char **env)
|
||||
{
|
||||
conf *conf = (struct CONF *)malloc(sizeof(struct CONF));
|
||||
read_conf("rhost.conf", conf);
|
||||
//ptintf_conf(conf);
|
||||
char path[BUFFER] = { 0 };
|
||||
char executable_filename[BUFFER] = { 0 };
|
||||
(void)get_executable_path(path, executable_filename, sizeof(path));
|
||||
|
||||
memset(public_ip, 0, BUFFER);
|
||||
get_public_ip(public_ip);
|
||||
strcat(executable_filename, ".conf");
|
||||
strcat(path, executable_filename);
|
||||
|
||||
|
||||
conf *conf = (struct CONF *)malloc(sizeof(struct CONF));
|
||||
read_conf(path, conf);
|
||||
//ptintf_conf(conf);
|
||||
|
||||
// 新版本获取公网IP
|
||||
public_ip = GET_PUBLIC_IP(conf->PUBLIC_IP);
|
||||
//printf("%s", public_ip);
|
||||
|
||||
signal(SIGCHLD, sig_child); // 创建捕捉子进程退出信号
|
||||
|
||||
if (0 == strcmp(conf->DAEMON, "on"))
|
||||
{
|
||||
if (0 == strcmp(conf->DAEMON, "on")) {
|
||||
goto goto_daemon;
|
||||
}
|
||||
|
||||
if (argv[1] != NULL && 0 == strcmp(argv[1], "-d"))
|
||||
{
|
||||
if (argv[1] != NULL && 0 == strcmp(argv[1], "-d")) {
|
||||
goto_daemon:
|
||||
if (daemon(1, 1)) // 守护进程
|
||||
{
|
||||
@ -351,16 +386,13 @@ goto_daemon:
|
||||
|
||||
sleep(conf->TIME);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
rule(conf);
|
||||
}
|
||||
|
||||
|
||||
free_conf(conf);
|
||||
free(conf);
|
||||
|
||||
free(public_ip);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,9 @@ global {
|
||||
DAEMON = "off"; // on开启后台运行,off不开启
|
||||
TIME = "60"; // 睡眠时间
|
||||
|
||||
REFUSE_NUMBER = 5; // 拒绝攻击次数
|
||||
PUBLIC_IP = "http://inet-ip.info"; // 获取公网IP
|
||||
|
||||
REFUSE_NUMBER = 3; // 拒绝攻击次数
|
||||
|
||||
IS_MAIL = 0; // 开启邮件告警
|
||||
|
||||
@ -11,7 +13,5 @@ global {
|
||||
DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=7f069c672cb878987aa6772cca336740eece4ce36bde12b51b45e9f440e0565a"; // 钉钉WEBHOOK
|
||||
|
||||
IS_QQMAIL = 0; // 开启QQ邮箱告警
|
||||
SEND_QQ = "1605227279"; // 发送者QQ
|
||||
QQMAIL_KEY = "caczsjchvyibiabe"; // 发送者QQ密钥
|
||||
RECV_MAIL = "1605227279"; // 接收者QQ
|
||||
RECV_MAIL = "1605227279@qq.com"; // 接收者QQ
|
||||
}
|
||||
|
11
rhost.h
11
rhost.h
@ -13,7 +13,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#define CENTOS_SYSTEM 1
|
||||
#define DEBISN_SYSTEM 2
|
||||
#define UNKNOWN_SYSTEM 3
|
||||
@ -31,12 +30,10 @@
|
||||
#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 "qqMail -l smtp.qq.com -p 25 -f %s -e %s -q NIUYULING -r %s@QQ.COM -n NIUYULING -s \"System ban IP\" -t \"%s\""
|
||||
#define QQMAIL "email -r %s -s \"System ban IP\" -t \"%s\""
|
||||
|
||||
|
||||
extern void read_conf(char *filename, conf *configure);
|
||||
extern void read_conf(char *filename, conf * configure);
|
||||
extern void free_conf(conf * conf);
|
||||
extern void ptintf_conf(conf *conf);
|
||||
extern void ptintf_conf(conf * conf);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user