You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by he...@apache.org on 2019/04/15 13:29:40 UTC
svn commit: r1857580 - in /spamassassin/trunk: UPGRADE
lib/Mail/SpamAssassin/Plugin/ASN.pm
Author: hege
Date: Mon Apr 15 13:29:40 2019
New Revision: 1857580
URL: http://svn.apache.org/viewvc?rev=1857580&view=rev
Log:
Add GeoDB support to ASN lookups (asn_use_geodb, asn_prefer_geodb, asn_use_dns)
Modified:
spamassassin/trunk/UPGRADE
spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/ASN.pm
Modified: spamassassin/trunk/UPGRADE
URL: http://svn.apache.org/viewvc/spamassassin/trunk/UPGRADE?rev=1857580&r1=1857579&r2=1857580&view=diff
==============================================================================
--- spamassassin/trunk/UPGRADE (original)
+++ spamassassin/trunk/UPGRADE Mon Apr 15 13:29:40 2019
@@ -80,7 +80,9 @@ Note for Users Upgrading to SpamAssassin
- Add check_hashbl_bodyre and hashbl_ignore to HashBL.pm
-- ASN: Support IPv6 with asn_lookup_ipv6 (Bug 7211)
+- ASN: Support IPv6 with asn_lookup_ipv6 (Bug 7211). Support GeoDB for ASN
+ lookups (asn_use_geodb, asn_prefer_geodb, asn_use_dns).
+
Note for Users Upgrading to SpamAssassin 3.4.2
----------------------------------------------
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/ASN.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/ASN.pm?rev=1857580&r1=1857579&r2=1857580&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/ASN.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/ASN.pm Mon Apr 15 13:29:40 2019
@@ -142,6 +142,9 @@ sub new {
#more robust version check from Damyan Ivanov - Bug 7095
$txtdata_can_provide_a_list = version->parse(Net::DNS->VERSION) >= version->parse('0.69');
+ # we need GeoDB ASN
+ $self->{main}->{geodb_wanted}->{asn} = 1;
+
return $self;
}
@@ -183,24 +186,16 @@ Examples:
asn_lookup in1tag.example.net _ASNDATA_ _ASNDATA_
-=back
-
=item asn_lookup_ipv6 asn-zone6.example.com [_ASN_ _ASNCIDR_]
Use specified zone for lookups of IPv6 addresses. If zone supports both
IPv4 and IPv6 queries, use both asn_lookup and asn_lookup_ipv6 for the same
zone.
-=over 4
-
=item clear_asn_lookups
-=back
-
Removes any previously declared I<asn_lookup> entries from a list of queries.
-=over 4
-
=item asn_prefix 'prefix_string' (default: 'AS')
The string specified in the argument is prepended to each ASN when storing
@@ -209,6 +204,25 @@ is kept for backward compatibility with
than 3.4.0. A sensible setting is an empty string. The argument may be (but
need not be) enclosed in single or double quotes for clarity.
+=item asn_use_geodb ( 0 / 1 ) (default: 1)
+
+Use Mail::SpamAssassin::GeoDB module to lookup ASN numbers. You need
+suitable supported module like GeoIP2 or GeoIP with ISP or ASN database
+installed (for example, add EditionIDs GeoLite2-ASN in GeoIP.conf for
+geoipupdate program).
+
+GeoDB can only set _ASN_ tag, it has no data for _ASNCIDR_. If you need
+both, then set asn_prefer_geodb 0 so DNS rules are tried.
+
+=item asn_prefer_geodb ( 0 / 1 ) (default: 1)
+
+If set, DNS lookups (asn_lookup rules) will not be run if GeoDB successfully
+finds ASN. Set this to 0 to get _ASNCIDR_ even if GeoDB finds _ASN_.
+
+=item asn_use_dns ( 0 / 1 ) (default: 1)
+
+Set to 0 to never allow DNS queries.
+
=back
=cut
@@ -280,6 +294,27 @@ need not be) enclosed in single or doubl
}
});
+ push (@cmds, {
+ setting => 'asn_use_geodb',
+ default => 1,
+ is_admin => 1,
+ type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL,
+ });
+
+ push (@cmds, {
+ setting => 'asn_prefer_geodb',
+ default => 1,
+ is_admin => 1,
+ type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL,
+ });
+
+ push (@cmds, {
+ setting => 'asn_use_dns',
+ default => 1,
+ is_admin => 1,
+ type => $Mail::SpamAssassin::Conf::CONF_TYPE_BOOL,
+ });
+
$conf->{parser}->register_commands(\@cmds);
}
@@ -289,16 +324,18 @@ sub parsed_metadata {
my ($self, $opts) = @_;
my $pms = $opts->{permsgstatus};
- my $conf = $self->{main}->{conf};
-
- if (!$pms->is_dns_available()) {
- dbg("asn: DNS is not available, skipping ASN checks");
- return;
- }
+ my $conf = $pms->{conf};
- if (!$conf->{asnlookups} && !$conf->{asnlookups_ipv6}) {
- dbg("asn: no asn_lookups configured, skipping ASN lookups");
- return;
+ my $geodb = $self->{main}->{geodb};
+ my $has_geodb = $conf->{asn_use_geodb} && $geodb && $geodb->can('asn');
+ if ($has_geodb) {
+ dbg("asn: using GeoDB ASN for lookups");
+ } else {
+ dbg("asn: GeoDB ASN not available");
+ if (!$conf->{asn_use_dns} || !$pms->is_dns_available()) {
+ dbg("asn: DNS is not available, skipping ASN check");
+ return;
+ }
}
# initialize the tag data so that if no result is returned from the DNS
@@ -317,8 +354,7 @@ sub parsed_metadata {
}
}
- # get reversed IP address of last external relay to lookup
- # don't return until we've initialized the template tags
+ # get IP address of last external relay to lookup
my $relay = $pms->{relays_external}->[0];
if (!defined $relay) {
dbg("asn: no first external relay IP available, skipping ASN check");
@@ -327,16 +363,36 @@ sub parsed_metadata {
dbg("asn: first external relay is a private IP, skipping ASN check");
return;
}
-
my $ip = $relay->{ip};
- my $reversed_ip = reverse_ip_address($ip);
- if (defined $reversed_ip) {
- dbg("asn: using first external relay IP for lookups: %s", $ip);
- } else {
- dbg("asn: could not parse first external relay IP: %s, skipping", $ip);
+ dbg("asn: using first external relay IP for lookups: %s", $ip);
+
+ # GeoDB lookup
+ my $asn_found;
+ if ($has_geodb) {
+ my $asn = $geodb->get_asn($ip);
+ if (!defined $asn) {
+ dbg("asn: GeoDB ASN lookup failed");
+ } else {
+ $asn_found = 1;
+ dbg("asn: GeoDB found ASN $asn");
+ $pms->set_tag('ASN', $conf->{asn_prefix}.$asn);
+ # For Bayes
+ $pms->{msg}->put_metadata('X-ASN', $asn);
+ }
+ }
+
+ # No point continuing without DNS from now on
+ if (!$conf->{asn_use_dns} || !$pms->is_dns_available()) {
+ dbg("asn: skipping disabled DNS lookups");
+ return;
+ }
+ # Skip DNS if GeoDB was successful and preferred
+ if ($asn_found && $conf->{asn_prefer_geodb}) {
+ dbg("asn: GeoDB lookup successful, skipping DNS lookups");
return;
}
+ dbg("asn: using DNS for lookups");
my $lookup_zone;
if ($ip =~ /^$IPV4_ADDRESS$/o) {
if (!defined $conf->{asnlookups}) {
@@ -352,6 +408,12 @@ sub parsed_metadata {
$lookup_zone = "asnlookups_ipv6";
}
+ my $reversed_ip = reverse_ip_address($ip);
+ if (!defined $reversed_ip) {
+ dbg("asn: could not parse IP: %s, skipping", $ip);
+ return;
+ }
+
# we use arrays and array indices rather than hashes and hash keys
# in case someone wants the same zone added to multiple sets of tags
my $index = 0;
@@ -493,5 +555,6 @@ sub process_dns_result {
# Version features
sub has_asn_lookup_ipv6 { 1 }
+sub has_asn_geodb { 1 }
1;