Skip to content

feat: general improvements on blacklist management#63

Merged
lucaforni merged 3 commits into
main-modalsourcefrom
feature/general-improvements
Jan 30, 2026
Merged

feat: general improvements on blacklist management#63
lucaforni merged 3 commits into
main-modalsourcefrom
feature/general-improvements

Conversation

@lucaforni
Copy link
Copy Markdown

This pull request introduces a new manual retry mechanism for SMTP-detected IP blacklist records, improves notification and tracking around blacklist retries, and enhances the accuracy of IP reputation statistics. It also expands SMTP response parsing to better detect iCloud/Apple-specific blocking patterns. The most important changes are grouped below.

Manual Retry for Blacklist Records

  • Added a retry_now controller action in IPBlacklistRecordsController to allow admins to manually trigger an immediate retry test for SMTP-detected blacklist records, with appropriate validation, logging, and error handling.
  • Introduced IPBlacklist::RetryService, which encapsulates the logic for performing a retry test by sending a test email, updating the record, and handling success, failure, or error cases.
  • Enforced rate limiting for manual retry actions (5 requests per hour per user per record) via new configuration and rate_limit_retry method. [1] [2] [3]

Tracking and Notification Enhancements

  • Extended the IPBlacklistRecord model with fields for retry tracking: last_retry_at, next_retry_at, retry_count, retry_result, and retry_result_details, along with supporting indexes. [1] [2]
  • Added new notification methods and Slack message formats for retry success, failure, and error events in IPBlacklist::Notifier, ensuring operational visibility for these actions. [1] [2]

IP Reputation and Health Calculation

  • Improved the calculation of "healthy" IPs in the dashboard by using a SQL UNION to avoid double-counting IPs that are both blacklisted and excluded, resulting in more accurate statistics.

Automatic Retry Scheduling

  • When handling SMTP rejections, the system now schedules an automatic retry for SMTP-detected blacklists two days after detection, streamlining the recovery process.

SMTP Response Parsing Improvements

  • Enhanced SMTPResponseParser to detect iCloud/Apple-specific SMTP rejection patterns, improving the accuracy of blacklist source identification. [1] [2] [3] [4]

When SMTP rejection indicates IP blacklist detection, convert HardFail to SoftFail to allow automatic retry with a different IP address. This prevents legitimate messages from failing permanently due to transient IP reputation issues.

Changes:
- SMTPSender: Return boolean from handle_smtp_error_response to indicate blacklist detection
- SMTPSender: Convert Net::SMTPFatalError to SoftFail when blacklist detected
- QueuedMessage: Use domain-aware IP selection in reallocate_ip_address to respect IP exclusions
- SMTPResponseParser: Add iCloud/Apple policy rejection patterns
- Add test coverage for iCloud blacklist patterns
The count_healthy_ips method was summing IPs with blacklists and IPs with
domain exclusions separately, causing IPs that have both conditions to be
counted twice. This resulted in incorrect healthy IP counts (e.g. showing
0 healthy IPs when 10 blacklisted + 5 excluded = 15, but only 13 total IPs
with 2 appearing in both categories).

Now uses OR query with distinct count to properly count unique IPs that
have either blacklist records OR domain exclusions (or both).
- Add retry tracking fields to ip_blacklist_records (next_retry_at, last_retry_at, retry_count, retry_result)
- Implement RetryService to test if IP is still blacklisted by sending test SMTP connection
- Create scheduled task that automatically retries blacklisted IPs every 2 days
- Add manual retry trigger via web UI with rate limiting (5 requests/hour)
- Auto-schedule first retry when SMTP blacklist is detected
- Resolve blacklist automatically when retry test succeeds and start warmup
- Add retry notifications (success/failed/error) to webhook/email/Slack system
- Show retry information and 'Retry Now' button in blacklist record detail page
- Add comprehensive tests for retry functionality
@lucaforni lucaforni merged commit 9dcc8fb into main-modalsource Jan 30, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant