procmail
[Top] [All Lists]

Re: Not relaying spam?

1998-04-01 02:53:58

Vikas Agnihotri <VikasA(_at_)att(_dot_)com> asks:

   >   How can I prevent my host/machine being used as a stepping stone
   >   to relay spam?  Any machine can just connect to my SMTP port 25
   >   and relay spam off of it, right? 
   >
   >   I am running sendmail 8.8.8


This is a sendmail question, nothing to do with procmail. But since
you ask, I'd like to recomend the following "plug-n-play"
access & relay-control package for sendmail 8.8 which I think is
pretty cool. I include the README file below so you can check it out.

Regards
Gjermund Sørseth


---------------------------------------------------------------------------
    This package adds two independent features to sendmail, access control
and relay control. They will be described here simultaneously, but you
can elect to include support for only one of them (either one) on
your mail server. Access control lets you deny access to the server
based on the senders envelope address or his IP address. Relay control
lets you decide who gets to relay email through your server.

    The package was designed with the needs of large ISP's in mind, but
is simple enough for anyone to use.

    I will assume you are using the common method of generating a
sendmail.cf file from a .mc master file using the m4 macros, but you can
also use this package if you are editing your sendmail.cf by hand.
You need to use sendmail version 8.8.6 or later (I recomend you use 8.8.8)
with support for either "Berkeley-db" or "dbm" compiled in.

I suggest you read the CONFIGURATION section first, to get a feel of
what this is all about and what is possible and not possible.

The latest version of this software is at:

               ftp://ftp.xyzzy.no/sendmail/access.tar.Z


CONFIGURATION
-------------

This section describes the contents of the two config files: smtp.access
(for SMTP access control) and smtp.relay (for SMTP relay control).
It demonstrates all the features.

This is a sample smtp.access file:

    deny    bozo(_at_)domain(_dot_)com
    deny    xyzzy(_at_)foo(_dot_)net        "Get Lost!"
    deny    @company.com
    permit  friend(_at_)company(_dot_)com
    deny    166.28.8.222/31
    deny    192.2
    permit  192.2.49
    deny    199.12.76.0  255.255.254.0

The first column can be either "permit" or "deny". This is followed by
either a complete adress (like "bozo(_at_)domain(_dot_)com"), or a "@" and a 
domain name
(like "@cyberpromo.com") which matches all addresses ending in that domain,
or 1-4 IP-address octets and an optional netmask which matches all
IP adresses in that range.

In all cases a most-exact-match comparison is performed. If you want to
deny access from all IP adresses beginning with 192.2 _except_ for
adresses beginning with 192.2.49, you could put:

    deny    192.2
    permit  192.2.49

Similarly, if you want to prevent everyone that supplies a return address
ending in "company.com" except "friend(_at_)company(_dot_)com" you could put:

    deny    @company.com
    permit  friend(_at_)company(_dot_)com

You can specify a netmask using either the modern slash (/) format or the
traditional dotted quad format. If you leave out the netmask, it is implied
by the number of octets you specify in the address. These are all equivalent:

    deny    50.12.76

    deny    50.12.76.0/24

    deny    50.12.76.0  255.255.255.0

So you could say something like this (whitespace before the mask is fine):

    deny    38.0.160.0  /20
    permit  38.0.168.0  /22
    deny    38.0.168.0  /24

...which denies every address starting with 38.0.160 to 38.0.175 _except_
adresses starting with 38.0.169 - 38.0.171  (Longest prefix matches first).

After email address deny-entries (_NOT_ after IP address entries) there
can be an optional third column with an error message enclosed in quotes
which will be sent to the client instead of the standard "Acces denied".
Example:

    deny    xyzzy(_at_)foo(_dot_)net        "Get Lost!"

There is an implicit "permit all" if no match is found or if the file is
empty or does not exist. I imagine that an empty smtp.access file would be
the common case.

Be aware that the access control just described consists of two 
_Completely_Different_ things - access control based on the client's IP
address which normally can't be faked (_very_ useful!), and access control
based on the sender's envelope return address, which is trivial to bypass
but which is still useful.

Everything following a  #  through the rest of the line is a comment.
This goes for the smtp.relay file too:

This is a sample (and a typical) smtp.relay file:


    # IP address ranges that can relay anywhere:
    #
    127
    10.128/9        # Our own addresses
    195.18.160/23   # Customer X
    163.22          # Customer Y
    100.22.2.56     # Mail server Z
    #
    # Domain names we accept mail for:
    #
    mydomain.com
    another-domain.com
    yet-another-domain.com
    #
    include sendmail.cw
    include mailertable
    include secondary-mx


This file contains two types of entries - a collection of the ranges of
IP adresses that we will allow to connect to our mail server to perform
unlimited relaying (typicly our own and our customers IP addresses),
and a collection of domain names we accept mail for.

How this works, in short:

   The mail server will accept mail destined for the domain names in this
   file from ANYWHERE, and will accept mail for OTHER domains ONLY from
   clients whose IP adresses are in this file.

This gives you complete relay control.

The syntactis details:

The file contains one entry per line, which is either 1-4 IP octets 
optionaly followed by a netmask (like in the smtp.access file) or
a domain name. The contents of other files may be included with the
"include filename" directive. This is very useful since you probably
have several files containing domain names you accept mail for
(like "sendmail.cw", "mailertable" and others) and you'd rather not
have to keep multiple records of these domain names. If an entry is
a domain name, the rest of the line following the domain name is ignored.
This is perfect for including files like "mailertable" which contains
other stuff after the domain. (Includes may be nested as deep as you like).

The software will complain if addresses and masks are inconsistent.
Example:

    50.12.72.0 /18     <====  Illegal because bit 21 is a 1

    50.12.64.0 /18     <====  Ok, all 0's after bit 18

One last thing - you can specify all subdomains of a domain with a leading
dot (just like in sendmail's "mailertable"):  .domain.com matches
dept1.domain.com, sect1.dept1.domain.com and so on.



DESCRIPTION of how a typical SMTP connection will work
------------------------------------------------------

-   The SMTP client connects to the server.

    The server picks up his IP address and looks it up in the banned/accepted
    database. If banned, the server will reply "Access denied" to all
    further SMTP commands. Otherwise:

-   The client says "MAIL FROM: <sender(_at_)domain>.

    The server then looks up "domain" in DNS (you can disable this part).
    It does not accept domains that are not in the DNS unless the domain
    is comprised of N >= 3 parts and the rightmost N-1 parts are in
    the DNS. Example: xxx.com is denied if xxx.com was not found, but
    xxx.yyy.com is accepted even if only yyy.com is found. If you don't disable
    this DNS test (recomendation: keep it), and the sender domain did not
    pass the test, the server will reject with "Sender domain not in DNS"
    and a temporary error code so that the client can try again later if
    this was just due to a temporary DNS failure. Otherwise:

    The server looks up "sender(_at_)domain" in the banned/accepted database.
    If banned, it denies access (with a message you can tailor yourself
    if you like). Otherwise it looks up "@domain". If that was ok also:

-   The client says "RCPT TO: <receiver(_at_)destination>" once for each 
receipient.

    The server looks up the client IP adress in the database containing
    the IP address ranges you consider to be "yours" (or your customers).
    If found, access is granted. Otherwise:

    The "destination" domain is looked up in the database of the domain names
    your server is willing to accept mail to. If found, access is granted.
    Otherwise this is an unauthorised relay attempt and the sever will
    say "We do not relay" with a permanent error code.


INSTALLATION
------------

1)  Copy the two files "access_control.m4" and "relay_control.m4" to
    your sendmail installation's cf/hack directory. You won't be touching
    these files again, they contain sendmail.cf code that will be included
    in your sendmail.cf when you refer to them in your master configuration
    (.mc) file.

    (The reason they're in the "hack" directory is not because this package
     is a hack, but since it's not a part of sendmail it should go
     somewhere else than in the "feature" directory).


2)  Copy the two awk scripts "mk-accessdb" and "mk-relaydb" to whereever you
    keep your mail support programs.  The first line in each of these
    files reads:  #!/bin/nawk -f.  If your system keeps the modern version
    of awk in a place other then /bin/nawk, substitute as appropriate.
    Some systems only have the old version of awk - if this applies to
    your system you can, for example, get gawk (GNU awk) and use that.


3)  Copy the two config files "smtp.access" and "smtp.relay" to
    whereever you put your mail configuration files (in /etc or /local/mail
    or somewhere else). These are the files you will be editing
    when you update your access or relay policy.


4)  Edit those two files so that they conform to your particular environment
    and policy. The CONFIGURATION section in this file describes
    the possibilities.


5)  Convert those text config files to their database counterparts using the
    mk-accessdb and mk-relaydb scripts mentioned in section 2 above:

       # mk-accessdb smtp.access | makemap hash smtp.access
       # mk-relaydb  smtp.relay  | makemap hash smtp.relay

    (Replace "hash" with "dbm" if you are using dbm and not Berkeley-db).

    This will create the "smtp.access.db" and "smtp.relay.db" (or .pag and
    .dir suffixes if you use dbm) databases which are the files sendmail
    actually uses.

    This will need to be done every time you change the text versions.
    You edit the text files, then generate the database versions.
    I suggest you use "make" to automate this task.

    (The makemap program comes with the sendmail distribution.)


6)  Edit your .mc master configuration file and include access and/or
    relay control by inserting:

       HACK(relay_control)
       HACK(access_control)

    They assume you use /etc for your mail configuration files and
    the Berkeley-db format for your databases. If this is not correct,
    insert these instead:

       HACK(relay_control,  `hash    -a:FOUND /etc/smtp.relay')
       HACK(access_control, `hash -o -a:FOUND /etc/smtp.access')

    Change "/etc" to what you use at your site, and
    change "hash" to "dbm" if you use dbm instead of Berkeley-db.

    If you don't want to deny access based on the senders reply address
    not being found in the DNS, you can disable it by putting:

       define(`confAC_DNS_CHECK', `False')

    before the HACK directives. The default is `True'. See the DESCRIPTION
    section for an explanation.


7)  Generate a new sendmail.cf file in your usual way and restart sendmail.

That's it.

All denial of service will be logged by sendmail. Watch for log entries
that contain "ruleset=". "ruleset=check_mail" are invalid or banned
sender addresses, "ruleset=check_rcpt" are relay attempts and
"ruleset=check_relay" are banned hosts.

These features have been in use on our server for a some months now, and
they seem to do their job very well.


CREDITS
-------

Many good ideas and some sendmail.cf code herein is taken from
Robert Harker's LISA '97 paper on rejecting spam using sendmail.


OTHER USEFUL RESOURCES
----------------------

http://www.sendmail.org
http://www.harker.com/sendmail
http://www.informatik.uni-kiel.de/~ca/email/check.html


AUTHOR
------

Gjermund Sørseth  <gjermund(_at_)xyzzy(_dot_)no>  1997/1998

Feel free to email any questions about this package to the author.


RIGHTS
------

This is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

<Prev in Thread] Current Thread [Next in Thread>