添加ip审计功能

This commit is contained in:
bjdgyc
2021-08-05 18:20:13 +08:00
parent 1bb76e5d60
commit 0d4d2bb3c4
15 changed files with 173 additions and 32 deletions

View File

@@ -1,6 +1,7 @@
package handler
import (
"bufio"
"encoding/binary"
"net"
"time"
@@ -9,7 +10,7 @@ import (
"github.com/bjdgyc/anylink/sessdata"
)
func LinkCstp(conn net.Conn, cSess *sessdata.ConnSession) {
func LinkCstp(conn net.Conn, bufRW *bufio.ReadWriter, cSess *sessdata.ConnSession) {
defer func() {
base.Debug("LinkCstp return", cSess.IpAddr)
_ = conn.Close()
@@ -23,7 +24,7 @@ func LinkCstp(conn net.Conn, cSess *sessdata.ConnSession) {
dead = time.Duration(cSess.CstpDpd+5) * time.Second
)
go cstpWrite(conn, cSess)
go cstpWrite(conn, bufRW, cSess)
for {
@@ -35,7 +36,7 @@ func LinkCstp(conn net.Conn, cSess *sessdata.ConnSession) {
}
// hdata := make([]byte, BufferSize)
pl := getPayload()
n, err = conn.Read(pl.Data)
n, err = bufRW.Read(pl.Data)
if err != nil {
base.Error("read hdata: ", err)
return
@@ -77,7 +78,7 @@ func LinkCstp(conn net.Conn, cSess *sessdata.ConnSession) {
}
}
func cstpWrite(conn net.Conn, cSess *sessdata.ConnSession) {
func cstpWrite(conn net.Conn, bufRW *bufio.ReadWriter, cSess *sessdata.ConnSession) {
defer func() {
base.Debug("cstpWrite return", cSess.IpAddr)
_ = conn.Close()

View File

@@ -147,7 +147,7 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) {
base.Debug(buf.String())
hj := w.(http.Hijacker)
conn, _, err := hj.Hijack()
conn, bufRW, err := hj.Hijack()
if err != nil {
base.Error(err)
w.WriteHeader(http.StatusInternalServerError)
@@ -166,5 +166,5 @@ func LinkTunnel(w http.ResponseWriter, r *http.Request) {
return
}
go LinkCstp(conn, cSess)
go LinkCstp(conn, bufRW, cSess)
}

View File

@@ -1,17 +1,25 @@
package handler
import (
"encoding/binary"
"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"
)
func payloadIn(cSess *sessdata.ConnSession, pl *sessdata.Payload) bool {
// 进行Acl规则判断
check := checkLinkAcl(cSess.Group, pl)
if !check {
// 校验不通过直接丢弃
return false
if pl.LType == sessdata.LTypeIPData && pl.PType == 0x00 {
// 进行Acl规则判断
check := checkLinkAcl(cSess.Group, pl)
if !check {
// 校验不通过直接丢弃
return false
}
logAudit(cSess, pl)
}
closed := false
@@ -61,24 +69,23 @@ func checkLinkAcl(group *dbdata.Group, pl *sessdata.Payload) bool {
return true
}
data := pl.Data
ip_dst := waterutil.IPv4Destination(data)
ip_port := waterutil.IPv4DestinationPort(data)
ip_proto := waterutil.IPv4Protocol(data)
ipDst := waterutil.IPv4Destination(pl.Data)
ipPort := waterutil.IPv4DestinationPort(pl.Data)
ipProto := waterutil.IPv4Protocol(pl.Data)
// fmt.Println("sent:", ip_dst, ip_port)
// 优先放行dns端口
for _, v := range group.ClientDns {
if v.Val == ip_dst.String() && ip_port == 53 {
if v.Val == ipDst.String() && ipPort == 53 {
return true
}
}
for _, v := range group.LinkAcl {
// 循环判断ip和端口
if v.IpNet.Contains(ip_dst) {
if v.IpNet.Contains(ipDst) {
// 放行允许ip的ping
if v.Port == ip_port || v.Port == 0 || ip_proto == waterutil.ICMP {
if v.Port == ipPort || v.Port == 0 || ipProto == waterutil.ICMP {
if v.Action == dbdata.Allow {
return true
} else {
@@ -90,3 +97,49 @@ func checkLinkAcl(group *dbdata.Group, pl *sessdata.Payload) bool {
return false
}
// 访问日志审计
func logAudit(cSess *sessdata.ConnSession, pl *sessdata.Payload) {
ipSrc := waterutil.IPv4Source(pl.Data)
ipDst := waterutil.IPv4Destination(pl.Data)
ipPort := waterutil.IPv4DestinationPort(pl.Data)
ipProto := waterutil.IPv4Protocol(pl.Data)
// 只统计 tcp和udp 的访问
switch ipProto {
case waterutil.TCP:
case waterutil.UDP:
default:
return
}
b := getByte34()
key := *b
copy(key[:16], ipSrc)
copy(key[16:32], ipDst)
binary.BigEndian.PutUint16(key[32:34], ipPort)
s := utils.BytesToString(key)
nu := utils.NowSec().Unix()
// 判断已经存在,并且没有过期
v, ok := cSess.IpAuditMap[s]
if ok && nu-v < int64(base.Cfg.AuditInterval) {
// 回收byte对象
putByte34(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(),
}
_ = dbdata.Add(audit)
}

View File

@@ -9,7 +9,12 @@ import (
// 不允许直接修改
// [6] => PType
var plHeader = []byte{'S', 'T', 'F', 0x01, 0x00, 0x00, 0x00, 0x00}
var plHeader = []byte{
'S', 'T', 'F', 1,
0x00, 0x00, /* Length */
0x00, /* Type */
0x00, /* Unknown */
}
var plPool = sync.Pool{
New: func() interface{} {
@@ -64,3 +69,21 @@ func putByte(b *[]byte) {
*b = (*b)[:BufferSize]
bytePool.Put(b)
}
// 长度 34 小对象
var byte34Pool = sync.Pool{
New: func() interface{} {
b := make([]byte, 34)
return &b
},
}
func getByte34() *[]byte {
b := byte34Pool.Get().(*[]byte)
return b
}
func putByte34(b *[]byte) {
*b = (*b)[:34]
byte34Pool.Put(b)
}

View File

@@ -10,11 +10,10 @@ import (
"os"
"time"
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
"github.com/bjdgyc/anylink/base"
"github.com/bjdgyc/anylink/pkg/proxyproto"
"github.com/gorilla/mux"
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
)
func startTls() {