From b5989710e8ad31f7f8bd335e04516b58481ff01a Mon Sep 17 00:00:00 2001 From: Martin/Geno Date: Fri, 10 Aug 2018 17:17:00 +0200 Subject: [PATCH] use duration for blacklist --- config_example.conf | 2 ++ main.go | 4 +-- runtime/config.go | 2 ++ runtime/node.go | 14 +++++----- runtime/node_ssh.go | 9 ++++--- runtime/yanic.go | 60 ++++++++++++++++++++--------------------- websocket/hd_connect.go | 11 +++++--- websocket/server.go | 25 +++++++++-------- 8 files changed, 71 insertions(+), 56 deletions(-) diff --git a/config_example.conf b/config_example.conf index b6dce46..a8b6257 100644 --- a/config_example.conf +++ b/config_example.conf @@ -6,6 +6,8 @@ webroot = "./webroot/" secret = "passw0rd" +blacklist_for = "1w" + ssh_key = "~/.ssh/id_rsa" ssh_ipaddress_prefix = "fd2f:" ssh_timeout = "1m" diff --git a/main.go b/main.go index 0688f67..58b2ac8 100644 --- a/main.go +++ b/main.go @@ -53,9 +53,9 @@ func main() { sshmanager := ssh.NewManager(config.SSHPrivateKey, config.SSHTimeout.Duration) nodesYanic := runtimeYanic.NewNodes(&runtimeYanic.NodesConfig{}) - ws := websocket.NewWebsocketServer(config.Secret, config.SSHIPAddressPrefix, db, nodesYanic) + ws := websocket.NewWebsocketServer(config.Secret, config.SSHIPAddressPrefix, db, config.BlacklistFor.Duration, nodesYanic) - yanic := runtime.NewYanicDB(db, sshmanager, ws.SendNode, ws.SendStats, config.SSHIPAddressPrefix) + yanic := runtime.NewYanicDB(db, sshmanager, config.BlacklistFor.Duration, ws.SendNode, ws.SendStats, config.SSHIPAddressPrefix) if config.YanicEnable { if duration := config.YanicSynchronize.Duration; duration > 0 { diff --git a/runtime/config.go b/runtime/config.go index a8bb972..0f31de4 100644 --- a/runtime/config.go +++ b/runtime/config.go @@ -17,6 +17,8 @@ type Config struct { // path to deliver static content Webroot string `toml:"webroot"` + BlacklistFor duration.Duration `toml:"blacklist_for"` + // auth secret Secret string `toml:"secret"` diff --git a/runtime/node.go b/runtime/node.go index 27e604b..9cb006d 100644 --- a/runtime/node.go +++ b/runtime/node.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "strings" + "time" yanicData "github.com/FreifunkBremen/yanic/data" "github.com/FreifunkBremen/yanic/lib/jsontime" @@ -11,19 +12,19 @@ import ( ) type Node struct { - Lastseen jsontime.Time `json:"lastseen" mapstructure:"-"` + Lastseen jsontime.Time `json:"lastseen" gorm:"-"` NodeID string `json:"node_id" gorm:"primary_key" mapstructure:"node_id"` - Blacklist bool `json:"blacklist"` + Blacklist *time.Time `json:"-"` Address string `json:"ip"` Hostname string `json:"hostname"` - HostnameRespondd string `json:"hostname_Respondd" gorm:"-"` + HostnameRespondd string `json:"hostname_respondd" gorm:"-"` Owner string `json:"owner"` - OwnerRespondd string `json:"owner_Respondd" gorm:"-"` + OwnerRespondd string `json:"owner_respondd" gorm:"-"` Location yanicData.Location `json:"location" gorm:"embedded;embedded_prefix:location_"` - LocationRespondd yanicData.Location `json:"location_Respondd" gorm:"-"` + LocationRespondd yanicData.Location `json:"location_respondd" gorm:"-"` Wireless yanicData.Wireless `json:"wireless" gorm:"embedded;embedded_prefix:wireless_"` - WirelessRespondd yanicData.Wireless `json:"wireless_Respondd" gorm:"-"` + WirelessRespondd yanicData.Wireless `json:"wireless_respondd" gorm:"-"` StatisticsRespondd struct { Wireless yanicData.WirelessStatistics `json:"wireless"` @@ -58,6 +59,7 @@ func (n *Node) Update(node *yanicRuntime.Node, ipPrefix string) { if node == nil { return } + n.Lastseen = jsontime.Now() if nodeinfo := node.Nodeinfo; nodeinfo != nil { n.HostnameRespondd = nodeinfo.Hostname diff --git a/runtime/node_ssh.go b/runtime/node_ssh.go index c26e335..8501e66 100644 --- a/runtime/node_ssh.go +++ b/runtime/node_ssh.go @@ -9,10 +9,10 @@ import ( "github.com/FreifunkBremen/freifunkmanager/ssh" ) -func (n *Node) SSHUpdate(sshmgmt *ssh.Manager) { +func (n *Node) SSHUpdate(sshmgmt *ssh.Manager) bool { client, err := sshmgmt.ConnectTo(n.GetAddress()) if err != nil { - return + return false } defer client.Close() @@ -53,7 +53,7 @@ func (n *Node) SSHUpdate(sshmgmt *ssh.Manager) { echo "radio1"; fi;`) if err != nil { - return + return true } radio := ssh.SSHResultToString(result) ch := GetChannel(n.Wireless.Channel24) @@ -82,7 +82,7 @@ func (n *Node) SSHUpdate(sshmgmt *ssh.Manager) { echo "radio1"; fi;`) if err != nil { - return + return true } radio = ssh.SSHResultToString(result) ch = GetChannel(n.Wireless.Channel5) @@ -103,4 +103,5 @@ func (n *Node) SSHUpdate(sshmgmt *ssh.Manager) { radio, n.Wireless.Channel5)) } } + return true } diff --git a/runtime/yanic.go b/runtime/yanic.go index d8b0b43..558d82e 100644 --- a/runtime/yanic.go +++ b/runtime/yanic.go @@ -7,7 +7,6 @@ import ( log "github.com/sirupsen/logrus" databaseYanic "github.com/FreifunkBremen/yanic/database" - "github.com/FreifunkBremen/yanic/lib/jsontime" runtimeYanic "github.com/FreifunkBremen/yanic/runtime" "github.com/FreifunkBremen/freifunkmanager/ssh" @@ -15,50 +14,52 @@ import ( type YanicDB struct { databaseYanic.Connection - db *gorm.DB - ssh *ssh.Manager - sendNode func(*Node) - sendStats func(*runtimeYanic.GlobalStats) - prefix string + blacklistFor time.Duration + db *gorm.DB + ssh *ssh.Manager + sendNode func(*Node) + sendStats func(*runtimeYanic.GlobalStats) + prefix string } -func NewYanicDB(db *gorm.DB, ssh *ssh.Manager, sendNode func(*Node), sendStats func(*runtimeYanic.GlobalStats), prefix string) *YanicDB { +func NewYanicDB(db *gorm.DB, ssh *ssh.Manager, blacklistFor time.Duration, sendNode func(*Node), sendStats func(*runtimeYanic.GlobalStats), prefix string) *YanicDB { return &YanicDB{ - db: db, - ssh: ssh, - sendNode: sendNode, - sendStats: sendStats, - prefix: prefix, + db: db, + ssh: ssh, + blacklistFor: blacklistFor, + sendNode: sendNode, + sendStats: sendStats, + prefix: prefix, } } func (conn *YanicDB) InsertNode(n *runtimeYanic.Node) { - nodeid := "" - if nodeinfo := n.Nodeinfo; nodeinfo != nil { - nodeid = nodeinfo.NodeID - } else { + if n.Nodeinfo == nil { return } - logger := log.WithField("method", "LearnNode").WithField("node_id", nodeid) + now := time.Now() + + logger := log.WithField("method", "LearnNode").WithField("node_id", n.Nodeinfo.NodeID) + lNode := Node{ - NodeID: nodeid, + NodeID: n.Nodeinfo.NodeID, } if conn.db.First(&lNode).Error == nil { lNode.Update(n, conn.prefix) - conn.db.Model(&lNode).Update(map[string]interface{}{ - "Lastseen": jsontime.Now(), - //"StatsWireless": node.StatsWireless, - //"StatsClients": node.StatsClients, - "Address": lNode.Address, - }) - if lNode.Blacklist { + conn.db.Model(&lNode).Update(map[string]interface{}{"address": lNode.Address}) + + if lNode.Blacklist != nil && lNode.Blacklist.After(now.Add(-conn.blacklistFor)) { logger.Debug("on blacklist") return } conn.sendNode(&lNode) if !lNode.CheckRespondd() { - lNode.SSHUpdate(conn.ssh) - logger.Debug("yanic trigger sshupdate again") + if !lNode.SSHUpdate(conn.ssh) { + conn.db.Model(&lNode).Update(map[string]interface{}{"blacklist": &now}) + logger.Warn("yanic trigger sshupdate failed - set blacklist") + } else { + logger.Debug("yanic trigger sshupdate again") + } } else { logger.Debug("yanic update") } @@ -68,15 +69,14 @@ func (conn *YanicDB) InsertNode(n *runtimeYanic.Node) { if node == nil { return } - node.Lastseen = jsontime.Now() _, err := conn.ssh.RunOn(node.GetAddress(), "uptime") if err != nil { logger.Debugf("set on blacklist: %s", err.Error()) - node.Blacklist = true + node.Blacklist = &now } conn.db.Create(&node) - if !node.Blacklist { + if node.Blacklist == nil { conn.sendNode(node) } } diff --git a/websocket/hd_connect.go b/websocket/hd_connect.go index 377a9d0..d8b8cc2 100644 --- a/websocket/hd_connect.go +++ b/websocket/hd_connect.go @@ -1,6 +1,8 @@ package websocket import ( + "time" + log "github.com/sirupsen/logrus" wsLib "dev.sum7.eu/genofire/golang-lib/websocket" @@ -12,16 +14,19 @@ var wifi24Channels []uint32 var wifi5Channels []uint32 func (ws *WebsocketServer) connectHandler(logger *log.Entry, msg *wsLib.Message) error { - //msg.From.Write(&wsLib.Message{Subject: MessageTypeStats, Body: ws.nodes.Statistics}) var nodes []*runtime.Node var count int - ws.db.Where("blacklist = false").Find(&nodes).Count(&count) + now := time.Now() + + ws.db.Find(&nodes).Count(&count) ws.nodes.Lock() i := 0 for _, node := range nodes { - //TODO skip blacklist + if node.Blacklist != nil && node.Blacklist.After(now.Add(-ws.blacklistFor)) { + continue + } node.Update(ws.nodes.List[node.NodeID], ws.ipPrefix) msg.From.Write(&wsLib.Message{Subject: MessageTypeNode, Body: node}) i++ diff --git a/websocket/server.go b/websocket/server.go index 335ff71..cca2a8f 100644 --- a/websocket/server.go +++ b/websocket/server.go @@ -2,6 +2,7 @@ package websocket import ( "net/http" + "time" wsLib "dev.sum7.eu/genofire/golang-lib/websocket" "github.com/jinzhu/gorm" @@ -10,24 +11,26 @@ import ( ) type WebsocketServer struct { - nodes *runtime.Nodes - db *gorm.DB - secret string - ipPrefix string + nodes *runtime.Nodes + db *gorm.DB + blacklistFor time.Duration + secret string + ipPrefix string inputMSG chan *wsLib.Message ws *wsLib.Server handlers map[string]WebsocketHandlerFunc } -func NewWebsocketServer(secret string, ipPrefix string, db *gorm.DB, nodes *runtime.Nodes) *WebsocketServer { +func NewWebsocketServer(secret string, ipPrefix string, db *gorm.DB, blacklistFor time.Duration, nodes *runtime.Nodes) *WebsocketServer { ownWS := WebsocketServer{ - nodes: nodes, - db: db, - handlers: make(map[string]WebsocketHandlerFunc), - inputMSG: make(chan *wsLib.Message), - secret: secret, - ipPrefix: ipPrefix, + nodes: nodes, + db: db, + blacklistFor: blacklistFor, + handlers: make(map[string]WebsocketHandlerFunc), + inputMSG: make(chan *wsLib.Message), + secret: secret, + ipPrefix: ipPrefix, } ownWS.ws = wsLib.NewServer(ownWS.inputMSG, wsLib.NewSessionManager())