This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
## 特性
|
||||
|
||||
- **PAM集成**:自动监控SSH登录失败尝试
|
||||
- **连接限速**:防御TCP洪水攻击(每IP每分钟最多20次SSH新连接)
|
||||
- **双栈支持**:完整支持IPv4/IPv6和CIDR网段
|
||||
- **智能聚合**:自动检测并聚合为更大网段,减少规则数量
|
||||
- **白名单保护**:白名单规则优先级高于黑名单,保护信任IP
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
@@ -76,4 +76,7 @@ int get_max_retries_from_config(void);
|
||||
/* 保存最大重试次数到配置文件 */
|
||||
int save_max_retries_to_config(int max_retries);
|
||||
|
||||
/* 获取SSH端口 */
|
||||
int get_ssh_port(void);
|
||||
|
||||
#endif /* COMMON_H */
|
||||
|
||||
@@ -199,3 +199,59 @@ int save_max_retries_to_config(int max_retries) {
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int get_ssh_port(void) {
|
||||
int port = 22; /* 默认SSH端口 */
|
||||
char line[MAX_LINE_LEN];
|
||||
FILE *fp = NULL;
|
||||
|
||||
/* 方法1: ss 匹配ssh相关进程 */
|
||||
fp = popen("ss -tlnp 2>/dev/null | grep -E 'sshd|dropbear' | awk '{print $4}' | head -1", "r");
|
||||
if (fp) {
|
||||
if (fgets(line, sizeof(line), fp)) {
|
||||
char *colon = strrchr(line, ':');
|
||||
if (colon) {
|
||||
int p = atoi(colon + 1);
|
||||
if (p > 0 && p < 65536) {
|
||||
pclose(fp);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
|
||||
/* 方法2: netstat 匹配ssh相关进程 */
|
||||
fp = popen("netstat -tlnp 2>/dev/null | grep -E 'sshd|dropbear' | awk '{print $4}' | head -1", "r");
|
||||
if (fp) {
|
||||
if (fgets(line, sizeof(line), fp)) {
|
||||
char *colon = strrchr(line, ':');
|
||||
if (colon) {
|
||||
int p = atoi(colon + 1);
|
||||
if (p > 0 && p < 65536) {
|
||||
pclose(fp);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
|
||||
/* 方法3: lsof 匹配ssh相关进程 */
|
||||
fp = popen("lsof -iTCP -sTCP:LISTEN -P -n 2>/dev/null | grep -E 'sshd|dropbear' | awk '{print $9}' | head -1", "r");
|
||||
if (fp) {
|
||||
if (fgets(line, sizeof(line), fp)) {
|
||||
char *colon = strrchr(line, ':');
|
||||
if (colon) {
|
||||
int p = atoi(colon + 1);
|
||||
if (p > 0 && p < 65536) {
|
||||
pclose(fp);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
pclose(fp);
|
||||
}
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
@@ -95,6 +95,15 @@ int init_nftables_rules(void) {
|
||||
NFT_TABLE, NFT_WHITELIST, NFT_TABLE, NFT_WHITELIST);
|
||||
system(command);
|
||||
|
||||
/* 1b. SSH连接速率限制(每IP每分钟最多20次新连接,防止TCP洪水) */
|
||||
int ssh_port = get_ssh_port();
|
||||
snprintf(command, sizeof(command),
|
||||
"nft list chain %s input | grep -q 'limit rate' || "
|
||||
"nft add rule %s input tcp dport %d ct state new "
|
||||
"meter ssh-ratelimit '{ ip saddr limit rate over 20/minute burst 5 packets }' drop",
|
||||
NFT_TABLE, NFT_TABLE, ssh_port);
|
||||
system(command);
|
||||
|
||||
/* 2. IPv6白名单 accept */
|
||||
snprintf(command, sizeof(command),
|
||||
"nft list chain %s input | grep -q '@%s' || nft add rule %s input ip6 saddr @%s accept",
|
||||
|
||||
Reference in New Issue
Block a user