Installing Sendmail 8.12.1 for Milter Support
Testing a Filter
4.1 Installing Sendmail 8.12.1 for Milter support
Starting with sendmail 8.12, sendmail is no longer set-user-ID root by default. As a result of this, you need to install two .cf files. See steps 4 and 6 in this document. We also strongly recommend reading sendmail/SECURITY for more installation information.
1. Read all the README files noted in the INTRODUCTION section of the README file in this top-level directory.
2. Create any necessary site configuration build files, as noted in devtools/Site/README.
3. In the sendmail/ directory, run "sh Build" (see sendmail/README for details).
4. Change to the cf/cf/ directory (that's not a typo): Copy whichever .mc file best matches your environment to sendmail.mc, where config can be any name. Next, tailor it as explained in cf/README. Then run "sh Build sendmail.cf".
5. Back up your current /etc/mail/sendmail.cf and the sendmail binary (whose location varies from operating system to operating system, but is usually in /usr/sbin or /usr/lib).
6. Install sendmail.cf as /etc/mail/sendmail.cf and submit.cf as /etc/mail/submit.cf. This can be done in the cf/cf by using "sh Build install-cf". Read sendmail/SECURITY before continuing; you have to create a new user smmsp and a new group smmsp for the default installation. Then install the sendmail binary built in step 3 by cd-ing back to sendmail/ and running "sh Build install".
7. For each of the associated sendmail utilities (makemap, mailstats, etc.), read the README in the utility's directory. When you are ready to install it, back up your installed version and type "sh Build install".
8. If you are upgrading from an older version of sendmail and are using any database maps, be sure to rebuild them with the new version of makemap, in case you are now using a different (and thereby incompatible) version of Berkeley DB.
To compile a filter, modify the Makefile provided with the sample program, or:
Your compile command line will look like
cc -I/path/to/include -I/path/to/sendmail -c myfile.c
and your linking command line will look something like
cc -o myfilter [object-files] -L[library-location] -lmilter -pthread
To run the filter, the Milter shared library must be available to the run-time linker.
First, you must compile sendmail versions before 8.12 with _FFR_MILTER defined. To do this, add the following lines to your build configuration file (devtools/Site/config.site.m4)
./Build -c in
your sendmail directory.
Next, you must add the desired filters to your sendmail
configuration (.mc) file. With versions before 8.12, the file must then be processed
with _FFR_MILTER defined. Mail filters have three equates: The required
S= equate specifies
the socket where sendmail should look for the filter; The optional
T= equates specify
flags and timeouts, respectively. All equates names, equate field names, and
flag values are case sensitive.
The current flags (
Reject connection if filter unavailable
Temporary fail connection if filter unavailable
If a filter is unavailable or unresponsive and no flags have been specified, the MTA will continue normal handling of the current connection. The MTA will try to contact the filter again on each new connection.
There are three fields inside of the
equate: S, R, and E. Note the separator between each is a ";" (semicolon),
as "," (comma) already separates equates. The value of each field
is a decimal number followed by a single letter designating the units ("s"
for seconds, "m" for minutes). The fields have the following meanings:
Timeout for connecting to a filter. If set
to 0, the system's
Timeout for sending information from the MTA to a filter. Default: 10s
Timeout for reading reply from the filter. Default: 10s
Overall timeout between sending end-of-message to filter and waiting for the final acknowledgment. Default: 5m
The following sendmail.mc example specifies three filters. The first two rendezvous on Unix-domain sockets in the /var/run directory; the third uses an IP socket on port 999.
INPUT_MAIL_FILTER(`filter1', `S=unix:/var/run/f1.sock, F=R')
INPUT_MAIL_FILTER(`filter2', `S=unix:/var/run/f2.sock, F=T, T=S:1s;R:1s;E:5m')
INPUT_MAIL_FILTER(`filter3', `S=inet:999@localhost, T=C:2m')
m4 -D_FFR_MILTER ../m4/cf.m4 myconfig.mc > myconfig.cf
By default, the filters would be run in the order
declared, i.e. "filter1, filter2, filter3"; however, since
confINPUT_MAIL_FILTERS is defined, the
filters will be run "filter2, filter1, filter3". Also note that a
filter can be defined without adding it to the input filter list by using MAIL_FILTER()
instead of INPUT_MAIL_FILTER().
The above macros will result in the following lines being added to your .cf file:
Xfilter1, S=unix:/var/run/f1.sock, F=R
Xfilter2, S=unix:/var/run/f2.sock, F=T, T=S:1s;R:1s;E:5m
Xfilter3, S=inet:999@localhost, T=C:2m
Finally, the sendmail macros accessible via smfi_getsymval can be configured by defining the following m4 variables (or cf options):
In .mc file
In .cf file
4.4 Testing a filter
Once you have compiled a filter, modified your .mc file and restarted the sendmail process, you will want to test that the filter performs as intended.
The sample filter takes one argument -p, which indicates the local port on which to create a listening socket for the filter. Maintaining consistency with the suggested options for sendmail.cf, this would be the UNIX domain socket located in /var/run/f1.sock.
% ./sample -p local:/var/run/f1.sock
If the sample filter returns immediately to a command line, there was either an error with your command or a problem creating the specified socket. Further logging can be captured through the syslogd daemon. Using the 'netstat -a' command can ensure that your filter process is listening on the appropriate local socket.
Email messages must be injected via SMTP to be filtered. There are two simple means of doing this; either using the 'sendmail -bs' command, or by telnetting to port 25 of the machine configured for milter. Once connected via one of these options, the session can be continued through the use of standard SMTP commands.
% sendmail -bs
220 test.sendmail.com ESMTP Sendmail 8.11.0/8.11.0; Tue, 10 Nov 1970 13:05:23 -0500 (EST)
250 test.sendmail.com Hello testy@localhost, pleased to meet you
250 2.1.0 <testy>... Sender ok
250 2.1.5 <root>... Recipient ok
354 Enter mail, end with "." on a line by itself
Subject: testing sample filter
250 2.0.0 dB73Zxi25236 Message accepted for delivery
221 2.0.0 test.sendmail.com closing connection
In the above example, the lines beginning with numbers are output by the mail server, and those without are your input. If everything is working properly, you will find a file in /tmp by the name of msg.XXXXXXXX (where the Xs represent any combination of letters and numbers). This file should contain the message body and headers from the test email entered above.
If the sample filter did not log your test email, there are a number of methods to narrow down the source of the problem. Check your system logs written by syslogd and see if there are any pertinent lines. You may need to reconfigure syslogd to capture all relevant data. Additionally, the logging level of sendmail can be raised with the LogLevel option. See the sendmail(8) manual page for more information.
4.5 Security Concerns
Even though sendmail goes through great lengths to assure that it can't be compromised even if the system it is running on is incorrectly or insecurely configured, it can't work around everything. This has been demonstrated by recent OS problems which have subsequently been used to compromise the root account using sendmail as a vector. One way to minimize the possibility of such problems is to install sendmail without set-user-ID root, which avoids local exploits. This configuration, which is the default starting with 8.12, is described in the first section of security guide.
** sendmail configuration without set-user-ID root **
sendmail needs to run as root for several purposes:
- bind to port 25
- call the local delivery agent (LDA) as root (or other user) if the LDA
isn't set-user-ID root (unless some other method of storing e-mail in
local mailboxes is used).
- read .forward files
- write e-mail submitted via the command line to the queue directory.
Only the last item requires a set-user-ID/set-group-ID program to avoid problems with a world-writable directory. It is however sufficient to have a set-group-ID program and a group-writable queue directory. The other requirements listed above can be fulfilled by a sendmail daemon that is started by root. Hence this section explains how to use two sendmail configurations to accomplish the goal to have a sendmail binary that is not set-user-ID root, and hence is not open to system configuration/OS problems or at
least less problematic in presence of those.
The default configuration starting with sendmail 8.12 uses one sendmail binary which acts differently based on operation mode and supplied options.
sendmail must be a set-group-ID (default group: smmsp, recommended gid: 25) program to allow for queueing mail in a group-writable directory. Two .cf files are required: sendmail.cf for the daemon and submit.cf for the submission program. The following permissions should be used:
-r-xr-sr-x root smmsp ... /PATH/TO/sendmail
drwxrwx--- smmsp smmsp ... /var/spool/clientmqueue
drwx------ root wheel ... /var/spool/mqueue
-r--r--r-- root wheel ... /etc/mail/sendmail.cf
-r--r--r-- root wheel ... /etc/mail/submit.cf
That is, the owner of sendmail is root, the group is smmsp, and the binary is set-group-ID. The client mail queue is owned by smmsp with group smmsp and is group writable. The client mail queue directory must be writable by smmsp, but it must not be
accessible for others. That is, do not use world read or execute permissions. In submit.cf the option UseMSP must be set, and QueueFileMode must be set to 0660. submit.cf is available in cf/cf/, which has been built from cf/cf/submit.mc. The file can be used as-is, if you want to add more options, use cf/cf/submit.mc as starting point and read cf/README: MESSAGE SUBMISSION PROGRAM carefully.
The .cf file is chosen based on the operation mode. For -bm (default), -bs, and -t it is submit.cf (if it exists) for all others it is sendmail.cf. This selection can be changed by -Ac or -Am (alternative .cf file: client or mta).
The daemon must be started by root as usual, e.g.,
/PATH/TO/sendmail -L sm-mta -bd -q1h
(replace /PATH/TO with the right path for your OS, e.g.,
/usr/sbin or /usr/lib).
Notice: if you run sendmail from inetd (which in general is not a good idea), you must specify -Am in addition to -bs.
Mail will end up in the client queue if the daemon doesn't accept connections or if an address is temporarily not resolvable. The latter problem can be minimized by using
which, however, may have undesired side effects. See cf/README for a discussion. In general it is necessary to clean the queue either via a cronjob or by running a daemon, e.g.,
/PATH/TO/sendmail -L sm-msp-queue -Ac -q30m
If the option UseMSP is not set, sendmail will complain during queue runs about bogus file permission. If you want a queue runner for the client queue, you probably have to change OS specific scripts to accomplish this (check the man pages of your OS for more information.) You can start this program as root, it will change its user id to RunAsUser (smmsp by default, recommended uid: 25).
This way smmsp does not need a valid shell.
This is a brief summary how the two configuration files are used:
sendmail.cf For the MTA (mail transmission agent)
The MTA is started by root as daemon:
/PATH/TO/sendmail -L sm-mta -bd -q1h
it accepts SMTP connections (on ports 25 and 587 by default);
it runs the main queue (/var/spool/mqueue by default).
submit.cf For the MSP (mail submission program)
The MSP is used to submit e-mails, hence it is invoked
by programs (and maybe users); it does not run as SMTP
daemon; it uses /var/spool/clientmqueue by default; it
can be started to run that queue periodically:
/PATH/TO/sendmail -L sm-msp-queue -Ac -q30m
Prev TOP NEXT