Skip to content

Commit

Permalink
Update caddywaf.go
Browse files Browse the repository at this point in the history
rules reloading on changes fixed.
  • Loading branch information
fabriziosalmi authored Jan 9, 2025
1 parent c4fbf8c commit 684ee98
Showing 1 changed file with 88 additions and 7 deletions.
95 changes: 88 additions & 7 deletions caddywaf.go
Original file line number Diff line number Diff line change
Expand Up @@ -1464,13 +1464,26 @@ func (m *Middleware) startFileWatcher(filePaths []string) {
m.logger.Info("Detected configuration change. Reloading...",
zap.String("file", file),
)
err := m.ReloadConfig()
if err != nil {
m.logger.Error("Failed to reload config after change",
zap.Error(err),
)
if strings.Contains(file, "rule") { // Detect rule file changes
if err := m.ReloadRules(); err != nil {
m.logger.Error("Failed to reload rules after change",
zap.String("file", file),
zap.Error(err),
)
} else {
m.logger.Info("Rules reloaded successfully",
zap.String("file", file),
)
}
} else {
m.logger.Info("Configuration reloaded successfully")
err := m.ReloadConfig()
if err != nil {
m.logger.Error("Failed to reload config after change",
zap.Error(err),
)
} else {
m.logger.Info("Configuration reloaded successfully")
}
}
}
case err := <-watcher.Errors:
Expand All @@ -1481,6 +1494,71 @@ func (m *Middleware) startFileWatcher(filePaths []string) {
}
}

func (m *Middleware) ReloadRules() error {
m.mu.Lock()
defer m.mu.Unlock()

m.logger.Info("Reloading WAF rules")

// Temporary map for new rules
newRules := make(map[int][]Rule)

// Load rules into temporary map
for _, file := range m.RuleFiles {
content, err := os.ReadFile(file)
if err != nil {
m.logger.Error("Failed to read rule file",
zap.String("file", file),
zap.Error(err),
)
continue
}

var rules []Rule
if err := json.Unmarshal(content, &rules); err != nil {
m.logger.Error("Failed to unmarshal rules from file",
zap.String("file", file),
zap.Error(err),
)
continue
}

for _, rule := range rules {
// Validate and compile rule
if err := validateRule(&rule); err != nil {
m.logger.Warn("Invalid rule encountered",
zap.String("file", file),
zap.String("rule_id", rule.ID),
zap.Error(err),
)
continue
}

// Compile regex
rule.regex, err = regexp.Compile(rule.Pattern)
if err != nil {
m.logger.Error("Failed to compile regex for rule",
zap.String("rule_id", rule.ID),
zap.Error(err),
)
continue
}

// Add to appropriate phase
if _, exists := newRules[rule.Phase]; !exists {
newRules[rule.Phase] = []Rule{}
}
newRules[rule.Phase] = append(newRules[rule.Phase], rule)
}
}

// Replace the old rules with the new rules
m.Rules = newRules
m.logger.Info("WAF rules reloaded successfully")

return nil
}

func caddyTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006/01/02 15:04:05.000"))
}
Expand Down Expand Up @@ -1554,7 +1632,10 @@ func (m *Middleware) Provision(ctx caddy.Context) error {
// Log the dynamically fetched version
m.logVersion()

// Start watching files for reload (IP blacklist, DNS blacklist)
// Watch rule files for changes
m.startFileWatcher(m.RuleFiles)

// Watch IP and DNS blacklist files
m.startFileWatcher([]string{m.IPBlacklistFile, m.DNSBlacklistFile})

// Rate Limiter Setup
Expand Down

0 comments on commit 684ee98

Please sign in to comment.