Golang编写的HTTP服务器如何防御DDoS攻击?
Golang编写的HTTP服务器如何防御DDoS攻击? 能否请您列出一些您已经应用过的策略或方法,来预防/保护/减少针对RESTful Web服务的DDOS攻击?
提前感谢。
将您的Go代码运行在类似NGINX的反向代理之后。这有助于防范DDOS攻击。
更多关于Golang编写的HTTP服务器如何防御DDoS攻击?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
虽然不是严格与DoS相关(我也不确定如何实现你的需求),但《如何在互联网上暴露Go服务》这篇文章提供了一些很好的建议。不过这篇文章已经发布一年多了,内容可能不是完全最新。
速率限制似乎是一种有效的方法,并且可以在中间件中轻松实现。Alex Edwards 有一篇关于如何限制 HTTP 请求速率的文章,我觉得很有用。当然,OWASP 始终是获取安全信息的绝佳资源。
在Go语言中,防御针对HTTP服务器的DDoS攻击需要结合多种策略,包括限流、连接管理、超时设置和中间件防护。以下是我在实际项目中应用的有效方法,附带示例代码。
1. 实现速率限制(Rate Limiting)
使用令牌桶算法限制每个客户端的请求频率,防止资源耗尽。Go标准库的golang.org/x/time/rate包非常适合此场景。
package main
import (
"net/http"
"golang.org/x/time/rate"
"sync"
)
// IPRateLimiter 结构存储每个IP的限流器
type IPRateLimiter struct {
ips map[string]*rate.Limiter
mu *sync.RWMutex
r rate.Limit
b int
}
// NewIPRateLimiter 初始化一个IPRateLimiter实例
func NewIPRateLimiter(r rate.Limit, b int) *IPRateLimiter {
return &IPRateLimiter{
ips: make(map[string]*rate.Limiter),
mu: &sync.RWMutex{},
r: r,
b: b,
}
}
// AddIP 为指定IP创建限流器
func (i *IPRateLimiter) AddIP(ip string) *rate.Limiter {
i.mu.Lock()
defer i.mu.Unlock()
limiter := rate.NewLimiter(i.r, i.b)
i.ips[ip] = limiter
return limiter
}
// GetLimiter 获取IP对应的限流器,不存在则创建
func (i *IPRateLimiter) GetLimiter(ip string) *rate.Limiter {
i.mu.RLock()
limiter, exists := i.ips[ip]
i.mu.RUnlock()
if !exists {
return i.AddIP(ip)
}
return limiter
}
// rateLimitMiddleware 限流中间件
func rateLimitMiddleware(next http.Handler) http.Handler {
limiter := NewIPRateLimiter(1, 5) // 每秒1个令牌,桶大小5
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ip := r.RemoteAddr
lim := limiter.GetLimiter(ip)
if !lim.Allow() {
http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests)
return
}
next.ServeHTTP(w, r)
})
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
// 应用限流中间件
http.ListenAndServe(":8080", rateLimitMiddleware(mux))
}
2. 设置连接超时和读写超时
在HTTP服务器配置中定义超时,防止慢速连接占用资源。
package main
import (
"net/http"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
time.Sleep(2 * time.Second) // 模拟处理延迟
w.Write([]byte("Hello, World!"))
})
server := &http.Server{
Addr: ":8080",
Handler: mux,
ReadTimeout: 5 * time.Second, // 读取请求超时
WriteTimeout: 10 * time.Second, // 写入响应超时
IdleTimeout: 15 * time.Second, // 空闲连接超时
}
server.ListenAndServe()
}
3. 使用反向代理和负载均衡器
在生产环境中,结合Nginx或HAProxy作为反向代理,提供额外的DDoS防护层,例如限制连接数和请求大小。以下是一个Nginx配置示例(非Go代码,但常与Go服务配合使用):
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
server {
listen 80;
location / {
limit_req zone=one burst=20 nodelay;
proxy_pass http://localhost:8080;
}
}
}
4. 实施IP黑名单/白名单
通过中间件过滤恶意IP地址。
package main
import (
"net/http"
"strings"
)
var blacklist = map[string]bool{
"192.168.1.100": true,
"10.0.0.5": true,
}
func ipFilterMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ip := strings.Split(r.RemoteAddr, ":")[0] // 提取IP部分
if blacklist[ip] {
http.Error(w, "Forbidden", http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
http.ListenAndServe(":8080", ipFilterMiddleware(mux))
}
5. 限制请求体大小
防止大请求体消耗内存。
package main
import (
"net/http"
)
func maxBodySizeMiddleware(next http.Handler, maxSize int64) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, maxSize)
next.ServeHTTP(w, r)
})
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
// 限制请求体最大为1MB
http.ListenAndServe(":8080", maxBodySizeMiddleware(mux, 1<<20))
}
这些方法结合使用,可以有效减轻DDoS攻击的影响。在实际部署中,建议监控服务指标并根据流量模式调整参数。

