Dec 022010
 

Just recently I had to set up a sendmail server for an office with 7 local users and more roaming users. The current setup had all users checking email via POP3 to the ISP. This is an issue as email sent locally within the office passed over the ADSL connection twice. Sendmail however is quite difficult to work with when it can’t handle the entire domain. As not all users on the domain have an account on the office server, email would bounce back as user unknown – even though a POP3 account existed with the ISP.

Read on for more.

I’ll write up a dummy scenario to make this clearer.

  • local1 – Checks email on the local server via IMAP. Server downloads email via fetchmail and throws it in the users IMAP mailstore.
  • local2 – Same configuration as local1.
  • remote1 – This user doesn’t have an account on the local server but gets email via the ISPs POP3 mail account.
  • All users have the same domain name in their email address. For this example, we’ll use mydomain.com.au.

    The issue starts with a couple of common problems.
    a) If we put mydomain.com.au in /etc/mail/local-host-names, then email between local1 and local2 will be handled locally – which is great. The problem though is that mail between local1 and remote1 will bounce with a ‘user unknown’ error.

    b) Having a smarthost defined to send email out via the ISPs mail server will also mean that mail between local1 and local2 will also go to the smarthost – essentially uploading it to be downloaded again. This adds delay and also slows things down.

    To fix this, we can use the virtusertable to rewrite the addresses of the email addresses – but by default, sendmail does not run the virtusertable on any addresses of domains it does not own.

    We can however modify our sendmail.mc with the following code to tell sendmail to run domains we specify through the virtusertable! The code is as follows:
    FEATURE(`virtusertable', `hash -o /etc/mail/virtusertable.db')dnl
    LOCAL_CONFIG
    F{VirtHost}/etc/mail/virtual-domains

    Now we can add the domains we want to run the virtusertable on in /etc/mail/virtual-domains:

    mydomain.com.au

    The final step in this solution is to then specify what users we want to rewrite to be local users. This is in /etc/mail/virtusertable:

    local1@mydomain.com.au local1@localhost
    local2@mydomain.com.au local2@localhost

    Now when we test these addresses using sendmail -bt from the server, we see the address translation happen:
    # sendmail -bt
    ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
    Enter <ruleset> <address>
    > /parse local1@mydomain.com.au
    Cracked address = $g
    Parsing envelope recipient address
    canonify input: local1 @ mydomain . com . au
    Canonify2 input: local1 < @ mydomain . com . au >
    Canonify2 returns: local1 < @ mydomain . com . au . >
    canonify returns: local1 < @ mydomain . com . au . >
    parse input: local1 < @ mydomain . com . au . >
    Parse0 input: local1 < @ mydomain . com . au . >
    Parse0 returns: local1 < @ mydomain . com . au . >
    ParseLocal input: local1 < @ mydomain . com . au . >
    ParseLocal returns: local1 < @ mydomain . com . au . >
    Parse1 input: local1 < @ mydomain . com . au . >
    Recurse input: local1 @ localhost
    canonify input: local1 @ localhost
    Canonify2 input: local1 < @ localhost >
    Canonify2 returns: local1 < @ intranet . mydomain . com . au . >
    canonify returns: local1 < @ intranet . mydomain . com . au . >
    parse input: local1 < @ intranet . mydomain . com . au . >
    Parse0 input: local1 < @ intranet . mydomain . com . au . >
    Parse0 returns: local1 < @ intranet . mydomain . com . au . >
    ParseLocal input: local1 < @ intranet . mydomain . com . au . >
    ParseLocal returns: local1 < @ intranet . mydomain . com . au . >
    Parse1 input: local1 < @ intranet . mydomain . com . au . >
    Parse1 returns: $# local $: local1
    parse returns: $# local $: local1
    Recurse returns: $# local $: local1
    Parse1 returns: $# local $: local1
    parse returns: $# local $: local1
    2 input: local1
    2 returns: local1
    EnvToL input: local1
    EnvToL returns: local1
    final input: local1
    final returns: local1
    mailer local, user local1

    Checking against any other email address should show the normal delivery method – either normal MX lookup and delivery, or via a defined smarthost.

      One Response to “Sendmail and ‘partly-there’ domains”

    1. Very interesting read, Usefull!

     Leave a Reply

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

    (required)

    (required)