mirror of
				https://github.com/bjdgyc/anylink.git
				synced 2025-10-31 16:43:28 +08:00 
			
		
		
		
	新增审计日志的http/https域名信息
This commit is contained in:
		| @@ -59,14 +59,16 @@ type Setting struct { | ||||
| } | ||||
|  | ||||
| type AccessAudit struct { | ||||
| 	Id        int       `json:"id" xorm:"pk autoincr not null"` | ||||
| 	Username  string    `json:"username" xorm:"varchar(60) not null"` | ||||
| 	Protocol  uint8     `json:"protocol" xorm:"not null"` | ||||
| 	Src       string    `json:"src" xorm:"varchar(60) not null"` | ||||
| 	SrcPort   uint16    `json:"src_port" xorm:"not null"` | ||||
| 	Dst       string    `json:"dst" xorm:"varchar(60) not null"` | ||||
| 	DstPort   uint16    `json:"dst_port" xorm:"not null"` | ||||
| 	CreatedAt time.Time `json:"created_at" xorm:"DateTime"` | ||||
| 	Id          int       `json:"id" xorm:"pk autoincr not null"` | ||||
| 	Username    string    `json:"username" xorm:"varchar(60) not null"` | ||||
| 	Protocol    uint8     `json:"protocol" xorm:"not null"` | ||||
| 	Src         string    `json:"src" xorm:"varchar(60) not null"` | ||||
| 	SrcPort     uint16    `json:"src_port" xorm:"not null"` | ||||
| 	Dst         string    `json:"dst" xorm:"varchar(60) not null"` | ||||
| 	DstPort     uint16    `json:"dst_port" xorm:"not null"` | ||||
| 	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 { | ||||
|   | ||||
| @@ -10,6 +10,13 @@ import ( | ||||
| 	"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规则判断 | ||||
| @@ -105,10 +112,13 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) { | ||||
| 	} | ||||
|  | ||||
| 	ipProto := waterutil.IPv4Protocol(pl.Data) | ||||
| 	// 访问协议 | ||||
| 	var accessProto uint8 = acc_proto_tcp | ||||
| 	// 只统计 tcp和udp 的访问 | ||||
| 	switch ipProto { | ||||
| 	case waterutil.TCP: | ||||
| 	case waterutil.UDP: | ||||
| 		accessProto = acc_proto_udp | ||||
| 	default: | ||||
| 		return | ||||
| 	} | ||||
| @@ -117,12 +127,21 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) { | ||||
| 	ipDst := waterutil.IPv4Destination(pl.Data) | ||||
| 	ipPort := waterutil.IPv4DestinationPort(pl.Data) | ||||
|  | ||||
| 	b := getByte34() | ||||
| 	b := getByte290() | ||||
| 	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 != "" { | ||||
| 		copy(key[35:35+len(info)], info) | ||||
| 	} | ||||
|  | ||||
| 	s := utils.BytesToString(key) | ||||
| 	nu := utils.NowSec().Unix() | ||||
|  | ||||
| @@ -130,19 +149,21 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) { | ||||
| 	v, ok := cSess.IpAuditMap[s] | ||||
| 	if ok && nu-v < int64(base.Cfg.AuditInterval) { | ||||
| 		// 回收byte对象 | ||||
| 		putByte34(b) | ||||
| 		putByte290(b) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	cSess.IpAuditMap[s] = nu | ||||
|  | ||||
| 	audit := dbdata.AccessAudit{ | ||||
| 		Username:  cSess.Sess.Username, | ||||
| 		Protocol:  uint8(ipProto), | ||||
| 		Src:       ipSrc.String(), | ||||
| 		Dst:       ipDst.String(), | ||||
| 		DstPort:   ipPort, | ||||
| 		CreatedAt: utils.NowSec(), | ||||
| 		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) | ||||
|   | ||||
							
								
								
									
										48
									
								
								server/handler/payload_tcp_parser.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								server/handler/payload_tcp_parser.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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] | ||||
| 	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) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user