mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-07 18:50:27 +08:00
因WAF规则拦截而关闭连接时,不记录499
This commit is contained in:
7
internal/nodes/client_conn_closer.go
Normal file
7
internal/nodes/client_conn_closer.go
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package nodes
|
||||
|
||||
type ClientConnCloser interface {
|
||||
IsClosed() bool
|
||||
}
|
||||
@@ -11,12 +11,10 @@ func isClientConnClosed(conn net.Conn) bool {
|
||||
if conn == nil {
|
||||
return true
|
||||
}
|
||||
clientConn, ok := conn.(*ClientConn)
|
||||
clientConn, ok := conn.(ClientConnCloser)
|
||||
if ok {
|
||||
return clientConn.IsClosed()
|
||||
}
|
||||
|
||||
// TODO 解决tls.Conn无法获取底层连接对象的问题
|
||||
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
57
internal/nodes/client_tls_conn.go
Normal file
57
internal/nodes/client_tls_conn.go
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package nodes
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ClientTLSConn struct {
|
||||
rawConn *tls.Conn
|
||||
isClosed bool
|
||||
}
|
||||
|
||||
func NewClientTLSConn(conn *tls.Conn) net.Conn {
|
||||
return &ClientTLSConn{rawConn: conn}
|
||||
}
|
||||
|
||||
func (this *ClientTLSConn) Read(b []byte) (n int, err error) {
|
||||
n, err = this.rawConn.Read(b)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *ClientTLSConn) Write(b []byte) (n int, err error) {
|
||||
n, err = this.rawConn.Write(b)
|
||||
return
|
||||
}
|
||||
|
||||
func (this *ClientTLSConn) Close() error {
|
||||
this.isClosed = true
|
||||
return this.rawConn.Close()
|
||||
}
|
||||
|
||||
func (this *ClientTLSConn) LocalAddr() net.Addr {
|
||||
return this.rawConn.LocalAddr()
|
||||
}
|
||||
|
||||
func (this *ClientTLSConn) RemoteAddr() net.Addr {
|
||||
return this.rawConn.RemoteAddr()
|
||||
}
|
||||
|
||||
func (this *ClientTLSConn) SetDeadline(t time.Time) error {
|
||||
return this.rawConn.SetDeadline(t)
|
||||
}
|
||||
|
||||
func (this *ClientTLSConn) SetReadDeadline(t time.Time) error {
|
||||
return this.rawConn.SetReadDeadline(t)
|
||||
}
|
||||
|
||||
func (this *ClientTLSConn) SetWriteDeadline(t time.Time) error {
|
||||
return this.rawConn.SetWriteDeadline(t)
|
||||
}
|
||||
|
||||
func (this *ClientTLSConn) IsClosed() bool {
|
||||
return this.isClosed
|
||||
}
|
||||
@@ -1279,3 +1279,34 @@ func (this *HTTPRequest) canIgnore(err error) bool {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 关闭当前连接
|
||||
func (this *HTTPRequest) closeConn() {
|
||||
requestConn := this.RawReq.Context().Value(HTTPConnContextKey)
|
||||
if requestConn == nil {
|
||||
return
|
||||
}
|
||||
|
||||
conn, ok := requestConn.(net.Conn)
|
||||
if ok {
|
||||
_ = conn.Close()
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 检查连接是否已关闭
|
||||
func (this *HTTPRequest) isConnClosed() bool {
|
||||
requestConn := this.RawReq.Context().Value(HTTPConnContextKey)
|
||||
if requestConn == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
conn, ok := requestConn.(net.Conn)
|
||||
if ok {
|
||||
return isClientConnClosed(conn)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -327,6 +327,8 @@ func (this *HTTPRequest) doCacheRead() (shouldStop bool) {
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
this.varMapping["cache.status"] = "MISS"
|
||||
|
||||
if err == caches.ErrInvalidRange {
|
||||
this.processResponseHeaders(http.StatusRequestedRangeNotSatisfiable)
|
||||
this.writer.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
|
||||
@@ -387,6 +389,8 @@ func (this *HTTPRequest) doCacheRead() (shouldStop bool) {
|
||||
|
||||
_, err = this.writer.WriteString("\r\n--" + boundary + "--\r\n")
|
||||
if err != nil {
|
||||
this.varMapping["cache.status"] = "MISS"
|
||||
|
||||
// 不提示写入客户端错误
|
||||
return true
|
||||
}
|
||||
@@ -402,6 +406,8 @@ func (this *HTTPRequest) doCacheRead() (shouldStop bool) {
|
||||
return true, nil
|
||||
})
|
||||
if err != nil {
|
||||
this.varMapping["cache.status"] = "MISS"
|
||||
|
||||
if !this.canIgnore(err) {
|
||||
remotelogs.Warn("HTTP_REQUEST_CACHE", "read from cache failed: "+err.Error())
|
||||
}
|
||||
|
||||
@@ -186,6 +186,12 @@ func (this *HTTPRequest) doReverseProxy() {
|
||||
isClientError := false
|
||||
if ok {
|
||||
if httpErr.Err == context.Canceled {
|
||||
// 如果是服务器端主动关闭,则无需提示
|
||||
if this.isConnClosed() {
|
||||
this.disableLog = true
|
||||
return
|
||||
}
|
||||
|
||||
isClientError = true
|
||||
this.addError(errors.New(httpErr.Op + " " + httpErr.URL + ": client closed the connection"))
|
||||
this.writer.WriteHeader(499) // 仿照nginx
|
||||
|
||||
@@ -11,37 +11,29 @@ import (
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// 调用WAF
|
||||
func (this *HTTPRequest) doWAFRequest() (blocked bool) {
|
||||
// 当前连接是否已关闭
|
||||
var conn = this.RawReq.Context().Value(HTTPConnContextKey)
|
||||
if conn != nil {
|
||||
if isClientConnClosed(conn.(net.Conn)) {
|
||||
this.disableLog = true
|
||||
return true
|
||||
}
|
||||
if this.isConnClosed() {
|
||||
this.disableLog = true
|
||||
return true
|
||||
}
|
||||
|
||||
// 是否在全局名单中
|
||||
var remoteAddr = this.requestRemoteAddr(true)
|
||||
if !iplibrary.AllowIP(remoteAddr, this.Server.Id) {
|
||||
this.disableLog = true
|
||||
if conn != nil {
|
||||
_ = conn.(net.Conn).Close()
|
||||
}
|
||||
this.closeConn()
|
||||
return true
|
||||
}
|
||||
|
||||
// 检查是否在临时黑名单中
|
||||
if waf.SharedIPBlackList.Contains(waf.IPTypeAll, firewallconfigs.FirewallScopeService, this.Server.Id, remoteAddr) || waf.SharedIPBlackList.Contains(waf.IPTypeAll, firewallconfigs.FirewallScopeGlobal, 0, remoteAddr) {
|
||||
this.disableLog = true
|
||||
if conn != nil {
|
||||
_ = conn.(net.Conn).Close()
|
||||
}
|
||||
this.closeConn()
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -317,16 +309,7 @@ func (this *HTTPRequest) WAFServerId() int64 {
|
||||
|
||||
// WAFClose 关闭连接
|
||||
func (this *HTTPRequest) WAFClose() {
|
||||
requestConn := this.RawReq.Context().Value(HTTPConnContextKey)
|
||||
if requestConn == nil {
|
||||
return
|
||||
}
|
||||
conn, ok := requestConn.(net.Conn)
|
||||
if ok {
|
||||
_ = conn.Close()
|
||||
return
|
||||
}
|
||||
return
|
||||
this.closeConn()
|
||||
}
|
||||
|
||||
func (this *HTTPRequest) WAFOnAction(action interface{}) (goNext bool) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package nodes
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
||||
"golang.org/x/net/http2"
|
||||
@@ -68,6 +69,10 @@ func (this *HTTPListener) Serve() error {
|
||||
}
|
||||
},
|
||||
ConnContext: func(ctx context.Context, c net.Conn) context.Context {
|
||||
tlsConn, ok := c.(*tls.Conn)
|
||||
if ok {
|
||||
c = NewClientTLSConn(tlsConn)
|
||||
}
|
||||
return context.WithValue(ctx, HTTPConnContextKey, c)
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user