不在使用curl命令获取公网IP

This commit is contained in:
aixiao 2022-09-29 13:45:29 +08:00
parent a7ff1174c0
commit 5bf87613f1
6 changed files with 119 additions and 95 deletions

View File

@ -1,6 +1,6 @@
CROSS_COMPILE ?= CROSS_COMPILE ?=
CC := $(CROSS_COMPILE)gcc CC := $(CROSS_COMPILE)gcc
CFLAGS += -O2 -g -Wall CFLAGS += -Os -g -Wall
LIB += -lcurl -lip4tc LIB += -lcurl -lip4tc
OBG = rhost OBG = rhost

View File

@ -45,8 +45,6 @@ global {
DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=7f069c672cb878987aa6772cca336740eece4ce36bde12b51b45e9f440e0565a"; // 钉钉WEBHOOK DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=7f069c672cb878987aa6772cca336740eece4ce36bde12b51b45e9f440e0565a"; // 钉钉WEBHOOK
IS_QQMAIL = 0; // 开启QQ邮箱告警0关闭1开启 IS_QQMAIL = 0; // 开启QQ邮箱告警0关闭1开启
SEND_QQ = "1605227279"; // 发送者QQ
QQMAIL_KEY = "caczsjchvyibiabe"; // 发送者QQ密钥
RECV_MAIL = "1605227279"; // 接收者QQ RECV_MAIL = "1605227279"; // 接收者QQ
} }
``` ```

View File

@ -137,7 +137,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)); 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);
entry_target->u.user.target_size = 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) { if (entry_match) {
match_size = entry_match->u.match_size; match_size = entry_match->u.match_size;

198
rhost.c
View File

@ -1,11 +1,76 @@
#include "conf.h" #include "conf.h"
#include "rhost.h" #include "rhost.h"
#include "libiptc.h" #include "libiptc.h"
// 存储公网IP // 存储公网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() int check_system()
@ -19,70 +84,19 @@ int check_system()
return UNKNOWN_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; FILE *fp;
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){ if ((fp = fopen("libcurl_ding.log", "wt+")) == NULL){
return 1; return 1;
} }
@ -95,22 +109,20 @@ int dingding_warning(char *illegal_ip, char *public_ip, conf *conf)
if (curl == NULL) { if (curl == NULL) {
return 1; return 1;
} }
char jsonObj[BUFFER] = "{ \ #define JSIN "{ \
\"msgtype\": \"text\", \ \"msgtype\": \"text\", \
\"text\": { \ \"text\": { \
\"content\": \"Alert @PHONE 主机PUBLIC 非法主机IP被封禁 Warning!\" \ \"content\": \"Alert @%s 服务器地址:%s封禁非法入侵主机:%s\" \
}, \ }, \
\"at\": { \ \"at\": { \
\"atMobiles\": [\"PHONE\"], \ \"atMobiles\": [\"%s\"], \
\"isAtAll\": false \ \"isAtAll\": false \
} \ } \
}"; }"
strReplaceAll(jsonObj, "IP", illegal_ip); sprintf(jsonObj, JSIN, conf->PHONE, temp, illegal_ip, conf->PHONE);
strReplaceAll(jsonObj, "PHONE", conf->PHONE); printf("%s\n", jsonObj);
strReplaceAll(jsonObj, "PUBLIC", public_ip);
//printf("%s\n", jsonObj);
struct curl_slist *headers = NULL; struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: application/json"); headers = curl_slist_append(headers, "Accept: application/json");
@ -140,12 +152,18 @@ int mail_warning(char *illegal_ip, char *public_ip)
{ {
FILE *fp = NULL; FILE *fp = NULL;
char buff[BUFFER]; char buff[BUFFER];
char text[BUFFER] = "echo \"主机:HOST, 禁止IP访问!\" |"; char text[BUFFER];
char temp[64];
memset(buff, 0, BUFFER); memset(buff, 0, BUFFER);
strReplaceAll(text, "IP", illegal_ip); memset(text, 0, BUFFER);
strReplaceAll(text, "HOST", public_ip); memset(temp, 0, 64);
strcpy(temp, public_ip);
temp[strlen(public_ip)-1] = '\0';
sprintf(text, "主机:%s, 禁止%s访问", temp, illegal_ip);
strcat(text, " mail -s \"System ban IP\" 1605227279@qq.com"); strcat(text, " mail -s \"System ban IP\" 1605227279@qq.com");
if (NULL == (fp = popen(text, "r"))) { if (NULL == (fp = popen(text, "r"))) {
@ -165,17 +183,22 @@ 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 string[BUFFER+(sizeof(QQMAIL))];
char text[BUFFER] = "主机:HOST, 禁止IP访问"; char text[BUFFER];
char temp[32];
strReplaceAll(text, "IP", illegal_ip);
strReplaceAll(text, "HOST", public_ip);
memset(string, 0, BUFFER+(sizeof(QQMAIL))); memset(string, 0, BUFFER+(sizeof(QQMAIL)));
memset(text, 0, BUFFER);
memset(temp, 0, 32);
sprintf(string, QQMAIL, conf->SEND_QQ, conf->QQMAIL_KEY, conf->RECV_MAIL, text);
strcpy(temp, public_ip);
temp[strlen(public_ip)-1] = '\0';
sprintf(text, "主机:%s, 禁止%s访问", temp, illegal_ip);
sprintf(string, QQMAIL, conf->RECV_MAIL, text);
printf("%s\n", string);
system(string); system(string);
return 0; return 0;
@ -327,8 +350,12 @@ int main(int argc, char *argv[], char **env)
read_conf("rhost.conf", conf); read_conf("rhost.conf", conf);
//ptintf_conf(conf); //ptintf_conf(conf);
memset(public_ip, 0, BUFFER);
get_public_ip(public_ip); // 新版本获取公网IP
public_ip = GET_PUBLIC_IP("http://ip.sb");
//printf("%s", public_ip);
signal(SIGCHLD, sig_child); // 创建捕捉子进程退出信号 signal(SIGCHLD, sig_child); // 创建捕捉子进程退出信号
@ -360,6 +387,7 @@ goto_daemon:
free_conf(conf); free_conf(conf);
free(conf); free(conf);
free(public_ip);
return 0; return 0;
} }

View File

@ -2,7 +2,7 @@ global {
DAEMON = "off"; // on开启后台运行off不开启 DAEMON = "off"; // on开启后台运行off不开启
TIME = "60"; // 睡眠时间 TIME = "60"; // 睡眠时间
REFUSE_NUMBER = 5; // 拒绝攻击次数 REFUSE_NUMBER = 3; // 拒绝攻击次数
IS_MAIL = 0; // 开启邮件告警 IS_MAIL = 0; // 开启邮件告警
@ -10,8 +10,6 @@ global {
PHONE = "15565979082"; // @的人手机号 PHONE = "15565979082"; // @的人手机号
DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=7f069c672cb878987aa6772cca336740eece4ce36bde12b51b45e9f440e0565a"; // 钉钉WEBHOOK DING_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=7f069c672cb878987aa6772cca336740eece4ce36bde12b51b45e9f440e0565a"; // 钉钉WEBHOOK
IS_QQMAIL = 0; // 开启QQ邮箱告警 IS_QQMAIL = 1; // 开启QQ邮箱告警
SEND_QQ = "1605227279"; // 发送者QQ RECV_MAIL = "1605227279@qq.com"; // 接收者QQ
QQMAIL_KEY = "caczsjchvyibiabe"; // 发送者QQ密钥
RECV_MAIL = "1605227279"; // 接收者QQ
} }

View File

@ -31,7 +31,7 @@
#define IPTABLES "`which iptables` -t filter -I INPUT -s %s -j DROP" #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 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);