# Please don't modify this file as your changes might be overwritten with
# the next update.
#
# You can modify 'local.d/rbl.conf' to add and merge
# parameters defined inside this section
#
# You can modify 'override.d/rbl.conf' to strictly override all
# parameters defined inside this section
#
# See https://rspamd.com/doc/faq.html#what-are-the-locald-and-overrided-directories
# for details
#
# Module documentation can be found at  https://rspamd.com/doc/modules/rbl.html

rbl {
  default_exclude_users = true;
  default_unknown = true;

  url_whitelist = [
    "{= env.MAPS_MIRROR | default "https://maps.rspamd.com" =}/rspamd/surbl-whitelist.inc.zst",
    "$LOCAL_CONFDIR/local.d/maps.d/surbl-whitelist.inc.local",
    "${DBDIR}/surbl-whitelist.inc.local",
    "fallback+file://${CONFDIR}/maps.d/surbl-whitelist.inc"
  ];

  disabled_rbl_suffixes_map = "{= env.MAPS_MIRROR | default "https://maps.rspamd.com" =}/rspamd/disabled_rbls.inc.zst";

  attached_maps = [
    {
      selector_alias = "surbl_hashbl_map",
      description = "SURBL hashbl map",
      url = "regexp;http://sa-update.surbl.org/rspamd/surbl-hashbl-map.inc",
    }
  ]

  rbls {
    spamhaus {
      symbol = "SPAMHAUS";
      rbl = "zen.spamhaus.org";
      checks = ["from", "received"];
      symbols_prefixes = {
        received = "RECEIVED",
        from = "RBL",
      }
      returncodes {
        SPAMHAUS_SBL = "127.0.0.2";
        SPAMHAUS_CSS = "127.0.0.3";
        SPAMHAUS_XBL = ["127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7"];
        SPAMHAUS_PBL = ["127.0.0.10", "127.0.0.11"];
        SPAMHAUS_DROP = "127.0.0.9";
        SPAMHAUS_BLOCKED_OPENRESOLVER = "127.255.255.254";
        SPAMHAUS_BLOCKED= "127.255.255.255";
      }
    }

    mailspike {
      symbol = "MAILSPIKE";
      rbl = "rep.mailspike.net";
      checks = ["from"];
      is_whitelist = true;
      whitelist_exception = [
        "MAILSPIKE",
        "RWL_MAILSPIKE_GOOD",
        "RWL_MAILSPIKE_NEUTRAL",
        "RWL_MAILSPIKE_POSSIBLE",
        "RBL_MAILSPIKE_WORST",
        "RBL_MAILSPIKE_VERYBAD",
        "RBL_MAILSPIKE_BAD"
      ];
      returncodes {
        RBL_MAILSPIKE_WORST = "127.0.0.10";
        RBL_MAILSPIKE_VERYBAD = "127.0.0.11";
        RBL_MAILSPIKE_BAD = "127.0.0.12";
        RWL_MAILSPIKE_NEUTRAL = ["127.0.0.16", "127.0.0.15", "127.0.0.14", "127.0.0.13"];
        RWL_MAILSPIKE_POSSIBLE = "127.0.0.17";
        RWL_MAILSPIKE_GOOD = "127.0.0.18";
        RWL_MAILSPIKE_VERYGOOD = "127.0.0.19";
        RWL_MAILSPIKE_EXCELLENT = "127.0.0.20";
      }
    }

    senderscore {
      # Disabled by default. Requires a registered MyValidity account to function:
      # unregistered IPs receive 127.255.255.255 (blocked) regardless of query volume.
      # See https://knowledge.validity.com/hc/en-us/articles/20961730681243.
      enabled = false;
      symbol = "RBL_SENDERSCORE_UNKNOWN";
      checks = ["from"];
      rbl = "bl.score.senderscore.com";
      returncodes {
        RBL_SENDERSCORE_BOT = "127.0.0.1";
        RBL_SENDERSCORE_NA = "127.0.0.2";
        RBL_SENDERSCORE_NA_BOT = "127.0.0.3";
        RBL_SENDERSCORE_PRST = "127.0.0.4";
        RBL_SENDERSCORE_PRST_BOT = "127.0.0.5";
        RBL_SENDERSCORE_PRST_NA = "127.0.0.6";
        RBL_SENDERSCORE_PRST_NA_BOT = "127.0.0.7";
        RBL_SENDERSCORE_SUS_ATT = "127.0.0.8";
        RBL_SENDERSCORE_SUS_ATT_NA = "127.0.0.10";
        RBL_SENDERSCORE_SUS_ATT_NA_BOT = "127.0.0.11";
        RBL_SENDERSCORE_SUS_ATT_PRST_NA = "127.0.0.14";
        RBL_SENDERSCORE_SUS_ATT_PRST_NA_BOT = "127.0.0.15";
        RBL_SENDERSCORE_SCORE = "127.0.0.16";
        RBL_SENDERSCORE_SCORE_NA = "127.0.0.18";
        RBL_SENDERSCORE_SCORE_PRST = "127.0.0.20";
        RBL_SENDERSCORE_SCORE_PRST_NA = "127.0.0.22";
        RBL_SENDERSCORE_SCORE_SUS_ATT_NA = "127.0.0.26";
        RBL_SENDERSCORE_BLOCKED = "127.255.255.255";
      }
    }

    senderscore_reputation {
      # Disabled by default. Requires a registered MyValidity account to function:
      # unregistered IPs receive 127.255.255.255 (blocked) regardless of query volume.
      # See https://knowledge.validity.com/hc/en-us/articles/20961730681243.
      enabled = false;
      symbol = "RBL_SENDERSCORE_REPUT_UNKNOWN";
      checks = ["from"];
      rbl = "score.senderscore.com";
      returncodes_matcher = "luapattern";
      returncodes {
        RBL_SENDERSCORE_REPUT_0 = "127%.0%.4%.%d";
        RBL_SENDERSCORE_REPUT_1 = "127%.0%.4%.1%d";
        RBL_SENDERSCORE_REPUT_2 = "127%.0%.4%.2%d";
        RBL_SENDERSCORE_REPUT_3 = "127%.0%.4%.3%d";
        RBL_SENDERSCORE_REPUT_4 = "127%.0%.4%.4%d";
        RBL_SENDERSCORE_REPUT_5 = "127%.0%.4%.5%d";
        RBL_SENDERSCORE_REPUT_6 = "127%.0%.4%.6%d";
        RBL_SENDERSCORE_REPUT_7 = "127%.0%.4%.7%d";
        RBL_SENDERSCORE_REPUT_8 = "127%.0%.4%.8%d";  # Neutral reputation (80-89).
        RBL_SENDERSCORE_REPUT_9 = ["127%.0%.4%.9%d", "127%.0%.4%.100"];  # Good reputation (90-100).
        RBL_SENDERSCORE_REPUT_BLOCKED = "127%.255%.255%.255";
      }
    }

    sem {
      symbol = "RBL_SEM";
      rbl = "bl.spameatingmonkey.net";
      checks = ["from"];
      ipv6 = false;
    }

    semIPv6 {
      symbol = "RBL_SEM_IPV6";
      rbl = "bl.ipv6.spameatingmonkey.net";
      checks = ["from"];
      ipv4 = false;
      ipv6 = true;
    }

    dnswl {
      symbol = "RCVD_IN_DNSWL";
      rbl = "list.dnswl.org";
      checks = ["from", "received"];
      ipv6 = true;
      is_whitelist = true;
      returncodes_matcher = "luapattern";
      whitelist_exception = "RCVD_IN_DNSWL";
      whitelist_exception = "RCVD_IN_DNSWL_NONE";
      whitelist_exception = "RCVD_IN_DNSWL_LOW";
      whitelist_exception = "DNSWL_BLOCKED";
      returncodes {
        RCVD_IN_DNSWL_NONE = ["127%.0%.%d%.0", "127%.0%.[02-9]%d%.0", "127%.0%.1[1-9]%.0", "127%.0%.[12]%d%d%.0"];
        RCVD_IN_DNSWL_LOW = ["127%.0%.%d%.1", "127%.0%.[02-9]%d%.1", "127%.0%.1[1-9]%.1", "127%.0%.[12]%d%d%.1"];
        RCVD_IN_DNSWL_MED = ["127%.0%.%d%.2", "127%.0%.[02-9]%d%.2", "127%.0%.1[1-9]%.2", "127%.0%.[12]%d%d%.2"];
        RCVD_IN_DNSWL_HI = ["127%.0%.%d%.3", "127%.0%.[02-9]%d%.3", "127%.0%.1[1-9]%.3", "127%.0%.[12]%d%d%.3"];
        DNSWL_BLOCKED = ["127%.0%.0%.255", "127%.0%.10%.%d+"];
      }
    }

    # Provided by https://virusfree.cz
    virusfree {
      symbol = "RBL_VIRUSFREE_UNKNOWN";
      rbl = "bip.virusfree.cz";
      checks = ["from"];
      ipv6 = true;
      returncodes {
        RBL_VIRUSFREE_BOTNET = "127.0.0.2";
      }
    }

    blocklistde {
      symbol = "BLOCKLISTDE";
      rbl = "bl.blocklist.de";
      checks = ["from", "received"];
      symbols_prefixes = {
        received = "RECEIVED",
        from = "RBL",
      }
    }

    # DKIM whitelist
    dnswl_dwl {
      symbol = "DWL_DNSWL";
      rbl = "dwl.dnswl.org";
      checks = ["dkim"];
      ignore_whitelist = true;
      unknown = false;
      returncodes_matcher = "luapattern";
      returncodes {
        DWL_DNSWL_NONE = ["127%.0%.%d%.0", "127%.0%.[02-9]%d%.0", "127%.0%.1[1-9]%.0", "127%.0%.[12]%d%d%.0"];
        DWL_DNSWL_LOW = ["127%.0%.%d%.1", "127%.0%.[02-9]%d%.1", "127%.0%.1[1-9]%.1", "127%.0%.[12]%d%d%.1"];
        DWL_DNSWL_MED = ["127%.0%.%d%.2", "127%.0%.[02-9]%d%.2", "127%.0%.1[1-9]%.2", "127%.0%.[12]%d%d%.2"];
        DWL_DNSWL_HI = ["127%.0%.%d%.3", "127%.0%.[02-9]%d%.3", "127%.0%.1[1-9]%.3", "127%.0%.[12]%d%d%.3"];
        DWL_DNSWL_BLOCKED = ["127%.0%.0%.255", "127%.0%.10%.%d+"];
      }
    }

    RSPAMD_EMAILBL {
      rbl = "email.rspamd.com";
      checks = ["emails", "replyto"];
      hash = "blake2";
      hash_len = 32;
      hash_format = "base32";
      ignore_whitelist = true;
      ignore_url_whitelist = true;
      ignore_defaults = true;
      exclude_users = false;
      emails_delimiter = ".";
      emails_domainonly = false;
      selector = {
        from_smtp = "from('smtp'):addr.lower_utf8";
        from_mime = "from('mime'):addr.lower_utf8";
      }
      returncodes = {
        RSPAMD_EMAILBL = "127.0.0.2";
      }
    }

    MSBL_EBL {
      rbl = "ebl.msbl.org";
      checks = ["emails", "replyto"];
      hash = "sha1";
      ignore_whitelist = true;
      ignore_url_whitelist = true;
      ignore_defaults = true;
      exclude_users = false;
      emails_domainonly = false;
      selector = {
        from_smtp = "from('smtp'):addr.lower_utf8";
        from_mime = "from('mime'):addr.lower_utf8";
      }
      returncodes = {
        MSBL_EBL = [
          "127.0.0.2",
          "127.0.0.3"
        ];
        MSBL_EBL_GREY = [
          "127.0.1.2",
          "127.0.1.3"
        ];
      }
    }

    SURBL_MULTI {
      rbl = "multi.surbl.org";
      checks = ["emails", "dkim", "helo", "rdns", "replyto", "urls", "content_urls"];
      ignore_defaults = true;
      exclude_users = false;
      url_full_hostname = true; # According to SURBL rules
      emails_domainonly = true;
      selector = {
        from_smtp = "from('smtp'):domain";
        from_mime = "from('mime'):domain";
        mid = "header(Message-Id).regexp('@([^\.]+\.[^>]+)').last";
      }
      returnbits = {
        CRACKED_SURBL = 128;
        ABUSE_SURBL = 64;
        CT_SURBL = 32;
        MW_SURBL_MULTI = 16;
        PH_SURBL_MULTI = 8;
        DM_SURBL = 4;
        SURBL_BLOCKED = 1;
      }
    }

    SURBL_HASHBL {
      rbl = "hashbl.surbl.org";
      # TODO: make limit more configurable maybe?
      selector = "specific_urls_filter_map('surbl_hashbl_map', {limit = 10}).apply_methods('get_host', 'get_path').join_tables('/')";
      hash = "md5";
      hash_len = 32;
      random_monitored = true;
      ignore_defaults = true;
      returncodes_matcher = "luapattern";
      returncodes = {
        SURBL_HASHBL_PHISH = "127.0.0.8";
        SURBL_HASHBL_MALWARE = "127.0.0.16";
        SURBL_HASHBL_ABUSE = "127.0.0.64";
        SURBL_HASHBL_CRACKED = "127.0.0.128";
        SURBL_HASHBL_EMAIL = "127.0.1.%d+";
      }
    }

    URIBL_MULTI {
      rbl = "multi.uribl.com";
      checks = ["emails", "dkim", "helo", "rdns", "replyto", "urls", "content_urls"];
      ignore_defaults = true;
      exclude_users = false;
      emails_domainonly = true;
      selector = {
        from_smtp = "from('smtp'):domain";
        from_mime = "from('mime'):domain";
        mid = "header(Message-Id).regexp('@([^\.]+\.[^>]+)').last";
      }
      returnbits {
        URIBL_BLOCKED = 1;
        URIBL_BLACK = 2;
        URIBL_GREY = 4;
        URIBL_RED = 8;
      }
    }

    RSPAMD_URIBL {
      rbl = "uribl.rspamd.com";
      checks = ["emails", "dkim", "urls", "content_urls"];
      hash = "blake2";
      hash_len = 32;
      hash_format = "base32";
      ignore_defaults = true;
      exclude_users = false;
      emails_domainonly = true;
      selector = {
        from_smtp = "from('smtp'):domain.lower_utf8";
        from_mime = "from('mime'):domain.lower_utf8";
        mid = "header(Message-Id).regexp('@([^\.]+\.[^>]+)').last.lower_utf8";
      }
      returncodes = {
        RSPAMD_URIBL = [
          "127.0.0.2",
        ];
      }
    }

    DBL {
      rbl = "dbl.spamhaus.org";
      checks = ["emails", "dkim", "helo", "rdns", "replyto", "urls", "content_urls"];
      no_ip = true;
      ignore_defaults = true;
      exclude_users = false;
      emails_domainonly = true;
      selector = {
        from_smtp = "from('smtp'):domain";
        from_mime = "from('mime'):domain";
        mid = "header(Message-Id).regexp('@([^\.]+\.[^>]+)').last";
      }
      returncodes = {
        # spam domain
        DBL_SPAM = "127.0.1.2";
        # phish domain
        DBL_PHISH = "127.0.1.4";
        # malware domain
        DBL_MALWARE = "127.0.1.5";
        # botnet C&C domain
        DBL_BOTNET = "127.0.1.6";
        # abused legit spam
        DBL_ABUSE = "127.0.1.102";
        # abused spammed redirector domain
        DBL_ABUSE_REDIR = "127.0.1.103";
        # abused legit phish
        DBL_ABUSE_PHISH = "127.0.1.104";
        # abused legit malware
        DBL_ABUSE_MALWARE = "127.0.1.105";
        # abused legit botnet C&C
        DBL_ABUSE_BOTNET = "127.0.1.106";
        # error - IP queries prohibited!
        DBL_PROHIBIT = "127.0.1.255";
        # issue #3074
        DBL_BLOCKED_OPENRESOLVER = "127.255.255.254";
        DBL_BLOCKED = "127.255.255.255";
      }
    }

    # Not enabled by default due to privacy concerns! (see also groups.d/surbl_group.conf)
    SPAMHAUS_ZEN_URIBL {
      enabled = false;
      rbl = "zen.spamhaus.org";
      checks = ["emails"];
      resolve_ip = true;
      returncodes = {
        URIBL_SBL = "127.0.0.2";
        URIBL_SBL_CSS = "127.0.0.3";
        URIBL_XBL = ["127.0.0.4", "127.0.0.5", "127.0.0.6", "127.0.0.7"];
        URIBL_PBL = ["127.0.0.10", "127.0.0.11"];
        URIBL_DROP = "127.0.0.9";
      }
    }

    SEM_URIBL_UNKNOWN {
      rbl = "uribl.spameatingmonkey.net";
      checks = ["emails", "dkim", "urls", "content_urls"];
      no_ip = true;
      ignore_defaults = true;
      emails_domainonly = true;
      selector = {
        from_smtp = "from('smtp'):domain";
        from_mime = "from('mime'):domain";
        mid = "header(Message-Id).regexp('@([^\.]+\.[^>]+)').last";
      }
      returnbits {
        SEM_URIBL = 2;
      }
    }

    SEM_URIBL_FRESH15_UNKNOWN {
      rbl = "fresh15.spameatingmonkey.net";
      checks = ["emails", "dkim", "urls", "content_urls"];
      no_ip = true;
      ignore_defaults = true;
      exclude_users = true;
      emails_domainonly = true;
      selector = {
        from_smtp = "from('smtp'):domain";
        from_mime = "from('mime'):domain";
        mid = "header(Message-Id).regexp('@([^\.]+\.[^>]+)').last";
      }
      returnbits {
        SEM_URIBL_FRESH15 = 2;
      }
    }
  }

  .include(try=true,priority=5) "${DBDIR}/dynamic/rbl.conf"
  .include(try=true,priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/rbl.conf"
  .include(try=true,priority=10) "$LOCAL_CONFDIR/override.d/rbl.conf"
}
