mirror of
https://github.com/swissmakers/fail2ban-ui.git
synced 2026-04-15 05:03:14 +02:00
initial push
This commit is contained in:
130
pkg/web/handlers.go
Normal file
130
pkg/web/handlers.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/swissmakers/fail2ban-ui/internal/fail2ban"
|
||||
)
|
||||
|
||||
// SummaryResponse is what we return from /api/summary
|
||||
type SummaryResponse struct {
|
||||
Jails []fail2ban.JailInfo `json:"jails"`
|
||||
LastBans []fail2ban.BanEvent `json:"lastBans"`
|
||||
}
|
||||
|
||||
// SummaryHandler returns a JSON summary of all jails, including
|
||||
// number of banned IPs, how many are new in the last hour, etc.
|
||||
// and the last 5 overall ban events from the log.
|
||||
func SummaryHandler(c *gin.Context) {
|
||||
const logPath = "/var/log/fail2ban.log"
|
||||
|
||||
jailInfos, err := fail2ban.BuildJailInfos(logPath)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// Parse the log to find last 5 ban events
|
||||
eventsByJail, err := fail2ban.ParseBanLog(logPath)
|
||||
lastBans := make([]fail2ban.BanEvent, 0)
|
||||
if err == nil {
|
||||
// If we can parse logs successfully, let's gather all events
|
||||
var all []fail2ban.BanEvent
|
||||
for _, evs := range eventsByJail {
|
||||
all = append(all, evs...)
|
||||
}
|
||||
// Sort by descending time
|
||||
sortByTimeDesc(all)
|
||||
if len(all) > 5 {
|
||||
lastBans = all[:5]
|
||||
} else {
|
||||
lastBans = all
|
||||
}
|
||||
}
|
||||
|
||||
resp := SummaryResponse{
|
||||
Jails: jailInfos,
|
||||
LastBans: lastBans,
|
||||
}
|
||||
c.JSON(http.StatusOK, resp)
|
||||
}
|
||||
|
||||
// UnbanIPHandler unbans a given IP in a specific jail.
|
||||
func UnbanIPHandler(c *gin.Context) {
|
||||
jail := c.Param("jail")
|
||||
ip := c.Param("ip")
|
||||
|
||||
err := fail2ban.UnbanIP(jail, ip)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "IP unbanned successfully",
|
||||
})
|
||||
}
|
||||
|
||||
func sortByTimeDesc(events []fail2ban.BanEvent) {
|
||||
for i := 0; i < len(events); i++ {
|
||||
for j := i + 1; j < len(events); j++ {
|
||||
if events[j].Time.After(events[i].Time) {
|
||||
events[i], events[j] = events[j], events[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IndexHandler serves the main HTML page
|
||||
func IndexHandler(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "index.html", gin.H{
|
||||
"timestamp": time.Now().Format(time.RFC1123),
|
||||
})
|
||||
}
|
||||
|
||||
// GetJailConfigHandler returns the raw config for a given jail
|
||||
func GetJailConfigHandler(c *gin.Context) {
|
||||
jail := c.Param("jail")
|
||||
cfg, err := fail2ban.GetJailConfig(jail)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"jail": jail,
|
||||
"config": cfg,
|
||||
})
|
||||
}
|
||||
|
||||
// SetJailConfigHandler overwrites the jail config with new content
|
||||
func SetJailConfigHandler(c *gin.Context) {
|
||||
jail := c.Param("jail")
|
||||
|
||||
var req struct {
|
||||
Config string `json:"config"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid JSON body"})
|
||||
return
|
||||
}
|
||||
|
||||
if err := fail2ban.SetJailConfig(jail, req.Config); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "jail config updated"})
|
||||
}
|
||||
|
||||
// ReloadFail2banHandler reloads the Fail2ban service
|
||||
func ReloadFail2banHandler(c *gin.Context) {
|
||||
err := fail2ban.ReloadFail2ban()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Fail2ban reloaded successfully"})
|
||||
}
|
||||
Reference in New Issue
Block a user