blacklist moved to it's own yml

This commit is contained in:
0ceanSlim 2024-10-16 14:07:37 -04:00
parent 5133c3a005
commit 3de1aeb998
8 changed files with 134 additions and 97 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
/tmp /tmp
config.yml config.yml
whitelist.yml whitelist.yml
blacklist.yml
relay_metadata.json relay_metadata.json
grain.exe grain.exe
/build /build

View File

@ -0,0 +1,13 @@
enabled: true
permanent_ban_words:
- nigger
temp_ban_words:
- crypto
- web3
- airdrop
max_temp_bans: 3
temp_ban_duration: 3600
permanent_blacklist_pubkeys:
- db0c9b8acd6101adb9b281c5321f98f6eebb33c5719d230ed1870997538a9765
permanent_blacklist_npubs:
- npub1x0r5gflnk2mn6h3c70nvnywpy2j46gzqwg6k7uw6fxswyz0md9qqnhshtn

View File

@ -63,20 +63,6 @@ rate_limit:
limit: 25 limit: 25
burst: 50 burst: 50
blacklist: #Removing a pubkey from the Blacklist requires a hard restart; Blacklist overides the Whitelist
enabled: true
permanent_ban_words: [] # Words that trigger a permanent ban
temp_ban_words: # Words that trigger a temporary ban
- crypto
- web3
- airdrop
max_temp_bans: 3 # Number of temporary bans before a permanent ban
temp_ban_duration: 3600 # Temporary ban duration in seconds
permanent_blacklist_pubkeys: # List of permanently banned public keys
- db0c9b8acd6101adb9b281c5321f98f6eebb33c5719d230ed1870997538a9765
permanent_blacklist_npubs: # List of permanently banned npubs
- npub1x0r5gflnk2mn6h3c70nvnywpy2j46gzqwg6k7uw6fxswyz0md9qqnhshtn
event_purge: event_purge:
enabled: true # Toggle to enable/disable event purging enabled: true # Toggle to enable/disable event purging
keep_duration_days: 2 # Number of days to keep events keep_duration_days: 2 # Number of days to keep events

View File

@ -15,51 +15,51 @@ import (
// 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) {
blacklistConfig := GetConfig().Blacklist blacklistConfig := GetBlacklistConfig()
if blacklistConfig == nil || !blacklistConfig.Enabled {
return false, ""
}
if !blacklistConfig.Enabled { log.Printf("Checking blacklist for pubkey: %s", pubkey)
return false, ""
}
log.Printf("Checking blacklist for pubkey: %s", pubkey) // Check for permanent blacklist by pubkey or npub.
if isPubKeyPermanentlyBlacklisted(pubkey, blacklistConfig) {
log.Printf("Pubkey %s is permanently blacklisted", pubkey)
return true, fmt.Sprintf("pubkey %s is permanently blacklisted", pubkey)
}
// Check for permanent blacklist by pubkey or npub // Check for temporary ban.
if isPubKeyPermanentlyBlacklisted(pubkey, blacklistConfig) { if isPubKeyTemporarilyBlacklisted(pubkey) {
log.Printf("Pubkey %s is permanently blacklisted", pubkey) log.Printf("Pubkey %s is temporarily blacklisted", pubkey)
return true, fmt.Sprintf("pubkey %s is permanently blacklisted", pubkey) return true, fmt.Sprintf("pubkey %s is temporarily blacklisted", pubkey)
} }
// Check for temporary ban // Check for permanent ban based on wordlist.
if isPubKeyTemporarilyBlacklisted(pubkey) { for _, word := range blacklistConfig.PermanentBanWords {
log.Printf("Pubkey %s is temporarily blacklisted", pubkey) if strings.Contains(eventContent, word) {
return true, fmt.Sprintf("pubkey %s is temporarily blacklisted", pubkey) err := AddToPermanentBlacklist(pubkey)
} if err != nil {
return true, fmt.Sprintf("pubkey %s is permanently banned and failed to save: %v", pubkey, err)
}
return true, "blocked: pubkey is permanently banned"
}
}
// Check for permanent ban based on wordlist // Check for temporary ban based on wordlist.
for _, word := range blacklistConfig.PermanentBanWords { for _, word := range blacklistConfig.TempBanWords {
if strings.Contains(eventContent, word) { if strings.Contains(eventContent, word) {
err := AddToPermanentBlacklist(pubkey) err := AddToTemporaryBlacklist(pubkey, *blacklistConfig)
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 temporarily banned and failed to save: %v", pubkey, err)
} }
return true, "blocked: pubkey is permanently banned" return true, "blocked: pubkey is temporarily banned"
} }
} }
// Check for temporary ban based on wordlist return false, ""
for _, word := range blacklistConfig.TempBanWords {
if strings.Contains(eventContent, word) {
err := AddToTemporaryBlacklist(pubkey, blacklistConfig)
if err != nil {
return true, fmt.Sprintf("pubkey %s is temporarily banned and failed to save: %v", pubkey, err)
}
return true, "blocked: pubkey is temporarily banned"
}
}
return false, ""
} }
// Checks if a pubkey is temporarily blacklisted // Checks if a pubkey is temporarily blacklisted
func isPubKeyTemporarilyBlacklisted(pubkey string) bool { func isPubKeyTemporarilyBlacklisted(pubkey string) bool {
mu.Lock() mu.Lock()
@ -142,63 +142,61 @@ func AddToTemporaryBlacklist(pubkey string, blacklistConfig types.BlacklistConfi
return nil return nil
} }
// Checks if a pubkey is permanently blacklisted (only using config.yml) func isPubKeyPermanentlyBlacklisted(pubKey string, blacklistConfig *types.BlacklistConfig) bool {
func isPubKeyPermanentlyBlacklisted(pubKey string, blacklistConfig types.BlacklistConfig) bool { if blacklistConfig == nil || !blacklistConfig.Enabled {
if !blacklistConfig.Enabled { return false
return false }
}
// Check pubkeys // Check pubkeys.
for _, blacklistedKey := range blacklistConfig.PermanentBlacklistPubkeys { for _, blacklistedKey := range blacklistConfig.PermanentBlacklistPubkeys {
if pubKey == blacklistedKey { if pubKey == blacklistedKey {
return true return true
} }
} }
// Check npubs // Check npubs.
for _, npub := range blacklistConfig.PermanentBlacklistNpubs { for _, npub := range blacklistConfig.PermanentBlacklistNpubs {
decodedPubKey, err := utils.DecodeNpub(npub) decodedPubKey, err := utils.DecodeNpub(npub)
if err != nil { if err != nil {
fmt.Println("Error decoding npub:", err) fmt.Println("Error decoding npub:", err)
continue continue
} }
if pubKey == decodedPubKey { if pubKey == decodedPubKey {
return true return true
} }
} }
return false return false
} }
func AddToPermanentBlacklist(pubkey string) error { func AddToPermanentBlacklist(pubkey string) error {
// Remove the mutex lock from here blacklistConfig := GetBlacklistConfig()
blacklistConfig := GetConfig().Blacklist if blacklistConfig == nil {
return fmt.Errorf("blacklist configuration is not loaded")
}
// Check if already blacklisted // Check if already blacklisted.
if isPubKeyPermanentlyBlacklisted(pubkey, blacklistConfig) { if isPubKeyPermanentlyBlacklisted(pubkey, blacklistConfig) {
return fmt.Errorf("pubkey %s is already in the permanent blacklist", pubkey) return fmt.Errorf("pubkey %s is already in the permanent blacklist", pubkey)
} }
// Add pubkey to the blacklist // Add pubkey to the permanent blacklist.
blacklistConfig.PermanentBlacklistPubkeys = append(blacklistConfig.PermanentBlacklistPubkeys, pubkey) blacklistConfig.PermanentBlacklistPubkeys = append(blacklistConfig.PermanentBlacklistPubkeys, pubkey)
// Persist changes to config.yml // Persist changes to blacklist.yml.
return saveBlacklistConfig(blacklistConfig) return saveBlacklistConfig(*blacklistConfig)
} }
func saveBlacklistConfig(blacklistConfig types.BlacklistConfig) error { func saveBlacklistConfig(blacklistConfig types.BlacklistConfig) error {
configData := GetConfig() data, err := yaml.Marshal(blacklistConfig)
configData.Blacklist = blacklistConfig if err != nil {
return fmt.Errorf("failed to marshal blacklist config: %v", err)
}
data, err := yaml.Marshal(configData) err = os.WriteFile("blacklist.yml", data, 0644)
if err != nil { if err != nil {
return fmt.Errorf("failed to marshal config: %v", err) return fmt.Errorf("failed to write config to file: %v", err)
} }
err = os.WriteFile("config.yml", data, 0644) return nil
if err != nil {
return fmt.Errorf("failed to write config to file: %v", err)
}
return nil
} }

View File

@ -12,8 +12,10 @@ import (
var ( var (
cfg *configTypes.ServerConfig cfg *configTypes.ServerConfig
whitelistCfg *configTypes.WhitelistConfig whitelistCfg *configTypes.WhitelistConfig
blacklistCfg *configTypes.BlacklistConfig
once sync.Once once sync.Once
whitelistOnce sync.Once whitelistOnce sync.Once
blacklistOnce sync.Once
) )
// LoadConfig loads the server configuration from config.yml // LoadConfig loads the server configuration from config.yml
@ -63,3 +65,27 @@ func GetConfig() *configTypes.ServerConfig {
func GetWhitelistConfig() *configTypes.WhitelistConfig { func GetWhitelistConfig() *configTypes.WhitelistConfig {
return whitelistCfg return whitelistCfg
} }
// LoadBlacklistConfig loads the blacklist configuration from blacklist.yml
func LoadBlacklistConfig(filename string) (*configTypes.BlacklistConfig, error) {
data, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
var config configTypes.BlacklistConfig
err = yaml.Unmarshal(data, &config)
if err != nil {
return nil, err
}
blacklistOnce.Do(func() {
blacklistCfg = &config
})
return blacklistCfg, nil
}
func GetBlacklistConfig() *configTypes.BlacklistConfig {
return blacklistCfg
}

View File

@ -23,6 +23,7 @@ import (
func main() { func main() {
utils.EnsureFileExists("config.yml", "app/static/examples/config.example.yml") utils.EnsureFileExists("config.yml", "app/static/examples/config.example.yml")
utils.EnsureFileExists("whitelist.yml", "app/static/examples/whitelist.example.yml") utils.EnsureFileExists("whitelist.yml", "app/static/examples/whitelist.example.yml")
utils.EnsureFileExists("blacklist.yml", "app/static/examples/blacklist.example.yml")
utils.EnsureFileExists("relay_metadata.json", "app/static/examples/relay_metadata.example.json") utils.EnsureFileExists("relay_metadata.json", "app/static/examples/relay_metadata.example.json")
restartChan := make(chan struct{}) restartChan := make(chan struct{})
@ -45,6 +46,11 @@ func main() {
log.Fatal("Error loading whitelist config: ", err) log.Fatal("Error loading whitelist config: ", err)
} }
_, err = config.LoadBlacklistConfig("blacklist.yml")
if err != nil {
log.Fatal("Error loading blacklist config: ", err)
}
go mongo.ScheduleEventPurging(cfg) go mongo.ScheduleEventPurging(cfg)
config.SetResourceLimit(&cfg.ResourceLimits) config.SetResourceLimit(&cfg.ResourceLimits)

View File

@ -68,7 +68,13 @@ func HandleEvent(ws *websocket.Conn, message []interface{}) {
} }
func handleBlacklistAndWhitelist(ws *websocket.Conn, evt nostr.Event) bool { func handleBlacklistAndWhitelist(ws *websocket.Conn, evt nostr.Event) bool {
// Get the current whitelist configuration
whitelistCfg := config.GetWhitelistConfig() whitelistCfg := config.GetWhitelistConfig()
if whitelistCfg == nil {
fmt.Println("Whitelist configuration is not loaded.")
response.SendNotice(ws, "", "Internal server error: whitelist configuration is missing")
return false
}
// If domain whitelisting is enabled, dynamically fetch pubkeys from domains // If domain whitelisting is enabled, dynamically fetch pubkeys from domains
if whitelistCfg.DomainWhitelist.Enabled { if whitelistCfg.DomainWhitelist.Enabled {
@ -103,6 +109,7 @@ func handleBlacklistAndWhitelist(ws *websocket.Conn, evt nostr.Event) bool {
return true return true
} }
func handleRateAndSizeLimits(ws *websocket.Conn, evt nostr.Event, eventSize int) bool { func handleRateAndSizeLimits(ws *websocket.Conn, evt nostr.Event, eventSize int) bool {
rateLimiter := config.GetRateLimiter() rateLimiter := config.GetRateLimiter()
sizeLimiter := config.GetSizeLimiter() sizeLimiter := config.GetSizeLimiter()