Re-configuring Sendmail

I had configured exim to use masquerading when sending mail outside of my domain, but not use it for mail directed at machines within the local domain. I suspected I could enable sendmail to behave in the same way, but it took a little research.

I dug through the O'Reilly Sendmail book, trying to work out how I could achieve the desired affect. I determined the re-writing capabilities, on their own, did not offer me want I needed. The rules I needed to implement would need to cause a re-writing of the sender address, if the recipient was not a machine on the local domain. The rules either dealt with senders or recipients, but not both at the same time.

Eventually, I realised that the same technique used with exim would work with sendmail: use the rules to define different transport agents (mailers) for intra-domain and extra-domain traffic, and then use the re-writing rules at this level to omit masquerading for intra-domain mails.

The sendmail facility, SMART_HOST, uses the RELAY mailer by default. As this mailer had to apply masquerading, its definition was left unchanged. The LOCAL_NET_CONFIG rule, which detected mail that should be directed to a local domain machine, used the SMTP mailer. I therefore had to define new envelope and header re-writing rules that did not perform the masquerade step, and re-define the SMTP mailer to use the rules.

NOTE WELL: The recipient machine must be registered in the local DNS for sendmail to use the SMTP mailer.

The sendmail.mc changes to make this happen are shown below. The lines that follow the MAILER_DEFINITION directive are added directly to the resulting sendmail.cf file. The new rules (EnvFromSMPTNET and HdrFromSMPTNET) were just lifted from the existing rules (EnvFromSMTP and HdrFromSMTP) in the original sendmail.cf file, modified to remove the rule invocation which caused the final masquerading to take place.

  dnl The masquerade applies to mail going outside of the local 
  dnl domain.  Mail inside the domain is not masqueraded, since 
  dnl hydrus.org.uk is not a valid domain as far as my Alcatel 
  dnl DNS server is concerned.  The rules to turn off masquerading 
  dnl are defined in MAILER_DEFINITIONS below.
  FEATURE(masquerade_envelope)
  MASQUERADE_AS(hydrus.org.uk)
  
  dnl Dialup users should uncomment and define this appropriately
  define(`SMART_HOST', `smtp.isp.com')
  
  dnl This rule causes mail destined within the domain to be directed 
  dnl at the recipient machine, rather than the SMART_HOST.
  LOCAL_NET_CONFIG
  R $* < @ $+ .$m. > $* $#smtp $@ $2.$m $: $1 < @ $2.$m > $3
  
  
  dnl Re-writing rules which omit masquerading, and a re-defined 
  dnl SMTP mailer which uses the rules.  SMART_HOST uses the 
  dnl RELAY mailer, not SMTP.
  MAILER_DEFINITIONS
  #
  #  local network envelope sender rewriting, sans masquerading
  #
  SEnvFromSMTPNET
  R$+               $: $>PseudoToReal $1    sender/recipient common
  R$* :; <@>        $@                      list:; special case
  R$*               $: $>MasqSMTP $1        qualify unqual'ed names
  
  SHdrFromSMTPNET
  R$+               $: $>PseudoToReal $1    sender/recipient common
  R:; <@>           $@                      list:; special case
  
  # do special header rewriting
  R$* <@> $*        $@ $1 <@> $2            pass null host through
  R< @ $* > $*      $@ < @ $1 > $2          pass route-addr through
  R$*               $: $>MasqSMTP $1        qualify unqual'ed names
  
  # redefine smtp to use non-masquerading rules defined above
  # [N.B. Line folded to fit]
  Msmtp,        P=[IPC], F=mDFMuX, S=EnvFromSMTPNET/HdrFromSMTPNET, \
  R=EnvToSMTP, E=\r\n, L=990,
  T=DNS/RFC822/SMTP,
  A=TCP $h

Addendum (17th April, 2004)

I performed the testing of this on amber, and I noticed that for mail delivered locally, the following message appeared in the sendmail log file:

  relay=Speedtouch.hydrus.org.uk [127.0.0.1] (may be forged)

I couldn't understand why the name of the router was appearing as the local host. This didn't happen on the other sendmail machines. However, if I used nslookup for a reverse lookup of 127.0.0.1, it returned Speedtouch.hydrus.org.uk. So sendmail must be looking up the local host address via DNS. At first I thought the /etc/mail/service.switch file might be at fault, but it was no different on amber to the other FreeBSD systems. I then discovered that someone (and that someone would be me) had messed with the /etc/host.conf on amber, putting bind before hosts. By setting back to the default (an /etc/hosts lookup is performed first, and then a DNS lookup), sendmail stopped complaining about forged addresses.

Alternate sendmail configuration

After creating the sendmail configuration outlined here, it became clear there was another way to achieve the effect I was seeking. Crimson would become the SMART_HOST for the other machines on the local domain. The sendmail configuration file for crimson would contain the following additional lines:

  MASQUERADE_DOMAIN(hydrus.org.uk)
  FEATURE(masquerade_entire_domain)

This would cause crimson to masquerade the sender address of all machines on the network, for email destined for the outside world. The crimson configuration file still needs the LOCAL_NET_CONFIG, and the revised version of smtp under MAILER_DEFINITIONS to send non-masqueraded sender addresses to other machines in the local domain.

However, while the sendmail configuration files for other machines in the local domain would no longer need the MAILER_DEFINITIONS, the LOCAL_NET_CONFIG would still be required, in order to send mail directly to other domain machines, rather than using crimson. Masquerading on the other domain machines would not be necessary, since the SMART_HOST would be defined as crimson and it would provide masquerading for local domain machines.

I decided that this scheme was not worth pursuing since, if crimson should die, the sendmail configuration file on each machine would need to be changed to point to chrome. With the existing setup, machines are independent of the mail recipient machine for hydrus.org.uk