Page Body

GNU/Linux Mail

Published

Category: Longform

Tags: Mail

Configuring mail services on a GNU/Linux machine involves Mail Transfer Agents (MTAs) and Mail User Agents (MUAs).

Note: If you are not familiar with the GNU/Linux command line interface, review the Conventions page before proceeding.

Mail Transfer Agents (MTAs) and Mail User Agents (MUAs)

Electronic mail is one of the most popular services on the Internet. MTAs, programs that forward or receive electronic mail, play a central role in this. Users directly interact with MUAs (e.g., programs like KMail, Evolution, or Outlook) to read, compose, reply to, sort, or delete messages. However, MUAs use MTAs to transport messages to their recipients.

MTAs can be located with Internet Service Providers (ISPs) or be locally installed. Tasks performed by MTAs include address rewriting to canonical form or one suitable for replying to, retrying mail deliveries that failed, notifying the sender of errors during delivery, or optimizing for delivery time, network load, or cost. Among themselves, MTAs on the Internet communicate using the Simple Mail Transfer Protocol (SMTP).

One common MTA for UNIX and GNU/Linux systems is the Sendmail program (now, referred to as Sendmail Open Source by Proofpoint), which was originally implemented by Eric Allman at the University of California in Berkeley in the early 1980s. Despite its complex configuration and history of security vulnerabilities, Sendmail still commands a large community of devoted users.

Other popular MTAs include Postfix by Wietse Venema, Exim by Philip Hazel, and Qmail by Daniel J. Bernstein. Postfix and Exim make efforts to be compatible with Sendmail, as far as certain aspects of their configuration and command structure are concerned. Qmail actively tries to be distinct.

In general, Sendmail and Exim resemble each other closest as far as their architecture is concerned. Both MTAs run as a single process. On the other hand, Postfix and Qmail separate the MTA functionality into a whole family of processes, mostly for security reasons.

The advantage of this approach is that every process can concentrate on one part of the task, communication between the individual processes is only possible across well-defined interfaces, and every process can run with the minimal set of required privileges.

Potentially, all parts of Sendmail and Exim have access to administrator privileges. For Postfix and Qmail, this access is restricted to the foreman process, as well as those processes that deliver mail to users, which therefore need to be able to assume their identities (which requires administrator privileges).

Qmail deliberately offers only restricted functionality, also for security reasons. This omits many features that other MTAs provide out-of-the-box and which must be explicitly added to Qmail. Of the previously mentioned MTAs, Sendmail and Qmail may be viewed as the most difficult to maintain.

GNU/Linux Mail Transfer Agents (MTAs)

Sendmail
More of a system for building an MTA out of a language called M4 (a scripting language). Exists as a single process and has a history of security problems. The binary for this file is located at /usr/lib/sendmail.
Exim
Like Sendmail, exists as a single process, but has a better security record. This is the MTA that is included in Debian.
Postfix
Separates concerns into separate processes for security. Very good external filtering. Uses the Queue Manager (qmgr) daemon to handle mail.
Qmail
Like Postfix, concerns are compartmentalized. Simple configuration. Designed to be a secure replacement for Sendmail.
Uses the Quick Mail Queuing Protocol (QMQP) to share email queues among different MTAs and the Quick Mail Transport Protocol (QMTP) to transmit mail.

Most GNU/Linux MTAs do not include any Post Office Protocol version 3 (POP3) or Internet Message Access Protocol (IMAP) functionality. These must be separately installed.

Sendmail

An MTA like Sendmail has two major jobs to perform:

  1. Listen on the SMTP port 25 for connections from other MTAs that want to deliver mail to local recipients. These messages are written to users' mailboxes by means of a Mail Delivery Agent (MDA) or else forwarded (e.g., to other addresses according to their preferences).

    To receive messages on port 25, the MTA must either permanently run as a free-standing daemon, or be started on-demand by a super server (e.g., xinetd). The latter is only worthwhile if there is very little mail to process.

  2. Send messages that have been submitted for delivery by local MUAs and other programs either by directly calling the MTA or by sending it via SMTP. Since these messages may be addressed to local users, as well as remote ones, this function cannot be separated from mail reception.

You do not need to simultaneously use both functions. For example, if you do not need to receive messages from the Internet (e.g., your computer is not directly connected to the Internet), you do not need to run a MTA on port 25, at least not on other IP addresses than localhost.

Conversely, you can allow sending local mail without receiving it. In local area networks (LANs), it is common to designate one host as the mail server and, on the other hosts, to install a minimally configured MTA that just forwards all submitted mail to the mail server, which then delivers it locally or sends it to the Internet.

Usually, Sendmail delivers messages to local users to their mailboxes in the /var/mail/ directory (on many GNU/Linux systems, the officially deprecated /var/spool/mail/ directory is still in use and is often mapped to /var/mail/ using a symbolic link), where MUAs (or IMAP or POP servers) can pick them up. Every mailbox is a file whose name corresponds to that of the user it belongs to.

New messages are appended to that file. For this to reliably work, all programs using the mailbox must be able to lock it, so that the MUA does not try to delete messages while the MTA appends new messages. The absence of standardized and reliable file locking methods on GNU/Linux sometimes makes this a risky endeavor.

Unlike Sendmail, Qmail uses its own mailbox format called Maildir, where instead of one large file for all messages, an intricate arrangement of directories where each message occupies its own file is used. This obviates most problems with locking. By convention, Maildir-style mailboxes are not located in /var/mail/, but in a user's home directory, which makes backups and quota management easier.

By default, Postfix and Exim operate like Sendmail, but optionally also allow the delivery of mail to Qmail-style Maildir files.

Sendmail tries to get rid of messages to remote recipients as soon as possible. If this does not immediately work (e.g., if the receiving station is not available), any undelivered messages are stored in the /var/spool/mqueue/ directory. The other MTAs use similar directories to store undelivered messages and other internal data, e.g., /var/spool/postfix/ for Postfix, /var/spool/exim/ (or something similar) for Exim, and /var/qmail/ for Qmail.

Usually, it is not a good idea to place directories like /var/mail/ and /var/spool/mqueue/ on the / partition. This prevents eager mail senders or recipients from filling up all of the disk space there and thereby putting the entire system into jeopardy.

MTAs store undelivered messages (e.g., due to errors at the other end) in queues. If you want to check what is in the queue, you can use the sendmail -bp command.

The same applies to Exim and Postfix, which deliberately come with Sendmail-compatible programs for this purpose (e.g., mailq for Postfix). Only with Qmail do you have to resort to its own software like qmail-qread or qmail-stat.

A daemonized Sendmail can process the queue at given fixed intervals. This is a good idea, so that delivery attempts can be later retried if the destination MTAs could not be reached. You can arrange for Sendmail to do this by passing the -q option on the command line, immediately followed by a time specification:

# sendmail -bd -q30m

The above command starts a daemon and causes it to run through its queue every 30 minutes.

You can get Sendmail to immediately process its queue by invoking it with only -q (without an interval, e.g., # sendmail -q). Then, Sendmail tries to deliver all the messages in the queue.

You can automatically execute this command after your computer has established a connection, or use systemd timers/cron to make a connection to the Internet at appropriate times and deliver mail. Again, Postfix and Exim work substantially the same here. To get Qmail to process its queue, you need to send SIGALRM to the qmail-send process.

Usually, Sendmail writes messages to local recipients to their mailbox in /var/mail/ (Qmail uses the Maildir directory in their home directories, instead). However, there are several methods of changing this default.

The /etc/aliases file (possibly also /etc/mail/aliases) allows you to configure a different delivery method for certain local addresses. The format for an email alias is:

ex_alias: ex_recipient

ex_recipient can be the username of a user's account, a fully qualified email address, a file, or (if you use a pipe) a script (e.g., ex_alias: | ex_path_to_script).

Mail aliases are system-wide because they do not belong to a user. The MDA checks the /etc/aliases file for additional instructions on how to handle email and delivers the email to the user specified in the alias.

Comments in the /etc/aliases file are allowed with the hash mark (#).

An entry like root: amnesia forwards messages addressed to root to the local user amnesia, instead. This is a sensible approach, since you should not read mail as root, for security reasons.

An alias can have multiple recipients:

ex_alias: ex_recipient_1,ex_recipient_2

The following example forwards messages addressed to amnesia both to the jlpicard@enterprise.org address and amnesia's local mailbox:

amnesia: \amnesia,jlpicard@enterprise.org

The backslash is necessary in order to avoid an infinite loop.

The following example illustrates some other features of /etc/aliases:

file:     '/tmp/mail_file.txt'
program:  '| /usr/local/bin/program foo'
list:     :include:/var/lib/list.txt

Messages to file are appended to /tmp/mail_file.txt. The format is identical to that of the mailboxes in /var/mail/.

Messages to program are passed to the /usr/local/bin/program foo command on its standard input.

Messages to list cause the /var/lib/list.txt file to be consulted. Every line in this file may be another forwarding instruction in the same format as used on the right-hand side of /etc/aliases. This is particularly useful for mailing lists, which can store their subscriber lists in such files, so that mailing list software can easily manipulate them.

Postfix and Exim understand this sort of alias file, as well, sometimes with additional features. For example, it may be possible to control whether message forwarding to files or programs is allowed in /etc/aliases only, in :include: lists, or combinations of these.

To configure forwarding with Qmail, you must create a file for the address in question in the /var/qmail/alias/ directory. echo &amnesia > '/var/qmail/alias/.qmail-root' forwards all mail to root to amnesia instead (the & at the start indicates that the rest of the line is an email address). In Qmail's alias files, you can do approximately what you can do with Sendmail. The only feature not directly supported is :include: lists.

Sendmail does not directly read /etc/aliases, but uses a database format that allows quicker access. The details are system-dependent. For your changes to /etc/aliases to be become effective, you must transform the file to the binary format using the sendmail -bi command.

Here, Postfix (newaliases) and Exim roughly behave the same way. Postfix also comes with a program called postalias, which creates or queries one or more Postfix alias databases, or updates an existing one. Qmail has its own approach and does not use a binary format, so the problem does not come up.

Users can make their own arrangements by putting the same style of forwarding specification allowed on the right-hand side of /etc/aliases into a file called .forward inside their home directories. Sendmail observes these settings when a message is to be delivered to the user in question.

The most popular example may be:

$ cat '/home/amnesia/.forward'
\amnesia, '| /usr/bin/vacation amnesia'

The vacation program is an automatic mail answering service that replies to incoming messages using the content of the ${HOME}/.vacation.msg file. You can use this to inform your correspondents that you are unavailable for a prolonged period of time because of a vacation or other absence.

Postfix and Exim can also handle .forward files, which are stored in each user's home directory (i.e., ${HOME}/.forward). The format of this file is the same as for the /etc/aliases file, except that you leave out the aliased user, as it is the owner of the ${HOME}/.forward file. Basically, mail to this user will be forwarded to the entries listed in this file.

Qmail supports an equivalent feature under the name of .qmail-default (the possible entries are subtly different; run man 5 dot-qmail for more information).

The delivery of messages to arbitrary programs, and the remote invocation of arbitrary programs via the Internet by people without actual access privileges to the system, does present a security risk. Many system administrators confine the choice of programs allowed in ${HOME}/.forward to a few selected ones that are considered safe.

Mail Commands

mail
Start the interactive mail command. The prompt begins with a ?.

mail commands include:

d ex_message_number...
Delete a message.
e ex_message_number
Edit a message.
m ex_address...
Send a new message.
n
Display the next message in the queue.
q
Quit mail.
r ex_message_number...
Reply to all recipients.
R ex_message_number...
Reply to the message sender.
t ex_message_number...
Read a message.
u ex_message_number...
Undelete a message.
mail ex_address...
Send mail from the current user account to ex_address.
mailq
List the current user's mail queue (Postfix).
# newaliases
Update the /etc/aliases.db file (Postfix).
# sendmail -bi
Update the /etc/aliases.db file (Sendmail).
The /etc/aliases.db database file is created from /etc/aliases. /etc/aliases.db is what the Mail Delivery Agent (MDA) searches.
sendmail -bp
List the current user's mail queue (Sendmail).

Documentation

You can find more information on the commands discussed above by examining the Linux User's Manual, either at the command line or online.

Enjoyed this post?

Subscribe to the feed for the latest updates.