You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by Apache Wiki <wi...@apache.org> on 2006/11/01 11:29:22 UTC

[Spamassassin Wiki] Update of "TrustedRelays" by JustinMason

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Spamassassin Wiki" for change notification.

The following page has been changed by JustinMason:
http://wiki.apache.org/spamassassin/TrustedRelays

The comment on the change is:
expand this documentation a bit -- it's very useful data

------------------------------------------------------------------------------
  
   * optimize DNSBL lookups
   * detect when mails never left a trusted network path
-  * and know when a Received header can be trusted for whitelisting purposes
+  * know when a Received header can be trusted for whitelisting purposes
+  * produce synthetic 'pseudo-headers', allowing rules to match against the message's network traversal portably
  
  This page details the concept of 'trust' internally to SpamAssassin, and how it appears in the output.  See also TrustPath for details on how to influence this by setting the 'trusted_networks' parameter, etc.
  
@@ -37, +38 @@

  hello
  }}}
  
- Assuming the scanner is running on 'internal.example.com', and the TrustPath on that machine is set up to trust the DMZ machine 'dmz.example.com' at 150.51.53.1 (and also consider that internal using 'internal_networks'), and a trustworthy external machine 'friend.example.com' at 212.17.35.14, this means that the message passed through the following relays:
+ Assuming SpamAssassin is running on 'internal.example.com', and the TrustPath on that machine is set up to trust the DMZ machine 'dmz.example.com' at 150.51.53.1 (and also consider that internal using {{{internal_networks}}}), and a trustworthy external machine 'friend.example.com' at 212.17.35.14, this means that the message passed through the following relays:
  
   * '''Untrusted''' source at evil.example.net [144.137.3.98]
   * '''Untrusted''' relay at chaos.example.net [210.73.88.134]
@@ -47, +48 @@

   * '''Trusted''' and '''internal''' relay at dmz.example.com [150.51.53.1]
   * '''Trusted''' and '''internal''' localhost handover at internal.example.com [127.0.0.1]
  
- A side note: the header lines for 'evil', 'chaos', and 'loser' could all be faked, for all we know, since who knows if an untrusted host is running legitimate MTA software, or is under the control of a spammer?  Therefore, it's unwise to trust things you find in untrusted headers.  One exception to this is discussed below in 'DNSBL lookups and 'firsttrusted'', however.
+ A side note: the header lines for 'evil', 'chaos', and 'loser' could all be faked, for all we know, since who knows if an untrusted host is running legitimate MTA software, or is under the control of a spammer?  Therefore, it's unwise to trust things you find in untrusted headers.  (One exception to this is discussed at the end of this article.)
  
- Here's what SpamAssassin's trust path algorithm makes of this (pasted from "spamassassin -D -t" output):
+ Here's what SpamAssassin's trust path algorithm makes of this (pasted from "spamassassin -D -t" output): TrustedRelaysDebugExample.
  
+ == The 'X-Spam-Relays' Pseudo-headers ==
- {{{
- [16429] dbg: received-header: parsed as [ ip=127.0.0.1 rdns= helo=internal.example.com by=localhost ident= envfrom= intl=0 id= auth= ]
- [16429] dbg: received-header: relay 127.0.0.1 trusted? yes internal? yes
- [16429] dbg: dns: looking up PTR record for '150.51.53.1'
- [16429] dbg: dns: PTR for '150.51.53.1': ''
- [16429] dbg: received-header: parsed as [ ip=150.51.53.1 rdns= helo=dmz.example.com by=internal.example.com ident= envfrom= intl=0 id= auth= ]
- [16429] dbg: received-header: relay 150.51.53.1 trusted? yes internal? yes
- [16429] dbg: dns: looking up PTR record for '212.17.35.14'
- [16429] dbg: dns: PTR for '212.17.35.14': ''
- [16429] dbg: received-header: parsed as [ ip=212.17.35.14 rdns= helo=friend.example.com by=dmz.example.com ident= envfrom= intl=0 id= auth= ]
- [16429] dbg: received-header: relay 212.17.35.14 trusted? yes internal? yes
- [16429] dbg: dns: looking up PTR record for '193.120.149.226'
- [16429] dbg: dns: PTR for '193.120.149.226': ''
- [16429] dbg: received-header: parsed as [ ip=193.120.149.226 rdns= helo=notrust.example.com by=friend.example.com ident= envfrom= intl=0 id= auth= ]
- [16429] dbg: received-header: relay 193.120.149.226 trusted? no internal? no
- [16429] dbg: dns: looking up PTR record for '61.119.13.18'
- [16429] dbg: dns: PTR for '61.119.13.18': ''
- [16429] dbg: received-header: parsed as [ ip=61.119.13.18 rdns= helo=loser.example.org by=notrust.example.com ident= envfrom= intl=0 id= auth= ]
- [16429] dbg: received-header: relay 61.119.13.18 trusted? no internal? no
- [16429] dbg: dns: looking up PTR record for '210.73.88.134'
- [16429] dbg: dns: PTR for '210.73.88.134': ''
- [16429] dbg: received-header: parsed as [ ip=210.73.88.134 rdns= helo=chaos.example.net by=loser.example.org ident= envfrom= intl=0 id= auth= ]
- [16429] dbg: received-header: relay 210.73.88.134 trusted? no internal? no
- [16429] dbg: dns: looking up PTR record for '144.137.3.98'
- [16429] dbg: dns: PTR for '144.137.3.98': ''
- [16429] dbg: received-header: parsed as [ ip=144.137.3.98 rdns= helo=evil.example.net by=chaos.example.net ident= envfrom= intl=0 id= auth= ]
- [16429] dbg: received-header: relay 144.137.3.98 trusted? no internal? no
- }}}
  
- The next two lines are most noteworthy -- especially since rules can match against these ''metadata pseudoheaders''.  Here they are:
+ The last few lines of that debug output are most noteworthy -- especially since rules can match against these '''metadata pseudo-headers'''.  Here they are:
  
  the 'X-Spam-Relays-Trusted' pseudoheader:
  {{{
@@ -97, +71 @@

  [ ip=144.137.3.98 rdns= helo=evil.example.net by=chaos.example.net ident= envfrom= intl=0 id= auth= ]
  }}}
  
- You can see they list the contents of the Received header in a machine-readable, and standardised, format, so that rules can be insulated from the vagaries of the Received header, which has a tendency to look radically different between MTAs.
+ There are also two more -- 'X-Spam-Relays-Internal' and 'X-Spam-Relays-External'.
  
- Some sample rules that use this data can be seen in the standard SpamAssassin rules file, '20_fake_helo_tests.cf'.
+ They are divided into trusted/untrusted and internal/external pairs, depending on the setting of 'trusted_networks' and 'internal_networks'.
  
- == DNSBL lookups and 'firsttrusted' ==
+ You can see they list the contents of the Received header in a machine-readable, and standardised, format, so that rules can be insulated from the vagaries of the Received header, which has a tendency to look radically different between MTAs.  (Some MTAs even reverse the order of the items, but look otherwise identical!)
+ 
+ In the samples above, they include newlines; however, in the real pseudo-headers produced by SpamAssassin, each [...] block is simply space-separated.
+ 
+ Some sample rules that use this data can be seen in the standard SpamAssassin rules file, '20_fake_helo_tests.cf'.  Here is an example:
+ 
+ {{{
+ header RULENAME  X-Spam-Relays-Untrusted =~ /^[^\]]+ helo=foo /i
+ }}}
+ 
+ == DNSBL lookups and the most recent untrusted host ==
  
  DNSBL rules support '-firsttrusted' and '-untrusted' as special-case keywords to control IP address selection.  These keywords do not refer to the trust status of the lines themselves!  They refer to the trust status of the data that will be looked up in the DNSBL.
  
@@ -109, +93 @@

  
  Above, for example, 193.120.149.226 is listed as an untrusted host and is therefore listed in the 'X-Spam-Relays-Untrusted' pseudoheader.  However, its IP address was ''recorded'' by a trusted host, so the IP address data ''is'' trustworthy.
  
- This is the only 'grey area', however.  All the other hosts listed in the 'X-Spam-Relays-Untrusted' pseudoheader were both untrusted themselves, and their details were not recorded by a trusted host; both the lines themselves and the IP addresses are not trustworthy, since they could have been generated by a spamware application creating fake header data.  It's especially important not to trust that data for rules that could give negative points, since spammers can, and will, attempt to fake their way around your whitelisting rules.
+ This is the most commonly tested item in the string, since it's the most likely host to be a spam zombie or spammer MTA.
  
+ Testing the "most recent untrusted" host in a header rule is done as follows:
+ 
+ {{{
+   header RULENAME  X-Spam-Relays-Untrusted =~ /^[^\]]+ helo=foo /i
+ }}}
+ 
+ Note the {{{^[^\]]+}}} part of the pattern; that skips anything but "]" characters, ensuring that the match will only happen within the first [...] block of the pseudo-header string.
+ 
+ Checking that IP address in a DNSBL lookup using check_rbl() is performed by appending the string '-firsttrusted' to the set name:
+ 
+ {{{
+   header RULENAME  eval:check_rbl_txt('bsp-firsttrusted', 'sa-trusted.bondedsender.org.', '(?i:bonded)')
+ }}}
+ 
+ == Using Other Untrusted Hosts ==
+ 
+ The 'most recent untrusted' host is the only 'grey area', however.  All the other hosts listed in the 'X-Spam-Relays-Untrusted' pseudoheader were both untrusted themselves, and their details were not recorded by a trusted host; both the lines themselves and the IP addresses are not trustworthy, since they could have been generated by a spamware application creating fake header data.  It's especially important not to trust that data for rules that could give negative points, since spammers can, and will, attempt to fake their way around your whitelisting rules.
+