General
cancel
Showing results for 
Search instead for 
Did you mean: 

sendmail refuse mail with no reverse lookup (PTR) record.

SOLVED
Go to solution
Steven E. Protter
Exalted Contributor

sendmail refuse mail with no reverse lookup (PTR) record.

aol and other large internet providers no longer accept mail if the sender does not have a valid reverse DNS (PTR) record.

Below, I will attach some code from sendmail.org that will reject mail if the source address does not have a valid reverse lookup address.

It is implemented in the sendmail.mc or the HP equivalent, which I know how to use.

My questions are:

1) Is anyone using something similar or this exact hack? If so provide configuration instructions, is it just pasted into the .mc file?

2) Are there other ways of implementing this via .mc files. Because I have automated my spam detection(a script picks up port 25 exploits and whitelists the ip address) I can't deal with anything that requires a sendmail.mc edit. It must originate from the .mc file.

The solutions to either of these questions is worth a bunny. Points for every attempt.

The reasoning here is that three quarters of the port 25 spam attempts are coming from addresses without valid reverse DNS records. Implementing this code can cut exploit attempts 75%.

------ start macro code------
divert(-1)

dnl ## NOTE: This M4 file is suitable for sendmail
dnl ## 8.12.x . To use it with 8.10.x or 8.11.x, a one line
dnl ## change is required. Comments indicate which lines
dnl ## to change (to comment or uncomment)

dnl ################################################################
dnl ##
dnl ## This is a HACK to reject mail from connecting clients
dnl ## without proper rDNS (reverse DNS), functional
dnl ## gethostbyaddr() resolution.
dnl ##
dnl ## Use as:
dnl ##
dnl ## HACK(require_rdns)
dnl ##
dnl ## An optional second argument is available, and must be
dnl ## either `OK' or `REJECT'. With the second argument,
dnl ## the decision to reject depends on the recipient, and
dnl ## is based on access table entries for that recipient.
dnl ## The second argument gives the default assumed for
dnl ## recipients without access table entries. Currently,
dnl ## only the first letter of the second argument is
dnl ## checked.
dnl ##
dnl ## Note that the second argument makes no sense unless
dnl ## FEATURE(`delay_checks') is also in effect. It is
dnl ## best for the `delay_check' line to come first. This
dnl ## is not strictly required, but will avoid a warning
dnl ## message.
dnl ##
dnl ## The basis policy is to reject message with a 5xx
dnl ## error if the IP address fails to resolve. However,
dnl ## if this is a temporary failure, a 4xx temporary
dnl ## failure is returned. If the look succeeds, but
dnl ## returns an apparently forged value, this is treated
dnl ## as a temporary failure with a 4xx error code.
dnl ##
dnl ## EXCEPTIONS:
dnl ##
dnl ## Exceptions based on access entries are discussed
dnl ## below. Any IP address matched using $=R (the
dnl ## "relay-domains" file) is excepted from the rules.
dnl ## Since we have explicitely allowed relaying for this
dnl ## host, based on IP address, we ignore the rDNS
dnl ## failure.
dnl ##
dnl ## The philosophical assumption here is that most users
dnl ## do not control their rDNS. They should be able to
dnl ## send mail through their ISP, whether or not they have
dnl ## valid rDNS. The class $=R, roughly speaking,
dnl ## contains those IP addresses and address ranges for
dnl ## which we are the ISP, or are acting as if the ISP.
dnl ##
dnl ## If `delay_checks' is in effect (recommended), then
dnl ## any sender who has authenticated is also excepted
dnl ## from the restrictions. This happens because the
dnl ## rules produced by this HACK() will not be applied to
dnl ## authenticated senders (assuming `delay_checks').
dnl ##
dnl ## ACCESS MAP ENTRIES:
dnl ##
dnl ## Per-user entries:
dnl ##
dnl ## The per-user entries are of the form
dnl ## rdns:user OK
dnl ## where the RHS should be `OK' or `REJECT'. If `OK' is
dnl ## used, mail addressed to this user is not blocked on
dnl ## rDNS problems. If the value is `REJECT', it is
dnl ## checked. The second argument to the HACK() enables
dnl ## this feature, and provides the default for users with
dnl ## no entry.
dnl ##
dnl ## Note that the user in "rdns:user" is the user part in
dnl ## the mailer triple after address parsing. For a
dnl ## virtual address, this will be the user after
dnl ## virtusertable processing. If the mail is addressed
dnl ## to "user+detail" the "+detail" is stripped before
dnl ## this checking.
dnl ##
dnl ## If the recipient is on another host, then the key

dnl ## actually looked up is "rdns:@host." with the "host"
dnl ## being the destination to which we will send it. In
dnl ## some cases, this might come from a mailertable
dnl ## entry. It is not possible to individuate the
dnl ## decision for remote recipients. Note that the "."
dnl ## might be needed after the hostname. It is best to
dnl ## use the output of
dnl ## echo "/parse address" | sendmail -bt
dnl ## to decide what goes in the access map.
dnl ##
dnl ## IP address entries:
dnl ##
dnl ## Entries such as
dnl ## rdns:1.2.3 OK
dnl ## 1.2.3.4 OK
dnl ## 1.2 RELAY
dnl ## will whitelist IP address 1.2.3.4, so that the rDNS
dnl ## blocking does apply to that IP address
dnl ##
dnl ## Entries such as
dnl ## rdns:1.2.3 REJECT
dnl ## 1.2.3.4 REJECT
dnl ## will have the effect of forcing a temporary failure
dnl ## for that address to be treated as a permanent
dnl ## failure.
dnl ##
dnl ################################################################

divert(0)dnl
VERSIONID(`$Id: require_rdns.m4,v 1.7 2003/06/13 03:59:16 rickert Exp $')
divert(-1)

define(`_REQUIRE_RDNS_',
ifelse(defn(`_ARG_'), `', `',
lower(substr(_ARG_,0,1)), `o', `OK',
lower(substr(_ARG_,0,1)), `r', `REJECT',
`errprint(`*** Bad argument _ARG_ for require_rdns')'))

ifelse(_REQUIRE_RDNS_,`',`',
ifdef(`_DELAY_CHECKS_',`',
``errprint(`*** Warning: Optional argument to require_rdns needs delay_checks
')''
))

PUSHDIVERT(9)dnl
SLocal_check_relay
ifelse(_REQUIRE_RDNS_,`',dnl
R$* $| $* $:$2 <$&{client_resolve}>
,dnl
R$* $| $* $:$2 <$&{client_resolve}> $&{rcpt_addr}
)dnl
R$*$* $@OK Resolves.
R$=R $* <$*>$* $@RELAY We relay for these
ifelse(_REQUIRE_RDNS_,`',`',dnl
R$*<$*>$+@$+ $:$1<$2>@$&{rcpt_host} use @host for remote
R$*<$*>$+ + $* $:$1<$2>$3 remove +detail
R$*<$*>$+ `$:$1<$2>$(access rdns:$3 $:' _REQUIRE_RDNS_ `$)' Check rcpt
)dnl
ifelse(_REQUIRE_RDNS_, `REJECT',dnl
`R$*<$*>$={Accept} $@ $3 Bypass for this recipient
', _REQUIRE_RDNS_, `OK',dnl
`R$*<$*>REJECT $:$1<$2> mark rejections
R$*<$*>$+ $@OK bypass for others
',`')dnl
dnl ### The next line is sendmail version dependent
dnl ### Use this (with LookUpAddress)for sendmail-8.10 and 8.11
dnl`'R$+<$*>$* $:$1 $>LookUpAddress <$1> <$2> <+ rdns>
dnl ### but use to following, instead, for 8.12
R$+<$*>$* $:$1 $>A <$1> <+ rdns> <$2>
dnl ### end of version dependent text
R$*<$={Accept}><$+> $@ $2 OK or RELAY - whitelisted
R$*<$*> $: $1 REJECT - treat tempfail as fail
R$* $#error $@ 5.7.1 $: 550 Fix reverse DNS for $1, or use your ISP server
R$* $#error $@ 4.1.8 $: 451 Client IP address $1 does not resolve
R$* $#error $@ 4.1.8 $: 451 Possibly forged hostname for $1
POPDIVERT
undefine(`_REQUIRE_RDNS_')dnl

-------- end macro code ------

In other news, I've made it since Feb 13 with no successful spam relay. All attempts via formscript exploit have limited the recipient to me, all Port 25 attempts have triggered an automated whitelist function that rebuilds sendmail and locks the abuser out.

SEP
Steven E Protter
Owner of ISN Corporation
http://isnamerica.com
http://hpuxconsulting.com
Sponsor: http://hpux.ws
Twitter: http://twitter.com/hpuxlinux
Founder http://newdatacloud.com
5 REPLIES
Steven E. Protter
Exalted Contributor

Re: sendmail refuse mail with no reverse lookup (PTR) record.

ping.

This isn't too hard a question is it?

Anyone with a server exposed to the public Internet should think about this.

SEP
Steven E Protter
Owner of ISN Corporation
http://isnamerica.com
http://hpuxconsulting.com
Sponsor: http://hpux.ws
Twitter: http://twitter.com/hpuxlinux
Founder http://newdatacloud.com
Darron Christian
Occasional Visitor

Re: sendmail refuse mail with no reverse lookup (PTR) record.

When I try to implement this, I slap it in a m4 file and I call it from my sendmail.mc file.
It compiles and when I try to start up the sendmail.cf file, it complains about missing tab files.

For instance:

554 5.0.0 /etc/mail/sendmail.cf: line 1737: invalid rewrite line "R=R* <*>* @RELAY We relay for these" (tab expected)

I saw on another site that some of the spacing should be tabs, but I haven't a clue where in your code that might be.

Can you assist?
Steven E. Protter
Exalted Contributor

Re: sendmail refuse mail with no reverse lookup (PTR) record.

I have had no success implementing this hack at all.

Please provide the sendmail.mc code you used for more points. Then i can attempt to resolve the issue.

SEP
Steven E Protter
Owner of ISN Corporation
http://isnamerica.com
http://hpuxconsulting.com
Sponsor: http://hpux.ws
Twitter: http://twitter.com/hpuxlinux
Founder http://newdatacloud.com
Lee Hundley
Valued Contributor
Solution

Re: sendmail refuse mail with no reverse lookup (PTR) record.

Success!
(IP Addresses have been changed to preserve sanity)

I added the m4 file (which can be found with all its original whitespaces and tabs by googling for "require_rdns") to my $SENDMAIL_CF/hack/ dir, and added this to my sendmail.mc:

HACK(require_rdns)

Rebuilt the .cf files, installed, restarted sendmail. When I telnet to port 25 from a machine with no reverse dns, I get this in my maillog:
May 12 14:54:04 nailbunny sm-mta[22541]: ruleset=check_relay, arg1=[xx.xxx.xxx.xx], arg2=xx.xxx.xxx.xx, relay=[xx.xxx.xxx.xx], reject=550 5.7.1 Fix reverse DNS for xx.xxx.xxx.xx,or use your ISP server

Then, after issuing the EHLO command, and a "MAIL FROM:" command, it spits this out at me:
mail from: user@test.com
550 5.7.1 Fix reverse DNS for xx.xxx.xxx.xx,or use your ISP server

This was done on a FreeBSD machine running Sendmail 8.12.11, YMMV
It is my firm belief that it is a mistake to hold any firm beliefs
Sundar_7
Honored Contributor

Re: sendmail refuse mail with no reverse lookup (PTR) record.

I have implemented this in SUN long time back using m4, I cannot really recollect from the top of my head.

But I always used to wonder if the following scenario is very popular amongst the sendmail administrators.

"The guy trying to send the mail have a valid reverse lookup PTR entry but he intentionally changes the MAIL FROM to a user in a non-existent domain and forwards the mail to a non-existent user in YOUR DOMAIN. In this case, your MTA will receive the mail, tries to deliver to the non-existent user in YOUR DOMAIN and eventually tries to bounce the mail back to the sender which is in a non-existent domain. So the mail will simply remain in /var/spool/mqueue occupying space".

one can send huge attachments that are undeliverable and can just cloak your space.

I know it is common to validate the MAIL FROM DNS domain but surprisingly I have come across quiet a few MTAs that DO NOT do this check.
Learn What to do ,How to do and more importantly When to do ?