mirror of
https://github.com/swissmakers/fail2ban-ui.git
synced 2026-04-17 14:03:15 +02:00
Refactor the whole backend to support remote-fail2ban machines over ssh or over a agent-api(needs to be build)
This commit is contained in:
117
internal/fail2ban/manager.go
Normal file
117
internal/fail2ban/manager.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package fail2ban
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/swissmakers/fail2ban-ui/internal/config"
|
||||
)
|
||||
|
||||
// Connector describes a communication backend for a Fail2ban server.
|
||||
type Connector interface {
|
||||
ID() string
|
||||
Server() config.Fail2banServer
|
||||
|
||||
GetJailInfos(ctx context.Context) ([]JailInfo, error)
|
||||
GetBannedIPs(ctx context.Context, jail string) ([]string, error)
|
||||
UnbanIP(ctx context.Context, jail, ip string) error
|
||||
Reload(ctx context.Context) error
|
||||
Restart(ctx context.Context) error
|
||||
GetFilterConfig(ctx context.Context, jail string) (string, error)
|
||||
SetFilterConfig(ctx context.Context, jail, content string) error
|
||||
FetchBanEvents(ctx context.Context, limit int) ([]BanEvent, error)
|
||||
}
|
||||
|
||||
// Manager orchestrates all connectors for configured Fail2ban servers.
|
||||
type Manager struct {
|
||||
mu sync.RWMutex
|
||||
connectors map[string]Connector
|
||||
}
|
||||
|
||||
var (
|
||||
managerOnce sync.Once
|
||||
managerInst *Manager
|
||||
)
|
||||
|
||||
// GetManager returns the singleton connector manager.
|
||||
func GetManager() *Manager {
|
||||
managerOnce.Do(func() {
|
||||
managerInst = &Manager{
|
||||
connectors: make(map[string]Connector),
|
||||
}
|
||||
})
|
||||
return managerInst
|
||||
}
|
||||
|
||||
// ReloadFromSettings rebuilds connectors using the provided settings.
|
||||
func (m *Manager) ReloadFromSettings(settings config.AppSettings) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
connectors := make(map[string]Connector)
|
||||
for _, srv := range settings.Servers {
|
||||
if !srv.Enabled {
|
||||
continue
|
||||
}
|
||||
conn, err := newConnectorForServer(srv)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to initialise connector for %s (%s): %w", srv.Name, srv.ID, err)
|
||||
}
|
||||
connectors[srv.ID] = conn
|
||||
}
|
||||
|
||||
m.connectors = connectors
|
||||
return nil
|
||||
}
|
||||
|
||||
// Connector returns the connector for the specified server ID.
|
||||
func (m *Manager) Connector(serverID string) (Connector, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
if serverID == "" {
|
||||
return nil, fmt.Errorf("server id must be provided")
|
||||
}
|
||||
conn, ok := m.connectors[serverID]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("connector for server %s not found or not enabled", serverID)
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// DefaultConnector returns the default connector as defined in settings.
|
||||
func (m *Manager) DefaultConnector() (Connector, error) {
|
||||
server := config.GetDefaultServer()
|
||||
if server.ID == "" {
|
||||
return nil, fmt.Errorf("no active fail2ban server configured")
|
||||
}
|
||||
return m.Connector(server.ID)
|
||||
}
|
||||
|
||||
// Connectors returns all connectors.
|
||||
func (m *Manager) Connectors() []Connector {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
result := make([]Connector, 0, len(m.connectors))
|
||||
for _, conn := range m.connectors {
|
||||
result = append(result, conn)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func newConnectorForServer(server config.Fail2banServer) (Connector, error) {
|
||||
switch server.Type {
|
||||
case "local":
|
||||
if err := config.EnsureLocalFail2banAction(server); err != nil {
|
||||
fmt.Printf("warning: failed to ensure local fail2ban action: %v\n", err)
|
||||
}
|
||||
return NewLocalConnector(server), nil
|
||||
case "ssh":
|
||||
return NewSSHConnector(server)
|
||||
case "agent":
|
||||
return NewAgentConnector(server)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported server type %s", server.Type)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user