From 3c5acd31fbb961861ebe7009b49f4ecbd5b1eb84 Mon Sep 17 00:00:00 2001 From: lanrenwo Date: Tue, 27 Sep 2022 16:30:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=A1=E8=AE=A1=E6=97=A5=E5=BF=97=E5=BC=82?= =?UTF-8?q?=E6=AD=A5+=E6=89=B9=E9=87=8F=E5=85=A5=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/dbdata/db_orm.go | 5 + server/go.mod | 1 + server/go.sum | 2 + server/handler/payload.go | 84 +----------- server/handler/payload_access_audit.go | 172 +++++++++++++++++++++++++ server/handler/payload_tcp_parser.go | 137 +++++++++++++++++++- server/handler/payload_test.go | 72 +++++++++++ server/handler/start.go | 2 + server/sessdata/session.go | 10 +- 9 files changed, 393 insertions(+), 92 deletions(-) create mode 100644 server/handler/payload_access_audit.go create mode 100644 server/handler/payload_test.go diff --git a/server/dbdata/db_orm.go b/server/dbdata/db_orm.go index 656ff01..3de1fe5 100644 --- a/server/dbdata/db_orm.go +++ b/server/dbdata/db_orm.go @@ -16,6 +16,11 @@ func Add(data interface{}) error { return err } +func AddBatch(data interface{}) error { + _, err := xdb.Insert(data) + return err +} + func Update(fieldName string, value interface{}, data interface{}) error { _, err := xdb.Where(fieldName+"=?", value).Update(data) return err diff --git a/server/go.mod b/server/go.mod index 8830805..8343fc5 100644 --- a/server/go.mod +++ b/server/go.mod @@ -11,6 +11,7 @@ require ( github.com/google/gopacket v1.1.19 github.com/gorilla/handlers v1.5.1 github.com/gorilla/mux v1.8.0 + github.com/ivpusic/grpool v1.0.0 github.com/lib/pq v1.10.2 github.com/mattn/go-sqlite3 v1.14.8 github.com/orcaman/concurrent-map v1.0.0 diff --git a/server/go.sum b/server/go.sum index d641793..a016ffe 100644 --- a/server/go.sum +++ b/server/go.sum @@ -266,6 +266,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/ivpusic/grpool v1.0.0 h1:+FCiCo3GhfsvzfXuJWnpJUNb/VaqyYVgG8C+qvh07Rc= +github.com/ivpusic/grpool v1.0.0/go.mod h1:WPmiAI5ExAn06vg+0JzyPzXMQutJmpb7TrBtyLJkOHQ= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= diff --git a/server/handler/payload.go b/server/handler/payload.go index a66eabf..626ae6e 100644 --- a/server/handler/payload.go +++ b/server/handler/payload.go @@ -1,24 +1,12 @@ package handler import ( - "crypto/md5" - "encoding/binary" - "encoding/hex" - "github.com/bjdgyc/anylink/base" "github.com/bjdgyc/anylink/dbdata" - "github.com/bjdgyc/anylink/pkg/utils" "github.com/bjdgyc/anylink/sessdata" "github.com/songgao/water/waterutil" ) -const ( - acc_proto_udp = iota + 1 - acc_proto_tcp - acc_proto_https - acc_proto_http -) - func payloadIn(cSess *sessdata.ConnSession, pl *sessdata.Payload) bool { if pl.LType == sessdata.LTypeIPData && pl.PType == 0x00 { // 进行Acl规则判断 @@ -27,8 +15,11 @@ func payloadIn(cSess *sessdata.ConnSession, pl *sessdata.Payload) bool { // 校验不通过直接丢弃 return false } - - logAudit(cSess, pl) + if base.Cfg.AuditInterval >= 0 { + cSess.IpAuditPool.JobQueue <- func() { + logAudit(cSess, pl) + } + } } closed := false @@ -106,68 +97,3 @@ func checkLinkAcl(group *dbdata.Group, pl *sessdata.Payload) bool { return false } - -// 访问日志审计 -func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) { - if base.Cfg.AuditInterval < 0 { - return - } - - ipProto := waterutil.IPv4Protocol(pl.Data) - // 访问协议 - var accessProto uint8 - // 只统计 tcp和udp 的访问 - switch ipProto { - case waterutil.TCP: - accessProto = acc_proto_tcp - case waterutil.UDP: - accessProto = acc_proto_udp - default: - return - } - - ipSrc := waterutil.IPv4Source(pl.Data) - ipDst := waterutil.IPv4Destination(pl.Data) - ipPort := waterutil.IPv4DestinationPort(pl.Data) - - b := getByte51() - key := *b - copy(key[:16], ipSrc) - copy(key[16:32], ipDst) - binary.BigEndian.PutUint16(key[32:34], ipPort) - - info := "" - if ipProto == waterutil.TCP { - accessProto, info = onTCP(waterutil.IPv4Payload(pl.Data)) - } - key[34] = byte(accessProto) - if info != "" { - md5Sum := md5.Sum([]byte(info)) - copy(key[35:51], hex.EncodeToString(md5Sum[:])) - } - s := utils.BytesToString(key) - nu := utils.NowSec().Unix() - - // 判断已经存在,并且没有过期 - v, ok := cSess.IpAuditMap.Get(s) - if ok && nu-v.(int64) < int64(base.Cfg.AuditInterval) { - // 回收byte对象 - putByte51(b) - return - } - - cSess.IpAuditMap.Set(s, nu) - - audit := dbdata.AccessAudit{ - Username: cSess.Sess.Username, - Protocol: uint8(ipProto), - Src: ipSrc.String(), - Dst: ipDst.String(), - DstPort: ipPort, - CreatedAt: utils.NowSec(), - AccessProto: accessProto, - Info: info, - } - - _ = dbdata.Add(audit) -} diff --git a/server/handler/payload_access_audit.go b/server/handler/payload_access_audit.go new file mode 100644 index 0000000..59012ab --- /dev/null +++ b/server/handler/payload_access_audit.go @@ -0,0 +1,172 @@ +package handler + +import ( + "crypto/md5" + "encoding/binary" + "encoding/hex" + "time" + + "github.com/bjdgyc/anylink/base" + "github.com/bjdgyc/anylink/dbdata" + "github.com/bjdgyc/anylink/pkg/utils" + "github.com/bjdgyc/anylink/sessdata" + "github.com/songgao/water/waterutil" +) + +const ( + acc_proto_udp = iota + 1 + acc_proto_tcp + acc_proto_https + acc_proto_http +) + +// 保存批量的审计日志 +type LogBatch struct { + Logs []dbdata.AccessAudit +} + +// 日志池 +type LogSink struct { + logChan chan dbdata.AccessAudit + autoCommitChan chan *LogBatch // 超时通知 +} + +var logAuditSink *LogSink + +// 写入日志通道 +func logAuditWrite(aa dbdata.AccessAudit) { + logAuditSink.logChan <- aa +} + +// 批量写入数据表 +func logAuditBatch() { + if base.Cfg.AuditInterval < 0 { + return + } + logAuditSink = &LogSink{ + logChan: make(chan dbdata.AccessAudit, 1000), + autoCommitChan: make(chan *LogBatch, 10), + } + var ( + limit = 100 // 超过上限批量写入数据表 + logAudit dbdata.AccessAudit + logBatch *LogBatch + commitTimer *time.Timer // 超时自动提交 + timeOutBatch *LogBatch + ) + for { + select { + case logAudit = <-logAuditSink.logChan: + if logBatch == nil { + logBatch = &LogBatch{} + commitTimer = time.AfterFunc( + 1*time.Second, func(logBatch *LogBatch) func() { + return func() { + logAuditSink.autoCommitChan <- logBatch + } + }(logBatch), + ) + } + logBatch.Logs = append(logBatch.Logs, logAudit) + if len(logBatch.Logs) >= limit { + commitTimer.Stop() + _ = dbdata.AddBatch(logBatch.Logs) + logBatch = nil + } + case timeOutBatch = <-logAuditSink.autoCommitChan: + if timeOutBatch != logBatch { + continue + } + if logBatch != nil { + _ = dbdata.AddBatch(logBatch.Logs) + } + logBatch = nil + } + } +} + +// 解析IP包的数据 +func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) { + ipProto := waterutil.IPv4Protocol(pl.Data) + // 访问协议 + var accessProto uint8 + // 只统计 tcp和udp 的访问 + switch ipProto { + case waterutil.TCP: + accessProto = acc_proto_tcp + case waterutil.UDP: + accessProto = acc_proto_udp + default: + return + } + + ipSrc := waterutil.IPv4Source(pl.Data) + ipDst := waterutil.IPv4Destination(pl.Data) + ipPort := waterutil.IPv4DestinationPort(pl.Data) + + b := getByte51() + key := *b + copy(key[:16], ipSrc) + copy(key[16:32], ipDst) + binary.BigEndian.PutUint16(key[32:34], ipPort) + + info := "" + if ipProto == waterutil.TCP { + plData := waterutil.IPv4Payload(pl.Data) + if len(plData) < 14 { + return + } + flags := plData[13] + switch flags { + case flags & 0x20: + // base.Debug("URG "+info, "#", str) + return + case flags & 0x10: + // base.Debug("ACK ", ipSrc, "#", ipDst, "#", ipPort) + return + case flags & 0x08: + // base.Debug("PSH "+info, "#", str) + return + case flags & 0x04: + // base.Debug("RST "+info, "#", str) + return + case flags & 0x02: + // base.Debug("SYNC "+info, "#", str) + return + case flags & 0x01: + // base.Debug("FIN "+info, "#", str) + return + default: + accessProto, info = onTCP(plData) + } + } + key[34] = byte(accessProto) + if info != "" { + md5Sum := md5.Sum([]byte(info)) + copy(key[35:51], hex.EncodeToString(md5Sum[:])) + } + s := utils.BytesToString(key) + nu := utils.NowSec().Unix() + + // 判断已经存在,并且没有过期 + v, ok := cSess.IpAuditMap.Get(s) + if ok && nu-v.(int64) < int64(base.Cfg.AuditInterval) { + // 回收byte对象 + putByte51(b) + return + } + + cSess.IpAuditMap.Set(s, nu) + + audit := dbdata.AccessAudit{ + Username: cSess.Sess.Username, + Protocol: uint8(ipProto), + Src: ipSrc.String(), + Dst: ipDst.String(), + DstPort: ipPort, + CreatedAt: utils.NowSec(), + AccessProto: accessProto, + Info: info, + } + logAuditWrite(audit) +} diff --git a/server/handler/payload_tcp_parser.go b/server/handler/payload_tcp_parser.go index 18a8d6d..a6f9a7f 100644 --- a/server/handler/payload_tcp_parser.go +++ b/server/handler/payload_tcp_parser.go @@ -5,22 +5,23 @@ import ( "bytes" "net/http" "regexp" + "strings" ) var tcpParsers = []func([]byte) (uint8, string){ - sniParser, + sniNewParser, httpParser, } -var ( - sniRe = regexp.MustCompile("\x00\x00.{4}\x00.{2}([a-z0-9]+([\\-\\.]{1}[a-z0-9]+)*\\.[a-z]{2,6})\x00") -) - func onTCP(payload []byte) (uint8, string) { - if len(payload) < 13 { + size := len(payload) + if size < 13 { return acc_proto_tcp, "" - } + } ihl := (payload[12] & 0xf0) >> 2 + if int(ihl) > size { + return acc_proto_tcp, "" + } data := payload[ihl:] for _, parser := range tcpParsers { if proto, info := parser(data); info != "" { @@ -30,11 +31,133 @@ func onTCP(payload []byte) (uint8, string) { return acc_proto_tcp, "" } +func sniNewParser(b []byte) (uint8, string) { + dataSize := len(b) + if dataSize < 2 || b[0] != 0x16 || b[1] != 0x03 { + return acc_proto_tcp, "" + } + rest := b[5:] + restLen := len(rest) + if restLen == 0 { + return acc_proto_tcp, "" + } + current := 0 + handshakeType := rest[0] + current += 1 + if handshakeType != 0x1 { + return acc_proto_tcp, "" + } + // Skip over another length + current += 3 + // Skip over protocolversion + current += 2 + // Skip over random number + current += 4 + 28 + if current >= restLen { + return acc_proto_tcp, "" + } + // Skip over session ID + sessionIDLength := int(rest[current]) + current += 1 + current += sessionIDLength + if current >= restLen { + return acc_proto_tcp, "" + } + cipherSuiteLength := (int(rest[current]) << 8) + int(rest[current+1]) + current += 2 + current += cipherSuiteLength + if current >= restLen { + return acc_proto_tcp, "" + } + compressionMethodLength := int(rest[current]) + current += 1 + current += compressionMethodLength + + if current >= restLen { + return acc_proto_tcp, "" + } + current += 2 + hostname := "" + for current+4 < restLen && hostname == "" { + extensionType := (int(rest[current]) << 8) + int(rest[current+1]) + current += 2 + extensionDataLength := (int(rest[current]) << 8) + int(rest[current+1]) + current += 2 + if extensionType == 0 { + // Skip over number of names as we're assuming there's just one + current += 2 + if current >= restLen { + return acc_proto_tcp, "" + } + nameType := rest[current] + current += 1 + if nameType != 0 { + return acc_proto_tcp, "" + } + if current+1 >= restLen { + return acc_proto_tcp, "" + } + nameLen := (int(rest[current]) << 8) + int(rest[current+1]) + current += 2 + if current+nameLen >= restLen { + return acc_proto_tcp, "" + } + hostname = string(rest[current : current+nameLen]) + } + current += extensionDataLength + } + if hostname == "" { + return acc_proto_tcp, "" + } + return acc_proto_https, hostname +} + +// Beta +func httpNewParser(data []byte) (uint8, string) { + methodArr := []string{"OPTIONS", "HEAD", "GET", "POST", "PUT", "DELETE", "TRACE", "CONNECT"} + pos := bytes.IndexByte(data, 10) + if pos == -1 { + return acc_proto_tcp, "" + } + method, uri, _ := strings.Cut(string(data[:pos]), " ") + ok := false + for _, v := range methodArr { + if v == method { + ok = true + } + } + if !ok { + return acc_proto_tcp, "" + } + hostname := "" + // GET http://www.google.com/index.html HTTP/1.1 + if len(uri) > 7 && uri[:4] == "http" { + uriSlice := strings.Split(uri[7:], "/") + hostname = uriSlice[0] + return acc_proto_http, hostname + } + packet := string(data) + hostPos := strings.Index(packet, "Host: ") + if hostPos == -1 { + hostPos = strings.Index(packet, "HOST: ") + if hostPos == -1 { + return acc_proto_tcp, "" + } + } + hostEndPos := strings.Index(packet[hostPos:], "\n") + if hostEndPos == -1 { + return acc_proto_tcp, "" + } + hostname = packet[hostPos+6 : hostPos+hostEndPos-1] + return acc_proto_http, hostname +} + func sniParser(data []byte) (uint8, string) { dataSize := len(data) if dataSize < 2 || data[0] != 0x16 || data[1] != 0x03 { return acc_proto_tcp, "" } + sniRe := regexp.MustCompile("\x00\x00.{4}\x00.{2}([a-z0-9]+([\\-\\.]{1}[a-z0-9]+)*\\.[a-z]{2,6})\x00") m := sniRe.FindSubmatch(data) if len(m) < 2 { return acc_proto_tcp, "" diff --git a/server/handler/payload_test.go b/server/handler/payload_test.go new file mode 100644 index 0000000..f36a08c --- /dev/null +++ b/server/handler/payload_test.go @@ -0,0 +1,72 @@ +package handler + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +var ( + httpsPacket = []byte{148, 152, 1, 187, 110, 58, 1, 82, 45, 244, 84, 34, 80, 24, 1, 54, 130, 216, 0, 0, 22, 3, 1, 2, 0, 1, 0, 1, 252, 3, 3, 110, 25, 141, 34, 174, 156, 58, 62, 6, 81, 231, 155, 116, 22, 30, 12, 195, 250, 214, 125, 161, 255, 107, 203, 106, 173, 167, 25, 6, 78, 13, 5, 32, 228, 144, 162, 34, 197, 103, 28, 86, 28, 66, 156, 108, 36, 31, 171, 238, 245, 133, 82, 184, 67, 0, 89, 194, 8, 172, 219, 83, 62, 90, 133, 223, 0, 14, 19, 1, 19, 2, 19, 3, 192, 43, 192, 44, 192, 47, 192, 48, 1, 0, 1, 165, 0, 0, 0, 31, 0, 29, 0, 0, 26, 106, 103, 119, 45, 100, 114, 99, 110, 46, 106, 111, 115, 46, 100, 98, 97, 110, 107, 99, 108, 111, 117, 100, 46, 99, 110, 0, 23, 0, 0, 255, 1, 0, 1, 0, 0, 10, 0, 8, 0, 6, 0, 29, 0, 23, 0, 24, 0, 11, 0, 2, 1, 0, 0, 35, 0, 208, 204, 119, 182, 195, 85, 35, 227, 85, 38, 141, 121, 60, 221, 102, 189, 82, 161, 136, 147, 248, 243, 32, 17, 28, 191, 115, 109, 63, 239, 38, 44, 22, 180, 30, 142, 213, 136, 229, 115, 24, 99, 225, 150, 231, 152, 12, 7, 210, 230, 134, 189, 83, 193, 253, 130, 123, 242, 15, 60, 122, 146, 187, 107, 173, 113, 167, 28, 65, 242, 221, 224, 20, 130, 12, 35, 247, 29, 123, 145, 18, 171, 197, 193, 0, 152, 32, 129, 227, 54, 124, 94, 154, 65, 99, 5, 90, 141, 113, 224, 189, 232, 169, 33, 159, 66, 230, 39, 1, 206, 193, 213, 154, 217, 18, 8, 205, 168, 140, 25, 229, 82, 56, 14, 134, 209, 113, 209, 28, 205, 71, 143, 44, 89, 69, 58, 236, 211, 80, 41, 136, 44, 23, 87, 16, 81, 133, 54, 61, 19, 97, 133, 69, 182, 98, 201, 210, 139, 195, 0, 108, 215, 79, 194, 7, 56, 126, 203, 43, 229, 224, 138, 41, 55, 41, 207, 74, 67, 5, 26, 19, 156, 130, 218, 27, 223, 79, 204, 82, 209, 61, 239, 44, 247, 214, 175, 1, 192, 192, 192, 11, 247, 243, 48, 29, 77, 90, 100, 93, 0, 16, 0, 14, 0, 12, 2, 104, 50, 8, 104, 116, 116, 112, 47, 49, 46, 49, 0, 5, 0, 5, 1, 0, 0, 0, 0, 0, 13, 0, 20, 0, 18, 4, 3, 8, 4, 4, 1, 5, 3, 8, 5, 5, 1, 8, 6, 6, 1, 2, 1, 0, 51, 0, 38, 0, 36, 0, 29, 0, 32, 38, 165, 55, 231, 178, 23, 75, 55, 19, 164, 173, 248, 204, 115, 141, 138, 78, 66, 254, 21, 79, 109, 43, 124, 242, 80, 10, 185, 127, 92, 125, 36, 0, 45, 0, 2, 1, 1, 0, 43, 0, 5, 4, 3, 4, 3, 3, 0, 21, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + httpPacket = []byte{200, 102, 0, 80, 135, 147, 39, 86, 46, 120, 134, 242, 80, 24, 255, 255, 244, 240, 0, 0, 71, 69, 84, 32, 47, 32, 72, 84, 84, 80, 47, 49, 46, 49, 13, 10, 85, 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 68, 97, 108, 118, 105, 107, 47, 50, 46, 49, 46, 48, 32, 40, 76, 105, 110, 117, 120, 59, 32, 85, 59, 32, 65, 110, 100, 114, 111, 105, 100, 32, 49, 48, 59, 32, 69, 76, 83, 45, 65, 78, 48, 48, 32, 66, 117, 105, 108, 100, 47, 72, 85, 65, 87, 69, 73, 69, 76, 83, 45, 65, 78, 48, 48, 41, 13, 10, 72, 111, 115, 116, 58, 32, 119, 119, 119, 46, 103, 111, 111, 103, 108, 101, 46, 99, 111, 109, 13, 10, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 58, 32, 75, 101, 101, 112, 45, 65, 108, 105, 118, 101, 13, 10, 65, 99, 99, 101, 112, 116, 45, 69, 110, 99, 111, 100, 105, 110, 103, 58, 32, 103, 122, 105, 112, 13, 10, 13, 10} + httpPacket2 = []byte{200, 102, 0, 80, 135, 147, 39, 86, 46, 120, 134, 242, 80, 24, 255, 255, 244, 240, 0, 0, 71, 69, 84, 32, 47, 32, 72, 84, 84, 80, 47, 49, 46, 49, 13, 10, 85, 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 68, 97, 108, 118, 105, 107, 47, 50, 46, 49, 46, 48, 32, 40, 76, 105, 110, 117, 120, 59, 32, 85, 59, 32, 65, 110, 100, 114, 111, 105, 100, 32, 49, 48, 59, 32, 69, 76, 83, 45, 65, 78, 48, 48, 32, 66, 117, 105, 108, 100, 47, 72, 85, 65, 87, 69, 73, 69, 76, 83, 45, 65, 78, 48, 48, 41, 13, 10, 72, 79, 83, 84, 58, 32, 119, 119, 119, 46, 103, 111, 111, 103, 108, 101, 46, 99, 111, 109, 13, 10, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 58, 32, 75, 101, 101, 112, 45, 65, 108, 105, 118, 101, 13, 10, 65, 99, 99, 101, 112, 116, 45, 69, 110, 99, 111, 100, 105, 110, 103, 58, 32, 103, 122, 105, 112, 13, 10, 13, 10} + httpPacket3 = []byte{200, 102, 0, 80, 135, 147, 39, 86, 46, 120, 134, 242, 80, 24, 255, 255, 244, 240, 0, 0, 71, 69, 84, 32, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 103, 111, 111, 103, 108, 101, 46, 99, 111, 109, 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 32, 72, 84, 84, 80, 47, 49, 46, 49, 13, 10, 85, 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 68, 97, 108, 118, 105, 107, 47, 50, 46, 49, 46, 48, 32, 40, 76, 105, 110, 117, 120, 59, 32, 85, 59, 32, 65, 110, 100, 114, 111, 105, 100, 32, 49, 48, 59, 32, 69, 76, 83, 45, 65, 78, 48, 48, 32, 66, 117, 105, 108, 100, 47, 72, 85, 65, 87, 69, 73, 69, 76, 83, 45, 65, 78, 48, 48, 41, 13, 10, 72, 79, 83, 84, 58, 32, 119, 119, 119, 46, 103, 111, 111, 103, 108, 101, 46, 99, 111, 109, 13, 10, 67, 111, 110, 110, 101, 99, 116, 105, 111, 110, 58, 32, 75, 101, 101, 112, 45, 65, 108, 105, 118, 101, 13, 10, 65, 99, 99, 101, 112, 116, 45, 69, 110, 99, 111, 100, 105, 110, 103, 58, 32, 103, 122, 105, 112, 13, 10, 13, 10} + httpsSni = "jgw-drcn.jos.dbankcloud.cn" + httpHost = "www.google.com" +) + +func handlerTcpPayload(packet []byte) []byte { + ihl := (packet[12] & 0xf0) >> 2 + data := packet[ihl:] + return data +} +func BenchmarkSniParser(b *testing.B) { + data := handlerTcpPayload(httpsPacket) + for n := 0; n < b.N; n++ { + sniParser(data) + } +} + +func BenchmarkNewSniParser(b *testing.B) { + data := handlerTcpPayload(httpsPacket) + for n := 0; n < b.N; n++ { + sniNewParser(data) + } +} + +func BenchmarkHttpParser(b *testing.B) { + data := handlerTcpPayload(httpPacket) + for n := 0; n < b.N; n++ { + httpParser(data) + } +} + +func BenchmarkNewHttpParser(b *testing.B) { + data := handlerTcpPayload(httpPacket) + for n := 0; n < b.N; n++ { + httpNewParser(data) + } +} + +func TestNewSniParser(t *testing.T) { + ast := assert.New(t) + data := handlerTcpPayload(httpsPacket) + _, sni := sniNewParser(data) + ast.Equal(sni, httpsSni) +} + +func TestNewHttpParser(t *testing.T) { + ast := assert.New(t) + // Host + data := handlerTcpPayload(httpPacket) + _, hostname := httpNewParser(data) + ast.Equal(hostname, httpHost) + // HOST + data = handlerTcpPayload(httpPacket2) + _, hostname = httpNewParser(data) + ast.Equal(hostname, httpHost) + // GET http://www.google.com/index.html HTTP/1.1 + data = handlerTcpPayload(httpPacket3) + _, hostname = httpNewParser(data) + ast.Equal(hostname, httpHost) +} diff --git a/server/handler/start.go b/server/handler/start.go index 30ef2a0..117fa28 100644 --- a/server/handler/start.go +++ b/server/handler/start.go @@ -37,6 +37,8 @@ func Start() { go admin.StartAdmin() go startTls() go startDtls() + + go logAuditBatch() } func Stop() { diff --git a/server/sessdata/session.go b/server/sessdata/session.go index 87277d6..7a38710 100644 --- a/server/sessdata/session.go +++ b/server/sessdata/session.go @@ -14,6 +14,7 @@ import ( "github.com/bjdgyc/anylink/base" "github.com/bjdgyc/anylink/dbdata" "github.com/bjdgyc/anylink/pkg/utils" + "github.com/ivpusic/grpool" ) var ( @@ -50,7 +51,7 @@ type ConnSession struct { PayloadOutCstp chan *Payload // Cstp的数据 PayloadOutDtls chan *Payload // Dtls的数据 IpAuditMap utils.IMaps // 审计的ip数据 - + IpAuditPool *grpool.Pool // 审计的IP包解析池 // dSess *DtlsSession dSess *atomic.Value } @@ -192,11 +193,8 @@ func (s *Session) NewConn() *ConnSession { // ip 审计 if base.Cfg.AuditInterval >= 0 { - if base.Cfg.ServerDTLS { - cSess.IpAuditMap = utils.NewMap("cmap", 0) - } else { - cSess.IpAuditMap = utils.NewMap("", 512) - } + cSess.IpAuditMap = utils.NewMap("cmap", 0) + cSess.IpAuditPool = grpool.NewPool(1, 600) } dSess := &DtlsSession{