mirror of https://github.com/bjdgyc/anylink.git
优化审计日志异步写入
This commit is contained in:
parent
6fdc0e54d5
commit
890ff5753f
|
@ -16,9 +16,7 @@ func payloadIn(cSess *sessdata.ConnSession, pl *sessdata.Payload) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if base.Cfg.AuditInterval >= 0 {
|
if base.Cfg.AuditInterval >= 0 {
|
||||||
cSess.IpAuditPool.JobQueue <- func() {
|
auditPayload.Add(cSess.Username, pl)
|
||||||
logAudit(cSess, pl)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/bjdgyc/anylink/dbdata"
|
"github.com/bjdgyc/anylink/dbdata"
|
||||||
"github.com/bjdgyc/anylink/pkg/utils"
|
"github.com/bjdgyc/anylink/pkg/utils"
|
||||||
"github.com/bjdgyc/anylink/sessdata"
|
"github.com/bjdgyc/anylink/sessdata"
|
||||||
|
"github.com/ivpusic/grpool"
|
||||||
"github.com/songgao/water/waterutil"
|
"github.com/songgao/water/waterutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,33 +20,49 @@ const (
|
||||||
acc_proto_http
|
acc_proto_http
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
logAuditSink *LogSink
|
||||||
|
auditPayload *AuditPayload
|
||||||
|
)
|
||||||
|
|
||||||
|
// 审计日志
|
||||||
|
type AuditPayload struct {
|
||||||
|
Pool *grpool.Pool
|
||||||
|
IpAuditMap utils.IMaps
|
||||||
|
}
|
||||||
|
|
||||||
// 保存批量的审计日志
|
// 保存批量的审计日志
|
||||||
type LogBatch struct {
|
type LogBatch struct {
|
||||||
Logs []dbdata.AccessAudit
|
Logs []dbdata.AccessAudit
|
||||||
}
|
}
|
||||||
|
|
||||||
// 日志池
|
// 批量日志池
|
||||||
type LogSink struct {
|
type LogSink struct {
|
||||||
logChan chan dbdata.AccessAudit
|
logChan chan dbdata.AccessAudit
|
||||||
autoCommitChan chan *LogBatch // 超时通知
|
autoCommitChan chan *LogBatch // 超时通知
|
||||||
}
|
}
|
||||||
|
|
||||||
var logAuditSink *LogSink
|
func (p *AuditPayload) Add(userName string, pl *sessdata.Payload) {
|
||||||
|
bPlData := getByteFull()
|
||||||
// 写入日志通道
|
copy(*bPlData, pl.Data)
|
||||||
func logAuditWrite(aa dbdata.AccessAudit) {
|
p.Pool.JobQueue <- func() {
|
||||||
logAuditSink.logChan <- aa
|
logAudit(userName, bPlData)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量写入数据表
|
// 开启批量写入数据功能
|
||||||
func logAuditBatch() {
|
func logAuditBatch() {
|
||||||
if base.Cfg.AuditInterval < 0 {
|
if base.Cfg.AuditInterval < 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logAuditSink = &LogSink{
|
logAuditSink = &LogSink{
|
||||||
logChan: make(chan dbdata.AccessAudit, 1000),
|
logChan: make(chan dbdata.AccessAudit, 5000),
|
||||||
autoCommitChan: make(chan *LogBatch, 10),
|
autoCommitChan: make(chan *LogBatch, 10),
|
||||||
}
|
}
|
||||||
|
auditPayload = &AuditPayload{
|
||||||
|
Pool: grpool.NewPool(10, 500),
|
||||||
|
IpAuditMap: utils.NewMap("cmap", 0),
|
||||||
|
}
|
||||||
var (
|
var (
|
||||||
limit = 100 // 超过上限批量写入数据表
|
limit = 100 // 超过上限批量写入数据表
|
||||||
logAudit dbdata.AccessAudit
|
logAudit dbdata.AccessAudit
|
||||||
|
@ -53,6 +70,7 @@ func logAuditBatch() {
|
||||||
commitTimer *time.Timer // 超时自动提交
|
commitTimer *time.Timer // 超时自动提交
|
||||||
timeOutBatch *LogBatch
|
timeOutBatch *LogBatch
|
||||||
)
|
)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case logAudit = <-logAuditSink.logChan:
|
case logAudit = <-logAuditSink.logChan:
|
||||||
|
@ -85,8 +103,11 @@ func logAuditBatch() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析IP包的数据
|
// 解析IP包的数据
|
||||||
func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
|
func logAudit(userName string, bPlData *[]byte) {
|
||||||
ipProto := waterutil.IPv4Protocol(pl.Data)
|
defer putByte(bPlData)
|
||||||
|
|
||||||
|
plData := *bPlData
|
||||||
|
ipProto := waterutil.IPv4Protocol(plData)
|
||||||
// 访问协议
|
// 访问协议
|
||||||
var accessProto uint8
|
var accessProto uint8
|
||||||
// 只统计 tcp和udp 的访问
|
// 只统计 tcp和udp 的访问
|
||||||
|
@ -99,9 +120,9 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ipSrc := waterutil.IPv4Source(pl.Data)
|
ipSrc := waterutil.IPv4Source(plData)
|
||||||
ipDst := waterutil.IPv4Destination(pl.Data)
|
ipDst := waterutil.IPv4Destination(plData)
|
||||||
ipPort := waterutil.IPv4DestinationPort(pl.Data)
|
ipPort := waterutil.IPv4DestinationPort(plData)
|
||||||
|
|
||||||
b := getByte51()
|
b := getByte51()
|
||||||
key := *b
|
key := *b
|
||||||
|
@ -114,79 +135,42 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
|
||||||
info := ""
|
info := ""
|
||||||
nu := utils.NowSec().Unix()
|
nu := utils.NowSec().Unix()
|
||||||
if ipProto == waterutil.TCP {
|
if ipProto == waterutil.TCP {
|
||||||
plData := waterutil.IPv4Payload(pl.Data)
|
tcpPlData := waterutil.IPv4Payload(plData)
|
||||||
if len(plData) < 14 {
|
// 24 (ACK PSH)
|
||||||
|
if len(tcpPlData) < 14 || tcpPlData[13] != 24 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
flags := plData[13]
|
accessProto, info = onTCP(tcpPlData)
|
||||||
switch flags {
|
// HTTPS or HTTP
|
||||||
case flags & 0x20:
|
if accessProto != acc_proto_tcp {
|
||||||
// URG
|
// 提前存储只含ip数据的key, 避免即记录域名又记录一笔IP数据的记录
|
||||||
return
|
ipKey := make([]byte, 51)
|
||||||
case flags & 0x14:
|
copy(ipKey, key)
|
||||||
// RST ACK
|
ipS := utils.BytesToString(ipKey)
|
||||||
return
|
auditPayload.IpAuditMap.Set(ipS, nu)
|
||||||
case flags & 0x12:
|
|
||||||
// SYN ACK
|
|
||||||
return
|
|
||||||
case flags & 0x11:
|
|
||||||
// Client FIN
|
|
||||||
return
|
|
||||||
case flags & 0x10:
|
|
||||||
// ACK
|
|
||||||
return
|
|
||||||
case flags & 0x08:
|
|
||||||
// PSH
|
|
||||||
return
|
|
||||||
case flags & 0x04:
|
|
||||||
// RST
|
|
||||||
return
|
|
||||||
case flags & 0x02:
|
|
||||||
// SYN
|
|
||||||
return
|
|
||||||
case flags & 0x01:
|
|
||||||
// FIN
|
|
||||||
return
|
|
||||||
case flags & 0x18:
|
|
||||||
// PSH ACK
|
|
||||||
accessProto, info = onTCP(plData)
|
|
||||||
// HTTPS or HTTP
|
|
||||||
if accessProto != acc_proto_tcp {
|
|
||||||
// 提前存储只含ip数据的key, 避免即记录域名又记录一笔IP数据的记录
|
|
||||||
ipKey := make([]byte, 51)
|
|
||||||
copy(ipKey, key)
|
|
||||||
ipS := utils.BytesToString(ipKey)
|
|
||||||
cSess.IpAuditMap.Set(ipS, nu)
|
|
||||||
|
|
||||||
key[34] = byte(accessProto)
|
key[34] = byte(accessProto)
|
||||||
// 存储含域名的key
|
// 存储含域名的key
|
||||||
if info != "" {
|
if info != "" {
|
||||||
md5Sum := md5.Sum([]byte(info))
|
md5Sum := md5.Sum([]byte(info))
|
||||||
copy(key[35:51], md5Sum[:])
|
copy(key[35:51], md5Sum[:])
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case flags & 0x19:
|
|
||||||
// URG
|
|
||||||
return
|
|
||||||
case flags & 0xC2:
|
|
||||||
// SYN-ECE-CWR
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s := utils.BytesToString(key)
|
s := utils.BytesToString(key)
|
||||||
|
|
||||||
// 判断已经存在,并且没有过期
|
// 判断已经存在,并且没有过期
|
||||||
v, ok := cSess.IpAuditMap.Get(s)
|
v, ok := auditPayload.IpAuditMap.Get(s)
|
||||||
if ok && nu-v.(int64) < int64(base.Cfg.AuditInterval) {
|
if ok && nu-v.(int64) < int64(base.Cfg.AuditInterval) {
|
||||||
// 回收byte对象
|
// 回收byte对象
|
||||||
putByte51(b)
|
putByte51(b)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cSess.IpAuditMap.Set(s, nu)
|
auditPayload.IpAuditMap.Set(s, nu)
|
||||||
|
|
||||||
audit := dbdata.AccessAudit{
|
audit := dbdata.AccessAudit{
|
||||||
Username: cSess.Username,
|
Username: userName,
|
||||||
Protocol: uint8(ipProto),
|
Protocol: uint8(ipProto),
|
||||||
Src: ipSrc.String(),
|
Src: ipSrc.String(),
|
||||||
Dst: ipDst.String(),
|
Dst: ipDst.String(),
|
||||||
|
@ -195,5 +179,5 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
|
||||||
AccessProto: accessProto,
|
AccessProto: accessProto,
|
||||||
Info: info,
|
Info: info,
|
||||||
}
|
}
|
||||||
logAuditWrite(audit)
|
logAuditSink.logChan <- audit
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,7 @@ import (
|
||||||
|
|
||||||
"github.com/bjdgyc/anylink/base"
|
"github.com/bjdgyc/anylink/base"
|
||||||
"github.com/bjdgyc/anylink/dbdata"
|
"github.com/bjdgyc/anylink/dbdata"
|
||||||
"github.com/bjdgyc/anylink/pkg/utils"
|
|
||||||
mapset "github.com/deckarep/golang-set"
|
mapset "github.com/deckarep/golang-set"
|
||||||
"github.com/ivpusic/grpool"
|
|
||||||
atomic2 "go.uber.org/atomic"
|
atomic2 "go.uber.org/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -52,8 +50,6 @@ type ConnSession struct {
|
||||||
PayloadIn chan *Payload
|
PayloadIn chan *Payload
|
||||||
PayloadOutCstp chan *Payload // Cstp的数据
|
PayloadOutCstp chan *Payload // Cstp的数据
|
||||||
PayloadOutDtls chan *Payload // Dtls的数据
|
PayloadOutDtls chan *Payload // Dtls的数据
|
||||||
IpAuditMap utils.IMaps // 审计的ip数据
|
|
||||||
IpAuditPool *grpool.Pool // 审计的IP包解析池
|
|
||||||
// dSess *DtlsSession
|
// dSess *DtlsSession
|
||||||
dSess *atomic.Value
|
dSess *atomic.Value
|
||||||
}
|
}
|
||||||
|
@ -206,12 +202,6 @@ func (s *Session) NewConn() *ConnSession {
|
||||||
dSess: &atomic.Value{},
|
dSess: &atomic.Value{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// ip 审计
|
|
||||||
if base.Cfg.AuditInterval >= 0 {
|
|
||||||
cSess.IpAuditMap = utils.NewMap("cmap", 0)
|
|
||||||
cSess.IpAuditPool = grpool.NewPool(1, 600)
|
|
||||||
}
|
|
||||||
|
|
||||||
dSess := &DtlsSession{
|
dSess := &DtlsSession{
|
||||||
isActive: -1,
|
isActive: -1,
|
||||||
}
|
}
|
||||||
|
@ -244,10 +234,6 @@ func (cs *ConnSession) Close() {
|
||||||
cs.Sess.LastLogin = time.Now()
|
cs.Sess.LastLogin = time.Now()
|
||||||
cs.Sess.CSess = nil
|
cs.Sess.CSess = nil
|
||||||
|
|
||||||
if cs.IpAuditPool != nil {
|
|
||||||
cs.IpAuditPool.Release()
|
|
||||||
}
|
|
||||||
|
|
||||||
dSess := cs.GetDtlsSession()
|
dSess := cs.GetDtlsSession()
|
||||||
if dSess != nil {
|
if dSess != nil {
|
||||||
dSess.Close()
|
dSess.Close()
|
||||||
|
|
Loading…
Reference in New Issue