mirror of https://github.com/bjdgyc/anylink.git
新增审计日志的http/https域名信息
This commit is contained in:
parent
cd21dec605
commit
8837a07fac
|
@ -59,14 +59,16 @@ type Setting struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccessAudit struct {
|
type AccessAudit struct {
|
||||||
Id int `json:"id" xorm:"pk autoincr not null"`
|
Id int `json:"id" xorm:"pk autoincr not null"`
|
||||||
Username string `json:"username" xorm:"varchar(60) not null"`
|
Username string `json:"username" xorm:"varchar(60) not null"`
|
||||||
Protocol uint8 `json:"protocol" xorm:"not null"`
|
Protocol uint8 `json:"protocol" xorm:"not null"`
|
||||||
Src string `json:"src" xorm:"varchar(60) not null"`
|
Src string `json:"src" xorm:"varchar(60) not null"`
|
||||||
SrcPort uint16 `json:"src_port" xorm:"not null"`
|
SrcPort uint16 `json:"src_port" xorm:"not null"`
|
||||||
Dst string `json:"dst" xorm:"varchar(60) not null"`
|
Dst string `json:"dst" xorm:"varchar(60) not null"`
|
||||||
DstPort uint16 `json:"dst_port" xorm:"not null"`
|
DstPort uint16 `json:"dst_port" xorm:"not null"`
|
||||||
CreatedAt time.Time `json:"created_at" xorm:"DateTime"`
|
AccessProto uint8 `json:"access_proto" xorm:"not null"` // 访问协议
|
||||||
|
Info string `json:"info" xorm:"varchar(255) not null"` // 详情
|
||||||
|
CreatedAt time.Time `json:"created_at" xorm:"DateTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Policy struct {
|
type Policy struct {
|
||||||
|
|
|
@ -10,6 +10,13 @@ import (
|
||||||
"github.com/songgao/water/waterutil"
|
"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 {
|
func payloadIn(cSess *sessdata.ConnSession, pl *sessdata.Payload) bool {
|
||||||
if pl.LType == sessdata.LTypeIPData && pl.PType == 0x00 {
|
if pl.LType == sessdata.LTypeIPData && pl.PType == 0x00 {
|
||||||
// 进行Acl规则判断
|
// 进行Acl规则判断
|
||||||
|
@ -105,10 +112,13 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ipProto := waterutil.IPv4Protocol(pl.Data)
|
ipProto := waterutil.IPv4Protocol(pl.Data)
|
||||||
|
// 访问协议
|
||||||
|
var accessProto uint8 = acc_proto_tcp
|
||||||
// 只统计 tcp和udp 的访问
|
// 只统计 tcp和udp 的访问
|
||||||
switch ipProto {
|
switch ipProto {
|
||||||
case waterutil.TCP:
|
case waterutil.TCP:
|
||||||
case waterutil.UDP:
|
case waterutil.UDP:
|
||||||
|
accessProto = acc_proto_udp
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -117,12 +127,21 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
|
||||||
ipDst := waterutil.IPv4Destination(pl.Data)
|
ipDst := waterutil.IPv4Destination(pl.Data)
|
||||||
ipPort := waterutil.IPv4DestinationPort(pl.Data)
|
ipPort := waterutil.IPv4DestinationPort(pl.Data)
|
||||||
|
|
||||||
b := getByte34()
|
b := getByte290()
|
||||||
key := *b
|
key := *b
|
||||||
copy(key[:16], ipSrc)
|
copy(key[:16], ipSrc)
|
||||||
copy(key[16:32], ipDst)
|
copy(key[16:32], ipDst)
|
||||||
binary.BigEndian.PutUint16(key[32:34], ipPort)
|
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 != "" {
|
||||||
|
copy(key[35:35+len(info)], info)
|
||||||
|
}
|
||||||
|
|
||||||
s := utils.BytesToString(key)
|
s := utils.BytesToString(key)
|
||||||
nu := utils.NowSec().Unix()
|
nu := utils.NowSec().Unix()
|
||||||
|
|
||||||
|
@ -130,19 +149,21 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
|
||||||
v, ok := cSess.IpAuditMap[s]
|
v, ok := cSess.IpAuditMap[s]
|
||||||
if ok && nu-v < int64(base.Cfg.AuditInterval) {
|
if ok && nu-v < int64(base.Cfg.AuditInterval) {
|
||||||
// 回收byte对象
|
// 回收byte对象
|
||||||
putByte34(b)
|
putByte290(b)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cSess.IpAuditMap[s] = nu
|
cSess.IpAuditMap[s] = nu
|
||||||
|
|
||||||
audit := dbdata.AccessAudit{
|
audit := dbdata.AccessAudit{
|
||||||
Username: cSess.Sess.Username,
|
Username: cSess.Sess.Username,
|
||||||
Protocol: uint8(ipProto),
|
Protocol: uint8(ipProto),
|
||||||
Src: ipSrc.String(),
|
Src: ipSrc.String(),
|
||||||
Dst: ipDst.String(),
|
Dst: ipDst.String(),
|
||||||
DstPort: ipPort,
|
DstPort: ipPort,
|
||||||
CreatedAt: utils.NowSec(),
|
CreatedAt: utils.NowSec(),
|
||||||
|
AccessProto: accessProto,
|
||||||
|
Info: info,
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = dbdata.Add(audit)
|
_ = dbdata.Add(audit)
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
var tcpParsers = []func([]byte) (uint8, string){
|
||||||
|
sniParser,
|
||||||
|
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) {
|
||||||
|
ihl := (payload[12] & 0xf0) >> 2
|
||||||
|
data := payload[ihl:]
|
||||||
|
for _, parser := range tcpParsers {
|
||||||
|
if proto, info := parser(data); info != "" {
|
||||||
|
return proto, info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return acc_proto_tcp, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func sniParser(data []byte) (uint8, string) {
|
||||||
|
dataSize := len(data)
|
||||||
|
if dataSize < 2 || data[0] != 0x16 || data[1] != 0x03 {
|
||||||
|
return acc_proto_tcp, ""
|
||||||
|
}
|
||||||
|
m := sniRe.FindSubmatch(data)
|
||||||
|
if len(m) < 2 {
|
||||||
|
return acc_proto_tcp, ""
|
||||||
|
}
|
||||||
|
host := string(m[1])
|
||||||
|
return acc_proto_https, host
|
||||||
|
}
|
||||||
|
|
||||||
|
func httpParser(data []byte) (uint8, string) {
|
||||||
|
if req, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(data))); err == nil {
|
||||||
|
return acc_proto_http, req.Host
|
||||||
|
}
|
||||||
|
return acc_proto_tcp, ""
|
||||||
|
}
|
|
@ -87,3 +87,25 @@ func putByte34(b *[]byte) {
|
||||||
*b = (*b)[:34]
|
*b = (*b)[:34]
|
||||||
byte34Pool.Put(b)
|
byte34Pool.Put(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BufferPool struct {
|
||||||
|
sync.Pool
|
||||||
|
}
|
||||||
|
|
||||||
|
// 长度 290 对象
|
||||||
|
var byte290Pool = sync.Pool{
|
||||||
|
New: func() interface{} {
|
||||||
|
b := make([]byte, 290)
|
||||||
|
return &b
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func getByte290() *[]byte {
|
||||||
|
b := byte290Pool.Get().(*[]byte)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func putByte290(b *[]byte) {
|
||||||
|
*b = (*b)[:290]
|
||||||
|
byte290Pool.Put(b)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue