mirror of https://github.com/bjdgyc/anylink.git
commit
1dceffc327
|
@ -66,6 +66,8 @@ type AccessAudit struct {
|
|||
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"`
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/bjdgyc/anylink/base"
|
||||
"github.com/bjdgyc/anylink/dbdata"
|
||||
|
@ -10,6 +12,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 +114,14 @@ 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
|
||||
}
|
||||
|
@ -117,12 +130,21 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
|
|||
ipDst := waterutil.IPv4Destination(pl.Data)
|
||||
ipPort := waterutil.IPv4DestinationPort(pl.Data)
|
||||
|
||||
b := getByte34()
|
||||
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()
|
||||
|
||||
|
@ -130,7 +152,7 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
|
|||
v, ok := cSess.IpAuditMap[s]
|
||||
if ok && nu-v < int64(base.Cfg.AuditInterval) {
|
||||
// 回收byte对象
|
||||
putByte34(b)
|
||||
putByte51(b)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -143,6 +165,8 @@ func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
|
|||
Dst: ipDst.String(),
|
||||
DstPort: ipPort,
|
||||
CreatedAt: utils.NowSec(),
|
||||
AccessProto: accessProto,
|
||||
Info: info,
|
||||
}
|
||||
|
||||
_ = 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]
|
||||
byte34Pool.Put(b)
|
||||
}
|
||||
|
||||
type BufferPool struct {
|
||||
sync.Pool
|
||||
}
|
||||
|
||||
// 长度 51 小对象
|
||||
var byte51Pool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
b := make([]byte, 51)
|
||||
return &b
|
||||
},
|
||||
}
|
||||
|
||||
func getByte51() *[]byte {
|
||||
b := byte51Pool.Get().(*[]byte)
|
||||
return b
|
||||
}
|
||||
|
||||
func putByte51(b *[]byte) {
|
||||
*b = (*b)[:51]
|
||||
byte51Pool.Put(b)
|
||||
}
|
||||
|
|
|
@ -16,39 +16,50 @@
|
|||
|
||||
<el-table-column
|
||||
prop="username"
|
||||
label="用户名">
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column
|
||||
prop="protocol"
|
||||
label="协议">
|
||||
label="用户名"
|
||||
width="120">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="src"
|
||||
label="源IP地址">
|
||||
label="源IP地址"
|
||||
width="140">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="dst"
|
||||
label="目的IP地址">
|
||||
label="目的IP地址"
|
||||
width="140">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="dst_port"
|
||||
label="目的端口">
|
||||
label="目的端口"
|
||||
width="85">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="access_proto"
|
||||
label="访问协议"
|
||||
width="85"
|
||||
:formatter="protoFormat">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="info"
|
||||
label="详情">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="created_at"
|
||||
label="创建时间"
|
||||
width="150"
|
||||
:formatter="tableDateFormat">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="150">
|
||||
width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-popconfirm
|
||||
class="m-left-10"
|
||||
|
@ -89,7 +100,7 @@ export default {
|
|||
mixins: [],
|
||||
created() {
|
||||
this.$emit('update:route_path', this.$route.path)
|
||||
this.$emit('update:route_name', ['基础信息', 'IP审计'])
|
||||
this.$emit('update:route_name', ['基础信息', '审计日志'])
|
||||
},
|
||||
mounted() {
|
||||
this.getData(1)
|
||||
|
@ -99,6 +110,7 @@ export default {
|
|||
tableData: [],
|
||||
count: 10,
|
||||
nowIndex: 0,
|
||||
accessProtoArr:["", "UDP", "TCP", "HTTPS", "HTTP"],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -136,6 +148,16 @@ export default {
|
|||
console.log(error);
|
||||
});
|
||||
},
|
||||
protoFormat(row) {
|
||||
var access_proto = row.access_proto
|
||||
if (row.access_proto == 0) {
|
||||
switch (row.protocol) {
|
||||
case 6: access_proto = 2; break;
|
||||
case 17: access_proto = 1; break;
|
||||
}
|
||||
}
|
||||
return this.accessProtoArr[access_proto]
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue