mirror of
https://github.com/0ceanSlim/grain.git
synced 2024-11-22 08:37:13 +00:00
temp bans working,temp ban threshold still not working, removing permabans requires hard restart
This commit is contained in:
parent
39436b564e
commit
7d288cec1e
15
main.go
15
main.go
@ -21,8 +21,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
utils.EnsureFileExists("config.yml", "app/static/examples/config.example.yml")
|
utils.ClearTemporaryBans()
|
||||||
utils.EnsureFileExists("relay_metadata.json", "app/static/examples/relay_metadata.example.json")
|
|
||||||
|
|
||||||
restartChan := make(chan struct{})
|
restartChan := make(chan struct{})
|
||||||
go utils.WatchConfigFile("config.yml", restartChan)
|
go utils.WatchConfigFile("config.yml", restartChan)
|
||||||
@ -46,6 +45,8 @@ func main() {
|
|||||||
config.SetupRateLimiter(cfg)
|
config.SetupRateLimiter(cfg)
|
||||||
config.SetupSizeLimiter(cfg)
|
config.SetupSizeLimiter(cfg)
|
||||||
|
|
||||||
|
utils.ClearTemporaryBans()
|
||||||
|
|
||||||
err = utils.LoadRelayMetadataJSON()
|
err = utils.LoadRelayMetadataJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Failed to load relay metadata: ", err)
|
log.Fatal("Failed to load relay metadata: ", err)
|
||||||
@ -57,15 +58,17 @@ func main() {
|
|||||||
select {
|
select {
|
||||||
case <-restartChan:
|
case <-restartChan:
|
||||||
log.Println("Restarting server...")
|
log.Println("Restarting server...")
|
||||||
|
|
||||||
|
// Close server before restart
|
||||||
server.Close()
|
server.Close()
|
||||||
db.DisconnectDB(client)
|
wg.Wait()
|
||||||
wg.Wait() // Wait for the server to fully shut down before restarting
|
|
||||||
time.Sleep(3 * time.Second) // Add a delay before restarting
|
time.Sleep(3 * time.Second)
|
||||||
case <-signalChan:
|
case <-signalChan:
|
||||||
log.Println("Shutting down server...")
|
log.Println("Shutting down server...")
|
||||||
server.Close()
|
server.Close()
|
||||||
db.DisconnectDB(client)
|
db.DisconnectDB(client)
|
||||||
wg.Wait() // Wait for the server to fully shut down before exiting
|
wg.Wait()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,12 @@ func HandleKind(ctx context.Context, evt relay.Event, ws *websocket.Conn, eventS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check against manual blacklist
|
||||||
|
if blacklisted, msg := utils.CheckBlacklist(evt.PubKey, evt.Content); blacklisted {
|
||||||
|
response.SendOK(ws, evt.ID, false, msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the kind is whitelisted
|
// Check if the kind is whitelisted
|
||||||
if config.GetConfig().KindWhitelist.Enabled && !utils.IsKindWhitelisted(evt.Kind) {
|
if config.GetConfig().KindWhitelist.Enabled && !utils.IsKindWhitelisted(evt.Kind) {
|
||||||
response.SendOK(ws, evt.ID, false, "not allowed: event kind is not whitelisted")
|
response.SendOK(ws, evt.ID, false, "not allowed: event kind is not whitelisted")
|
||||||
@ -84,13 +90,6 @@ func HandleKind(ctx context.Context, evt relay.Event, ws *websocket.Conn, eventS
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check against manual blacklist
|
|
||||||
blacklisted, msg := utils.CheckBlacklist(evt.PubKey, evt.Content)
|
|
||||||
if blacklisted {
|
|
||||||
response.SendOK(ws, evt.ID, false, msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
category := determineCategory(evt.Kind)
|
category := determineCategory(evt.Kind)
|
||||||
|
|
||||||
if allowed, msg := rateLimiter.AllowEvent(evt.Kind, category); !allowed {
|
if allowed, msg := rateLimiter.AllowEvent(evt.Kind, category); !allowed {
|
||||||
|
@ -6,10 +6,30 @@ import (
|
|||||||
cfg "grain/config/types"
|
cfg "grain/config/types"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Structure to manage temporary bans with timestamps
|
||||||
|
type tempBanEntry struct {
|
||||||
|
count int // Number of temporary bans
|
||||||
|
unbanTime time.Time // Time when the pubkey should be unbanned
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
tempBannedPubkeys = make(map[string]*tempBanEntry)
|
||||||
|
mu sync.Mutex
|
||||||
|
)
|
||||||
|
|
||||||
|
func ClearTemporaryBans() {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
tempBannedPubkeys = make(map[string]*tempBanEntry)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// CheckBlacklist checks if a pubkey is in the blacklist based on event content
|
// CheckBlacklist checks if a pubkey is in the blacklist based on event content
|
||||||
func CheckBlacklist(pubkey, eventContent string) (bool, string) {
|
func CheckBlacklist(pubkey, eventContent string) (bool, string) {
|
||||||
cfg := config.GetConfig().Blacklist
|
cfg := config.GetConfig().Blacklist
|
||||||
@ -23,10 +43,14 @@ func CheckBlacklist(pubkey, eventContent string) (bool, string) {
|
|||||||
return true, fmt.Sprintf("pubkey %s is permanently blacklisted", pubkey)
|
return true, fmt.Sprintf("pubkey %s is permanently blacklisted", pubkey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for temporary ban
|
||||||
|
if isPubKeyTemporarilyBlacklisted(pubkey) {
|
||||||
|
return true, fmt.Sprintf("pubkey %s is temporarily blacklisted", pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
// Check for permanent ban based on wordlist
|
// Check for permanent ban based on wordlist
|
||||||
for _, word := range cfg.PermanentBanWords {
|
for _, word := range cfg.PermanentBanWords {
|
||||||
if strings.Contains(eventContent, word) {
|
if strings.Contains(eventContent, word) {
|
||||||
// Permanently ban the pubkey
|
|
||||||
err := AddToPermanentBlacklist(pubkey)
|
err := AddToPermanentBlacklist(pubkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, fmt.Sprintf("pubkey %s is permanently banned and failed to save: %v", pubkey, err)
|
return true, fmt.Sprintf("pubkey %s is permanently banned and failed to save: %v", pubkey, err)
|
||||||
@ -35,11 +59,74 @@ func CheckBlacklist(pubkey, eventContent string) (bool, string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for temporary ban based on wordlist
|
||||||
|
for _, word := range cfg.TempBanWords {
|
||||||
|
if strings.Contains(eventContent, word) {
|
||||||
|
err := AddToTemporaryBlacklist(pubkey)
|
||||||
|
if err != nil {
|
||||||
|
return true, fmt.Sprintf("pubkey %s is temporarily banned and failed to save: %v", pubkey, err)
|
||||||
|
}
|
||||||
|
return true, fmt.Sprintf("pubkey %s is temporarily banned for containing forbidden words", pubkey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false, ""
|
return false, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func isPubKeyPermanentlyBlacklisted(pubKey string) bool {
|
|
||||||
|
// Checks if a pubkey is temporarily blacklisted
|
||||||
|
func isPubKeyTemporarilyBlacklisted(pubkey string) bool {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
|
||||||
|
entry, exists := tempBannedPubkeys[pubkey]
|
||||||
|
if !exists {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the ban has expired, remove it from the temporary ban list
|
||||||
|
if time.Now().After(entry.unbanTime) {
|
||||||
|
delete(tempBannedPubkeys, pubkey)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds a pubkey to the temporary blacklist
|
||||||
|
func AddToTemporaryBlacklist(pubkey string) error {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
|
||||||
cfg := config.GetConfig().Blacklist
|
cfg := config.GetConfig().Blacklist
|
||||||
|
|
||||||
|
// Check if the pubkey is already temporarily banned
|
||||||
|
entry, exists := tempBannedPubkeys[pubkey]
|
||||||
|
if !exists {
|
||||||
|
entry = &tempBanEntry{
|
||||||
|
count: 1,
|
||||||
|
unbanTime: time.Now().Add(time.Duration(cfg.TempBanDuration) * time.Second),
|
||||||
|
}
|
||||||
|
tempBannedPubkeys[pubkey] = entry
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment the temporary ban count and set the unban time
|
||||||
|
entry.count++
|
||||||
|
entry.unbanTime = time.Now().Add(time.Duration(cfg.TempBanDuration) * time.Second)
|
||||||
|
|
||||||
|
// If the count exceeds max_temp_bans, move to permanent blacklist
|
||||||
|
if entry.count >= cfg.MaxTempBans {
|
||||||
|
delete(tempBannedPubkeys, pubkey)
|
||||||
|
return AddToPermanentBlacklist(pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if a pubkey is permanently blacklisted (only using config.yml)
|
||||||
|
func isPubKeyPermanentlyBlacklisted(pubKey string) bool {
|
||||||
|
cfg := config.GetConfig().Blacklist // Get the latest configuration
|
||||||
|
|
||||||
if !cfg.Enabled {
|
if !cfg.Enabled {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -67,6 +154,9 @@ func isPubKeyPermanentlyBlacklisted(pubKey string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func AddToPermanentBlacklist(pubkey string) error {
|
func AddToPermanentBlacklist(pubkey string) error {
|
||||||
|
mu.Lock()
|
||||||
|
defer mu.Unlock()
|
||||||
|
|
||||||
cfg := config.GetConfig().Blacklist
|
cfg := config.GetConfig().Blacklist
|
||||||
|
|
||||||
// Check if already blacklisted
|
// Check if already blacklisted
|
||||||
@ -82,10 +172,10 @@ func AddToPermanentBlacklist(pubkey string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func saveBlacklistConfig(blacklistConfig cfg.BlacklistConfig) error {
|
func saveBlacklistConfig(blacklistConfig cfg.BlacklistConfig) error {
|
||||||
cfg := config.GetConfig()
|
configData := config.GetConfig()
|
||||||
cfg.Blacklist = blacklistConfig
|
configData.Blacklist = blacklistConfig
|
||||||
|
|
||||||
data, err := yaml.Marshal(cfg)
|
data, err := yaml.Marshal(configData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal config: %v", err)
|
return fmt.Errorf("failed to marshal config: %v", err)
|
||||||
}
|
}
|
||||||
@ -97,3 +187,4 @@ func saveBlacklistConfig(blacklistConfig cfg.BlacklistConfig) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user