Sendmail milter – build and install from the source

http://linux-sxs.org/internet_serving/sendm2.html

This document describes installing Sendmail to utilize some of it’s neater features, to be a little more secure (we will run Sendmail under a non-root id, and with TLS), to support SMTP AUTH, and so we have a better understanding of Sendmail itself. Please note that we assume you have already installed Procmail and SASL and OpenSSL.

Since early in the 11.x series, Sendmail’s milter interface has been greatly improved and enhanced. We are going to build Sendmail with its libmilter feature turned on. We do this because the milter interface is the preferred method of enhancing and extending Sendmail. The milter interface can be used to “hook” anti-spam, anti-virus, and many other features into the Sendmail daemon. If you’re interested, please see www.milter.org for the latest developments in milter features.

Please note that on some distros, you will need to replace every ‘sh ./Build’ with ‘sh ./Build -c’ below.

    1. Download the latest source archive from www.sendmail.org and extract it
      • tar zxvf sendmail.8.x.x.tar.gz
    2. Create Sendmail’s needed directories, and ensure their proper permissions/ownerships
      • mkdir -p /etc/mail /var/spool/mqueue/.hoststat /var/spool/clientmqueue
      • chmod go-w / /etc /etc/mail /usr /var /var/spool
    3. Add our new user and group for Sendmail to run as
      • groupadd smmsp
      • useradd -g smmsp smmsp
      • (might need -G instead. depends on which useradd you have)
    4. Ensure ownership of needed directories
      • chown root / /etc /etc/mail /usr /var /var/spool /var/spool/mqueue
      • chown smmsp:smmsp /var/spool/clientmqueue
      • chmod 770 /var/spool/clientmqueue
      • chmod 700 /var/spool/mqueue
      • chmod 755 /var/spool/mqueue/.hoststat
    5. Configure Sendmail to use the libmilter interface and TLS
      • cd sendmail-8.x.x
      • echo "APPENDDEF(\`conf_sendmail_ENVDEF', \`-DMILTER')" > /etc/mail/site.config.m4
      • echo "APPENDDEF(\`conf_sendmail_ENVDEF', \`-DSOCKETMAP')" >> /etc/mail/site.config.m4
      • echo "APPENDDEF(\`conf_sendmail_ENVDEF',\`-DSASL=2')" >> /etc/mail/site.config.m4
      • echo "APPENDDEF(\`conf_sendmail_LIBS',\`-lsasl2')" >> /etc/mail/site.config.m4
      • echo "APPENDDEF(\`conf_sendmail_ENVDEF',\`-DSTARTTLS')" >> /etc/mail/site.config.m4
      • echo "APPENDDEF(\`conf_sendmail_ENVDEF',\`-D_FFR_SMTP_SSL')" >> /etc/mail/site.config.m4
      • echo "APPENDDEF(\`conf_sendmail_LIBS',\`-lssl -lcrypto -L/usr/lib')" >> /etc/mail/site.config.m4
      • echo "APPENDDEF(\`conf_libmilter_ENVDEF', \`-D_FFR_MILTER_ROOT_UNSAFE')" >> /etc/mail/site.config.m4
      • echo "APPENDDEF(\`confMAPDEF',`\-DMAP_REGEX')" >> /etc/mail/site.config.m4
      • echo "define(\`confNO_HELPFILE_INSTALL')" >> /etc/mail/site.config.m4
      • echo "define(\`confMANGROUP',\`root')" >> /etc/mail/site.config.m4
      • echo "define(\`confMANOWN',\`root')" >> /etc/mail/site.config.m4
      • echo "define(\`confMSBINGRP',\`root')" >> /etc/mail/site.config.m4
      • echo "define(\`confUBINGRP',\`root')" >> /etc/mail/site.config.m4
      • echo "define(\`confUBINOWN',\`root')" >> /etc/mail/site.config.m4
      • please note that the above are NOT all single-quotes. they are:
      • backtick,quote,backtick,quote
    6. Build and install libmilter
      • cd libmilter
      • sh Build && sh Build install
      • cd - && cd /usr/lib && ln -s . libmilter
      • cd -
    7. Build the sendmail daemon
      • cd sendmail
      • if [ ! -e /usr/share/man ] ; then ln -s /usr/man /usr/share/man; fi
      • sh Build -f /etc/mail/site.config.m4 && sh Build install
        • you should see ‘-DMILTER’ periodically during the compile
      • cd ../obj. ( will differ from machine to machine)
      • cd libsmutil
      • install libsmutil.a /usr/lib
      • cd ../libsm
      • install libsm.a /usr/lib
    8. (If following the Sendmail Anti-SPAM instructions, stop here)
    9. Now we need to configure and build the dreaded CF files
      • copy rhsbl.m4 to ../../cf/feature
      • cd ../../cf/cf
      • cp generic-linux.mc config.mc
      • vi config.mc (make it look like this:)
      • (note that ‘confPRIVACY_FLAGS’ below is arguably redundant as ‘goaway’ sets a lot of options. I choose to specify them in case ‘goaway’ changes meanings at some point)(also note for MAX_DAEMON_CHILDREN use 40 for every 128M of RAM you have (so 80 for 256M, 120 for 768M, etc)
        • divert(0)dnl
        • VERSIONID(`Custom Linux config by Douglas Hunley /doug at hunley.homeip.net/ ')
        • OSTYPE(linux)dnl
        • DOMAIN(generic)dnl
        • FEATURE(access_db, `hash -T /etc/mail/access')dnl
        • FEATURE(always_add_domain)dnl
        • FEATURE(badmx)dnl
        • FEATURE(block_bad_helo)dnl
        • FEATURE(conncontrol)dnl
        • FEATURE(greet_pause, `5000')dnl
        • FEATURE(local_procmail)dnl
        • FEATURE(mailertable)dnl
        • FEATURE(mtamark)dnl
        • FEATURE(nouucp, `reject')dnl
        • FEATURE(ratecontrol)dnl
        • FEATURE(rhsbl, `dsn.rfc-ignorant.org', `"550 Mail from domain " $`'&{RHS} " refused. MX of domain do not accept bounces. This violates RFC 821/2505/2821 - see http://www.rfc-ignorant.org/"')dnl
        • FEATURE(rhsbl,`postmaster.rfc-ignorant.org',`"550 Mail from domain " $`'&{RHS} " refused. MX of domain does not have a working postmaster address - see http://www.rfc-ignorant.org/"')dnl
        • FEATURE(smrsh, `/usr/sbin/smrsh')dnl
        • FEATURE(use_ct_file)dnl
        • FEATURE(use_cw_file)dnl
        • FEATURE(virtusertable, `hash /etc/mail/virtusertable')dnl
        • define(`confAUTH_MECHANISMS',`LOGIN PLAIN DIGEST-MD5 CRAM-MD5')dnl
        • define(`confAUTH_OPTIONS',`A')dnl
        • define(`confBAD_RCPT_THROTTLE',`3')dnl
        • define(`confCACERT', `/etc/mail/certs/cacert.pem')dnl
        • define(`confCACERT_PATH', `/etc/mail/certs')dnl
        • define(`confCLIENT_CERT', `/etc/mail/certs/sendmail.pem')dnl
        • define(`confCLIENT_KEY', `/etc/mail/certs/sendmail.pem')dnl
        • define(`confCONNECTION_RATE_THROTTLE', `8')dnl
        • define(`confDONT_PROBE_INTERFACES', true)dnl
        • define(`confHOST_STATUS_DIRECTORY', `.hoststat')dnl
        • define(`confMAX_DAEMON_CHILDREN', 320)dnl
        • define(`confMAX_HEADERS_LENGTH', 32768)dnl
        • define(`confMAX_MESSAGE_SIZE', 10485760)dnl
        • define(`confMAX_MIME_HEADER_LENGTH', `256/128')dnl
        • define(`confMAX_RCPTS_PER_MESSAGE' 25)dnl
        • define(`confMILTER_MACROS_ENVFROM', confMILTER_MACROS_ENVFROM`, {msg_size}')dnl
        • define(`confMILTER_MACROS_HELO', confMILTER_MACROS_HELO`, {verify}')dnl
        • define(`confMILTER_MACROS_CONNECT', `j, {if_addr}')dnl
        • define(`confMIN_FREE_BLOCKS', 4000)dnl
        • define(`confNO_RCPT_ACTION', `add-to-undisclosed')dnl
        • define(`confPIDFILE', `/var/run/sendmail.pid')dnl
        • define(`confPRIVACY_FLAGS', `authwarnings,goaway,noreceipts,noexpn,novrfy,noetrn,needmailhelo,restrictmailq,restrictqrun,restrictexpand,nobodyreturn')dnl
        • define(`confSAFE_FILE_ENV', `/exports/users')dnl
        • define(`confSERVER_CERT', `/etc/mail/certs/sendmail.pem')dnl
        • define(`confSERVER_KEY', `/etc/mail/certs/sendmail.pem')dnl
        • define(`confSINGLE_LINE_FROM_HEADER', `true')dnl
        • define(`confSMTP_LOGIN_MSG', `')dnl
        • define(`confTLS_SRV_OPTIONS', `V')dnl
        • define(`confTO_IDENT', `0')dnl
        • define(`HELP_FILE', `')dnl
        • define(`PROCMAIL_MAILER_PATH', `/usr/bin/procmail')dnl
        • define(`STATUS_FILE', `/etc/mail/statistics')dnl
        • define(`confTO_ICONNECT', `15s')dnl
        • define(`confTO_CONNECT', `3m')dnl
        • define(`confTO_HELO',`2m')dnl
        • define(`confTO_MAIL', `1m')dnl
        • define(`confTO_RCPT', `1m')dnl
        • define(`confTO_DATAINIT',`1m')dnl
        • define(`confTO_DATABLOCK', `1m')dnl
        • define(`confTO_DATAFINAL', `1m')dnl
        • define(`confTO_RSET', `1m')dnl
        • define(`confTO_QUIT', `1m')dnl
        • define(`confTO_MISC', `1m')dnl
        • define(`confTO_COMMAND', `1m')dnl
        • define(`confTO_RESOLVER_RETRANS', `7s')dnl
        • define(`confTO_RESOLVER_RETRY', `4')dnl
        • undefine(`UUCP_RELAY')dnl
        • undefine(`BITNET_RELAY')dnl
        • dnl ## INPUT_MAIL_FILTER stuff for milters goes here
        • MAILER(local)dnl
        • MAILER(procmail)dnl
        • MAILER(smtp)dnl
        • TRUST_AUTH_MECH(`LOGIN PLAIN DIGEST-MD5 CRAM-MD5')dnl

 

  • sh Build config.cf
  • install submit.cf /etc/mail && install config.cf /etc/mail/sendmail.cf

 

  • The supporting tools are now built and installed
  • cd ../..
  • sh Build && sh Build install
  • Final configuration
  • cd /etc
  • ln -sf mail/aliases
  • ln -sf mail/sendmail.cf
  • Configure local-host-names file
    • hostname -f > /etc/mail/local-host-names
  • Configure access file
    • echo -e "127.0.0.1\tOK" > /etc/mail/access
    • echo -e "ClientRate:127.0.0.1\t0\nClientRate:\t10" >> /etc/mail/access
    • echo -e "ClientConn:127.0.0.1\t0\nClientConn:\t10" >> /etc/mail/access
    • echo -e "GreetPause:localhost\t0" >> /etc/mail/access
    • makemap -v hash /etc/mail/access < /etc/mail/access
  • Configure virtuser file
    • touch /etc/mail/virtusertable
    • makemap -v hash /etc/mail/virtusertable < /etc/mail/virtusertable
  • Configure mailertable
    • echo "aol.com your.isp.mail.server" > /etc/mail/mailertable
    • makemap -v hash /etc/mail/mailertable < /etc/mail/mailertable
    • (replace your.isp.mail.server with whatever mail server your ISP told you to use for outbound mail)
    • this is needed to get around AOL blocking mail from us ‘home’ users
  • create /etc/mail/aliases
    • touch /etc/mail/aliases
  • Rebuild your aliases file
    • newaliases
  • Setup smrsh
    • mkdir /etc/smrsh
    • mkdir /var/adm /usr/adm
    • ln -sf /etc/smrsh /var/adm/sm.bin
    • ln -sf /etc/smrsh /usr/adm/sm.bin
  • Configure SASL for Sendmail
    • mkdir /etc/sasl2
    • echo “pwcheck_method: saslauthd” > /etc/sasl2/Sendmail.conf
    • echo “mech_list: login plain” >> /etc/sasl2/Sendmail.conf
  • Create your certificates for TLS
    • mkdir /etc/mail/certs
    • openssl req -new -x509 -keyout cakey.pem -out cacert.pem -days 365
    • openssl req -nodes -new -x509 -keyout sendmail.pem -out sendmail.pem -days 365
    • openssl x509 -noout -text -in sendmail.pem
    • chmod 600 sendmail.pem

Ensure that saslauthd is started with ‘-a shadow‘ if you’re going to make use of the SMTP AUTH feature.

Decide if you machine is going to accept incoming mail from other systems, or if it is going to only send outbound mail. If you have a need for incoming mail on this machine, edit your sendmail startup script (usually in /etc/rc.d somewhere) and change it to something like:

  • #!/bin/sh
    
    SENDMAIL_ARGS="-bd -q5m"
    
    case "$1" in
        start)
    	find /var/spool/mqueue/ /var/spool/clientmqueue/ -maxdepth 1 -type f -mtime +7 -exec rm {} \;
    
    	echo "Starting Sendmail `grep ^DZ /etc/sendmail.cf|cut -c3-`"
    	/usr/sbin/sendmail $SENDMAIL_ARGS
    
    	echo "Starting Sendmail Queue Runner"
    	/usr/sbin/sendmail -Ac -qp1m
    
    	/bin/chmod 640 /var/run/sendmail.pid &>/dev/null
    
    	;;
        stop)
    	echo "Shutting down Sendmail"
    	killproc -TERM /usr/sbin/sendmail
    
    	;;
        reload)
    	$0 stop
    	$0 start
    	;;
        *)
    	echo "Usage: $0 {start|stop|reload}"
    	exit 1
    esac
    
    exit 0
    

If you don't need incoming mail, edit your sendmail startup script to something like this:

  • #!/bin/sh
    
    SENDMAIL_ARGS="-q5m"
    
    case "$1" in
        start)
    
    	find /var/spool/mqueue/ /var/spool/clientmqueue/ -maxdepth 1 -type f -mtime +7 -exec rm {} \;
    
    	echo "Starting Sendmail `grep ^DZ /etc/sendmail.cf|cut -c3-`"
    	/usr/sbin/sendmail $SENDMAIL_ARGS 
    
    	/bin/chmod 640 /var/run/sendmail.pid &>/dev/null
    
    	;;
        stop)
    	echo "Shutting down Sendmail"
    	killproc -TERM /usr/sbin/sendmail 
    
    
    	;;
        reload)
    	$0 stop
    	$0 start
    	;;
        *)
    	echo "Usage: $0 {start|stop|reload}"
    	exit 1
    esac
    
    exit 0
    

This will prevent sendmail from starting up as a listening deamon.

Once Sendmail is up and running, check your system logs for something like:

  • sendmail[7333]: STARTTLS=server, relay=localhost [127.0.0.1], version=TLSv1/SSLv3, verify=NO, cipher=DHE-RSA-AES256-SHA, bits=256/256

You may see 'verify=FAIL' (or anything other than 'ok'). This is normal. It simply means that Sendmail couldn't walk the CA chain and verify the client's cert. As long as the cipher and bits have values like the above then TLS is being used.

Enjoy!