支持 Mysql

This commit is contained in:
SanJin 2019-09-08 23:14:24 +08:00
parent 56cc2e1ca2
commit 5062db1227
22 changed files with 457 additions and 182 deletions

View File

@ -120,7 +120,7 @@
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
_h += '<tr>'; _h += '<tr>';
var last_update_time = data[i].last_update_time.replace("T", " ").replace("+08:00", " "); var last_update_time = data[i].last_update_time.replace("T", " ").replace("+08:00", "").replace("Z", "");
last_update_time = last_update_time.substring(0, 19); last_update_time = last_update_time.substring(0, 19);
last_update_time = last_update_time.replace(/-/g, '/'); last_update_time = last_update_time.replace(/-/g, '/');
var timestamp = new Date(last_update_time).getTime(); var timestamp = new Date(last_update_time).getTime();
@ -143,7 +143,7 @@
_h += ' <td class="td" style="text-align: center;"><span class="closex"></span></td>'; _h += ' <td class="td" style="text-align: center;"><span class="closex"></span></td>';
} }
if (data[i].dart_status == 1) { if (data[i].deep_status == 1) {
_h += ' <td class="td" style="text-align: center;"><span class="openx"></span></td>'; _h += ' <td class="td" style="text-align: center;"><span class="openx"></span></td>';
} else { } else {
_h += ' <td class="td" style="text-align: center;"><span class="closex"></span></td>'; _h += ' <td class="td" style="text-align: center;"><span class="closex"></span></td>';

View File

@ -391,7 +391,7 @@
_h += ' <td><span class="info" onclick="show(' + data.result[i].id + ')">点击查看</span></td>'; _h += ' <td><span class="info" onclick="show(' + data.result[i].id + ')">点击查看</span></td>';
_h += ' <td class="td"><span class="cinfo">' + data.result[i].info.length + '</span></td>'; _h += ' <td class="td"><span class="cinfo">' + data.result[i].info.length + '</span></td>';
_h += ' <td class="td">' + data.result[i].create_time.replace("T", " ").replace("+08:00", " ") + '</td>'; _h += ' <td class="td">' + data.result[i].create_time.replace("T", " ").replace("+08:00", " ").replace("Z", "") + '</td>';
_h += '</tr>'; _h += '</tr>';
} }

View File

@ -59,7 +59,7 @@
<tr id="tr{{$e.type}}" data-id="{{$e.id}}"> <tr id="tr{{$e.type}}" data-id="{{$e.id}}">
<td style="font-weight: bold;">{{$e.setting_name}} </td> <td style="font-weight: bold;">{{$e.setting_name}} </td>
<td>{{$e.setting_dis}}</td> <td>{{$e.setting_dis}}</td>
<td id="trx{{$e.type}}"><script>var t={{$e.update_time}}; document.getElementById("trx{{$e.type}}").innerHTML= t.replace("T", " ").replace("+08:00", " ");</script></td> <td id="trx{{$e.type}}"><script>var t={{$e.update_time}}; document.getElementById("trx{{$e.type}}").innerHTML= t.replace("T", " ").replace("+08:00", " ").replace("Z", "");</script></td>
<td>{{if ne $e.info ""}} <td>{{if ne $e.info ""}}
<span class="yes_config">已配置</span> <span class="yes_config">已配置</span>
{{else}} {{else}}

View File

@ -1,5 +1,5 @@
[rpc] [rpc]
status = 1 # 模式 0关闭 1服务端 2客户端 status = 0 # 模式 0关闭 1服务端 2客户端
addr = 0.0.0.0:7879 # RPC 服务端地址 or 客户端地址 addr = 0.0.0.0:7879 # RPC 服务端地址 or 客户端地址
name = Server # 状态1 服务端 名称 状态2 客户端 名称 name = Server # 状态1 服务端 名称 状态2 客户端 名称
@ -7,8 +7,9 @@ name = Server # 状态1 服务端 名称 状
addr = 0.0.0.0:9001 # 管理后台启动地址 addr = 0.0.0.0:9001 # 管理后台启动地址
account = admin # 登录账号 account = admin # 登录账号
password = admin # 登录密码 password = admin # 登录密码
db_type = sqlite # 1 sqlite 2 mysql db_type = sqlite # sqlite or mysql
db_max_open = 5 # 最大连接池0 表示无限制 db_max_open = 50 # 最大连接池0 表示无限制
db_max_idle = 50 # 最大空闲数0 表示无限制
db_str = ./db/hfish.db?cache=shared&mode=rwc # sqlite or mysql 连接字符串 db_str = ./db/hfish.db?cache=shared&mode=rwc # sqlite or mysql 连接字符串
# sqlite : ./db/hfish.db?cache=shared&mode=rwc # sqlite : ./db/hfish.db?cache=shared&mode=rwc
# mysql : 账号:密码@tcp(地址:端口)/数据库名?charset=utf8&parseTime=true&loc=Local # mysql : 账号:密码@tcp(地址:端口)/数据库名?charset=utf8&parseTime=true&loc=Local
@ -54,7 +55,7 @@ addr = 0.0.0.0:3306 # Mysql 服务端地址 注意
files = /etc/passwd,/etc/group # Mysql 服务端读取客户端任意文件; 多写逗号分隔,会随机取 files = /etc/passwd,/etc/group # Mysql 服务端读取客户端任意文件; 多写逗号分隔,会随机取
[telnet] [telnet]
status = 0 # 是否启动 Telnet 0 关闭 1 启动 status = 1 # 是否启动 Telnet 0 关闭 1 启动
addr = 0.0.0.0:23 # Telnet 服务端地址 注意端口冲突 addr = 0.0.0.0:23 # Telnet 服务端地址 注意端口冲突
[ftp] [ftp]

View File

@ -13,9 +13,10 @@ import (
"HFish/view/data" "HFish/view/data"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"HFish/error" "HFish/error"
"sync"
) )
func AlertMail(model string, typex string, agent string, ipx string, country string, region string, city string, infox string) { func AlertMail(model string, typex string, agent string, ipx string, country string, region string, city string, infox string, wg *sync.WaitGroup) {
// 判断邮件通知 // 判断邮件通知
try.Try(func() { try.Try(func() {
// 只有新加入才会发送邮件通知 // 只有新加入才会发送邮件通知
@ -55,11 +56,14 @@ func AlertMail(model string, typex string, agent string, ipx string, country str
send.SendMail(config[4:], "[HFish]提醒你,"+typex+"有鱼上钩!", text, config) send.SendMail(config[4:], "[HFish]提醒你,"+typex+"有鱼上钩!", text, config)
} }
} }
wg.Done()
}).Catch(func() { }).Catch(func() {
wg.Done()
}) })
} }
func AlertWebHook(id string, model string, typex string, projectName string, agent string, ipx string, country string, region string, city string, infox string, time string) { func AlertWebHook(id string, model string, typex string, projectName string, agent string, ipx string, country string, region string, city string, infox string, time string, wg *sync.WaitGroup) {
// 判断 WebHook 通知 // 判断 WebHook 通知
try.Try(func() { try.Try(func() {
result, err := dbUtil.DB().Table("hfish_setting").Fields("status", "info").Where("type", "=", "webHook").First() result, err := dbUtil.DB().Table("hfish_setting").Fields("status", "info").Where("type", "=", "webHook").First()
@ -106,7 +110,10 @@ func AlertWebHook(id string, model string, typex string, projectName string, age
defer resp.Body.Close() defer resp.Body.Close()
//defer request.Body.Close() //defer request.Body.Close()
} }
wg.Done()
}).Catch(func() { }).Catch(func() {
wg.Done()
}) })
} }

View File

@ -1,11 +1,11 @@
package dbUtil package dbUtil
import ( import (
"github.com/gohouse/gorose"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
"HFish/utils/conf" "HFish/utils/conf"
"HFish/utils/log" "HFish/utils/log"
"github.com/gohouse/gorose"
) )
var engin *gorose.Engin var engin *gorose.Engin
@ -16,15 +16,16 @@ func init() {
dbType := conf.Get("admin", "db_type") dbType := conf.Get("admin", "db_type")
dbStr := conf.Get("admin", "db_str") dbStr := conf.Get("admin", "db_str")
dbMaxOpen := conf.GetInt("admin", "db_max_open") dbMaxOpen := conf.GetInt("admin", "db_max_open")
dbMaxIdle := conf.GetInt("admin", "db_max_idle")
if dbType == "sqlite" { if dbType == "sqlite" {
engin, err = gorose.Open(&gorose.Config{Driver: "sqlite3", Dsn: dbStr, SetMaxOpenConns: dbMaxOpen}) engin, err = gorose.Open(&gorose.Config{Driver: "sqlite3", Dsn: dbStr, SetMaxOpenConns: dbMaxOpen, SetMaxIdleConns: dbMaxIdle})
if err != nil { if err != nil {
log.Pr("HFish", "127.0.0.1", "连接 Sqlite 数据库失败", err) log.Pr("HFish", "127.0.0.1", "连接 Sqlite 数据库失败", err)
} }
} else if dbType == "mysql" { } else if dbType == "mysql" {
engin, err = gorose.Open(&gorose.Config{Driver: "mysql", Dsn: dbStr, SetMaxOpenConns: dbMaxOpen}) engin, err = gorose.Open(&gorose.Config{Driver: "mysql", Dsn: dbStr, SetMaxOpenConns: dbMaxOpen, SetMaxIdleConns: dbMaxIdle})
if err != nil { if err != nil {
log.Pr("HFish", "127.0.0.1", "连接 Mysql 数据库失败", err) log.Pr("HFish", "127.0.0.1", "连接 Mysql 数据库失败", err)

12
core/pool/pool.go Normal file
View File

@ -0,0 +1,12 @@
package pool
import (
"sync"
"github.com/panjf2000/ants"
)
func New(size int) (sync.WaitGroup, *ants.Pool) {
wg := sync.WaitGroup{}
pool, _ := ants.NewPool(size)
return wg, pool
}

View File

@ -11,6 +11,9 @@ import (
"HFish/core/report" "HFish/core/report"
"HFish/utils/is" "HFish/utils/is"
"HFish/core/rpc/client" "HFish/core/rpc/client"
"sync"
"github.com/panjf2000/ants"
"HFish/core/pool"
) )
type ftpCommand interface { type ftpCommand interface {
@ -329,24 +332,42 @@ func (cmd commandPass) RequireAuth() bool {
return false return false
} }
// 加入线程池
var (
wg sync.WaitGroup
poolX *ants.Pool
)
func init() {
wg, poolX = pool.New(10)
defer poolX.Release()
}
func (cmd commandPass) Execute(conn *ftpConn, param string) { func (cmd commandPass) Execute(conn *ftpConn, param string) {
info := conn.reqUser + "&&" + param wg.Add(1)
arr := strings.Split(conn.conn.RemoteAddr().String(), ":") poolX.Submit(func() {
// 判断是否为 RPC 客户端 info := conn.reqUser + "&&" + param
if is.Rpc() { arr := strings.Split(conn.conn.RemoteAddr().String(), ":")
go client.ReportResult("FTP", "", arr[0], info, "0")
} else {
go report.ReportFTP(arr[0], "本机", info)
}
if conn.driver.Authenticate(conn.reqUser, param) { // 判断是否为 RPC 客户端
conn.user = conn.reqUser if is.Rpc() {
conn.reqUser = "" go client.ReportResult("FTP", "", arr[0], info, "0")
conn.writeMessage(230, "Password ok, continue") } else {
} else { go report.ReportFTP(arr[0], "本机", info)
conn.writeMessage(530, "Incorrect password, not logged in") }
}
if conn.driver.Authenticate(conn.reqUser, param) {
conn.user = conn.reqUser
conn.reqUser = ""
conn.writeMessage(230, "Password ok, continue")
} else {
conn.writeMessage(530, "Incorrect password, not logged in")
}
wg.Done()
})
} }
// commandPasv responds to the PASV FTP command. // commandPasv responds to the PASV FTP command.

View File

@ -23,7 +23,6 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"io" "io"
"log"
"net" "net"
"os" "os"
"strconv" "strconv"
@ -32,6 +31,8 @@ import (
"HFish/utils/is" "HFish/utils/is"
"HFish/core/rpc/client" "HFish/core/rpc/client"
"HFish/core/report" "HFish/core/report"
"HFish/core/pool"
"HFish/utils/log"
) )
var linkedHashMap = LinkedHashMap.NewLinkedHashMap() var linkedHashMap = LinkedHashMap.NewLinkedHashMap()
@ -407,87 +408,91 @@ func tcpServer(address string, rateLimitChan chan int, exitChan chan int) {
exitChan <- 1 exitChan <- 1
} }
log.Println("[Memcache TCP] Listning on " + address)
defer l.Close() defer l.Close()
wg, poolX := pool.New(10)
defer poolX.Release()
for { for {
conn, err := l.Accept() wg.Add(1)
trackID := randNumber(100000, 999999) poolX.Submit(func() {
time.Sleep(time.Second * 2)
if err != nil { conn, err := l.Accept()
fmt.Println(err.Error())
continue
}
go func() { if err != nil {
skip := false log.Pr("Mysql", "127.0.0.1", "Mysql 连接失败", err)
reader := bufio.NewReader(conn)
log.Printf("[Memcache TCP %d] Accepted a client socket from %s\n", trackID, conn.RemoteAddr().String())
arr := strings.Split(conn.RemoteAddr().String(), ":")
// 判断是否为 RPC 客户端
var id string
if is.Rpc() {
id = client.ReportResult("MEMCACHE", "", arr[0], conn.RemoteAddr().String()+" 已经连接", "0")
} else {
id = strconv.FormatInt(report.ReportMemCche(arr[0], "本机", conn.RemoteAddr().String()+" 已经连接"), 10)
} }
for { go func() {
<-rateLimitChan skip := false
str, err := reader.ReadString('\n') reader := bufio.NewReader(conn)
if skip {
skip = false arr := strings.Split(conn.RemoteAddr().String(), ":")
continue
} // 判断是否为 RPC 客户端
if err != nil { var id string
log.Printf("[Memcache TCP %d] Closed a client socket.\n", trackID)
conn.Close()
break
}
str = strings.TrimSpace(str)
if is.Rpc() { if is.Rpc() {
go client.ReportResult("MEMCACHE", "", "", "&&"+str, id) id = client.ReportResult("MEMCACHE", "", arr[0], conn.RemoteAddr().String()+" 已经连接", "0")
} else { } else {
go report.ReportUpdateMemCche(id, "&&"+str) id = strconv.FormatInt(report.ReportMemCche(arr[0], "本机", conn.RemoteAddr().String()+" 已经连接"), 10)
} }
log.Printf("[Memcache TCP %d] Client request: %s.\n", trackID, str)
args := strings.Split(str, " ")
function, exist := commands[args[0]]
if !exist {
conn.Write(RESPONSE_ERROR)
continue
}
args = args[1:]
for { for {
response, requiredBytes := function(args) <-rateLimitChan
if requiredBytes == -1 { str, err := reader.ReadString('\n')
if skip {
skip = false
continue
}
if err != nil {
conn.Close() conn.Close()
break break
} }
if requiredBytes == 0 { str = strings.TrimSpace(str)
conn.Write(response)
break if is.Rpc() {
go client.ReportResult("MEMCACHE", "", "", "&&"+str, id)
} else {
go report.ReportUpdateMemCche(id, "&&"+str)
} }
data := make([]byte, requiredBytes) args := strings.Split(str, " ")
_, err = io.ReadFull(reader, data) function, exist := commands[args[0]]
if err != nil { if !exist {
break conn.Write(RESPONSE_ERROR)
continue
} }
skip = true
args = append(args, string(data)) args = args[1:]
for {
response, requiredBytes := function(args)
if requiredBytes == -1 {
conn.Close()
break
}
if requiredBytes == 0 {
conn.Write(response)
break
}
data := make([]byte, requiredBytes)
_, err = io.ReadFull(reader, data)
if err != nil {
break
}
skip = true
args = append(args, string(data))
}
} }
} }()
}()
wg.Done()
})
} }
} }
@ -505,8 +510,6 @@ func udpServer(address string, rateLimitChan chan int, exitChan chan int) {
exitChan <- 1 exitChan <- 1
} }
log.Println("[Memcache UDP] Listning on " + address)
go func() { go func() {
buf := make([]byte, 1500) buf := make([]byte, 1500)
for { for {
@ -523,7 +526,7 @@ func udpServer(address string, rateLimitChan chan int, exitChan chan int) {
if request == "" { if request == "" {
continue continue
} }
log.Printf("[Memcache UDP] Client request: [%s] from: %s\n", request, addr.String())
args := strings.Split(request, " ") args := strings.Split(request, " ")
function, exist := commands[args[0]] function, exist := commands[args[0]]
if !exist { if !exist {

View File

@ -13,6 +13,8 @@ import (
"HFish/utils/is" "HFish/utils/is"
"HFish/core/rpc/client" "HFish/core/rpc/client"
"strconv" "strconv"
"HFish/core/pool"
"time"
) )
//读取文件时每次读取的字节数 //读取文件时每次读取的字节数
@ -47,26 +49,38 @@ func Start(addr string, files string) {
// 读取文件列表 // 读取文件列表
fileNames = strings.Split(files, ",") fileNames = strings.Split(files, ",")
wg, poolX := pool.New(10)
defer poolX.Release()
for { for {
conn, _ := listener.Accept() wg.Add(1)
ip, _, _ := net.SplitHostPort(conn.RemoteAddr().String()) poolX.Submit(func() {
time.Sleep(time.Second * 2)
//由于文件最后保存的文件名包含ip地址为了本地测试加了这个 conn, err := listener.Accept()
if ip == "::1" {
ip = "localhost"
}
//这里记录每个客户端连接的次数,实现获取多个文件 if err != nil {
_, ok := recordClient[ip] log.Pr("Mysql", "127.0.0.1", "Mysql 连接失败", err)
if ok {
if recordClient[ip] < len(fileNames)-1 {
recordClient[ip] += 1
} }
} else {
recordClient[ip] = 0
}
go connectionClientHandler(conn) arr := strings.Split(conn.RemoteAddr().String(), ":")
ip := arr[0]
//这里记录每个客户端连接的次数,实现获取多个文件
_, ok := recordClient[ip]
if ok {
if recordClient[ip] < len(fileNames)-1 {
recordClient[ip] += 1
}
} else {
recordClient[ip] = 0
}
go connectionClientHandler(conn)
wg.Done()
})
} }
} }

View File

@ -11,6 +11,8 @@ import (
"HFish/utils/is" "HFish/utils/is"
"HFish/core/rpc/client" "HFish/core/rpc/client"
"fmt" "fmt"
"HFish/core/pool"
"time"
) )
var kvData map[string]string var kvData map[string]string
@ -23,25 +25,37 @@ func Start(addr string) {
defer netListen.Close() defer netListen.Close()
wg, poolX := pool.New(10)
defer poolX.Release()
for { for {
conn, err := netListen.Accept() wg.Add(1)
if err != nil { poolX.Submit(func() {
continue time.Sleep(time.Second * 2)
}
arr := strings.Split(conn.RemoteAddr().String(), ":")
// 判断是否为 RPC 客户端 conn, err := netListen.Accept()
var id string
if is.Rpc() { if err != nil {
id = client.ReportResult("REDIS", "", arr[0], conn.RemoteAddr().String()+" 已经连接", "0") log.Pr("Redis", "127.0.0.1", "Redis 连接失败", err)
} else { }
id = strconv.FormatInt(report.ReportRedis(arr[0], "本机", conn.RemoteAddr().String()+" 已经连接"), 10)
}
log.Pr("Redis", arr[0], "已经连接") arr := strings.Split(conn.RemoteAddr().String(), ":")
go handleConnection(conn, id) // 判断是否为 RPC 客户端
var id string
if is.Rpc() {
id = client.ReportResult("REDIS", "", arr[0], conn.RemoteAddr().String()+" 已经连接", "0")
} else {
id = strconv.FormatInt(report.ReportRedis(arr[0], "本机", conn.RemoteAddr().String()+" 已经连接"), 10)
}
log.Pr("Redis", arr[0], "已经连接")
go handleConnection(conn, id)
wg.Done()
})
} }
} }

View File

@ -8,12 +8,14 @@ import (
"os" "os"
"HFish/utils/is" "HFish/utils/is"
"HFish/core/rpc/client" "HFish/core/rpc/client"
"strconv"
"HFish/core/report" "HFish/core/report"
"HFish/utils/log" "HFish/utils/log"
"github.com/bitly/go-simplejson" "github.com/bitly/go-simplejson"
"HFish/utils/json" "HFish/utils/json"
"HFish/utils/file" "HFish/utils/file"
"strconv"
"time"
"HFish/core/pool"
) )
// 服务端连接 // 服务端连接
@ -27,29 +29,38 @@ func server(address string, exitChan chan int) {
defer l.Close() defer l.Close()
wg, poolX := pool.New(10)
defer poolX.Release()
for { for {
conn, err := l.Accept() wg.Add(1)
poolX.Submit(func() {
time.Sleep(time.Second * 2)
if err != nil { conn, err := l.Accept()
fmt.Println(err.Error())
continue
}
arr := strings.Split(conn.RemoteAddr().String(), ":") if err != nil {
log.Pr("Telnet", "127.0.0.1", "Telnet 连接失败", err)
}
// 判断是否为 RPC 客户端 arr := strings.Split(conn.RemoteAddr().String(), ":")
var id string
if is.Rpc() { var id string
id = client.ReportResult("TELNET", "", arr[0], conn.RemoteAddr().String()+" 已经连接", "0")
} else {
id = strconv.FormatInt(report.ReportTelnet(arr[0], "本机", conn.RemoteAddr().String()+" 已经连接"), 10)
}
log.Pr("Telnet", arr[0], "已经连接") // 判断是否为 RPC 客户端
if is.Rpc() {
id = client.ReportResult("TELNET", "", arr[0], conn.RemoteAddr().String()+" 已经连接", "0")
} else {
id = strconv.FormatInt(report.ReportTelnet(arr[0], "本机", conn.RemoteAddr().String()+" 已经连接"), 10)
}
// 根据连接开启会话, 这个过程需要并行执行 log.Pr("Telnet", arr[0], "已经连接")
go handleSession(conn, exitChan, id)
// 根据连接开启会话, 这个过程需要并行执行
go handleSession(conn, exitChan, id)
wg.Done()
})
} }
} }

View File

@ -10,6 +10,9 @@ import (
"strings" "strings"
"HFish/core/alert" "HFish/core/alert"
"HFish/utils/conf" "HFish/utils/conf"
"HFish/core/pool"
"sync"
"github.com/panjf2000/ants"
) )
type HFishInfo struct { type HFishInfo struct {
@ -26,16 +29,37 @@ type HFishInfo struct {
time string time string
} }
var (
wg sync.WaitGroup
poolX *ants.Pool
wgUpdate sync.WaitGroup
poolUpdateX *ants.Pool
)
func init() {
wg, poolX = pool.New(10)
defer poolX.Release()
wgUpdate, poolUpdateX = pool.New(10)
defer poolUpdateX.Release()
}
// 通知模块 // 通知模块
func alertx(id string, model string, typex string, projectName string, agent string, ipx string, country string, region string, city string, infox string, time string) { func alertx(id string, model string, typex string, projectName string, agent string, ipx string, country string, region string, city string, infox string, timex string) {
// 邮件通知 wg.Add(1)
alert.AlertMail(model, typex, agent, ipx, country, region, city, infox) poolX.Submit(func() {
time.Sleep(time.Second * 2)
// WebHook // 邮件通知
alert.AlertWebHook(id, model, typex, projectName, agent, ipx, country, region, city, infox, time) alert.AlertMail(model, typex, agent, ipx, country, region, city, infox, &wg)
// 大数据展示 // WebHook
//alert.AlertDataWs(model, typex, projectName, agent, ipx, country, region, city, time) alert.AlertWebHook(id, model, typex, projectName, agent, ipx, country, region, city, infox, timex, &wg)
// 大数据展示
//alert.AlertDataWs(model, typex, projectName, agent, ipx, country, region, city, time)
})
} }
// 上报 集群 状态 // 上报 集群 状态
@ -113,6 +137,7 @@ func isWhiteIp(ip string) bool {
// 通用的插入 // 通用的插入
func insertInfo(typex string, projectName string, agent string, ipx string, country string, region string, city string, info string) int64 { func insertInfo(typex string, projectName string, agent string, ipx string, country string, region string, city string, info string) int64 {
id, err := dbUtil.DB().Table("hfish_info").Data(map[string]interface{}{ id, err := dbUtil.DB().Table("hfish_info").Data(map[string]interface{}{
"type": typex, "type": typex,
"project_name": projectName, "project_name": projectName,
@ -128,38 +153,54 @@ func insertInfo(typex string, projectName string, agent string, ipx string, coun
if err != nil { if err != nil {
log.Pr("HFish", "127.0.0.1", "插入上钩信息失败", err) log.Pr("HFish", "127.0.0.1", "插入上钩信息失败", err)
} }
return id return id
} }
// 更新
func updateInfoCore(id string, info string) {
time.Sleep(time.Second * 2)
try.Try(func() {
var sql string
// 此处为了兼容 Mysql + Sqlite
dbType := conf.Get("admin", "db_type")
if dbType == "sqlite" {
sql = `
UPDATE hfish_info
SET info = info||?
WHERE
id = ?;
`
} else if dbType == "mysql" {
sql = `
UPDATE hfish_info
SET info = CONCAT(info, ?)
WHERE
id = ?;
`
}
_, err := dbUtil.DB().Execute(sql, info, id)
if err != nil {
log.Pr("HFish", "127.0.0.1", "更新上钩信息失败", err)
}
wgUpdate.Done()
}).Catch(func() {
wgUpdate.Done()
})
}
// 通用的更新 // 通用的更新
func updateInfo(id string, info string) { func updateInfo(id string, info string) {
wgUpdate.Add(1)
var sql string poolUpdateX.Submit(func() {
updateInfoCore(id, info)
// 此处为了兼容 Mysql + Sqlite })
dbType := conf.Get("admin", "db_type")
if dbType == "sqlite" {
sql = `
UPDATE hfish_info
SET info = info||?
WHERE
id = ?;
`
} else if dbType == "mysql" {
sql = `
UPDATE hfish_info
SET info = CONCAT(info, ?)
WHERE
id = ?;
`
}
_, err := dbUtil.DB().Execute(sql, info, id)
if err != nil {
log.Pr("HFish", "127.0.0.1", "更新上钩信息失败", err)
}
} }
// 上报 WEB // 上报 WEB
@ -194,6 +235,12 @@ func ReportPlugWeb(projectName string, agent string, ipx string, info string) {
// 上报 SSH // 上报 SSH
func ReportSSH(ipx string, agent string, info string) int64 { func ReportSSH(ipx string, agent string, info string) int64 {
defer func() {
if err := recover(); err != nil {
log.Pr("HFish", "127.0.0.1", "执行SSH插入失败", err)
}
}()
// IP 不在白名单,进行上报 // IP 不在白名单,进行上报
if (isWhiteIp(ipx) == false) { if (isWhiteIp(ipx) == false) {
country, region, city := ip.GetIp(ipx) country, region, city := ip.GetIp(ipx)
@ -206,6 +253,12 @@ func ReportSSH(ipx string, agent string, info string) int64 {
// 更新 SSH 操作 // 更新 SSH 操作
func ReportUpdateSSH(id string, info string) { func ReportUpdateSSH(id string, info string) {
defer func() {
if err := recover(); err != nil {
log.Pr("HFish", "127.0.0.1", "执行SSH更新失败", err)
}
}()
if (id != "0") { if (id != "0") {
go updateInfo(id, info) go updateInfo(id, info)
go alertx(id, "update", "SSH", "SSH蜜罐", "", "", "", "", "", info, time.Now().Format("2006-01-02 15:04:05")) go alertx(id, "update", "SSH", "SSH蜜罐", "", "", "", "", "", info, time.Now().Format("2006-01-02 15:04:05"))

Binary file not shown.

24
db/sql/hfish_colony.sql Normal file
View File

@ -0,0 +1,24 @@
-- ----------------------------
-- Table structure for `hfish_colony`
-- ----------------------------
DROP TABLE IF EXISTS `hfish_colony`;
CREATE TABLE `hfish_colony` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`agent_name` varchar(20) NOT NULL DEFAULT '',
`agent_ip` varchar(20) NOT NULL DEFAULT '',
`web_status` int(2) NOT NULL DEFAULT '0',
`deep_status` int(2) NOT NULL DEFAULT '0',
`ssh_status` int(2) NOT NULL DEFAULT '0',
`redis_status` int(2) NOT NULL DEFAULT '0',
`mysql_status` int(2) NOT NULL DEFAULT '0',
`http_status` int(2) NOT NULL DEFAULT '0',
`telnet_status` int(2) NOT NULL DEFAULT '0',
`ftp_status` int(2) NOT NULL DEFAULT '0',
`mem_cache_status` int(2) NOT NULL DEFAULT '0',
`plug_status` int(2) NOT NULL DEFAULT '0',
`last_update_time` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `un_agent` (`agent_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
SET FOREIGN_KEY_CHECKS = 1;

19
db/sql/hfish_info.sql Normal file
View File

@ -0,0 +1,19 @@
-- ----------------------------
-- Table structure for `hfish_info`
-- ----------------------------
DROP TABLE IF EXISTS `hfish_info`;
CREATE TABLE `hfish_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(20) NOT NULL DEFAULT '',
`project_name` varchar(20) NOT NULL DEFAULT '',
`agent` varchar(20) NOT NULL DEFAULT '',
`ip` varchar(20) NOT NULL DEFAULT '',
`country` varchar(10) NOT NULL DEFAULT '',
`region` varchar(10) NOT NULL DEFAULT '',
`city` varchar(10) NOT NULL,
`info` text NOT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
SET FOREIGN_KEY_CHECKS = 1;

24
db/sql/hfish_setting.sql Normal file
View File

@ -0,0 +1,24 @@
-- ----------------------------
-- Table structure for `hfish_setting`
-- ----------------------------
DROP TABLE IF EXISTS `hfish_setting`;
CREATE TABLE `hfish_setting` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(50) NOT NULL DEFAULT '',
`info` varchar(50) NOT NULL DEFAULT '',
`update_time` datetime NOT NULL,
`status` int(2) NOT NULL DEFAULT '0',
`setting_name` varchar(50) NOT NULL DEFAULT '',
`setting_dis` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `index_key` (`type`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
-- ----------------------------
-- Records of `hfish_setting`
-- ----------------------------
BEGIN;
INSERT INTO `hfish_setting` VALUES ('1', 'mail', '', '2019-09-02 20:15:00', '0', 'E-mail 群发', '群发邮件SMTP服务器配置'), ('2', 'alertMail', '', '2019-09-02 18:58:12', '0', 'E-mail 通知', '蜜罐告警会通过邮件告知信息'), ('3', 'webHook', '', '2019-09-03 11:49:00', '0', 'WebHook 通知', '蜜罐告警会请求指定API告知信息'), ('4', 'whiteIp', '', '2019-09-02 20:15:00', '0', 'IP 白名单', '蜜罐上钩会过滤掉白名单IP');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -19,6 +19,9 @@ const (
ErrFailConfigCode = 1004 ErrFailConfigCode = 1004
ErrFailConfigMsg = "请配置后在启用" ErrFailConfigMsg = "请配置后在启用"
ErrFailPlugCode = 1005
ErrFailPlugMsg = "上报信息错误"
) )
func Check(e error, tips string) { func Check(e error, tips string) {

8
go.mod
View File

@ -12,13 +12,17 @@ require (
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/gin-gonic/gin v1.4.0 github.com/gin-gonic/gin v1.4.0
github.com/gliderlabs/ssh v0.2.2 github.com/gliderlabs/ssh v0.2.2
github.com/gorilla/websocket v1.4.1 // indirect github.com/go-sql-driver/mysql v1.4.1
github.com/gohouse/gorose v0.0.0-20190830103550-ad3ce0985b9e
github.com/gorilla/websocket v1.4.1
github.com/ipipdotnet/ipdb-go v1.2.0 github.com/ipipdotnet/ipdb-go v1.2.0
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869
github.com/kr/pretty v0.1.0 // indirect github.com/kr/pretty v0.1.0 // indirect
github.com/mattn/go-sqlite3 v1.11.0 github.com/mattn/go-sqlite3 v1.11.0
github.com/panjf2000/ants v1.2.0
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5
google.golang.org/appengine v1.6.2 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ini.v1 v1.46.0 gopkg.in/ini.v1 v1.46.0

25
go.sum
View File

@ -20,6 +20,14 @@ github.com/gin-gonic/gin v1.4.0 h1:3tMoCCfM7ppqsR0ptz/wi1impNpT7/9wQtMZ8lr1mCQ=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/gohouse/gocar v0.0.2 h1:pzf7zhDSuWa7GpSszi6mEQslp+Pthypn5yi8c+zomK0=
github.com/gohouse/gocar v0.0.2/go.mod h1:zE2+ip1u8MKvLyqTKxQIeZEI4lN1XPXK7AZdbikD6RE=
github.com/gohouse/gorose v0.0.0-20190830103550-ad3ce0985b9e h1:gvQbXcpfZzyVnUOUDYdy2TRm0z8WATHgHQ+CJZYjFSE=
github.com/gohouse/gorose v0.0.0-20190830103550-ad3ce0985b9e/go.mod h1:+1d8SYnSZQxO01R1Vj65tKQ873DN6hHgVtJ9CmGPpQ0=
github.com/gohouse/t v0.0.5 h1:ol19APh/fC7usS2XgZ7i3Usgo8eF9xszOPfGPhR6Zg8=
github.com/gohouse/t v0.0.5/go.mod h1:CUtvHWNU9GY0Lvk+gcrhs9Ixmei7J5QQXiAvqcwccsk=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
@ -41,12 +49,15 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc= github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q= github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A/Q=
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/panjf2000/ants v1.2.0 h1:Ufw4aDz9RqH1RVblx2W9L9Uv5vSX5apbX5+peR7LQ5k=
github.com/panjf2000/ants v1.2.0/go.mod h1:AaACblRPzq35m1g3enqYcxspbbiOJJYaxU2wMpm1cXY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
@ -61,15 +72,29 @@ github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:58fnuSXlxZmFdJyvtTFVmVhcMLU6v5fEb/ok4wyqtNU=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c h1:+EXw7AwNOKzPFXMZ1yNjO40aWCh3PIquJB2fYlv9wcs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
google.golang.org/appengine v1.6.2 h1:j8RI1yW0SkI+paT6uGwMlrMI/6zwYA6/CFil8rxOzGI=
google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

View File

@ -17,7 +17,7 @@ func main() {
} else if args[1] == "init" || args[1] == "--init" { } else if args[1] == "init" || args[1] == "--init" {
setting.Init() setting.Init()
} else if args[1] == "version" || args[1] == "--version" { } else if args[1] == "version" || args[1] == "--version" {
fmt.Println("v0.3") fmt.Println("v0.3.1")
} else if args[1] == "run" || args[1] == "--run" { } else if args[1] == "run" || args[1] == "--run" {
setting.Run() setting.Run()
} else { } else {

View File

@ -10,6 +10,7 @@ import (
"HFish/core/rpc/client" "HFish/core/rpc/client"
"HFish/utils/is" "HFish/utils/is"
"HFish/utils/log" "HFish/utils/log"
"fmt"
) )
// 上报WEB蜜罐 // 上报WEB蜜罐
@ -30,6 +31,8 @@ func ReportWeb(c *gin.Context) {
"code": error.ErrFailApiKeyCode, "code": error.ErrFailApiKeyCode,
"msg": error.ErrFailApiKeyMsg, "msg": error.ErrFailApiKeyMsg,
}) })
return
} else { } else {
// 判断是否为 RPC 客户端 // 判断是否为 RPC 客户端
@ -64,6 +67,8 @@ func ReportDeepWeb(c *gin.Context) {
"code": error.ErrFailApiKeyCode, "code": error.ErrFailApiKeyCode,
"msg": error.ErrFailApiKeyMsg, "msg": error.ErrFailApiKeyMsg,
}) })
return
} else { } else {
// 判断是否为 RPC 客户端 // 判断是否为 RPC 客户端
@ -80,26 +85,60 @@ func ReportDeepWeb(c *gin.Context) {
} }
} }
type PlugInfo struct {
Name string `json:"name"`
Ip string `json:"ip"`
SecKey string `json:"sec_key"`
Info map[string]interface{} `json:"info"`
}
// 蜜罐插件API // 蜜罐插件API
func ReportPlugWeb(c *gin.Context) { func ReportPlugWeb(c *gin.Context) {
name := c.PostForm("name") var info PlugInfo
info := c.PostForm("info") err := c.BindJSON(&info)
secKey := c.PostForm("sec_key")
ip := c.PostForm("ip") if err != nil {
fmt.Println(err)
log.Pr("HFish", "127.0.0.1", "插件上报信息错误", err)
c.JSON(http.StatusOK, gin.H{
"code": error.ErrFailPlugCode,
"msg": error.ErrFailPlugMsg,
"data": err,
})
return
}
args := ""
if len(info.Info) != 0 {
for k, v := range info.Info["args"].(map[string]interface{}) {
if args == "" {
args += k + "=" + v.(string)
} else {
args += "&" + k + "=" + v.(string)
}
}
}
data := "Host:" + info.Info["host"].(string) + "&&Url:" + info.Info["uri"].(string) + "&&Method:" + info.Info["method"].(string) + "&&Args:" + args + "&&UserAgent:" + info.Info["http_user_agent"].(string) + "&&RemoteAddr:" + info.Info["remote_addr"].(string) + "&&TimeLocal:" + info.Info["time_local"].(string)
apiSecKey := conf.Get("api", "sec_key") apiSecKey := conf.Get("api", "sec_key")
if secKey != apiSecKey { if info.SecKey != apiSecKey {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"code": error.ErrFailApiKeyCode, "code": error.ErrFailApiKeyCode,
"msg": error.ErrFailApiKeyMsg, "msg": error.ErrFailApiKeyMsg,
}) })
return
} else { } else {
// 判断是否为 RPC 客户端 // 判断是否为 RPC 客户端
if is.Rpc() { if is.Rpc() {
go client.ReportResult("PLUG", name, ip, info, "0") go client.ReportResult("PLUG", info.Name, info.Ip, data, "0")
} else { } else {
go report.ReportPlugWeb(name, "本机", ip, info) go report.ReportPlugWeb(info.Name, "本机", info.Ip, data)
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{