DDoS防护增加秒级连接速率限制

This commit is contained in:
刘祥超
2022-08-31 10:00:38 +08:00
parent 8bba228745
commit 64e0ae80b7
2 changed files with 60 additions and 38 deletions

View File

@@ -195,29 +195,30 @@ func (this *DDoSProtectionManager) addTCPRules(tcpConfig *ddosconfigs.TCPConfig)
} }
} }
// new connections rate // new connections rate (minutely)
var newConnectionsRate = tcpConfig.NewConnectionsRate var newConnectionsMinutelyRate = tcpConfig.NewConnectionsMinutelyRate
if newConnectionsRate <= 0 { if newConnectionsMinutelyRate <= 0 {
newConnectionsRate = nodeconfigs.DefaultTCPNewConnectionsRate newConnectionsMinutelyRate = nodeconfigs.DefaultTCPNewConnectionsMinutelyRate
if newConnectionsRate <= 0 { if newConnectionsMinutelyRate <= 0 {
newConnectionsRate = 100000 newConnectionsMinutelyRate = 100000
} }
} }
var newConnectionsMinutelyRateBlockTimeout = tcpConfig.NewConnectionsMinutelyRateBlockTimeout
if newConnectionsMinutelyRateBlockTimeout < 0 {
newConnectionsMinutelyRateBlockTimeout = 0
}
// deny new connections rate // new connections rate (secondly)
var denyNewConnectionsRate = tcpConfig.DenyNewConnectionsRate var newConnectionsSecondlyRate = tcpConfig.NewConnectionsSecondlyRate
var denyNewConnectionsRateTimeout = tcpConfig.DenyNewConnectionsRateTimeout if newConnectionsSecondlyRate <= 0 {
if denyNewConnectionsRate <= 0 { newConnectionsSecondlyRate = nodeconfigs.DefaultTCPNewConnectionsSecondlyRate
denyNewConnectionsRate = nodeconfigs.DefaultTCPDenyNewConnectionsRate if newConnectionsSecondlyRate <= 0 {
if denyNewConnectionsRate <= 0 { newConnectionsSecondlyRate = 10000
denyNewConnectionsRate = 100000
} }
} }
if denyNewConnectionsRateTimeout <= 0 { var newConnectionsSecondlyRateBlockTimeout = tcpConfig.NewConnectionsSecondlyRateBlockTimeout
denyNewConnectionsRateTimeout = nodeconfigs.DefaultTCPDenyNewConnectionsRateTimeout if newConnectionsSecondlyRateBlockTimeout < 0 {
if denyNewConnectionsRateTimeout <= 0 { newConnectionsSecondlyRateBlockTimeout = 0
denyNewConnectionsRateTimeout = 1800
}
} }
// 检查是否有变化 // 检查是否有变化
@@ -231,11 +232,11 @@ func (this *DDoSProtectionManager) addTCPRules(tcpConfig *ddosconfigs.TCPConfig)
hasChanges = true hasChanges = true
break break
} }
if !this.existsRule(oldRules, []string{"tcp", types.String(port), "newConnectionsRate", types.String(newConnectionsRate)}) { if !this.existsRule(oldRules, []string{"tcp", types.String(port), "newConnectionsRate", types.String(newConnectionsMinutelyRate), types.String(newConnectionsMinutelyRateBlockTimeout)}) {
hasChanges = true hasChanges = true
break break
} }
if !this.existsRule(oldRules, []string{"tcp", types.String(port), "denyNewConnectionsRate", types.String(denyNewConnectionsRate), types.String(denyNewConnectionsRateTimeout)}) { if !this.existsRule(oldRules, []string{"tcp", types.String(port), "newConnectionsSecondlyRate", types.String(newConnectionsSecondlyRate), types.String(newConnectionsSecondlyRateBlockTimeout)}) {
hasChanges = true hasChanges = true
break break
} }
@@ -282,27 +283,48 @@ func (this *DDoSProtectionManager) addTCPRules(tcpConfig *ddosconfigs.TCPConfig)
} }
} }
// 超过一定速率就drop // 超过一定速率就drop或者加入黑名单(分钟)
// TODO 让用户选择是drop还是reject // TODO 让用户选择是drop还是reject
if newConnectionsRate > 0 { if newConnectionsMinutelyRate > 0 {
var cmd = exec.Command(this.nftPath, "add", "rule", protocol, filter.Name, nftablesChainName, "tcp", "dport", types.String(port), "ct", "state", "new", "meter", "meter-"+protocol+"-"+types.String(port)+"-new-connections-rate", "{ "+protocol+" saddr limit rate over "+types.String(newConnectionsRate)+"/minute burst "+types.String(newConnectionsRate+3)+" packets }" /**"add", "@deny_set", "{"+protocol+" saddr}",**/, "counter", "drop", "comment", this.encodeUserData([]string{"tcp", types.String(port), "newConnectionsRate", types.String(newConnectionsRate)})) if newConnectionsMinutelyRateBlockTimeout > 0 {
var cmd = exec.Command(this.nftPath, "add", "rule", protocol, filter.Name, nftablesChainName, "tcp", "dport", types.String(port), "ct", "state", "new", "meter", "meter-"+protocol+"-"+types.String(port)+"-new-connections-rate", "{ "+protocol+" saddr limit rate over "+types.String(newConnectionsMinutelyRate)+"/minute burst "+types.String(newConnectionsMinutelyRate+3)+" packets }", "add", "@deny_set", "{"+protocol+" saddr timeout "+types.String(newConnectionsMinutelyRateBlockTimeout)+"s}", "comment", this.encodeUserData([]string{"tcp", types.String(port), "newConnectionsRate", types.String(newConnectionsMinutelyRate), types.String(newConnectionsMinutelyRateBlockTimeout)}))
var stderr = &bytes.Buffer{} var stderr = &bytes.Buffer{}
cmd.Stderr = stderr cmd.Stderr = stderr
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
return errors.New("add nftables rule '" + cmd.String() + "' failed: " + err.Error() + " (" + stderr.String() + ")") return errors.New("add nftables rule '" + cmd.String() + "' failed: " + err.Error() + " (" + stderr.String() + ")")
} }
} else {
var cmd = exec.Command(this.nftPath, "add", "rule", protocol, filter.Name, nftablesChainName, "tcp", "dport", types.String(port), "ct", "state", "new", "meter", "meter-"+protocol+"-"+types.String(port)+"-new-connections-rate", "{ "+protocol+" saddr limit rate over "+types.String(newConnectionsMinutelyRate)+"/minute burst "+types.String(newConnectionsMinutelyRate+3)+" packets }" /**"add", "@deny_set", "{"+protocol+" saddr}",**/, "counter", "drop", "comment", this.encodeUserData([]string{"tcp", types.String(port), "newConnectionsRate", "0"}))
var stderr = &bytes.Buffer{}
cmd.Stderr = stderr
err := cmd.Run()
if err != nil {
return errors.New("add nftables rule '" + cmd.String() + "' failed: " + err.Error() + " (" + stderr.String() + ")")
}
}
} }
// 超过一定速率就自动加入黑名单 // 超过一定速率就drop或者加入黑名单(秒)
if denyNewConnectionsRate > 0 { // TODO 让用户选择是drop还是reject
var cmd = exec.Command(this.nftPath, "add", "rule", protocol, filter.Name, nftablesChainName, "tcp", "dport", types.String(port), "ct", "state", "new", "meter", "meter-"+protocol+"-"+types.String(port)+"-deny-new-connections-rate", "{ "+protocol+" saddr limit rate over "+types.String(denyNewConnectionsRate)+"/minute burst "+types.String(denyNewConnectionsRate+3)+" packets }", "add", "@deny_set", "{"+protocol+" saddr timeout "+types.String(denyNewConnectionsRateTimeout)+"s}", "comment", this.encodeUserData([]string{"tcp", types.String(port), "denyNewConnectionsRate", types.String(denyNewConnectionsRate), types.String(denyNewConnectionsRateTimeout)})) if newConnectionsSecondlyRate > 0 {
if newConnectionsSecondlyRateBlockTimeout > 0 {
var cmd = exec.Command(this.nftPath, "add", "rule", protocol, filter.Name, nftablesChainName, "tcp", "dport", types.String(port), "ct", "state", "new", "meter", "meter-"+protocol+"-"+types.String(port)+"-new-connections-secondly-rate", "{ "+protocol+" saddr limit rate over "+types.String(newConnectionsSecondlyRate)+"/second burst "+types.String(newConnectionsSecondlyRate+3)+" packets }", "add", "@deny_set", "{"+protocol+" saddr timeout "+types.String(newConnectionsSecondlyRateBlockTimeout)+"s}", "comment", this.encodeUserData([]string{"tcp", types.String(port), "newConnectionsSecondlyRate", types.String(newConnectionsSecondlyRate), types.String(newConnectionsSecondlyRateBlockTimeout)}))
var stderr = &bytes.Buffer{} var stderr = &bytes.Buffer{}
cmd.Stderr = stderr cmd.Stderr = stderr
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
return errors.New("add nftables rule '" + cmd.String() + "' failed: " + err.Error() + " (" + stderr.String() + ")") return errors.New("add nftables rule '" + cmd.String() + "' failed: " + err.Error() + " (" + stderr.String() + ")")
} }
} else {
var cmd = exec.Command(this.nftPath, "add", "rule", protocol, filter.Name, nftablesChainName, "tcp", "dport", types.String(port), "ct", "state", "new", "meter", "meter-"+protocol+"-"+types.String(port)+"-new-connections-secondly-rate", "{ "+protocol+" saddr limit rate over "+types.String(newConnectionsSecondlyRate)+"/second burst "+types.String(newConnectionsSecondlyRate+3)+" packets }" /**"add", "@deny_set", "{"+protocol+" saddr}",**/, "counter", "drop", "comment", this.encodeUserData([]string{"tcp", types.String(port), "newConnectionsSecondlyRate", "0"}))
var stderr = &bytes.Buffer{}
cmd.Stderr = stderr
err := cmd.Run()
if err != nil {
return errors.New("add nftables rule '" + cmd.String() + "' failed: " + err.Error() + " (" + stderr.String() + ")")
}
}
} }
} }
} }
@@ -375,7 +397,7 @@ func (this *DDoSProtectionManager) removeOldTCPRules(chain *nftables.Chain, rule
continue continue
} }
switch pieces[2] { switch pieces[2] {
case "maxConnections", "maxConnectionsPerIP", "newConnectionsRate", "denyNewConnectionsRate": case "maxConnections", "maxConnectionsPerIP", "newConnectionsRate", "newConnectionsSecondlyRate":
err := chain.DeleteRule(rule) err := chain.DeleteRule(rule)
if err != nil { if err != nil {
return err return err

View File

@@ -35,7 +35,7 @@ func Sync() error {
ntpdate, err := exec.LookPath("ntpdate") ntpdate, err := exec.LookPath("ntpdate")
if err != nil { if err != nil {
return err return nil
} }
if len(ntpdate) > 0 { if len(ntpdate) > 0 {
return syncNtpdate(ntpdate) return syncNtpdate(ntpdate)