笔者自己开发了一个脚本防范ssh攻击(代码附在下面)请尊重原创
在麒麟操作系统上,保护服务器免受SSH暴力攻击是至关重要的。通过编写一个简单的脚本,我们可以有效地阻止这种类型的攻击。接下来,我将向您展示如何在麒麟操作系统上创建和运行这样一个防御脚本。
步骤:
1. 安装gcc编辑器
首先,您需要安装gcc编辑器。您可以使用以下命令通过yum安装gcc:
yum install gcc
2. 创建一个简单的C语言示例代码
使用vi编辑器创建一个名为example.c的C语言源文件。您可以使用以下命令:
vi example.c
保存并退出编辑器(按Esc,然后输入“:wq”)。
3. 编译C代码
现在,使用gcc编译器将example.c源文件编译成一个可执行文件。在终端中运行以下命令:
gcc -o example example.c -pthread
4. 运行脚本
最后,运行生成的可执行文件以执行脚本。使用以下命令:
./example
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#define MAX_FAILED_ATTEMPTS 5 // 最大尝试失败次数
#define BLACKLIST_THRESHOLD 100 // 加入黑名单的阈值
#define LOG_FILE "/var/log/secure" // 系统登录日志文件
#define IPTABLES_CMD "iptables -A INPUT -s %s -j DROP" // 添加防火墙黑名单规则
#define LOG_PATH "/var/log/ssh_brute_force_detector.log" // 自定义日志文件路径
#define HASH_TABLE_SIZE 1024 // 哈希表大小
#define LOCK_FILE "/var/run/ssh_brute_force_detector.lock" // 锁文件路径
typedef struct {
char ip[20];
int failedAttempts;
} IPEntry;
IPEntry hashTable[HASH_TABLE_SIZE];
pthread_mutex_t hashTableLock = PTHREAD_MUTEX_INITIALIZER;
int configMaxFailedAttempts = MAX_FAILED_ATTEMPTS;
//int configBlacklistThreshold = BLACKLIST_THRESHOLD;
// 更新系统配置
void updateConfig() {
printf("更新系统配置:\n");
printf("最大尝试失败次数 (default %d): ", configMaxFailedAttempts);
scanf("%d", &configMaxFailedAttempts);
}
// 改进的哈希函数,采用MurmurHash算法
unsigned int hashFunction(char *ip) {
const unsigned int m = 0x5bd1e995;
const int r = 24;
unsigned int len = strlen(ip);
unsigned int seed = 0xdeadbeef;
unsigned int h = seed ^ len;
const unsigned char *data = (const unsigned char *)ip;
while (len >= 4) {
unsigned int k = *(unsigned int *)data;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
data += 4;
len -= 4;
}
switch (len) {
case 3:
h ^= data[2] << 16;
case 2:
h ^= data[1] << 8;
case 1:
h ^= data[0];
h *= m;
}
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h % HASH_TABLE_SIZE;
}
// 更新IP条目及失败尝试次数,双重散列法处理哈希冲突
void updateIPEntry(char *ip, int increment) {
pthread_mutex_lock(&hashTableLock);
unsigned int index = hashFunction(ip);
int start = index;
while (strlen(hashTable[index].ip) > 0 && strcmp(hashTable[index].ip, ip) != 0) {
index = (index + 1 + start) % HASH_TABLE_SIZE;
if (index == start) {
pthread_mutex_unlock(&hashTableLock);
return; // 哈希表已满,无法插入
}
}
if (strcmp(hashTable[index].ip, ip) == 0) {
hashTable[index].failedAttempts += increment;
} else {
strcpy(hashTable[index].ip, ip);
hashTable[index].failedAttempts = increment;
}
pthread_mutex_unlock(&hashTableLock);
}
if (strcmp(hashTable[index].ip, ip) == 0) {
hashTable[index].failedAttempts += increment;
} else {
strcpy(hashTable[index].ip, ip);
hashTable[index].failedAttempts = increment;
}
pthread_mutex_unlock(&hashTableLock);
}
// 封锁IP地址
void blockIP(char *ip) {
char command[100];
snprintf(command, sizeof(command), IPTABLES_CMD, ip);
if (system(command) != 0) {
openlog("ssh_brute_force_detector", LOG_CONS | LOG_PID, LOG_DAEMON);
syslog(LOG_ERR, "Failed to block IP %s", ip);
closelog();
fprintf(stderr, "Failed to block IP %s: %s\n", ip, strerror(errno));
} else {
openlog("ssh_brute_force_detector", LOG_CONS | LOG_PID, LOG_DAEMON);
syslog(LOG_INFO, "Blocked IP %s", ip);
closelog();
fprintf(stdout, "Blocked IP %s\n", ip);
}
}
// 监控哈希表并封锁IP地址
void* monitorHashTable(void *arg) {
int logfd = open(LOG_PATH, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (logfd == -1) {
fprintf(stderr, "Error opening log file: %s (%s)\n", LOG_PATH, strerror(errno));
return NULL;
}
while (1) {
sleep(60); // 每分钟检查一次
pthread_mutex_lock(&hashTableLock);
for (int i = 0; i < HASH_TABLE_SIZE; i++) {
if (strlen(hashTable[i].ip) > 0 && hashTable[i].failedAttempts >= BLACKLIST_THRESHOLD) {
char logMsg[200];
snprintf(logMsg, sizeof(logMsg), "Reached blacklist threshold for IP %s", hashTable[i].ip);
if (dprintf(logfd, "[%ld] %s\n", time(NULL), logMsg) < 0) {
fprintf(stderr, "Error writing to log file: %s\n", strerror(errno));
}
fprintf(stdout, "%s\n", logMsg);
blockIP(hashTable[i].ip);
hashTable[i].ip[0] = '\0';
}
}
pthread_mutex_unlock(&hashTableLock);
}
if (close(logfd) == -1) {
fprintf(stderr, "Error closing log file: %s\n", strerror(errno));
}
return NULL;
}
void createLockFile() {
int fd = open(LOCK_FILE, O_CREAT | O_EXCL | O_RDWR, 0600);
if (fd == -1) {
fprintf(stderr, "Failed to create lock file: %s (%s)\n", LOCK_FILE, strerror(errno));
exit(1);
}
close(fd);
}
void removeLockFile() {
if (remove(LOCK_FILE) != 0) {
fprintf(stderr, "Failed to remove lock file: %s (%s)\n", LOCK_FILE, strerror(errno));
}
}
void signalHandler(int signal) {
if (signal == SIGINT || signal == SIGTERM) {
removeLockFile();
exit(0);
}
}
int main() {
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
createLockFile(); // 创建锁文件
FILE *authLog;
char logLine[100];
char ip[20];
pthread_t monitorThread;
if (pthread_create(&monitorThread, NULL, monitorHashTable, NULL) != 0) {
fprintf(stderr, "Failed to create monitor thread.\n");
removeLockFile();
return 1; // 返回失败
}
authLog = fopen(LOG_FILE, "r");
if (authLog == NULL) {
fprintf(stderr, "Error opening log file: %s (%s)\n", LOG_FILE, strerror(errno));
removeLockFile();
return 1; // 返回失败
}
while (fgets(logLine, sizeof(logLine), authLog) != NULL) {
if (strstr(logLine, "Failed password for") != NULL) {
if (sscanf(strstr(logLine, "from ") + 5, "%s", ip) == 1) {
updateIPEntry(ip, 1);
}
}
}
if (fclose(authLog) != 0) {
fprintf(stderr, "Error closing log file: %s\n", strerror(errno));
}
pthread_join(monitorThread, NULL);
// 释放资源
pthread_mutex_destroy(&hashTableLock);
removeLockFile(); // 删除锁文件
printf("运行成功\n"); // 输出成功信息
return 0; // 返回成功
}