ddos是分布式拒绝服务,是一种常见的网络攻击方式,如果被不坏好意的坏人盯上,我们该如何捍卫正当权益?
用一种哈希算法(算法不是博主发明的,是国外某个大神发明的。博主只是记得有这么个算法,然后也忘记了名字。 一个朋友今天下午请教我如何防止ddos攻击的事情,因为忘记了算法名字也不能搜索源码,就索性用代码实现一把。),可以实现一段时间内最多可登录一次,这样就能有效扛住普通的ddos攻击。
伪代码如下(博主并没有去make and test,需要的请自行去补全算法):
#include <iostream>
#define BUCKET_SIZE 1024
unsigned char tab1[BUCKET_SIZE];
unsigned char tab2[BUCKET_SIZE];
unsigned char tab3[BUCKET_SIZE];
unsigned int tab1_stamp[BUCKET_SIZE * 8];
unsigned int tab2_stamp[BUCKET_SIZE * 8];
unsigned int tab3_stamp[BUCKET_SIZE * 8];
unsigned int hash1(unsigned int id)
{
return __hash1(id);
}
unsigned int hash2(unsigned int id)
{
return __hash2(id);
}
unsigned int hash3(unsigned int id)
{
return __hash3(id);
}
/*
*函数功能:判断ip是否在10s内登录过?
*返回值: 3 一定没有来过
*/
int judeg(unsigned int ip)
{
auto count = 0;
auto index1 = (hash1(ip) % BUCKET_SIZE);
auto byte1 = (hash1(ip) % BUCKET_SIZE) / 8;
auto bit1 = (hash1(ip) % BUCKET_SIZE) % 8;
auto index2 = (hash2(ip) % BUCKET_SIZE);
auto byte2 = (hash2(ip) % BUCKET_SIZE) / 8;
auto bit2 = (hash2(ip) % BUCKET_SIZE) % 8;
auto index3 = (hash3(ip) % BUCKET_SIZE);
auto byte3 = (hash3(ip) % BUCKET_SIZE) / 8;
auto bit3 = (hash3(ip) % BUCKET_SIZE) % 8;
// 判断记录是否过期?
if (tab1_stamp[index1] + 10s < 当前时间戳) {
//过期,重置记录
tab1_stamp[index1] = 当前时间戳;
tab1[byte1] &= ~(1 << bit1);
}
if (tab2_stamp[index2] + 10s < 当前时间戳) {
//过期,重置记录
tab2_stamp[index2] = 当前时间戳;
tab2[byte2] &= ~(1 << bit2);
}
if (tab3_stamp[index3] + 10s < 当前时间戳) {
//过期,重置记录
tab3_stamp[index3] = 当前时间戳;
tab3[byte3] &= ~(1 << bit3);
}
if ( tab1[byte1] & (1 << bit1) == 0) {
count++;
}
if ( tab2[byte2] & (1 << bit2) == 0) {
count++;
}
if ( tab3[byte3] & (1 << bit3) == 0) {
count++;
}
-
return count;
}
// 刷新注册表
void update_tabls(unsigned int ip)
{
auto count = 0;
auto index1 = (hash1(ip) % BUCKET_SIZE);
auto byte1 = (hash1(ip) % BUCKET_SIZE) / 8;
auto bit1 = (hash1(ip) % BUCKET_SIZE) % 8;
auto index2 = (hash2(ip) % BUCKET_SIZE);
auto byte2 = (hash2(ip) % BUCKET_SIZE) / 8;
auto bit2 = (hash2(ip) % BUCKET_SIZE) % 8;
auto index3 = (hash3(ip) % BUCKET_SIZE);
auto byte3 = (hash3(ip) % BUCKET_SIZE) / 8;
auto bit3 = (hash3(ip) % BUCKET_SIZE) % 8;
tab1_stamp[index1] = 当前时间戳;
tab1[byte1] |= (1 << bit1);
tab2_stamp[index2] = 当前时间戳;
tab2[byte2] |= (1 << bit2);
tab3_stamp[index3] = 当前时间戳;
tab3[byte3] |= (1 << bit3);
}
/*
*ddos防守:适用于一般的ddos攻击。
把BUCKET_SIZE设置的比较大后,就可以降低误判率(对正常客户端的误判)。
把hash数量从3变成5,会加大计算量,但是可以降低误判率(对算法本身的误判。3 / 4 / 5视情况而定)
*/
int main(int agr, char **agrv)
{
unsigned int ip;
//ip = socket__xxx_();
// 如果等于3则一定没有来过
// 如果等于2则也有可能没有来过(其他客户端也撞到了这个记录)
// 这里的条件,大于一大半以上即可登录
if (3 == judeg(ip) || 2 == judeg(ip)) {
//没有来过,则让它登录;
update_tabls(ip);
}
else {
// 拒绝登录。ddos防守成功
}
}
补充一下,算法名字叫布隆滤波器