增加解除IP封禁的选项
This commit is contained in:
@@ -1,12 +1,18 @@
|
|||||||
#include "client_msg.h"
|
#include "client_msg.h"
|
||||||
|
|
||||||
void dispath_client_msg(struct client_msg_t* msg) {
|
void dispath_client_msg(struct client_msg_t* msg) {
|
||||||
|
uint32_t target_ip_address;
|
||||||
|
size_t block_time;
|
||||||
switch (msg->type) {
|
switch (msg->type) {
|
||||||
case SD_MSG_TYPE_CLIENT_BLOCK_IP:
|
case SD_MSG_TYPE_CLIENT_BLOCK_IP:
|
||||||
const size_t target_ip_address = msg->u.ip_address.src_ip;
|
target_ip_address = msg->u.ip_address.src_ip;
|
||||||
const size_t block_time = msg->u.ip_address.block_time;
|
block_time = msg->u.ip_address.block_time;
|
||||||
block_ip_address(target_ip_address, block_time);
|
block_ip_address(target_ip_address, block_time);
|
||||||
break;
|
break;
|
||||||
|
case SD_MSG_TYPE_CLIENT_UNBLOCK_IP:
|
||||||
|
target_ip_address = msg->u.ip_address.src_ip;
|
||||||
|
unblock_ip_address(target_ip_address);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printk(KERN_INFO "Unknown msg type: %d\n", msg->type);
|
printk(KERN_INFO "Unknown msg type: %d\n", msg->type);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ typedef enum _msg_type {
|
|||||||
SD_MSG_TYPE_SYN_ATTACK = 1,
|
SD_MSG_TYPE_SYN_ATTACK = 1,
|
||||||
SD_MSG_TYPE_CLIENT_BLOCK_IP = 2,
|
SD_MSG_TYPE_CLIENT_BLOCK_IP = 2,
|
||||||
SD_MSG_TYPE_SSH_BF_ATTACK = 3,
|
SD_MSG_TYPE_SSH_BF_ATTACK = 3,
|
||||||
|
SD_MSG_TYPE_CLIENT_UNBLOCK_IP = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct kernel_msg_t {
|
typedef struct kernel_msg_t {
|
||||||
|
|||||||
@@ -24,6 +24,13 @@ bool check_is_blacklist_ip(u32 ip_address) {
|
|||||||
}
|
}
|
||||||
return data->info.ip_meta_info.is_attack;
|
return data->info.ip_meta_info.is_attack;
|
||||||
}
|
}
|
||||||
|
void unblock_ip_address(u32 ip_address) {
|
||||||
|
struct ip_hashmap_node_t *data = get_ipdata_by_hashmap(ip_address);
|
||||||
|
if (data == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data->info.ip_meta_info.is_attack = false;
|
||||||
|
}
|
||||||
bool check_syn_attack(struct iphdr *ip_header, struct sk_buff *skb) {
|
bool check_syn_attack(struct iphdr *ip_header, struct sk_buff *skb) {
|
||||||
bool is_block = false;
|
bool is_block = false;
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -13,3 +13,4 @@ extern unsigned int network_callback(const struct nf_hook_ops *ops,
|
|||||||
int (*okfn)(struct sk_buff *));
|
int (*okfn)(struct sk_buff *));
|
||||||
extern void block_ip_address(u32 ip_address, size_t time_sec);
|
extern void block_ip_address(u32 ip_address, size_t time_sec);
|
||||||
extern bool check_is_blacklist_ip(u32 ip_address);
|
extern bool check_is_blacklist_ip(u32 ip_address);
|
||||||
|
extern void unblock_ip_address(u32 ip_address);
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <shared_mutex>
|
||||||
|
#include <ctime>
|
||||||
|
#include <mutex>
|
||||||
namespace network_event {
|
namespace network_event {
|
||||||
|
// read write lock
|
||||||
|
std::shared_mutex ip_blacklist_lock;
|
||||||
|
std::unordered_map<uint32_t, std::time_t> ip_blacklist_cache;
|
||||||
auto block_ip(uint32_t ip_address, size_t time_sec) -> bool {
|
auto block_ip(uint32_t ip_address, size_t time_sec) -> bool {
|
||||||
client_msg_t msg{0};
|
client_msg_t msg{0};
|
||||||
msg.check_sum = MSG_CHECK_SUM;
|
msg.check_sum = MSG_CHECK_SUM;
|
||||||
@@ -9,11 +15,40 @@ auto block_ip(uint32_t ip_address, size_t time_sec) -> bool {
|
|||||||
msg.u.ip_address.block_time = time_sec;
|
msg.u.ip_address.block_time = time_sec;
|
||||||
return client_msg::call_driver(msg);
|
return client_msg::call_driver(msg);
|
||||||
}
|
}
|
||||||
|
auto unblock_ip(uint32_t ip_address) -> bool {
|
||||||
|
client_msg_t msg{0};
|
||||||
|
msg.check_sum = MSG_CHECK_SUM;
|
||||||
|
msg.type = static_cast<int>(_msg_type::SD_MSG_TYPE_CLIENT_UNBLOCK_IP);
|
||||||
|
msg.u.ip_address.src_ip = ip_address;
|
||||||
|
return client_msg::call_driver(msg);
|
||||||
|
}
|
||||||
auto on_ip_connect(uint32_t ip_address) -> bool {
|
auto on_ip_connect(uint32_t ip_address) -> bool {
|
||||||
|
std::shared_lock lock(ip_blacklist_lock);
|
||||||
|
if (ip_blacklist_cache.find(ip_address) != ip_blacklist_cache.end()) {
|
||||||
|
const auto current_time = std::time(nullptr);
|
||||||
|
const auto block_time = ip_blacklist_cache[ip_address];
|
||||||
|
if (current_time - block_time < MAX_BLOCK_TIME) {
|
||||||
|
LOG("IP %s is in cache block list\n",
|
||||||
|
tools::cover_ip(ip_address).c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// cover lock to write lock, remove the ip from cache
|
||||||
|
lock.unlock();
|
||||||
|
std::unique_lock ulock(ip_blacklist_lock);
|
||||||
|
ip_blacklist_cache.erase(ip_address);
|
||||||
|
}
|
||||||
const auto is_still_in_block_list =
|
const auto is_still_in_block_list =
|
||||||
global::ip_blacklist_db->selectRecordByIpAndTime(ip_address,
|
global::ip_blacklist_db->selectRecordByIpAndTime(ip_address,
|
||||||
MAX_BLOCK_TIME);
|
MAX_BLOCK_TIME);
|
||||||
if (is_still_in_block_list) {
|
if (is_still_in_block_list) {
|
||||||
|
const auto block_time = is_still_in_block_list.value().time;
|
||||||
|
if (block_time != 0) {
|
||||||
|
lock.unlock();
|
||||||
|
std::unique_lock ulock(ip_blacklist_lock);
|
||||||
|
ip_blacklist_cache[ip_address] =
|
||||||
|
is_still_in_block_list.value().time;
|
||||||
|
}
|
||||||
|
|
||||||
LOG("IP %s is still in block list\n",
|
LOG("IP %s is still in block list\n",
|
||||||
tools::cover_ip(ip_address).c_str());
|
tools::cover_ip(ip_address).c_str());
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ auto IpBlacklistDB::deleteRecord(int id) -> void {
|
|||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if time == 0 , it means forever
|
||||||
auto IpBlacklistDB::selectRecordByIpAndTime(uint32_t ip, uint64_t time_second)
|
auto IpBlacklistDB::selectRecordByIpAndTime(uint32_t ip, uint64_t time_second)
|
||||||
-> std::optional<IpBlacklistRecord> {
|
-> std::optional<IpBlacklistRecord> {
|
||||||
std::vector<IpBlacklistRecord> records;
|
std::vector<IpBlacklistRecord> records;
|
||||||
@@ -109,7 +110,8 @@ auto IpBlacklistDB::selectRecordByIpAndTime(uint32_t ip, uint64_t time_second)
|
|||||||
// Adjusted SQL query to check if the timestamp is greater than or equal to
|
// Adjusted SQL query to check if the timestamp is greater than or equal to
|
||||||
// past_time
|
// past_time
|
||||||
const char *sql =
|
const char *sql =
|
||||||
"SELECT * FROM ip_black_table WHERE ip = ? AND time >= ?;";
|
"SELECT * FROM ip_black_table WHERE ip = ? AND (time >= ? OR time = "
|
||||||
|
"0);";
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ enum class _msg_type {
|
|||||||
SD_MSG_TYPE_SYN_ATTACK = 1,
|
SD_MSG_TYPE_SYN_ATTACK = 1,
|
||||||
SD_MSG_TYPE_CLIENT_BLOCK_IP = 2,
|
SD_MSG_TYPE_CLIENT_BLOCK_IP = 2,
|
||||||
SD_MSG_TYPE_SSH_BF_ATTACK = 3,
|
SD_MSG_TYPE_SSH_BF_ATTACK = 3,
|
||||||
|
SD_MSG_TYPE_CLIENT_UNBLOCK_IP = 4,
|
||||||
};
|
};
|
||||||
typedef struct kernel_msg_t {
|
typedef struct kernel_msg_t {
|
||||||
unsigned long check_sum;
|
unsigned long check_sum;
|
||||||
|
|||||||
Reference in New Issue
Block a user