spf-discuss
[Top] [All Lists]

RE: [spf-discuss] SpamCop recommends SPF (and/or DomainKeys)

2005-01-26 18:24:31
Stuart D. Gathman [stuart(_at_)bmsi(_dot_)com] wrote:
A big help for SPF reliability is for *senders* to check their own SPF.
I.e., MTAs should check whether their own outgoing mail connections
would pass SPF if they were the receiver, and abort if there is a
problem.  Unfortunately, sendmail doesn't invoke milter for outgoing
connections.  I can get control at MAIL FROM time via a socket map
(in the same code already doing SRS/SES), but haven't figured out how
to get our IP.  I suppose I could assume a given sendmail instance will
always use the same IP for outgoing mail, and specify it in a config. 

I'm no Sendmail expert, but this is what I did in Courier::Filter's SPFout
(outbound checking) filter module:

I create a UDP socket to one of the recipient domain's MXes, but don't
send any data.  This causes the OS to make a route table lookup and choose
an appropriate outgoing IP address.  Of course this isn't perfectly
accurate when the system has multiple appropriate IP addresses but your
MTA software is bound to a specific one.  In that case you'd have to make
the outgoing IP address configurable (or read it from the MTA's config
file directly).

This is the relevant code from Courier::Filter::Module::SPFout:

| [...]
| 
| $message->remote_host =~ /^::ffff:($IPV4_ADDRESS)$/
|     or return;  # Ignore IPv6 senders for now, as M:S:Q doesn't support it.
| 
| my $remote_host_ipv4 = $1;
| 
| my ($recipient_domain) = ($message->recipients)[0] =~ /\@([^(_at_)]*)$/;
| 
| my $outbound_address_ipv4;
| try {
|     # Just try the recipient domain's first MX as the remote host:
|     my ($mx) = Net::DNS::mx($recipient_domain);
|     # Discover local outbound IP address:
|     $outbound_address_ipv4 =
|         defined($mx) ?
|             Net::Address::IPv4::Local->connected_to($mx->exchange)
|         :   Net::Address::IPv4::Local->public;
| };
| throw Courier::Error('Could not determine local outbound IP address')
|     if not defined($outbound_address_ipv4);
| 
| my $spf_query = Mail::SPF::Query->new(
|     ip          => $outbound_address_ipv4,
|     helo        => $message->remote_host_helo,
|     sender      => $message->sender,
|     default_explanation
|                 => $module->{default_response}
| );
| 
| [...]

Net::Address::IPv4::Local (also by me) does this:

| use constant DEFAULT_REMOTE_ADDRESS => '198.41.0.4';  # a.root-servers.net
| use constant DEFAULT_REMOTE_PORT    => 53;            # DNS
| 
| [...]
| 
| sub public {
|     my ($class) = @_;
|     return $class->connected_to(DEFAULT_REMOTE_ADDRESS);
| }
| 
| sub connected_to {
|     my ($class, $remote_address) = @_;
|     
|     my $socket = IO::Socket::INET->new(
|         Proto       => 'udp',
|         PeerAddr    => $remote_address,
|         PeerPort    => DEFAULT_REMOTE_PORT
|     );
|     
|     throw Net::Address::IPv4::Local::Error("Unable to create UDP socket: $!")
|         if not defined($socket);
|     
|     return inet_ntoa($socket->sockaddr);
| }

-------
To unsubscribe, change your address, or temporarily deactivate your 
subscription, 
please go to 
http://v2.listbox.com/member/?listname=spf-devel(_at_)v2(_dot_)listbox(_dot_)com