110 lines
4.2 KiB
Ruby
110 lines
4.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# ProcessWafPoliciesJob - Process firewall policies for a network range
|
|
#
|
|
# This job checks network ranges against active WAF policies and generates
|
|
# specific rules when matches are found.
|
|
class ProcessWafPoliciesJob < ApplicationJob
|
|
queue_as :waf_policies
|
|
|
|
retry_on StandardError, wait: 5.seconds, attempts: 3
|
|
|
|
def perform(network_range:, event: nil)
|
|
# network_range and event are passed as Global IDs and automatically deserialized
|
|
return if network_range.nil?
|
|
|
|
Rails.logger.debug "Processing WAF policies for network range #{network_range.cidr}"
|
|
|
|
# Use WafPolicyMatcher to find and generate rules
|
|
begin
|
|
matcher = WafPolicyMatcher.new(network_range: network_range)
|
|
result = matcher.match_and_generate_rules
|
|
rescue => e
|
|
Rails.logger.error "WafPolicyMatcher failed for network range #{network_range.cidr}: #{e.message}"
|
|
result = { matching_policies: [], generated_rules: [] }
|
|
end
|
|
|
|
# Log results
|
|
if result[:matching_policies].any?
|
|
Rails.logger.info "Network range #{network_range.cidr} matched #{result[:matching_policies].length} policies"
|
|
|
|
result[:matching_policies].each do |policy|
|
|
Rails.logger.info " - Matched policy: #{policy.name} (#{policy.policy_type}: #{policy.action})"
|
|
end
|
|
end
|
|
|
|
if result[:generated_rules].any?
|
|
Rails.logger.info "Generated #{result[:generated_rules].length} rules for network range #{network_range.cidr}"
|
|
|
|
result[:generated_rules].each do |rule|
|
|
Rails.logger.info " - Rule: #{rule.waf_rule_type} #{rule.waf_action} for #{rule.network_range&.cidr} (ID: #{rule.id})"
|
|
|
|
# Log if this is a redirect or challenge rule
|
|
if rule.redirect_action?
|
|
Rails.logger.info " Redirect to: #{rule.redirect_url} (#{rule.redirect_status})"
|
|
elsif rule.challenge_action?
|
|
Rails.logger.info " Challenge type: #{rule.challenge_type}"
|
|
end
|
|
end
|
|
else
|
|
Rails.logger.debug "No matching policies found for network range #{network_range.cidr}"
|
|
end
|
|
|
|
# Mark network range as evaluated
|
|
network_range.update_column(:policies_evaluated_at, Time.current)
|
|
|
|
# Update event record if provided
|
|
if event.present?
|
|
# Add policy match information to event metadata
|
|
# Handle potential nil payload or type issues
|
|
current_payload = event.payload || {}
|
|
|
|
# Ensure payload is a hash before merging
|
|
unless current_payload.is_a?(Hash)
|
|
Rails.logger.warn "Event #{event.id} has invalid payload type: #{current_payload.class}, resetting to hash"
|
|
current_payload = {}
|
|
end
|
|
|
|
event.update!(payload: current_payload.merge({
|
|
policy_matches: {
|
|
matching_policies_count: result[:matching_policies].length,
|
|
generated_rules_count: result[:generated_rules].length,
|
|
processed_at: Time.current.iso8601
|
|
}
|
|
}))
|
|
end
|
|
end
|
|
|
|
# Class method for batch processing multiple network ranges
|
|
def self.process_network_ranges(network_range_ids)
|
|
network_range_ids.each do |network_range_id|
|
|
network_range = NetworkRange.find_by(id: network_range_id)
|
|
perform_later(network_range: network_range) if network_range
|
|
end
|
|
end
|
|
|
|
# Class method to reprocess all network ranges for a specific policy
|
|
def self.reprocess_for_policy(waf_policy)
|
|
waf_policy_id = waf_policy.is_a?(WafPolicy) ? waf_policy.id : waf_policy
|
|
|
|
# Find all network ranges that could match this policy type
|
|
network_ranges = case waf_policy.policy_type
|
|
when 'country'
|
|
NetworkRange.where.not(country: nil)
|
|
when 'asn'
|
|
NetworkRange.where.not(asn: nil)
|
|
when 'company'
|
|
NetworkRange.where.not(company: nil)
|
|
when 'network_type'
|
|
NetworkRange.where("is_datacenter = ? OR is_proxy = ? OR is_vpn = ?", true, true, true)
|
|
else
|
|
NetworkRange.none
|
|
end
|
|
|
|
Rails.logger.info "Reprocessing #{network_ranges.count} network ranges for policy #{waf_policy_id}"
|
|
|
|
network_ranges.find_each do |network_range|
|
|
perform_later(network_range: network_range)
|
|
end
|
|
end
|
|
end |