You've already forked prometheus-fail2ban-exporter
feat: export metrics for failed/banned counts
Add new metric to track the total number of jails configured in fail2ban. Add new metrics for the current and total number of filter failures for each jail, as well as the current/total number of banned IPs per jail. The new metrics are collected by sending the `status [jail]` command to the fail2ban server and parsing the response data.
This commit is contained in:
@ -1,11 +1,12 @@
|
||||
package socket
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"fmt"
|
||||
"github.com/kisielk/og-rek"
|
||||
"github.com/nlpodyssey/gopickle/types"
|
||||
"log"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Fail2BanSocket struct {
|
||||
@ -13,6 +14,13 @@ type Fail2BanSocket struct {
|
||||
encoder *ogórek.Encoder
|
||||
}
|
||||
|
||||
type JailStats struct {
|
||||
FailedCurrent int
|
||||
FailedTotal int
|
||||
BannedCurrent int
|
||||
BannedTotal int
|
||||
}
|
||||
|
||||
func MustConnectToSocket(path string) *Fail2BanSocket {
|
||||
c, err := net.Dial("unix", path)
|
||||
if err != nil {
|
||||
@ -37,6 +45,85 @@ func (s *Fail2BanSocket) Ping() bool {
|
||||
}
|
||||
log.Printf("unexpected response data: %s", t)
|
||||
}
|
||||
log.Printf("unexpected response format - cannot parse: %v", response)
|
||||
log.Printf("(%s) unexpected response format - cannot parse: %v", pingCommand, response)
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Fail2BanSocket) GetJails() ([]string, error) {
|
||||
response, err := s.sendCommand([]string{statusCommand})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if lvl1, ok := response.(*types.Tuple); ok {
|
||||
if lvl2, ok := lvl1.Get(1).(*types.List); ok {
|
||||
if lvl3, ok := lvl2.Get(1).(*types.Tuple); ok {
|
||||
if lvl4, ok := lvl3.Get(1).(string); ok {
|
||||
splitJails := strings.Split(lvl4, ",")
|
||||
return trimSpaceForAll(splitJails), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, newBadFormatError(statusCommand, response)
|
||||
}
|
||||
|
||||
func (s *Fail2BanSocket) GetJailStats(jail string) (JailStats, error) {
|
||||
response, err := s.sendCommand([]string{statusCommand, jail})
|
||||
if err != nil {
|
||||
return JailStats{}, err
|
||||
}
|
||||
|
||||
stats := JailStats{
|
||||
FailedCurrent: -1,
|
||||
FailedTotal: -1,
|
||||
BannedCurrent: -1,
|
||||
BannedTotal: -1,
|
||||
}
|
||||
|
||||
if lvl1, ok := response.(*types.Tuple); ok {
|
||||
if lvl2, ok := lvl1.Get(1).(*types.List); ok {
|
||||
if filter, ok := lvl2.Get(0).(*types.Tuple); ok {
|
||||
if filterLvl1, ok := filter.Get(1).(*types.List); ok {
|
||||
if filterCurrentTuple, ok := filterLvl1.Get(0).(*types.Tuple); ok {
|
||||
if filterCurrent, ok := filterCurrentTuple.Get(1).(int); ok {
|
||||
stats.FailedCurrent = filterCurrent
|
||||
}
|
||||
}
|
||||
if filterTotalTuple, ok := filterLvl1.Get(1).(*types.Tuple); ok {
|
||||
if filterTotal, ok := filterTotalTuple.Get(1).(int); ok {
|
||||
stats.FailedTotal = filterTotal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if actions, ok := lvl2.Get(1).(*types.Tuple); ok {
|
||||
if actionsLvl1, ok := actions.Get(1).(*types.List); ok {
|
||||
if actionsCurrentTuple, ok := actionsLvl1.Get(0).(*types.Tuple); ok {
|
||||
if actionsCurrent, ok := actionsCurrentTuple.Get(1).(int); ok {
|
||||
stats.BannedCurrent = actionsCurrent
|
||||
}
|
||||
}
|
||||
if actionsTotalTuple, ok := actionsLvl1.Get(1).(*types.Tuple); ok {
|
||||
if actionsTotal, ok := actionsTotalTuple.Get(1).(int); ok {
|
||||
stats.BannedTotal = actionsTotal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return stats, nil
|
||||
}
|
||||
}
|
||||
return stats, newBadFormatError(statusCommand, response)
|
||||
}
|
||||
|
||||
func newBadFormatError(command string, data interface{}) error {
|
||||
return fmt.Errorf("(%s) unexpected response format - cannot parse: %v", command, data)
|
||||
}
|
||||
|
||||
func trimSpaceForAll(slice []string) []string {
|
||||
for i := range slice {
|
||||
slice[i] = strings.TrimSpace(slice[i])
|
||||
}
|
||||
return slice
|
||||
}
|
||||
|
Reference in New Issue
Block a user