From 14d156d42dd322aae8bfa4952be5881883fd086c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E7=A5=A5=E8=B6=85?= Date: Thu, 13 Jan 2022 11:36:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9BSYN=20Flood=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/nodes/client_conn.go | 22 +++++++++++++++------- internal/nodes/client_conn_base.go | 15 +++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/internal/nodes/client_conn.go b/internal/nodes/client_conn.go index 2ce783b..e357754 100644 --- a/internal/nodes/client_conn.go +++ b/internal/nodes/client_conn.go @@ -24,9 +24,10 @@ type ClientConn struct { once sync.Once globalLimiter *ratelimit.Counter - isTLS bool - hasDeadline bool - hasRead bool + isTLS bool + hasDeadline bool + hasRead bool + hasResetSYNFlood bool BaseClientConn } @@ -65,10 +66,13 @@ func (this *ClientConn) Read(b []byte) (n int, err error) { var synFloodConfig = sharedNodeConfig.SYNFloodConfig() if synFloodConfig != nil && synFloodConfig.IsOn { if err != nil && os.IsTimeout(err) { + _ = this.SetLinger(0) + if !this.hasRead { - this.checkSYNFlood(synFloodConfig) + this.increaseSYNFlood(synFloodConfig) } - } else if err == nil { + } else if err == nil && !this.hasResetSYNFlood { + this.hasResetSYNFlood = true this.resetSYNFlood() } } @@ -123,10 +127,10 @@ func (this *ClientConn) SetWriteDeadline(t time.Time) error { } func (this *ClientConn) resetSYNFlood() { - //ttlcache.SharedCache.Delete("SYN_FLOOD:" + this.RawIP()) + ttlcache.SharedCache.Delete("SYN_FLOOD:" + this.RawIP()) } -func (this *ClientConn) checkSYNFlood(synFloodConfig *firewallconfigs.SYNFloodConfig) { +func (this *ClientConn) increaseSYNFlood(synFloodConfig *firewallconfigs.SYNFloodConfig) { var ip = this.RawIP() if len(ip) > 0 && !iplibrary.IsInWhiteList(ip) && (!synFloodConfig.IgnoreLocal || !utils.IsLocalIP(ip)) { var timestamp = utils.NextMinuteUnixTime() @@ -135,6 +139,10 @@ func (this *ClientConn) checkSYNFlood(synFloodConfig *firewallconfigs.SYNFloodCo if minAttempts < 5 { minAttempts = 5 } + if !this.isTLS { + // 非TLS,设置为两倍,防止误封 + minAttempts = 2 * minAttempts + } if result >= int64(minAttempts) { var timeout = synFloodConfig.TimeoutSeconds if timeout <= 0 { diff --git a/internal/nodes/client_conn_base.go b/internal/nodes/client_conn_base.go index aa386ea..33bce03 100644 --- a/internal/nodes/client_conn_base.go +++ b/internal/nodes/client_conn_base.go @@ -41,3 +41,18 @@ func (this *BaseClientConn) RawIP() string { ip, _, _ := net.SplitHostPort(this.rawConn.RemoteAddr().String()) return ip } + +// TCPConn 转换为TCPConn +func (this *BaseClientConn) TCPConn() (*net.TCPConn, bool) { + conn, ok := this.rawConn.(*net.TCPConn) + return conn, ok +} + +// SetLinger 设置Linger +func (this *BaseClientConn) SetLinger(seconds int) error { + tcpConn, ok := this.TCPConn() + if ok { + return tcpConn.SetLinger(seconds) + } + return nil +}