Friday, October 15, 2010

Sendmail rebuild and Sendmail-access Lesson basic 101

SkyHi @ Friday, October 15, 2010
 sendmail - an electronic mail transport agent


# rpm -ihv sendmail-8.11.6-3.i386.rpm
# rpm -ihv sendmail-doc-8.11.6-3.i386.rpm
# rpm -ihv sendmail-cf-8.11.6-3.i386.rpm
# rpm -ihv imap-2000c-15.i386.rpm
# rpm -ihv imap-devel-2000c-15.i386.rpm

Location of setting file


How to make

  1. Edit /etc/mail/
  2. divert(-1)
    dnl This is the sendmail macro config file. If you make changes to this file,
    dnl you need the sendmail-cf rpm installed and then have to generate a
    dnl new /etc/ by running the following command:
    dnl        m4 /etc/mail/ > /etc/
    VERSIONID(`linux setup for Red Hat Linux')dnl
    define(`confTO_CONNECT', `1m')dnl
    define(`ALIAS_FILE', `/etc/aliases')dnl
    define(`UUCP_MAILER_MAX', `2000000')dnl
    define(`confUSERDB_SPEC', `/etc/mail/userdb.db')dnl
    define(`confPRIVACY_FLAGS', `authwarnings,novrfy,noexpn,restrictqrun')dnl
    define(`confAUTH_OPTIONS', `A')dnl
    FEATURE(`mailertable',`hash -o /etc/mail/mailertable.db')dnl
    FEATURE(`virtusertable',`hash -o /etc/mail/virtusertable.db')dnl
    FEATURE(local_procmail,`',`procmail -t -Y -a $h -d $u')dnl
    FEATURE(`access_db',`hash -o /etc/mail/access.db')dnl
    DAEMON_OPTIONS(`port=smtp,Addr=, Name=MTA')
  3. Edit /etc/mail/access
  4. # Check the /usr/share/doc/sendmail-8.11.6/ file for a description
    # of the format of this file. (search for access_db in that file)
    # The /usr/share/doc/sendmail-8.11.6/ is part of the sendmail-doc
    # package.
    # by default we allow relaying from localhost...
    # localhost.localdomain         RELAY
    # localhost                     RELAY
    #                     RELAY
  5. Edit /etc/mail/relay-domains
  6. 192.168.0.
  7. Edit /etc/mail/local-host-names
  8. # local-host-names - include all aliases for your machine here.
  9. Enable imap, imaps, ipop3, pop3s, sendmail using by ntsysv
    # ntsysv
  10. Compile and restart sendmail
    # m4 /etc/mail/ > /etc/
    # makemap hash /etc/mail/access.db < /etc/mail/access
    # /etc/init.d/sendmail restart
  11. Check the start-up log
    # tail /var/log/message
    Jun  6 22:28:45 yourname sendmail: sendmail shutdown succeeded
    Jun  6 22:28:47 yourname sendmail: sendmail startup succeeded

How to test

  1. Test by telnet
    # telnet 110
    Connected to
    Escape character is '^]'.
    +OK POP3 yourhost v6.50 server ready
    -ERR Unknown command in AUTHORIZATION state
    USER youruser
    +OK User name accepted, password please
    PASS ********
    +OK Mailbox open, 15 messages
    1 15086
    2 13874
    3 10065
    4 15055
    5 17742
    6 15442
    7 9176
    8 9052
    9 1471
    10 37106
    11 14620
    12 8343
    13 7457
    14 14941
    15 1418
    +OK Sayonara
    Connection closed by foreign host.
  2. Test
    # sendmail -bt -f /etc/
    ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
    > 0 youruser parse input: youruser Parse0 input: youruser Parse0 returns: youruser ParseLocal input: youruser ParseLocal returns: youruser Parse1 input: youruser Parse1 returns: $# local $: youruser parse returns: $# local $: youruser > 0 parse input: youruser @ yourdomain . bt Parse0 input: youruser @ yourdomain . bt Parse0 returns: youruser @ yourdomain . bt ParseLocal input: youruser @ yourdomain . bt ParseLocal returns: youruser @ yourdomain . bt Parse1 input: youruser @ yourdomain . bt Parse1 returns: $# local $: youruser @ yourdomain . bt parse returns: $# local $: youruser @ yourdomain . bt >

Reject SPAM domain

If you want to reject receiving mail (as SPAM) from particular domain, maintain /etc/mail/access
  1. Edit /etc/mail/access
    ...                            REJECT       REJECT                     REJECT                            REJECT
  2. Convert access to access.db
    # makemap hash /etc/mail/access.db < /etc/mail/access
  3. Restart sendmail
    # /etc/init.d/sendmail restart

Remove blacklist message automatically

Remove blacklist message automatically by procmail
  1. Edit $HOME/.procmailrc
    :0 h
    *$ ? test -s $BLACKLIST
    * ? (formail -x From: -x Reply-To: -x Sender: -x From | fgrep -iqf $BLACKLIST)
  2. Make a blacklist $HOME/.blacklist

Aliases name

  1. Edit /etc/aliases
    group1: user1, user2, user3, . . .
  2. Rebuild the data base for the mail aliases file
    Newaliases rebuilds the random access data base for the mail aliases file /etc/aliases. It must be run each time this file is changed in order for the change to take effect.
    # newaliases

Message forwarding

  1. Edit ~/.forward file to forward all messages.



sendmail access.db by example

The sendmail access database file can be created to accept or reject mail from selected domains.
Since "/etc/mail/access" is a database, after creating the text file, use makemap to create the database map.
# makemap hash /etc/mail/access.db < /etc/mail/access
Below is what my access file currently looks like and can be used as a starting point. All internal addresses have been changed except for spammers!!
# by default we allow relaying from localhost...
localhost.localdomain           RELAY
localhost                       RELAY                       RELAY

# Allow Connect from local server IPs
Connect:   OK

# Accept Mail
# accept mail from PayPal      OK

# Reject Mail     REJECT REJECT                 REJECT                     REJECT REJECT                   REJECT

# Discard Mail  DISCARD
# forum admin mails:         DISCARD

# Reject full mailbox ERROR:4.2.2:450 mailbox full REJECT

# Blacklist recipients ERROR:550 That host does not accept mail

# Spam friend domains: exempt domains from dnsbl list checking      FRIEND

# Spam friend users: exempt email users from dnsbl list checking
# example:
# Spam:user@domain.tld         FRIEND
# clients  FRIEND

# Auto REJECT via hourly cron added below

Below are more examples and explanations for reference which comes from the sendmail-cf distribution docs.
The table itself uses e-mail addresses, domain names, and network numbers as keys.
Note that IPv6 addresses must be prefaced with "IPv6:".
For example:                 REJECT                REJECT
        TLD                             REJECT
        192.168.212                     REJECT
        IPv6:2002:c0a8:02c7             RELAY
        IPv6:2002:c0a8:51d2::23f4       REJECT
would refuse mail from, any user from (or any host within the domain), any host in the entire top level domain TLD, 192.168.212.* network, and the IPv6 address 2002:c0a8:51d2::23f4. It would allow relay for the IPv6 network 2002:c0a8:02c7::/48.
The value part of the map can contain:
OK              Accept mail even if other rules in the running
                        ruleset would reject it, for example, if the domain
                        name is unresolvable.  "Accept" does not mean
                        "relay", but at most acceptance for local
                        recipients.  That is, OK allows less than RELAY.
        RELAY           Accept mail addressed to the indicated domain or
                        received from the indicated domain for relaying
                        through your SMTP server.  RELAY also serves as
                        an implicit OK for the other checks.
        REJECT          Reject the sender or recipient with a general
                        purpose message.
        DISCARD         Discard the message completely using the
                        $#discard mailer.  If it is used in check_compat,
                        it affects only the designated recipient, not
                        the whole message as it does in all other cases.
                        This should only be used if really necessary.
        SKIP            This can only be used for host/domain names
                        and IP addresses/nets.  It will abort the current
                        search for this entry without accepting or rejecting
                        it but causing the default action.
        ### any text    where ### is an RFC 821 compliant error code and
                        "any text" is a message to return for the command.
                        The string should be quoted to avoid surprises,
                        e.g., sendmail may remove spaces otherwise.
                        This type is deprecated, use one the two
                        ERROR:  entries below instead.
        ERROR:### any text
                        as above, but useful to mark error messages as such.
        ERROR:D.S.N:### any text
                        where D.S.N is an RFC 1893 compliant error code
                        and the rest as above.
For example:        ERROR:"550 We don't accept mail from spammers"   OK            RELAY
        128.32                  RELAY
        IPv6:1:2:3:4:5:6:7      RELAY
        []             OK
        [IPv6:1:2:3:4:5:6:7:8]  OK
would accept mail from, but would reject mail from all other hosts at with the indicated message. It would allow relaying mail from and to any hosts in the domain, and allow relaying from the 128.32.*.* network and the IPv6 1:2:3:4:5:6:7:* network. The latter two entries are for checks against ${client_name} if the IP address doesn't resolve to a hostname (or is considered as "may be forged"). That is, using square brackets means these are host names, not network numbers.
You can also use the access database to block sender addresses based on the username portion of the address.
For example:
FREE.STEALTH.MAILER@    ERROR:550 Spam not accepted
Note that you must include the @ after the username to signify that this database entry is for checking only the username portion of the sender address.
If you use:
then you can add entries to the map for local users, hosts in your domains, or addresses in your domain which should not receive mail:
badlocaluser@           ERROR:550 Mailbox disabled for this username       ERROR:550 That host does not accept mail     ERROR:550 Mailbox disabled for this recipient
This would prevent a recipient of, any user at, and the single address from receiving mail. Please note: a local username must be now tagged with an @ (this is consistent with the check of the sender address, and hence it is possible to distinguish between hostnames and usernames). Enabling this feature will keep you from sending mails to all addresses that have an error message or REJECT as value part in the access map. Taking the example from above:         REJECT        REJECT
Mail can't be sent to or anyone at
If using DNS Blackhole List Database via:
To avoid checking your own local domains against those blacklists, add:
Connect:10.1            OK
        Connect:       RELAY
where 10.1 is your local network. You may want to use "RELAY" instead of "OK" to allow also relaying instead of just disabling the DNS lookups in the backlists.
There is now the option to tag entries in the access map according to their type. Three tags are available:
Connect:        connection information (${client_addr}, ${client_name})
        From:           envelope sender
        To:             envelope recipient
If the required item is looked up in a map, it will be tried first with the corresponding tag in front, then (as fallback to enable backward compatibility) without any tag, unless the specific feature requires a tag.
For example:
From:spammer@some.dom   REJECT
        To:friend.domain        RELAY
        Connect:friend.domain   OK
        Connect:from.domain     RELAY
        From:good@another.dom   OK
        From:another.dom        REJECT
This would deny mails from spammer@some.dom but you could still send mail to that address even if FEATURE(`blacklist_recipients') is enabled. Your system will allow relaying to friend.domain, but not from it (unless enabled by other means). Connections from that domain will be allowed even if it ends up in one of the DNS based rejection lists. Relaying is enabled from from.domain but not to it (since relaying is based on the connection information for outgoing relaying, the tag Connect: must be used; for incoming relaying, which is based on the recipient address, To: must be used). The last two entries allow mails from good@another.dom but reject mail from all other addresses with another.dom as domain part.
By using FEATURE(`delay_checks') the rulesets check_mail and check_relay will not be called when a client connects or issues a MAIL command, respectively. Instead, those rulesets will be called by the check_rcpt ruleset; they will be skipped if a sender has been authenticated using a "trusted" mechanism, i.e., one that is defined via TRUST_AUTH_MECH(). If check_mail returns an error then the RCPT TO command will be rejected with that error. If it returns some other result starting with $# then check_relay will be skipped. If the sender address (or a part of it) is listed in the access map and it has a RHS of OK or RELAY, then check_relay will be skipped. This has an interesting side effect: if your domain is my.domain and you have
my.domain       RELAY
in the access map, then any e-mail with a sender address of will not be rejected by check_relay even though it would match the hostname or IP address. This allows spammers to get around DNS based blacklist by faking the sender address. To avoid this problem you have to use tagged entries:
To:my.domain            RELAY
        Connect:my.domain       RELAY
if you need those entries at all (class {R} may take care of them).
FEATURE(`delay_checks') can take an optional argument:
FEATURE(`delay_checks', `friend')
                 enables spamfriend test
        FEATURE(`delay_checks', `hater')
                 enables spamhater test
If such an argument is given, the recipient will be looked up in the access map (using the tag Spam:). If the argument is `friend', then the default behavior is to apply the other rulesets and make a SPAM friend the exception. The rulesets check_mail and check_relay will be skipped only if the recipient address is found and has RHS FRIEND. If the argument is `hater', then the default behavior is to skip the rulesets check_mail and check_relay and make a SPAM hater the exception. The other two rulesets will be applied only if the recipient address is found and has RHS HATER.
This allows for simple exceptions from the tests, e.g., by activating the friend option and having
Spam:abuse@     FRIEND
in the access map, mail to abuse@localdomain will get through (where "localdomain" is any domain in class {w}). It is also possible to specify a full address or an address with +detail:
Spam:abuse@my.domain    FRIEND
        Spam:me+abuse@          FRIEND
        Spam:spam.domain        FRIEND