mirror of
https://github.com/domainaware/parsedmarc.git
synced 2026-05-02 10:05:25 +00:00
2cda5bf59b
* Surface ASN info and fall back to it when a PTR is absent Adds three new fields to every IP source record — ``asn`` (integer, e.g. 15169), ``asn_name`` (``"Google LLC"``), ``asn_domain`` (``"google.com"``) — sourced from the bundled IPinfo Lite MMDB. These flow through to CSV, JSON, Elasticsearch, OpenSearch, and Splunk outputs as ``source_asn``, ``source_asn_name``, ``source_asn_domain``. More importantly: when an IP has no reverse DNS (common for many large senders), source attribution now falls back to the ASN domain as a lookup key into the same ``reverse_dns_map``. Thanks to #712 and #714, ~85% of routed IPv4 space now has an ``as_domain`` that hits the map, so rows that were previously unattributable now get a ``source_name``/``source_type`` derived from the ASN. When the ASN domain misses the map, the raw AS name is used as ``source_name`` with ``source_type`` left null — still better than nothing. Crucially, ``source_reverse_dns`` and ``source_base_domain`` remain null on ASN-derived rows, so downstream consumers can still tell a PTR-resolved attribution apart from an ASN-derived one. ASN is stored as an integer at the schema level (Elasticsearch / OpenSearch mappings use ``Integer``) so consumers can do range queries and numeric sorts; dashboards can prepend ``AS`` at display time. The MMDB reader normalizes both IPinfo's ``"AS15169"`` string and MaxMind's ``autonomous_system_number`` int to the same int form. Also fixes a pre-existing caching bug in ``get_ip_address_info``: entries without reverse DNS were never written to the IP-info cache, so every no-PTR IP re-did the MMDB read and DNS attempt on every call. The cache write is now unconditional. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Bump to 9.9.0 and document the ASN fallback work Updates the changelog with a 9.9.0 entry covering the ASN-domain aliases (#712, #714), map-maintenance tooling fixes (#713), and the ASN-fallback source attribution added in this branch. Extends AGENTS.md to explain that ``base_reverse_dns_map.csv`` is now a mixed-namespace map (rDNS bases alongside ASN domains) and adds a short recipe for finding high-value ASN-domain misses against the bundled MMDB, so future contributors know where the map's second lookup path comes from. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Document project conventions previously held only in agent memory Promotes four conventions out of per-agent memory and into AGENTS.md so every contributor — human or agent — works from the same baseline: - Run ruff check + format before committing (Code Style). - Store natively numeric values as numbers, not pre-formatted strings (e.g. ASN as int 15169, not "AS15169"; ES/OS mappings as Integer) (Code Style). - Before rewriting a tracked list/data file from freshly-generated content, verify the existing content via git — these files accumulate manually-curated entries across sessions (Editing tracked data files). - A release isn't done until hatch-built sdist + wheel are attached to the GitHub release page; full 8-step sequence documented (Releases). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Sean Whalen <seanthegeek@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
51 KiB
51 KiB
Changelog
9.9.0
Changes
- Source attribution now has an ASN fallback. Every IP source record carries three new fields —
asn(integer, e.g.15169),asn_name("Google LLC"), andasn_domain("google.com") — sourced from the bundled IPinfo Lite MMDB. When an IP has no reverse DNS,get_ip_address_info()usesasn_domainas a lookup into the samereverse_dns_map, and if that misses, falls back to the rawasn_name.reverse_dnsandbase_domainstay null on ASN-derived rows so consumers can still distinguish PTR-derived from ASN-derived attribution. - Added
source_asn,source_asn_name,source_asn_domainto CSV output (aggregate + forensic), JSON output, and the Elasticsearch / OpenSearch / Splunk integrations.source_asnis mapped asIntegerat the schema level so consumers can do range queries and numeric sorts; dashboards can prepend"AS"at display time. - Expanded
base_reverse_dns_map.csvwith 500 ASN-domain aliases for the most-routed IPv4 ranges. IPv4-weighted coverage of the bundledipinfo_lite.mmdbwent from ~34% of routed space matching a map entry via ASN domain to ~85%. Every alias is a brand that was already in the map under a different rDNS-base key (e.g. addingcomcast.comalongside the existingcomcast.net), plus a small number of large operators that previously had no entry. 11 entries were also promoted out ofknown_unknown_base_reverse_dns.txtbecause ASN context made their identity unambiguous. - Added
get_ip_address_db_record()inparsedmarc.utils, a single-open MMDB reader that returns country + ASN fields together.get_ip_address_country()is now a thin wrapper. Supports both IPinfo Lite's schema (country_code,asnas"AS15169",as_name,as_domain) and MaxMind's (country.iso_code,autonomous_system_numberas int,autonomous_system_organization) in one pass; ASN is normalized to a plain int from either. MaxMind users who drop in their own ASN MMDB getasn+asn_namepopulated;asn_domainstays null because MaxMind doesn't carry it.
Fixed
get_ip_address_info()now caches entries for IPs without reverse DNS. Previously the cache write was inside theif reverse_dns is not Nonebranch, so every no-PTR IP re-did the MMDB read and DNS attempt on every call.- Fixed three bugs in
parsedmarc/resources/maps/sortlists.pythat silently disabled thetype-column validator and sorted the map case-sensitively, contrary to its documented behavior:- Validator allowed-values map was keyed on
"Type"(capital T), but the CSV header is"type"(lowercase), so every row bypassed validation. - Types were read with trailing newlines via
f.readlines(), so comparisons would not have matched even if the column name had been right. sort_csv()was called withoutcase_insensitive_sort=True, which moved the sole mixed-case key (United-domains.de) to the top of the file instead of into its alphabetical position.
- Validator allowed-values map was keyed on
- Fixed eight pre-existing map rows with invalid or inconsistent
typevalues that the now-working validator surfaced: casing corrections fordhl.com(logistics→Logistics),ghm-grenoble.fr(healthcare→Healthcare), andregusnet.com(Real estate→Real Estate); reclassifiedlodestonegroup.comfrom the nonexistentInsurancetype toFinance; added missingReligionandUtilitiesentries tobase_reverse_dns_types.txtso it matches the README's industry list. - Fixed the
rt.rumap entry: was classified asRT,Government Media, which conflated Rostelecom (the Russian telco that owns and usesrt.ru) with RT / Russia Today (which usesrt.com). Corrected toRostelecom,ISP.
Upgrade notes
- Output schema change: CSV, JSON, Elasticsearch, OpenSearch, and Splunk all gain three new fields per row (
source_asn,source_asn_name,source_asn_domain). Existing queries and dashboards keep working; dashboards that want to consume the new fields will need to be updated. Elasticsearch / OpenSearch will add the new mappings on next document write. - Rows for IPs without reverse DNS now populate
source_name/source_typevia ASN fallback. If downstream dashboards treated "nullsource_name" as a signal for "no rDNS", switch to checkingsource_reverse_dns IS NULLinstead — that remains the unambiguous signal.
9.8.0
Changes
- Replaced the bundled DB-IP Country Lite database with the IPinfo Lite database (
parsedmarc/resources/ipinfo/ipinfo_lite.mmdb, under the Creative Commons Attribution-ShareAlike 4.0 License) for greater IP-to-country lookup accuracy. The download URL / cached filename / packaged module path have all moved fromdbip/dbip-country-lite.mmdbtoipinfo/ipinfo_lite.mmdb. get_ip_address_country()now reads MMDBs withmaxminddbdirectly and handles both schemas — the IPinfo flat-top-levelcountry_codefield and the MaxMind/DBIP nestedcountry.iso_codefield — so users who drop in their own MMDB from any of these providers continue to work. The in-disk search list for user-supplied files still includesipinfo_lite.mmdb,GeoLite2-Country.mmdb, anddbip-country-lite*.mmdb.- Dropped the
geoip2dependency (its only use was the.country()helper, which is incompatible with the IPinfo schema). Addedmaxminddbas a direct dependency — it was already installed transitively throughgeoip2, so this is a no-op for most environments.
Upgrade notes
- Callers that imported
parsedmarc.resources.dbipdirectly need to switch toparsedmarc.resources.ipinfo. Theparsedmarc.resources.dbipmodule has been removed. - Callers that imported
geoip2only becauseparsedmarcdepended on it will need to add it to their own requirements.parsedmarcitself no longer depends ongeoip2. - The auto-update download URL used by previous parsedmarc versions (
.../dbip/dbip-country-lite.mmdb) is no longer hosted onmaster; those versions will fail to download and fall back to their bundled copy, which is the documented behavior ofload_ip_db().
9.7.1
Changes
- Ported DNS lookup reliability improvements from checkdmarc 5.15.x:
- Per-query UDP timeout is now capped at
min(1.0, timeout)inquery_dns(), so a single dropped UDP datagram no longer consumes the entire lifetime budget — dnspython retries UDP within the lifetime window (mirroringdig's default+tries=3). With multiple nameservers configured, the same cap also makes a slow or broken nameserver fall through to the next quickly. - With multiple nameservers configured, the resolver lifetime is now
timeout × len(nameservers)so each nameserver gets its own timeout budget for failover rather than sharing one overall deadline. - New
retrieskwarg onquery_dns(),get_reverse_dns(), andget_ip_address_info()retries the whole query on transient errors (LifetimeTimeout,NoNameservers/SERVFAIL, andOSErrorduring TCP fallback).NXDOMAINandNoAnswerremain non-retryable. Default is 0 (no behavior change for existing callers). - Threaded
dns_retriesthrough the parser API (parse_report_file,parse_aggregate_report_xml,parse_forensic_report,parse_report_email,get_dmarc_reports_from_mbox,get_dmarc_reports_from_mailbox,watch_inbox).
- Per-query UDP timeout is now capped at
- Added
--dns-retries NCLI flag anddns_retriesINI option ([general]section, also surfaced viaPARSEDMARC_GENERAL_DNS_RETRIESenv var). - Centralized DNS defaults in
parsedmarc.constants:DEFAULT_DNS_TIMEOUT,DEFAULT_DNS_MAX_RETRIES, andRECOMMENDED_DNS_NAMESERVERS(a cross-provider mix —("1.1.1.1", "8.8.8.8")— for callers that want public-resolver failover). The existing default nameservers (all-Cloudflare) are preserved for backward compatibility; callers opt in by passingnameservers=RECOMMENDED_DNS_NAMESERVERS.
9.7.0
Changes
psl_overrides.txtis now automatically downloaded at startup (and on SIGHUP in watch mode) byload_psl_overrides()inparsedmarc.utils, with the same URL / local-file / offline fallback pattern as the reverse DNS map. It is also reloaded wheneverload_reverse_dns_map()runs, sobase_reverse_dns_map.csventries that depend on a recent overrides entry resolve correctly without requiring a new parsedmarc release.- Added the
local_psl_overrides_pathandpsl_overrides_urlconfiguration options ([general]section, also surfaced viaPARSEDMARC_GENERAL_*env vars) to override the default PSL overrides source. - Expanded
base_reverse_dns_map.csvsubstantially in this release, following a multi-pass classification pass across the unknown/known-unknown lists (net ~+1,000 entries). - Added
ReligionandUtilitiesto the allowedtypevalues inbase_reverse_dns_types.txtand documented them inparsedmarc/resources/maps/README.md. - Added
parsedmarc/resources/maps/collect_domain_info.py— a bulk enrichment collector that runs WHOIS, a size-capped HTTP GET, and A/AAAA + IP-WHOIS for every unmapped reverse-DNS base domain, writing a compact TSV suitable for a single classification pass. Respectspsl_overrides.txtand skips full-IP entries. - Added
parsedmarc/resources/maps/detect_psl_overrides.py— scansunknown_base_reverse_dns.csvfor IP-containing entries that share a brand suffix, auto-appends the suffix topsl_overrides.txt, folds affected entries in all three list files, and removes any remaining full-IP entries for privacy. find_unknown_base_reverse_dns.pynow drops full-IP entries at ingest so customer IPs never enter the pipeline.- Documented the full map-maintenance workflow (privacy rule, auto-override detection, conservative classification, known-unknown handling) in the top-level
AGENTS.md.
Fixed
- Reverse-DNS base domains containing a full IPv4 address (four dotted or dashed octets) are now blocked from entering
base_reverse_dns_map.csv,known_unknown_base_reverse_dns.txt, andunknown_base_reverse_dns.csv. Customer IPs were previously possible in these lists as part of ISP-generated reverse-DNS subdomain patterns. The filter is enforced infind_unknown_base_reverse_dns.py,collect_domain_info.py, anddetect_psl_overrides.py. The existing lists were swept and all pre-existing IP-containing entries removed.
9.6.0
Changes
- The included DB-IP Country Lite database is now automatically updated at startup (and on SIGHUP in watch mode) by downloading the latest copy from GitHub, unless the
offlineflag is set. Falls back to a previously cached copy or the bundled database on failure. This allows the IP-to-country database to stay current without requiring a new package release. - Updated the included DB-IP Country Lite database to the 2026-04 release.
- Added the
ip_db_urlconfiguration option (PARSEDMARC_GENERAL_IP_DB_URLenv var) to override the default download URL for the IP-to-country database.
9.5.5
Fixed
- Output client initialization now retries up to 4 times with exponential backoff before exiting. This fixes persistent
Connection refusederrors in Docker when OpenSearch or Elasticsearch is momentarily unavailable at startup. - Use tuple format for
http_authin OpenSearch and Elasticsearch connections, matching the documented convention and avoiding potential issues if the password contains a colon. - Fix current_time format for MSGraphConnection (current-time) (PR #708)
Changes
- Added debug logging to all output client initialization (S3, syslog, Splunk HEC, Kafka, GELF, webhook, Elasticsearch, OpenSearch).
DEBUG=trueandPARSEDMARC_DEBUG=trueare now accepted as short aliases forPARSEDMARC_GENERAL_DEBUG=true.
9.5.4
Fixed
- Maildir
fetch_messagesnow respects thereports_folderargument. Previously it always read from the top-level Maildir, ignoring the configured reports folder.fetch_message,delete_message, andmove_messagenow also operate on the correct active folder. - Config key aliases for env var compatibility:
[maildir] createandpathare now accepted as aliases formaildir_createandmaildir_path, and[msgraph] urlforgraph_url. This allows natural env var names likePARSEDMARC_MAILDIR_CREATEto work without the redundantPARSEDMARC_MAILDIR_MAILDIR_CREATE.
9.5.3
Fixed
- Fixed
FileNotFoundErrorwhen using Maildir with Docker volume mounts. Python'smailbox.Maildir(create=True)only createscur/new/tmpsubdirectories when the top-level directory doesn't exist; Docker volume mounts pre-create the directory as empty, skipping subdirectory creation. parsedmarc now explicitly creates the subdirectories whenmaildir_createis enabled. - Maildir UID mismatch no longer crashes the process. In Docker containers where volume ownership differs from the container UID, parsedmarc now logs a warning instead of raising an exception. Also handles
os.setuidfailures gracefully in containers withoutCAP_SETUID. - Token file writes (MS Graph and Gmail) now create parent directories automatically, preventing
FileNotFoundErrorwhen the token path points to a directory that doesn't yet exist. - File paths from config (
token_file,credentials_file,cert_path,log_file,output,ip_db_path,maildir_path, syslog cert paths, etc.) now expand~and$VARreferences viaos.path.expanduser/os.path.expandvars.
9.5.2
Fixed
- Fixed
ValueError: invalid interpolation syntaxwhen config values (from env vars or INI files) contain%characters, such as in passwords. Disabled ConfigParser's%-based string interpolation.
9.5.1
Changes
- Correct ISO format for MSGraphConnection timestamps (PR #706)
9.5.0
Added
- Environment variable configuration support: any config option can now be set via
PARSEDMARC_{SECTION}_{KEY}environment variables (e.g.PARSEDMARC_IMAP_PASSWORD,PARSEDMARC_SPLUNK_HEC_TOKEN). Environment variables override config file values but are overridden by CLI arguments. PARSEDMARC_CONFIG_FILEenvironment variable to specify the config file path without the-cflag.- Env-only mode: parsedmarc can now run without a config file when
PARSEDMARC_*environment variables are set, enabling fully file-less Docker deployments. - Explicit read permission check on config file, giving a clear error message when the container UID cannot read the file (e.g.
chmod 600with a UID mismatch).
9.4.0
Added
- Extracted
load_reverse_dns_map()utility function inutils.pyfor loading the reverse DNS map independently of individual IP lookups. - SIGHUP reload now re-downloads/reloads the reverse DNS map, so changes take effect without restarting.
- Add premade OpenSearch index patterns, visualizations, and dashboards
Changed
- When
index_prefix_domain_mapis configured, SMTP TLS reports for domains not in the map are now silently dropped instead of being output. Unlike DMARC, TLS-RPT has no DNS authorization records, so this filtering prevents processing reports for unrelated domains. - Bump OpenSearch support to
< 4
Fixed
- Fixed
get_index_prefixusing wrong key (domaininstead ofpolicy_domain) for SMTP TLS reports, which prevented domain map matching from working for TLS reports. - Domain matching in
get_index_prefixnow lowercases the domain for case-insensitive comparison.
9.3.1
Breaking changes
- Elasticsearch and OpenSearch now verify SSL certificates by default when
ssl = True, even without acert_path - Added
skip_certificate_verificationoption to theelasticsearchandopensearchconfiguration sections for consistency withsplunk_hec
Fixed
- Splunk HEC
skip_certificate_verificationnow works correctly - SMTP TLS reports no longer fail when saving to multiple output targets (e.g. Elasticsearch and OpenSearch) due to in-place mutation of the report dict
- Output client initialization errors now identify which module failed (e.g. "OpenSearch: ConnectionError..." instead of generic "Output client error")
9.3.0
Added
- SIGHUP-based configuration reload for watch mode — update output destinations, DNS/GeoIP settings, processing flags, and log level without restarting the service or interrupting in-progress report processing.
- Use
systemctl reload parsedmarcwhen running undersystemd. - On a successful reload, old output clients are closed and recreated.
- On a failed reload, the previous configuration remains fully active.
- Use
close()methods onGelfClient,KafkaClient,SyslogClient,WebhookClient, HECClient, andS3Clientfor clean resource teardown on reload.config_reloadingparameter on allMailboxConnection.watch()implementations andwatch_inbox()to ensure SIGHUP never triggers a new email batch mid-reload.- Elasticsearch and OpenSearch connections are now tracked and cleaned up on reload via
_close_output_clients(). - Extracted
_parse_config_file()and_init_output_clients()from_main()incli.pyto support config reload and reduce code duplication.
Fixed
get_index_prefix()crashed on forensic reports withTypeErrordue toreport()instead ofreport[]dict access.- Missing
exit(1)after IMAP user/password validation failure allowed execution to continue withNonecredentials.
9.2.1
Added
- Better checking of
msgraphconfiguration (PR #695)
Changed
- Updated
dbip-country-litedatabase to version2026-03 - DNS query error logging level from
warningtodebug
9.2.0
Added
- OpenSearch AWS SigV4 authentication support (PR #673)
- IMAP move/delete compatibility fallbacks (PR #671)
fail_on_output_errorCLI option for sink failures (PR #672)- Gmail service account auth mode for non-interactive runs (PR #676)
- Microsoft Graph certificate authentication support (PRs #692 and #693)
- Microsoft Graph well-known folder fallback for root listing failures (PR #618 and #684 close #609)
Fixed
- Pass mailbox since filter through
watch_inboxcallback (PR #670 closes issue #581) parsedmarc.mail.gmail.GmailConnection.delete_messagenow properly calls the Gmail API (PR #668)- Avoid extra mailbox fetch in batch and test mode (PR #691 closes #533)
9.1.2
Fixes
- Fix duplicate detection for normalized aggregate reports in Elasticsearch/OpenSearch (PR #666 fixes issue #665)
9.1.1
Fixes
- Fix the use of Elasticsearch and OpenSearch API keys (PR #660 fixes issue #653)
Changes
- Drop support for Python 3.9 (PR #661)
9.1.0
Enhancements
- Add TCP and TLS support for syslog output. (#656)
- Skip DNS lookups in GitHub Actions to prevent DNS timeouts during tests timeouts. (#657)
- Remove microseconds from DMARC aggregate report time ranges before parsing them.
9.0.10
- Support Python 3.14+
9.0.9
Fixes
- Validate that a string is base64-encoded before trying to base64 decode it. (PRs #648 and #649)
9.0.8
Fixes
- Fix logging configuration not propagating to child parser processes (#646).
- Update
mailsuitedependency to?=1.11.1to solve issues with iCloud IMAP (#493).
9.0.7
Fixes
- Fix IMAP
sinceoption (#PR 645 closes issues #581 and #643).
9.0.6
Fixes
- Fix #638.
- Fix/clarify report extraction and parsing behavior for multiple input types (bytes, base64 strings, and file-like objects).
- Fix type mismatches that could cause runtime issues in SMTP emailing and CLI option handling.
Improvements
- Improve type hints across the library (Pylance/Pyright friendliness) and reduce false-positive linter errors.
- Emails in Microsoft 365 are now marked read as they are read. This provides constancy with other mailbox types, and gives you a indication of when emails are being read as they are processed in batches. (Close #625)
Compatibility / Dependencies
- Set Python requirement to
>=3.9,<3.14. - Bump
mailsuiterequirement to>=1.11.0.
9.0.5
Fixes
- Fix report type detection introduced in
9.0.4.
9.0.4 (Yanked)
Fixes
- Fix saving reports to OpenSearch (#637)
- Fix parsing certain DMARC failure/forensic reports
- Some fixes to type hints (incomplete, but published as-is due to the above bugs)
9.0.3
Fixes
- Set
requires-pythonto>=3.9, <3.14to avoid this bug
9.0.2
Improvements
- Type hinting is now used properly across the entire library. (#445)
Fixes
- Decompress report files as needed when passed via the CLI.
- Fixed incomplete removal of the ability for
parsedmarc.utils.extract_reportto accept a file path directly in8.15.0.
Breaking changes
This version of the library requires consumers to pass certain arguments as keyword-only. Internally, the API uses a bare * in the function signature. This is standard per PEP 3102 and as documented in the Python Language Reference.
9.0.1
Fixes
- Allow multiple
recordsfor the same aggregate DMARC report in Elasticsearch and Opensearch
9.0.0 (yanked)
- Normalize aggregate DMARC report volumes when a report timespan exceeds 24 hours
8.19.1
- Ignore HTML content type in report email parsing (#626)
8.19.0
- Add multi-tenant support via an index-prefix domain mapping file
- PSL overrides so that services like AWS are correctly identified
- Additional improvements to report type detection
- Fix webhook timeout parsing (PR #623)
- Output to STDOUT when the new general config boolean
silentis set toFalse(Close #614) - Additional services added to
base_reverse_dns_map.csv
8.18.9
- Complete fix for #687 and more robust report type detection
8.18.8
- Fix parsing emails with an uncompressed aggregate report attachment (Closes #607)
- Add
--no-prettify-jsonCLI option (PR #617)
8.18.7
Removed improper spaces from base_reverse_dns_map.csv (Closes #612)
8.18.6
- Fix since option to correctly work with weeks (PR #604)
- Add 183 entries to
base_reverse_dns_map.csv - Add 57 entries to
known_unknown_base_reverse_dns.txt - Check for invalid UTF-8 bytes in
base_reverse_dns_map.csvat build - Exclude unneeded items from the
parsedmarc.resourcesmodule at build
8.18.5
- Fix CSV download
8.18.4
- Fix webhooks
8.18.3
- Move
__version__toparsedmarc.constants - Create a constant
USER_AGENT - Use the HTTP
User-Agentheader valueparsedmarc/versionfor all HTTP requests
8.18.2
- Merged PR #603
- Fixes issue #595 - CI test fails for Elasticsearch
- Moved Elasticsearch to a separate Docker service container for CI testing
- Dropped Python 3.8 from CI testing
- Fixes lookup and saving of DMARC forensic reports in Elasticsearch and OpenSearch
- Fixes issue #595 - CI test fails for Elasticsearch
- Updated fallback
base_reverse_dns_map.csv, which now includes over 1,400 lines - Updated included
dbip-country-lite.mmdbto the June 2025 release - Automatically fall back to the internal
base_reverse_dns_map.csvif the received file is not valid (Fixes #602)- Print the received data to the debug log
8.18.1
- Add missing
https://to the default Microsoft Graph URL
8.18.0
- Add support for Microsoft national clouds via Graph API base URL (PR #590)
- Avoid stopping processing when an invalid DMARC report is encountered (PR #587)
- Increase
http.client._MAXHEADERSfrom100to200to avoid errors connecting to Elasticsearch/OpenSearch (PR #589)
8.17.0
- Ignore duplicate aggregate DMARC reports with the same
org_nameandreport_idseen within the same hour (Fixes #535) - Fix saving SMTP TLS reports to OpenSearch (PR #585 closed issue #576)
- Add 303 entries to
base_reverse_dns_map.csv
8.16.1
- Failed attempt to ignore aggregate DMARC reports seen within a period of one hour (#535)
8.16.0
- Add a
sinceoption to only search for emails since a certain time (PR #527)
8.15.4
- Fix crash if aggregate report timespan is > 24 hours
8.15.3
- Ignore aggregate reports with a timespan of > 24 hours (Fixes #282)
8.15.2
- Require
mailsuite>=1.9.18- Pins
mail-parserversion at3.15.0due to a parsing regression in mail-parser4.0.0 - Parse aggregate reports with empty
<auth_results> - Do not overwrite the log on each run (PR #569 fixes issue #565)
- Pins
8.15.1
- Proper IMAP namespace fix (Closes issue #557 and issue #563)
- Require
mailsuite>=1.9.17 - Revert PR #552
- Require
- Add pre-flight check for nameservers (PR #562 closes issue #543)
- Reformat code with
ruff
8.15.0
- Fix processing of SMTP-TLS reports (#549), which broke in commit 410663d(PR #530)
- This PR enforced a stricter check for base64-encoded strings, which SMTP TLS reports from Google did not pass
- Removing the check introduced its own issue, because some file paths were treated as base64-encoded strings
- Create a separate
extract_report_from_file_path()function for processioning reports based on a file path - Remove report extraction based on a file path from
extract_report()
8.14.2
- Update
base_reverse_dns_map.csvto fix over-replacement onf3a5f10(PR #553)
8.14.1
- Failed attempt to fix processing of SMTP-TLS reports (#549)
8.14.0
- Skip invalid aggregate report rows without calling the whole report invalid
- Some providers such as GoDaddy will send reports with some rows missing a source IP address, while other rows are fine
- Fix Dovecot support by using the separator provided by the IMAP namespace when possible (PR #552 closes #551)
- Only download
base_reverse_dns_map.csvonce (fixes #542) - Update included
base_reverse_dns_map.csv- Replace University category with Education to be more inclusive
- Update included
dbip-country-lite.mmdb
8.13.0
- Add Elastic/OpenSearch index prefix option (PR #531 closes #159)
- Add GELF output support (PR #532)
8.12.0
- Fix for deadlock with large report (#508)
- Build: move to kafka-python-ng (#510)
- Fix new config variables previously not propagated in the code (#524)
- Fixes for kafka integration (#522)
- Fix if base_domain is None before get_service_from_reverse_dns_base_domain (#514)
- Update base_reverse_dns_map.csv
8.11.0
- Actually save
source_typeandsource_nameto Elasticsearch and OpenSearch - Reverse-lookup cache improvements (PR #501 closes issue #498)
- Update the included
dbip-country-lite.mmdbto the 2024-03 version - Update
base_reverse_dns_map.csv - Add new general config options (closes issue #500)
always_use_local_files- Disables the download of the reverse DNS maplocal_reverse_dns_map_path- Overrides the default local file path to use for the reverse DNS mapreverse_dns_map_url- Overrides the default download URL for the reverse DNS map
8.10.3
- Fix flaws in
base_reverse_dns_map.csv
8.10.2
- Fix flaws in
base_reverse_dns_map.csv
8.10.1
- Fix flaws in
base_reverse_dns_map.csv
8.10.0
- Fix MSGraph UsernamePassword Authentication (PR #497)
- Attempt to download an updated
base_reverse_dns_map.csvat runtime - Update included
base_reverse_dns_map.csv
8.9.4
- Update
base_reverse_dns_map.csv
8.9.3
- Revert change in 8.9.2
8.9.2
- Use
Uncategorizedinstead ofNoneas the service type when a service cannot be identified
8.9.1
- Fix broken CLI by removing obsolete parameter from
cli_parsecall (PR #496 closes issue #495)
8.9.0
- Fix broken cache (PR #494)
- Add source name and type information based on static mapping of the reverse DNS base domain
- See this documentation for more information, and to learn how to help!
- Replace
multiprocessing.PoolwithPipe+Process(PR #491 closes issue #489) - Remove unused parallel arguments (PR #492 closes issue #490)
8.8.0
- Add support for OpenSearch (PR #481 closes #480)
- Fix SMTP TLS reporting to Elasticsearch (PR #470)
8.7.0
- Add support for SMTP TLS reports (PR #453 closes issue #71)
- Do not replace content in forensic samples (fix #403)
- Pin
msgraph-coredependency at version0.2.2until Microsoft provides better documentation (PR #466 Close #464) - Properly handle base64-encoded email attachments (PR #453)
- Do not crash when attempting to parse invalid email content (PR #453)
- Ignore errors when parsing text-based forensic reports (PR #460)
- Add email date to email processing debug logs (PR #462)
- Set default batch size to 10 to match the documentation (PR #465)
- Properly handle none values (PR #468)
- Add Gmail pagination (PR #469)
- Use the correct
msgraphscope (PR #471)
8.6.4
- Properly process aggregate reports that incorrectly call
identifiersidentities - Ignore SPF results in aggregate report records if the domain is not provided
8.6.3
- Add an error message instead of raising an exception when an aggregate report time span is greater than 24 hours
8.6.2
- Use
zlibinstead ofGzipto decompress more.gzfiles, including the ones supplied by Mimecast (Based on #430 closes #429)
8.6.1
- Fix handling of non-domain organization names (PR #411 fixes issue #410)
- Skip processing of aggregate reports with a date range that is too long to be valid (PR #408 fixes issue #282)
- Better error handling for Elasticsearch queries and file parsing (PR #417)
8.6.0
- Replace publicsuffix2 with publicsuffixlist
8.5.0
- Add support for Azure Log Analytics (PR #394)
- Fix a bug in the Microsoft Graph integration that caused a crash when an inbox has 10+ folders (PR #398)
- Documentation fixes
8.4.2
- Only initialize the syslog, S3 and Kafka clients once (PR #386 closes issues #289 and #380)
8.4.1
- Fix bug introduced in 8.3.1 that caused
No such file or directoryerrors if output files didn't exist (PR #385 closes issues #358 and #382) - Make the
--silentCLI option only print errors. Add the--warningsoptions to also print warnings (PR #383)
8.4.0
- Provide a warning when no file is located at the path specified by the
ip_db_pathoption (based on PR #369 with improvements in grammar) - Add
allow_unencrypted_storageto possiblemsgraphsettings. See documentation for details. (PR #375) - Use the
check_timeoutvalue in the event of an IMAP connection error, instead of a static 5 second value (PR #377) - Update the included DBIP IP to Country Lite database to the December 2022 release
8.3.2
- Improvements to the Microsoft Graph integration (PR #352)
8.3.1
- Handle unexpected XML parsing errors more gracefully (PR #349)
- Migrate build from
setuptoolstohatch
8.3.0
- Support MFA for Microsoft Graph (PR #320 closes issue #319)
- Add more options for S3 export (PR #328)
- Provide a helpful error message when the log file cannot be created (closes issue #317)
8.2.0
- Support non-standard, text-based forensic reports sent by some mail hosts
- Set forensic report version to
None(nullin JSON) if the report was in a non-standard format and/or is missing a version number - The default value of the
mailboxbatch_sizeoption is now10(use0for no limit)
8.1.1
- Fix marking messages as read via Microsoft Graph
8.1.0
- Restore compatibility with <8.0.0 configuration files (with deprecation warnings)
- Set default
reports_foldertoInbox(rather thanINBOX) whenmsgraphis configured - Mark a message as read when fetching a message from Microsoft Graph
8.0.3
- Fix IMAP callback for
IDLEconnections (PR #313 closes issue #311) - Add warnings in documentation and log output for IMAP configuration changes introduced in 8.0.0 (Closes issue #309)
- Actually pin the
elasticsearchPython library version at<7.14.0(Closes issue #315) - Separate version numbers in
__init__.pyandsetup.pyto allowpipto install directly fromgit - Update
dateparserto 1.1.1 (closes issue #273)
8.0.2 (yanked)
- Strip leading and trailing whitespaces from Gmail scopes (Closes issue #310)
8.0.1 (yanked)
- Fix
ModuleNotFoundErrorby addingparsedmarc.mailto the list of packages insetup.py(PR #308)
8.0.0 (yanked)
- Update included copy of
dbip-country-lite.mmdbto the 2022-04 release - Add support for Microsoft/Office 365 via Microsoft Graph API (PR #301 closes issue #111)
- Pin
elasticsearch-dslversion at>=7.2.0<7.14.0(PR #297 closes issue #296) - Properly initialize
ip_dp_path(PR #294 closes issue #286) - Remove usage of
logging.basicConfig(PR #285) - Add support for the Gmail API (PR #284 and PR #307 close issue #96)
7.1.1
- Actually include
dbip-country-lite.mmdbfile in theparsedmarc.resourcespackage (PR #281) - Update
dbip-country-lite.mmdbto the 2022-01 release
7.1.0
- A static copy of the DBIP Country Lite database is now included for use when a copy of the MaxMind GeoLite2 Country database is not installed (Closes #275)
- Add
ip_db_pathto as a parameter andgeneralsetting for a custom IP geolocation database location (Closes #184) - Search default Homebrew path when searching for a copy of the MaxMind GeoLite2 Country database (Closes #272)
- Fix log messages written to root logger (PR #276)
- Fix
--offlineoption in CLI not being passed as a boolean (PR #265) - Set Elasticsearch shard replication to
0(PR #274) - Add support for syslog output (PR #263 closes #227)
- Do not print TQDDM progress bar when running in a no-interactive TTY (PR #264)
7.0.1
- Fix startup error (PR #254)
7.0.0
- Fix issue #221: Crash when handling invalid reports without root node (PR #248)
- Use UTC datetime objects for Elasticsearch output (PR #245)
- Fix issues #219, #155, and #103: IMAP connections break on large emails (PR #241)
- Add support for saving reports to S3 buckets (PR #223)
- Pass
offlineparameter towait_inbox()(PR #216) - Add more details to logging (PR #220)
- Add options customizing the names of output files (Modifications based on PR #225)
- Wait for 5 seconds before attempting to reconnect to an IMAP server (PR #217)
- Add option to process messages in batches (PR #222)
6.12.0
- Limit output filename length to 100 characters (PR #199)
- Add basic auth support for Elasticsearch (PR #191)
- Fix Windows paths when searching for the GeoIP database (PR #190)
- Remove
sixrequirement - Require
mailsuite>=1.6.1 - Require
dnspython>=2.0.0- Drop Python 3.5 support
6.11.0
- Fix parsing failure for some valid forensic reports (PR #170)
- Fix double count of messages in the Grafana dashboard (PR #182)
- Add begin and end date fields for aggregate DMARC reports in Elasticsearch (PR #183 fixes issue #162)
- Fix crash on IMAP timeout (PR #186 fixes issue #163)
- Fix IMAP debugging output
- Fix
User-Agentstring
6.10.0
- Ignore unknown forensic report fields when generating CSVs (Closes issue #148)
- Fix crash on IMAP timeout (PR #164 - closes issue #163)
- Use SMTP port from the config file when sending emails (PR #151)
- Add support for Elasticsearch 7.0 (PR #161 - closes issue #149)
- Remove temporary workaround for DMARC aggregate report records missing a SPF domain fields
6.9.0
- Use system nameservers instead of Cloudflare by default
- Parse aggregate report records with missing SPF domains
6.8.2
- Require
mailsuite>=1.5.4
6.8.1
- Use
match_phraseinstead ofmatchwhen looking for existing strings in Elasticsearch
6.8.0
- Display warning when
GeoLite2-Country.mmdbis missing, instead of trying to download it - Add documentation for MaxMind
geoipupdatechanges on January 30th, 2019 (closes issues #137 and #139) - Require
mail-parser>=3.11.0
6.7.4
- Update dependencies
6.7.3
- Make
dkim_alignedandspf_alignedcase-insensitive (PR #132)
6.7.2
- Fix SPF results field in CSV output (closes issue #128)
6.7.1
- Parse forensic email samples with non-standard date headers
- Graceful handling of a failure to download the GeoIP database (issue #123)
6.7.0
- Fix typos (PR #119)
- Make CSV output match JSON output (Issue # 22)
- Graceful processing of invalid aggregate DMARC reports (PR #122)
- Remove Python 3.4 support
6.6.1
- Close files after reading them
6.6.0
- Set a configurable default IMAP timeout of 30 seconds
- Set a configurable maximum of 4 IMAP timeout retry attempts
- Add support for reading
MBOXfiles - Set a configurable Elasticsearch timeout of 60 seconds
6.5.5
- Set minimum
publicsuffix2version
6.5.4
- Bump required
mailsuiteversion to1.2.1
6.5.3
- Fix typos in the CLI documentation
- Bump required
mailsuiteversion to1.1.1
6.5.2
- Merge PR #100 from michaeldavie
- Correct a bug introduced in 6.5.1 that caused only the last record's data to be used for each row in an aggregate report's CSV version.
- Use
mailsuite1.1.0 to fix issues with some IMAP servers (closes issue 103)- Always use
/as the folder hierarchy separator, and convert to the server's hierarchy separator in the background - Always remove folder name characters that conflict with the server's hierarchy separators
- Prepend the namespace to the folder path when required
- Always use
6.5.1
- Merge PR #98 from michaeldavie
- Add functions
parsed_aggregate_reports_to_csv_row(reports)parsed_forensic_reports_to_csv_row(reports)
- Add functions
- Require
dnspython>=1.16.0
6.5.0
- Move mail processing functions to the
mailsuitepackage - Add offline option (closes issue #90)
- Use UDP instead of TCP, and properly set the timeout when querying DNS (closes issue #79 and #92)
- Log the current file path being processed when
--debugis used (closes issue #95)
6.4.2
- Do not attempt to convert
org_nameto a base domain iforg_namecontains a space (closes issue #94) - Always lowercase the
header_from - Provide a more helpful warning message when
GeoLite2-Country.mmdbis missing
6.4.1
- Raise
utils.DownloadErrorexception when a GeoIP database or Public Suffix List (PSL) download fails (closes issue #73)
6.4.0
- Add
number_of_shardsandnumber_of_replicasas possible options in theelasticsearchconfiguration file section (closes issue #78)
6.3.7
- Work around some unexpected IMAP responses reported in issue #75
6.3.6
- Work around some unexpected IMAP responses reported in issue #70
- Show correct destination folder in debug logs when moving aggregate reports
6.3.5
- Normalize
Delivery-Resultvalue in forensic/failure reports (issue #76) Thanks Freddie Leeman of URIports for the troubleshooting assistance
6.3.4
- Fix Elasticsearch index creation (closes issue #74)
6.3.3
- Set
number_of_shardsandnumber_of_replicasto1when creating indexes - Fix dependency conflict
6.3.2
- Fix the
monthly_indexesoption in theelasticsearchconfiguration section
6.3.1
- Fix
strip_attachment_payloadsoption
6.3.0
- Fix IMAP IDLE response processing for some mail servers (#67)
- Exit with a critical error when required settings are missing (#68)
- XML parsing fixes (#69)
- Add IMAP responses to debug logging
- Add
smtpoptionskip_certificate_verification - Add
kafkaoptionskip_certificate_verification - Suppress
mailparserlogging output - Suppress
msgconvertwarnings
6.2.2
- Fix crash when trying to save forensic reports with missing fields to Elasticsearch
6.2.1
- Add missing
tqdmdependency tosetup.py
6.2.0
- Add support for multiprocess parallelized processing via CLI (Thanks zscholl - PR #62)
- Save sha256 hashes of attachments in forensic samples to Elasticsearch
6.1.8
- Actually fix GeoIP lookups
6.1.7
- Fix GeoIP lookups
6.1.6
- Better GeoIP error handling
6.1.5
- Always use Cloudflare's nameservers by default instead of Google's
- Avoid re-downloading the Geolite2 database (and tripping their DDoS protection)
- Add
geoipupdateto install instructions
6.1.4
- Actually package requirements
6.1.3
- Fix package requirements
6.1.2
- Use local Public Suffix List file instead of downloading it
- Fix argument name for
send_email()(closes issue #60)
6.1.1
- Fix aggregate report processing
- Check for the existence of a configuration file if a path is supplied
- Replace
publicsuffixwithpublicsuffix2 - Add minimum versions to requirements
6.1.0
- Fix aggregate report email parsing regression introduced in 6.0.3 (closes issue #57)
- Fix Davmail support (closes issue #56)
6.0.3
- Don't assume the report is the last part of the email message (issue #55)
6.0.2
- IMAP connectivity improvements (issue #53)
- Use a temp directory for temp files (issue #54)
6.0.1
- Fix Elasticsearch output (PR #50 - andrewmcgilvray)
6.0.0
- Move options from CLI to a config file (see updated installation documentation)
- Refactoring to make argument names consistent
5.3.0
- Fix crash on invalid forensic report sample (Issue #47)
- Fix DavMail support (Issue #45)
5.2.1
- Remove unnecessary debugging code
5.2.0
-
Add filename and line number to logging output
-
Improved IMAP error handling
-
Add CLI options
--elasticsearch-use-ssl Use SSL when connecting to Elasticsearch --elasticsearch-ssl-cert-path ELASTICSEARCH_SSL_CERT_PATH Path to the Elasticsearch SSL certificate --elasticsearch-monthly-indexes Use monthly Elasticsearch indexes instead of daily indexes --log-file LOG_FILE output logging to a file
5.1.3
- Remove
urllib3version upper limit
5.1.2
- Workaround unexpected Office 365/Exchange IMAP responses
5.1.1
- Bugfix: Crash when parsing invalid forensic report samples (#38)
- Bugfix: Crash when IMAP connection is lost
- Increase default Splunk HEC response timeout to 60 seconds
5.1.0
- Bugfix: Submit aggregate dates to Elasticsearch as lists, not tuples
- Support
elasticsearch-dsl<=6.3.0 - Add support for TLS/SSL and username/password auth to Kafka
5.0.2
- Revert to using
publicsuffixinstead ofpublicsuffix2
5.0.1
- Use
publixsuffix2(closes issue #4) - Add Elasticsearch to automated testing
- Lock
elasticsearch-dslrequired version to6.2.1(closes issue #25)
5.0.0
Note: Re-importing kibana_saved_objects.json in Kibana is required when upgrading to this version!
- Bugfix: Reindex the aggregate report index field
published_policy.foastextinstead oflong(Closes issue #31) - Bugfix: IDLE email processing in Gmail/G-Suite accounts (closes issue #33)
- Bugfix: Fix inaccurate DNS timeout in CLI documentation (closes issue #34)
- Bugfix: Forensic report processing via CLI
- Bugfix: Duplicate aggregate report Elasticsearch query broken
- Bugfix: Crash when
Arrival-Dateheader is missing in a forensic/failure/ruf report - IMAP reliability improvements
- Save data in separate indexes each day to make managing data retention easier
- Cache DNS queries in memory
4.4.1
- Don't crash if Elasticsearch returns an unexpected result (workaround for issue #31)
4.4.0
- Packaging fixes
4.3.9
- Kafka output improvements
- Moved some key values (
report_id,org_email,org_name) higher in the JSON structure - Recreated the
date_rangevalues from the ES client for easier parsing. - Started sending individual record slices. Kafka default message size is 1 MB, some aggregate reports were exceeding this. Now it appends meta-data and sends record by record.
- Moved some key values (
4.3.8
- Fix decoding of attachments inside forensic samples
- Add CLI option
--imap-skip-certificate-verification - Add optional
ssl_contextargument forget_dmarc_reports_from_inbox()andwatch_inbox() - Debug logging improvements
4.3.7
- When checking an inbox, always recheck for messages when processing is complete
4.3.6
- Be more forgiving for forensic reports with missing fields
4.3.5
- Fix base64 attachment decoding (#26)
4.3.4
- Fix crash on empty aggregate report comments (brakhane - #25)
- Add SHA256 hashes of attachments to output
- Add
strip_attachment_payloadsoption to functions and--strip-attachment-payloadsoption to the CLI (#23) - Set
urllib3version requirements to matchrequests
4.3.3
- Fix forensic report email processing
4.3.2
- Fix normalization of the forensic sample from address
4.3.1
- Fix parsing of some emails
- Fix duplicate forensic report search for Elasticsearch
4.3.0
- Fix bug where
parsedmarcwould always try to save to Elastic search, even if only--hecwas used - Add options to save reports as a Kafka topic (mikesiegel - #21)
- Major refactoring of functions
- Support parsing forensic reports generated by Brightmail
- Make
sample_headers_onlyflag more reliable - Functions that might be useful to other projects are now stored in
parsedmarc.utils:get_base_domain(domain)get_filename_safe_string(string)get_ip_address_country(ip_address)get_ip_address_info(ip_address, nameservers=None, timeout=2.0)get_reverse_dns(ip_address, nameservers=None, timeout=2.0)human_timestamp_to_datetime(human_timestamp)human_timestamp_to_timestamp(human_timestamp)parse_email(data)
4.2.0
- Save each aggregate report record as a separate Splunk event
- Fix IMAP delete action (#20)
- Suppress Splunk SSL validation warnings
- Change default logging level to
WARNING
4.1.9
- Workaround for forensic/ruf reports that are missing
Arrival-Dateand/orReported-Domain
4.1.8
- Be more forgiving of weird XML
4.1.7
- Remove any invalid XML schema tags before parsing the XML (#18)
4.1.6
- Fix typo in CLI parser
4.1.5
- Only move or delete IMAP emails after they all have been parsed
- Move/delete messages one at a time - do not exit on error
- Reconnect to IMAP if connection is broken during
get_dmarc_reports_from_inbox() - Add
--imap-portand--imap-no-sslCLI options
4.1.4
- Change default logging level to
ERROR
4.1.3
- Fix crash introduced in 4.1.0 when creating Elasticsearch indexes (Issue #15)
4.1.2
- Fix packaging bug
4.1.1
- Add splunk instructions
- Reconnect reset IMAP connections when watching a folder
4.1.0
- Add options for Elasticsearch prefixes and suffixes
- If an aggregate report has the invalid
dispositionvaluepass, change it tonone
4.0.2
- Use report timestamps for Splunk timestamps
4.0.1
- When saving aggregate reports in Elasticsearch store
domaininpublished_policy - Rename
policy_publishedtopublished_policywhen saving aggregate reports to Splunk
4.0.0
- Add support for sending DMARC reports to a Splunk HTTP Events Collector (HEC)
- Use a browser-like
User-Agentwhen downloading the Public Suffix List and GeoIP DB to avoid being blocked by security proxies - Reduce default DNS timeout to 2.0 seconds
- Add alignment booleans to JSON output
- Fix
.msgparsing CLI exception whenmsgconvertis not found in the system path - Add
--outgoing-portand--outgoing-ssloptions - Fall back to plain text SMTP if
--outgoing-sslis not used andSTARTTLSis not supported by the server - Always use
as the newline when generating CSVs - Workaround for random Exchange/Office 365
Server UnavailableIMAP errors
3.9.7
- Completely reset IMAP connection when a broken pipe is encountered
3.9.6
- Finish incomplete broken pipe fix
3.9.5
-
Refactor to use a shared IMAP connection for inbox watching and message downloads
-
Gracefully recover from broken pipes in IMAP
3.9.4
- Fix moving/deleting emails
3.9.3
- Fix crash when forensic reports are missing
Arrival-Date
3.9.2
- Fix PEP 8 spacing
- Update build script to fail when CI tests fail
3.9.1
- Use
COPYand delete if an IMAP server does not supportMOVE(closes issue #9)
3.9.0
- Reduce IMAP
IDLErefresh rate to 5 minutes to avoid session timeouts in Gmail - Fix parsing of some forensic/failure/ruf reports
- Include email subject in all warning messages
- Fix example NGINX configuration in the installation documentation (closes issue #6)
3.8.2
- Fix
nameserversoption (mikesiegel) - Move or delete invalid report emails in an IMAP inbox (closes issue #7)
3.8.1
- Better handling of
.msgfiles whenmsgconvertis not installed
3.8.0
- Use
.instead of/as the IMAP folder hierarchy separator when/does not work - fixes dovecot support (#5) - Fix parsing of base64-encoded forensic report data
3.7.3
- Fix saving attachment from forensic sample to Elasticsearch
3.7.2
- Change uses of the
DocTypeclass toDocument, to properly supportelasticsearch-dsl6.2.0(this also fixes use in pypy) - Add documentation for installation under pypy
3.7.1
- Require
elasticsearch>=6.2.1,<7.0.0andelasticsearch-dsl>=6.2.1,<7.0.0 - Update for class changes in
elasticsearch-dsl6.2.0
3.7.0
- Fix bug where PSL would be called before it was downloaded if the PSL was older than 24 Hours
3.6.1
- Parse aggregate reports with missing SPF domain
3.6.0
- Much more robust error handling
3.5.1
- Fix dashboard message counts for source IP addresses visualizations
- Improve dashboard loading times
- Improve dashboard layout
- Add country rankings to the dashboards
- Fix crash when parsing report with empty <auth_results></auth_results>
3.5.0
- Use Cloudflare's public DNS resolvers by default instead of Google's
- Fix installation from virtualenv
- Fix documentation typos
3.4.1
- Documentation fixes
- Fix console output
3.4.0
- Maintain IMAP IDLE state when watching the inbox
- The
-i/--idleCLI option is now-w/--watch - Improved Exception handling and documentation
3.3.0
- Fix errors when saving to Elasticsearch
3.2.0
- Fix existing aggregate report error message
3.1.0
- Fix existing aggregate report query
3.0.0
New features
- Add option to select the IMAP folder where reports are stored
- Add options to send data to Elasticsearch
Changes
- Use Google's public nameservers (
8.8.8.8and4.4.4.4) by default - Detect aggregate report email attachments by file content rather than file extension
- If an aggregate report's
org_nameis a FQDN, the base is used - Normalize aggregate report IDs
2.1.2
- Rename
parsed_dmarc_forensic_reports_to_csv()toparsed_forensic_reports_to_csv()to match other functions - Rename
parsed_aggregate_report_to_csv()toparsed_aggregate_reports_to_csv()to match other functions - Use local time when generating the default email subject
2.1.1
- Documentation fixes
2.1.0
- Add
get_report_zip()andemail_results() - Add support for sending report emails via the command line
2.0.1
- Fix documentation
- Remove Python 2 code
2.0.0
New features
- Parse forensic reports
- Parse reports from IMAP inbox
Changes
- Drop support for Python 2
- Command line output is always a JSON object containing the lists
aggregate_reportsandforensic_reports -o/--outputoption is now a path to an output directory, instead of an output file
1.1.0
- Add
extract_xml()andhuman_timestamp_to_datetimemethods
1.0.5
- Prefix public suffix and GeoIP2 database filenames with
. - Properly format errors list in CSV output
1.0.3
- Fix documentation formatting
1.0.2
- Fix more packaging flaws
1.0.1
- Fix packaging flaw
1.0.0
- Initial release