© David Both 2020
D. BothUsing and Administering Linux: Volume 3https://doi.org/10.1007/978-1-4842-5485-1_7

7. Introducing Email

David Both1 
(1)
Raleigh, NC, USA
 

Objectives

In this chapter you will learn
  • How email clients and servers function to transmit email from one user to another

  • How to install and configure SendMail to act as a mail transfer agent (MTA)

  • To configure the firewall for email

  • To configure name services to accommodate email with an MX record

  • How to test email using a command line email client

  • To use email headers to trace the origin and route of an email

  • To configure a host to use the email server as a smart host

  • To configure the aliases file to forward system level email intended for root to another email address like the student user

Introduction

Email is a ubiquitous messaging service and is available on devices ranging from work and home desktop computers to various mobile devices such as smart phones and tablets. There are two sides to email. The IMAP and POP protocols are used to receive email on your device and the SMTP protocol is used to send email from your device to and between email servers.

Email is an asynchronous messaging protocol at the macro level. That is, if I send you an email message, you do not have to be at the receiving computer at that moment in order to receive the message. The computer does not even need to be turned on. The message is stored at the server until the computer is turned on and you retrieve it.

A typical synchronous messaging system is a face-to-face conversation or a telephone call which requires both parties to the conversation to be on the line or in the same place at the same time. Voicemail is just a corrupted version of a telephone call in which we leave messages for each other – another form of asynchronous messaging.

Email services were originally limited to users on a local Unix computer. All users of an email system had to be connected via a hardware terminal to the Unix computer. Because computers were not normally connected in any way, email systems were very localized. As slow dial-up connections became available, remote computers could be connected but only for specified and relatively short periods of time. Email messages could be stored on the sending server until the connection was made and all messages intended for the remote email server would be sent using that temporary connection. Email bound for other remote servers were held on the local server until a connection to the destination remote server was made. It is these ancient requirements that helped to define many of today’s email protocols such as the ability to store messages for a period of time until the remote server is available.

Today we can send email to almost anyone on the planet, but spam is a major issue. With so many people connected to the same Internet that allows us to communicate with email, there are also those who use email for scamming the rest of us. We will discuss dealing with spam in Chapter 9 of this volume.

Definitions

Let’s define a few terms before going any further.
  • Protocol – A set of formal rules describing how to transmit data, especially across a network.

  • SMTP – Simple Mail Transfer Protocol: A protocol used to transfer electronic mail between computers.

  • POP – Post Office Protocol: A simple protocol designed to allow single user computers to retrieve electronic mail from a POP server. Once retrieved by the client, the email is deleted from the server.

  • IMAP – Internet Message Access Protocol: A protocol allowing a client to access and manipulate electronic mail messages on a server. Emails are retained on the server until explicitly deleted by the user.

  • MTA – Mail Transfer Agent: An agent such as Sendmail that transfers email from one host to another. These transfers may not only be between email servers but also from a sending email client to an email server.

  • SendMail – A very common MTA that has been around for many years.

Email data flow

Figure 7-1 is a simplified diagram of the flow of an email message from the sending client to the receiving client. Note that the sending client uses SMTP as the protocol to send the outbound email to the local email server. Let’s track the progress of an email through this diagram.
  1. 1.

    The client adds an initial set of headers to the email to be sent. This includes the subject line, a date stamp, and the From: and To: lines.

     
  2. 2.

    The sending client uses SMTP to send the email to the local email (SMTP) server, SMTP server1, as defined in the client configuration. So, for clients in the domain example.com, their email would typically go to an email server for example.com. One common method is to identify that server as mail.example.com in the internal name services (DNS) database.

     
  3. 3.

    SMTP Server1 receives the email and adds a Received: line to the headers that lists where the email came from with IP address and host name if possible, along with a timestamp. The header entry also indicates the addressee.

     
  4. 4.

    SMTP Server1 parses the address(es) to which the email is destined.

     
  5. 5.

    SMTP Server1 uses DNS to specifically request the MX (Mail eXchanger) record for the target domain.

     
  6. 6.

    SMTP Server1 then sends the email to the receiving server, SMTP Server2, through the Internet.

     
  7. 7.

    SMTP Server2 adds another Received: line to the headers.

     
  8. 8.

    SMTP Server2 holds the email in the user’s inbox until the client connects to the server to retrieve the email. Using the relatively more common and newer IMAP protocol on the receiving client, the user can view the email on SMTP Server2.

     
Emails remain in the inbox which is located in /var/spool/email/<username> until they are moved to another email folder or deleted. The email remains on the server until it is deleted regardless of which folder it is in.
../images/473483_1_En_7_Chapter/473483_1_En_7_Fig1_HTML.png
Figure 7-1

The flow of data for email messages

Structure of an email

The primary structure of an email message has two parts as defined in RFC 822, the headers and the message body. The headers are separated from the message body by a single blank line.

The message body can contain ASCII plain text or MIME1 components consisting of HTML messages, images, or other types. The text body content of an email message is limited to 7-bit ASCII which is why MIME is used to attach data types based on 8-bit data.

Email headers

The email headers provide a record of the email's travels and can help us identify their true source. Each MTA adds one or more lines to the headers to record the email's passage. The email headers are normally hidden from users by the email clients, but a SysAdmin can access them to use in the task of problem determination for email delivery issues. I refer to email headers frequently for various types of problems including spam source identification, to determine where an email may have been delayed in its transit across the Internet from sender to receiver, and to use as the basis for blocking spam.

Figure 7-2 shows the headers from a test email I sent to myself from a network for which I am the SysAdmin. This email was sent from the remote host, host1, using the following command. We will use mailx commands like this to test our own email server later in this chapter.
[root@host1 ~]# echo "This is a test email" | mailx -s "Test email" [email protected]
I have hacked some of the host names and external IP addresses in Figure 7-2 to obscure their true identities.
../images/473483_1_En_7_Chapter/473483_1_En_7_Fig2_HTML.png
Figure 7-2

Typical email headers

Let’s examine these headers from bottom to top as that is the order in which they will make the most sense.
X-Spam-Score: -40.5 () ALL_TRUSTED,USER_IN_WHITELIST
X-Spam-Status: No, score=-28.2 required=10.6 tests=BAYES_50,RDNS_DYNAMIC,USER_IN_WHITELIST
X-Spam-Status: No, score=-40.5 required=10.9 tests=ALL_TRUSTED,USER_IN_WHITELIST
X-Scanned-By: MIMEDefang 2.84 on 192.168.0.52
X-Scanned-By: MIMEDefang 2.84 on 192.168.0.75
This series of headers were all added by MIMEdefang and SpamAssassin, the anti-spam software we will explore in Chapter 9. There are two sets of entries because the email was scanned by the outbound server and the inbound server. Email should be scanned before it is sent in order to ensure that we are not spamming others from our mail server or via an internal email client that uses our outbound mail server.
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
These two lines define the basic content type in our message. In this case, it is simple plain text, 7-bit ASCII which was the original encoding for email when it was first developed. This is the simplest form of encoding for email messages and requires no special processing like that needed for special forms like various MIME types.
Content-Type: multipart/mixed; boundary="----------=_1560989912-23914-8"
Although this line does not appear in our headers, you will see a header like this if there are multiple MIME parts in the body. The long number at the end is a boundary identifier to specify the beginning and ending of a MIME part.
MIME-Version: 1.0

This line is an indicator that the body of the email is ASCII plain text, or that there is a non-text attachment. It can also mean that the message body has multiple parts, that is, more than one type such as text and image.

This header can also mean that some other header information might be in a non-ASCII text character set. This can occur when spammers try to obfuscate the subject line in order to circumvent anti-spam filters. A typical sample of this is shown here.
Subject: =?utf-8?B?V2hpdGXCoEtpZG5lecKgQmVhbnPCoEJsb2NrwqBDYXJicw==?=
By specifying the character set utf-8 at the beginning of the subject line, the client can use that set to generate the ASCII text version of the subject so that you can read whatever nastiness they are peddling.
User-Agent: Heirloom mailx 12.5 7/5/10
The user agent is the sending email client. In this case, it is the mailx command I used to send the email. You might also see something like this which is for Thunderbird or other Mozilla-based email clients.
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101
Subject: Test email
This is the subject line. It can contain almost anything. I have seen some users that are new to email manage to place their entire message in the subject line. I have also seen this field to be blank. This is normally a few words describing the subject of the email.
This is, quite obviously, the email account to which this email is addressed.
Date: Wed, 26 Jun 2019 03:54:35 -0400
This header specifies the date and time the email was sent as well as the time zone offset. In this case -0400 means GMT -4 hours or EDT.
Message-Id: <[email protected]>

Every message has an ID, and this is the ID for the message from which our headers were extracted. This message ID was generated after the sending software, Fail2Ban, sent it to the local email MTA on the local host.

Each message has a different ID one every server through which it travels. This is to prevent the possibility of having a message sent from one server having the same ID as a message sent from another server. These message IDs are stored in the headers as a permanent record which enables us to locate log entries pertaining to the message in each server.

The first part of the message ID is a date and time in YYYYMMDDNNNN where NNNN is a sequence number. Many email servers are so busy that many emails can arrive at exactly the same time. The second part of the ID is the assigned ID. Message ID formats may vary between email servers that use different operating systems, but that is OK so long as we have the IDs in the headers to work with.
From: root <[email protected]>

This line identifies the sending host of the email. This, like many of the other headers, can be spoofed so that it looks like it came from another email account entirely. We will explore that later in this chapter. But for this example, we can be sure that none of the headers have been tampered with.

This line is added by the mailx email client which now sends the email to the MTA on the local host.
Received: (from root@localhost)
      by host1.example.net (8.14.7/8.14.7/Submit) id x5Q7sZZ3032629
      for [email protected]; Wed, 26 Jun 2019 03:54:35 -0400

This header tells us that the email MTA on host1 received the email from the localhost. It might sound confusing, but so far we are still working on host1, which originated the email message. Each MTA that the email passes through always adds its own received header.

The fact that this was received from root@localhost indicates that the mailx email program sent this email to the MTA.
Received: from host1.example.net (localhost [127.0.0.1])
      by host1.example.net (8.14.7/8.14.7) with ESMTP id x5Q7sZxO032630
      for <[email protected]>; Wed, 26 Jun 2019 03:54:35 -0400
This received header was also added by host1. It indicates that the email has passed into the mail queue and that it has a new ID. At this point, host1 sends the email to the mail server in its own domain, example.net.
Received: from host1.example.net (host1.example.net [192.168.0.1])
      by mailserver.example.net (8.14.7/8.14.4) with ESMTP id x5Q7sZgN028979
      for <[email protected]>; Wed, 26 Jun 2019 03:54:35 -0400

This, the third received header, shows that the email was received by the email server for the example.net domain.

Note that there is no time difference within the 1 second granularity of these headers between the original date stamp placed on the email and this header. All of these time stamps so far place the date and time at Wed, 26 Jun 2019 03:54:35 -0400. So far the email has been processed on two computers.

Now the mail server for the example.com domain sends the email to the destination domain, my own both.org.
Received: from mailserver.example.net (rrcs-96-10-0-10.se.biz.rr.com [96.10.0.10])
      by yorktown.both.org (8.15.2/8.15.2) with ESMTP id x5Q7sZwg006558
      for <[email protected]>; Wed, 26 Jun 2019 03:54:38 -0400

The email has now been received by my email server, yorktown.both.org. We now notice a 3-second time difference since the previous header. This is due to two factors: the time required to process the email through the spam detection software on the mailserver.example.net system and the time needed to connect with my server and to perform the handshaking and data transfer. Almost all of this time is due to the spam filtering.

Different email servers use somewhat different formats for some of the headers and they also may insert headers in different places in the stream. As we proceed through this chapter and these next chapters that also relate closely to email, I suggest that you take time to view the headers of the emails we send as part of the experiments.

SendMail on the server

Sendmail is a common email transfer agent. It has been around since 1983 and is still widely used on many email servers. There are a number of other good MTAs available, many of which are open source. Understanding SendMail – at least what we will be able to do here in this course – will provide a good basis for understanding email and mail transfer agents in general.

Although I use SendMail for my domain email server, it is also useful on a host that is not being used as the primary email server for a domain. Sendmail can be used on any host to provide an MTA to deal with emails sent to root by various system level applications and servers. If not sent to an email server, the local emails will be sent to the root user on the local host. Thus, they may never be read and acted upon. SendMail is required for each host that is intended to send its system management emails to a central mail server for further relay and distribution. When a network of hosts is configured to send all emails to the email server for the domain, that email server is called a smart host.

In the experiments below, we will install and configure SendMail as the primary mail server for our domain on StudentVM2 and we will install it on StudentVM1 to act as a transfer agent which can forward emails to the domain email server on StudentVM2. From there, these emails can be sent to any email client account.

Sendmail installation

Let’s start by installing SendMail on both of our virtual machines.

Experiment 7-1

Perform this experiment as the root user on both VMs. We will install the sendmail and sendmail-cf packages on both of our virtual machines in this experiment.

StudentVM1 may already have SendMail installed. Even so, the sendmail-cf RPM must also be installed. The sendmail-cf package provides the makefiles2 and configuration files that allow configuration and recompilation of sendmail.mc and other SendMail configuration files and databases.

We also install mailx, an email client that can be used as a text mode email client and as a command in a pipeline to send a data stream from its STDIN to the local mail transfer agent. This is a good tool for use to send emails in scripts. We can also use it from the command line to easily send test email.

Do this on both VMs.
# dnf -y install sendmail sendmail-cf mailx

This does not require a reboot.

SendMail configuration

Sendmail is already well configured by Red Hat in its distributions including Fedora. SendMail does still need a bit of additional configuration and it needs to be configured just a bit differently for the domain email server than for a system that will only send emails to the smart host.

It is only necessary to make some minor changes to the SendMail configuration itself.

Experiment 7-2

Perform this experiment as root on StudentVM2. We will make StudentVM1 into the domain mail server by configuring SendMail. For the moment, we will concentrate on sending email from our server although this first change is for inbound email.

Use a text editor to make the changes to the configuration files.

In order to receive email from any remote computer on your virtual network, you will need to comment out the following line in /etc/mail/sendmail.mc. This line forces SendMail to listen for email only on the internal lo localhost interface. We want SendMail to listen on the external interface, emnp0s8, as well.
DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl
Prepend “dnl” to the above line in order to “comment it out.” SendMail will now listen for inbound emails on all network interfaces.
dnl DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

In the M4 language used in sendmail.mc, dnl means “delete through newline,” which further translates into something meaningful as “ignore the rest of this line.” It is an instruction for the specialized compiler used by SendMail.

Add the following lines to the /etc/mail/local-host-names file. This will tell SendMail to accept email addressed to this domain as well as the specified hosts which are all aliases for the mail server.
example.com
studentvm2.example.com
mail.example.com
Add the following line to the access database file, /etc/mail/access. This allows hosts on the 192.168.56.0/24 network to relay email through this mail server. By limiting the IP addresses to those of our network, spammers are unable to use our mail server to relay spam for them. Without this limitation, we would be running an “open relay” and the IP address of our server would be blocked by many legitimate email systems.
192.168.56             RELAY
Now, with /etc/mail as the PWD, run the make command. The make command runs the instructions required to convert the various text configuration files we have modified into the database files in the proper formats needed by SendMail.
# make

Verify that the timestamps for the *.db files that correspond to the altered files have been changed.

In a separate terminal session as the root user, tail the /var/log/maillog file. This will inform us of any SendMail activity including startup information and any errors that might occur. This terminal session should be placed somewhere it can be seen on the desktop while you work in the other session to make changes and start and stop SendMail.
[root@studentvm2 ~]# cd /var/log/ ; tail -f maillog
Start SendMail, enable it to restart on boot, and verify the results.
 # systemctl start sendmail
That took a long time. Too long in fact. Figuring this one out was pretty easy because you should find some error messages in the maillog file like I did.
Jun 27 11:56:36 studentvm2 sendmail[6078]: My unqualified host name (studentvm2) unknown; sleeping for retry

This error occurs because we set the virtual machines’s host name without using the fully qualified domain name (FQDN).

What?! You did not think I would divulge all of my secrets at once, did you? I learned a lot about configuring SendMail from the many mistakes I made while doing so the first several times I did it. It took me hours to work my way through some of these problems even using search engines. So my intent here is to give you a feel for SendMail, not just what we need to do but also the why of it.

So let’s set the system’s hostname, and this time we will include the FQDN.
[root@studentvm2 mail]# hostnamectl
   Static hostname: studentvm2
         Icon name: computer-vm
           Chassis: vm
        Machine ID: b62e5e58cdf74e0e967b39bc94328d81
           Boot ID: 7ae8d2bbbfaf44a6b1dd8082321d2f81
    Virtualization: oracle
  Operating System: Fedora 29 (Twenty Nine)
       CPE OS Name: cpe:/o:fedoraproject:fedora:29
            Kernel: Linux 5.1.9-200.fc29.x86_64
      Architecture: x86-64
[root@studentvm2 mail]# hostnamectl set-hostname studentvm2.example.com
[root@studentvm2 mail]# hostnamectl
   Static hostname: studentvm2.example.com
<snip>

Also check the /etc/hostname file which is where the hostname is stored. We could have changed the host name in that file but activating it would require a reboot. Using the hostnamectl command does all of that for us.

Now restart SendMail.
# systemctl restart sendmail

You should notice immediately that the command only took a very short time. You should also see an informational message on the screen following the maillog but no errors.

It is time to test our server. Let’s first test from StudentVM2 in order to verify that it is working because we have not yet fixed the firewall to let other hosts send email through this server. We will use the mailx command to test for us. As the student user on StuidentVM2, enter the following command. The -s option of the mailx command sets the subject text – in double quotes – of the email.
[student@studentvm2 ~]$ echo "Hello world" | mailx -s "Test mail 1 from StudentVM2" [email protected]

You should also see four log entries added to the maillog file. The last one should have a status of Sent.

Let’s use the mailx command in its role as an interactive email client to view our email. In another session as the student user, start mailx. You may have some emails in this student account but probably not.
[student@studentvm2 ~]$ mailx
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/student": 1 message 1 new
>N  1 Student User          Thu Jun 27 12:34  21/895   "Test mail 1 from StudentVM2"
&
The ampersand (&) is the command prompt for the mailx email client interface. Just hit the Enter key to start looking at the email messages starting with the first one.
& <Enter>
Message  1:
From [email protected]  Thu Jun 27 12:34:50 2019
Return-Path: <[email protected]>
From: Student User <[email protected]>
Date: Thu, 27 Jun 2019 12:34:48 -0400
Subject: Test mail 1 from StudentVM2
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
Status: RO
Hello world
&

Do not delete this email. That worked and you could use q<Enter> to quit from mailx, but let’s just leave it open because we will be using it a bit more.

Notice that there are very few headers because the message was delivered by the email server on the local host, StudentVM2. It is time to send an email message to the outside world. For this, you will need an external email account that you can access from wherever you are taking this course. A computer, mobile phone, or tablet that you have configured to access your real-world email account would work. If you do not have one of these, you will be able to determine the success of sending these emails from the maillog. This is what SysAdmins and especially email administrators need to do in real life anyway.

As the student user on StudentVM2, do the following. Substitute your own external email instead of mine. Remember, these commands are all on a single line unless otherwise noted.
[student@studentvm2 ~]$ echo "Hello world" | mailx -s "Test mail 2 from StudentVM2" [email protected]
But don’t be fooled by the last line of the latest set of log entries. It does say “Sent” but check the To: address. Read through this list of log entries and see if you can figure out what happened before continuing below my sample log entries. I have separated the outbound log entries from the inbound ones with an empty line to make it a bit easier.
Jun 27 13:02:17 studentvm2 sendmail[6565]: x5RH2HBh006565: from=student, size=245, class=0, nrcpts=1, msgid=<[email protected]>, relay=student@localhost
Jun 27 13:02:18 studentvm2 sendmail[6565]: STARTTLS=client, relay=[127.0.0.1], version=TLSv1.3, verify=FAIL, cipher=TLS_AES_256_GCM_SHA384, bits=256/256
Jun 27 13:02:18 studentvm2 sendmail[6572]: STARTTLS=server, relay=localhost [127.0.0.1], version=TLSv1.3, verify=NOT, cipher=TLS_AES_256_GCM_SHA384, bits=256/256
Jun 27 13:02:18 studentvm2 sendmail[6572]: x5RH2IT4006572: from=<[email protected]>, size=524, class=0, nrcpts=1, msgid=<[email protected]>, proto=ESMTPS, daemon=MTA, relay=localhost [127.0.0.1]
Jun 27 13:02:19 studentvm2 sendmail[6565]: x5RH2HBh006565: [email protected], ctladdr=student (1000/1000), delay=00:00:02, xdelay=00:00:01, mailer=relay, pri=30245, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (x5RH2IT4006572 Message accepted for delivery)
Jun 27 13:02:19 studentvm2 sendmail[6574]: x5RH2IT4006572: to=<[email protected]>, ctladdr=<[email protected]> (1000/1000), delay=00:00:01, xdelay=00:00:00, mailer=esmtp, pri=120524, relay=mail.both.org. [24.199.159.59], dsn=5.1.8, stat=User unknown
Jun 27 13:02:19 studentvm2 sendmail[6574]: x5RH2IT4006572: x5RH2JT3006574: DSN: User unknown
Jun 27 13:02:20 studentvm2 sendmail[6574]: x5RH2JT3006574: to=<[email protected]>, delay=00:00:01, xdelay=00:00:00, mailer=local, pri=31843, dsn=2.0.0, stat=Sent

So, did you figure it out? It took me a long time at first, so let me explain it. The first set of five log entries from Jun 27 13:02:17 through Jun 27 13:02:19 are from the outbound interaction with the remote email server. In my case, this was the email server for the both.org domain. The last log entry for this series shows that the message was accepted by the remote server.

However, starting almost immediately, the next set of log entries shows that the mail server for both.org has sent us a notification via the connection that we initiated to send the mail in the first place, that the user is unknown. The final line is the indication that our email server sent an email to the sender indicating that this was the case.

As the student user in the already open mailx session, press h to refresh and view the headers of any new emails. You should see a new entry, message number 2. Type 2 and view the new message.
& h
    1 Student User          Thu Jun 27 12:34  22/906   "Test mail 1 from StudentVM2"
>   2 Mail Delivery Subsys  Thu Jun 27 13:11  73/2862  "Returned mail: see transcript fo"
& 2
Message  2:
From [email protected]  Thu Jun 27 13:11:29 2019
Return-Path: <[email protected]>
Date: Thu, 27 Jun 2019 13:11:28 -0400
From: Mail Delivery Subsystem <[email protected]>
Content-Type: multipart/report; report-type=delivery-status;
   boundary="x5RHBSk3006610.1561655488/studentvm2.example.com"
Subject: Returned mail: see transcript for details
Auto-Submitted: auto-generated (failure)
Status: RO
Part 1:
The original message was received at Thu, 27 Jun 2019 13:11:27 -0400
from localhost [127.0.0.1]
   ----- The following addresses had permanent fatal errors -----
    (reason: 553 5.1.8 <[email protected]>... Domain of sender address [email protected] does not exist)
   ----- Transcript of session follows -----
... while talking to mail.both.org.:
>>> DATA
<<< 553 5.1.8 <[email protected]>... Domain of sender address [email protected] does not exist
550 5.1.1 <[email protected]>... User unknown
<<< 503 5.0.0 Need RCPT (recipient)
Part 2:
Content-Type: message/delivery-status
Part 3:
Content-Type: message/rfc822
From [email protected] Thu Jun 27 13:11:27 2019
Return-Path: <[email protected]>
From: Student User <[email protected]>
Date: Thu, 27 Jun 2019 13:11:25 -0400
Subject: Test mail 2 from StudentVM2
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
Hello world
&

Note the 553 message that says, “Domain of sender address [email protected] does not exist).” Do you see the problem now? The domain for this email is not really a domain; it is a host name studentvm2.example.com. It includes the domain name. I ran into this problem, too, the first couple times I set up an email server. It is an unintended side effect of specifying the hostname of our server with the FQDN.

The reason for this failure is that the Internet name servers, not the ones in our own network, do not have any domains named <hostname>.example.com. They do have example.com. The remote mail server, in my case, mail.both.org, checks to see that DNS has an IP address for the domain name in the From: header of the email message. If studentvm2.example.com does not exist, the mail server rejects the email.

However, we do have some good news. Our server is definitely talking to the remote server or we would not be getting this type of error message. The other good news is that this, too, is easily correctable. Down near the bottom of the sendmail.cf file there are three lines we need to change so that SendMail will change the domain from host.example.com to just example.com. Change the highlighted lines:
dnl # The following example makes mail from this host and any additional
dnl # specified domains appear to be sent from mydomain.com
dnl #
dnl MASQUERADE_AS(`mydomain.com')dnl
dnl #
dnl # masquerade not just the headers, but the envelope as well
dnl #
dnl FEATURE(masquerade_envelope)dnl
dnl #
dnl # masquerade not just @mydomainalias.com, but @∗.mydomainalias.com as well
dnl #
dnl FEATURE(masquerade_entire_domain)dnl
To this:
dnl # The following example makes mail from this host and any additional
dnl # specified domains appear to be sent from mydomain.com
dnl #
MASQUERADE_AS(`example.com')dnl
dnl #
dnl # masquerade not just the headers, but the envelope as well
dnl #
FEATURE(masquerade_envelope)dnl
dnl #
dnl # masquerade not just @mydomainalias.com, but @∗.mydomainalias.com as well
dnl #
FEATURE(masquerade_entire_domain)dnl

These lines now masquerade hostnames like studentvm1.example.com and studentvm2.example.com to a true, two-part domain name, example.com.

With /etc/mail as the PWD, make and restart SendMail.
# make ; systemctl restart sendmail

Now send the email to your real-world email account. The log should show a successful delivery with no entries to indicate a return error message. Check your external email account to verify the successful receipt of the test email.

This is the source of the email as viewed on my real mail client.
Received: from studentvm2.example.com (wally1.both.org [192.168.0.254])
    by yorktown.both.org (8.15.2/8.15.2) with ESMTP id x5RKTGa1030600
    for <[email protected]>; Thu, 27 Jun 2019 16:29:16 -0400
Received: from studentvm2.example.com (localhost [127.0.0.1])
    by studentvm2.example.com (8.15.2/8.15.2) with ESMTPS id x5RKTFBw007324
    (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT)
    for <[email protected]>; Thu, 27 Jun 2019 16:29:15 -0400
Received: (from student@localhost)
    by studentvm2.example.com (8.15.2/8.15.2/Submit) id x5RKTE1h007323
    for [email protected]; Thu, 27 Jun 2019 16:29:14 -0400
From: Student User <[email protected]>
Message-Id: <[email protected]>
Date: Thu, 27 Jun 2019 16:29:14 -0400
Subject: Test mail 3 from StudentVM2
User-Agent: Heirloom mailx 12.5 7/5/10
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-Spam-Status: No, score=-0.5 required=10.6 tests=ALL_TRUSTED,BAYES_50
X-Scanned-By: MIMEDefang 2.84 on 192.168.0.52
Hello world
Now enable sendmail to restart on boot, and verify the results.
 # systemctl enable sendmail ; systemctl status sendmail

Our email server is now capable of sending emails to external, real-world mail servers so long as the email originates from a local account.

Firewall and DNS configuration

Now that our email server can send emails, we need it to also receive emails. Let us start with using it as a “smart host” so that it accepts email from other hosts on our network and can pass them on to the external world. We also want to set up a CNAME record for mail.example.com and a Mail eXchanger (MX) record that explicitly defines the mail server for a domain no matter its given hostname.

Experiment 7-3

Perform this Experiment as root on StudentVM2. We will configure both DNS and the firewall.

Let’s start with DNS. Edit the DNS forward lookup database file, /var/named/example.com.zone. Edit this file and add the following lines to it. You can add them at the bottom of the file, or wherever your own organizational desires decide, so long as they are placed after the Origin line. Be sure to change the serial number to the current date and time using the format YYYYMMDDHHMMSS, where SS is a sequence number and not seconds.
mail                    IN      CNAME   studentvm2
example.org.            IN      MX      10      mail.example.org.
My file looks like this after making these changes as shown highlighted in bold.
; Authoritative data for example.com zone
;
$TTL 1D
@   IN SOA  studentvm2.example.com   root.studentvm2.example.com. (
                                        2019062701      ; serial
                                        1D              ; refresh
                                        1H              ; retry
                                        1W              ; expire
                                        3H )            ; minimum
$ORIGIN         example.com.
example.com.            IN      NS      studentvm2.example.com.
router                  IN      A       192.168.56.1
studentvm2              IN      A       192.168.56.1
server                  IN      CNAME   studentvm2
mail                    IN      CNAME   studentvm2
studentvm1              IN      A       192.168.56.21
workstation1            IN      CNAME   studentvm1
ws1                     IN      CNAME   studentvm1
wkst1                   IN      CNAME   ws1
studentvm3              IN      A       192.168.56.22
studentvm4              IN      A       192.168.56.23
testvm1                 IN      A       192.168.56.50
; Mail server MX record
example.org.            IN      MX      10      mail.example.org.
Restart name services.
# systemctl restart named
We need to add a rule to the firewall to allow access on port 25, SMTP. Edit /etc/sysconfig/iptables and add the highlighted line to the existing filter table.
∗nat
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 192.168.56.0/24 -j MASQUERADE
COMMIT
∗filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i enp0s8 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
Make /etc/sysconfig the PWD, load the new rule set, and verify the new rule is active.
# iptables-restore iptables ; iptables-save

The email server is now ready to accept emails from hosts inside our virtual network.

SendMail on the client

Now we can configure SendMail on the StudentVM1 client host. We already installed it in Experiment 7-1.

Experiment 7-4

Perform this experiment starting as root on StudentVM1. We will configure this host to use StudentVM2, the domain mail server, as the smart host. Start by using the FQDN for the hostname.
# hostnamectl set-hostname studentvm1.example.com
Edit /etc/mail/sendmail.mc and change the following line:
dnl define(`SMART_HOST', `smtp.your.provider')dnl
To:
define(`SMART_HOST', `mail.example.com')dnl
We also need to set up email domain masquerading on StudentVM1 as we did on StudentVM2. Near the bottom of the sendmail.cf file, there are the three lines we need to change so that SendMail will change the domain from host.example.com to just example.com. Change the highlighted lines:
dnl # The following example makes mail from this host and any additional
dnl # specified domains appear to be sent from mydomain.com
dnl #
dnl MASQUERADE_AS(`mydomain.com')dnl
dnl #
dnl # masquerade not just the headers, but the envelope as well
dnl #
dnl FEATURE(masquerade_envelope)dnl
dnl #
dnl # masquerade not just @mydomainalias.com, but @∗.mydomainalias.com as well
dnl #
dnl FEATURE(masquerade_entire_domain)dnl
To this:
dnl # The following example makes mail from this host and any additional
dnl # specified domains appear to be sent from mydomain.com
dnl #
MASQUERADE_AS(`example.com')dnl
dnl #
dnl # masquerade not just the headers, but the envelope as well
dnl #
FEATURE(masquerade_envelope)dnl
dnl #
dnl # masquerade not just @mydomainalias.com, but @∗.mydomainalias.com as well
dnl #
FEATURE(masquerade_entire_domain)dnl
With /etc/mail as the PWD, make and restart SendMail.
# make ; systemctl restart sendmail
Enable SendMail it to start on boot, and check its status to ensure that it started correctly.
# systemctl enable sendmail ; systemctl status sendmail

Now let’s test our configuration. On StudentVM1, open a terminal window as root and use it to tail -f /var/log/maillog. Do the same thing on StudentVM2. On StudentVM1, enter the following command and watch the log files. You may see some log entries indicating deliveries of LogWatch notifications to [email protected]. This is normal and I had about 30 days’ worth.

As root on StudentVM1, enter the following to send an email.
# echo "Hello world from StudentVM1" | mailx -s "Test email 1" [email protected]

You should first see some log messages on StudentVM1 indicating that its own instance of SendMail has received the message and various steps in processing it. A moment or so later, you should also see some messages in the log for StudentVM2 indicating it has received the email and is processing it.

Now, as the student user on StudentVM2, use mailx to view the email. It should look something like this:
From [email protected]  Sat Jun 29 09:06:35 2019
Return-Path: <[email protected]>
From: Student User <[email protected]>
Date: Sat, 29 Jun 2019 09:06:30 -0400
Subject: Test email 1
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
Status: RO
Hello world from StudentVM1

We now know that our email server is working and that it is being used as the smart host by StudentVM1. Let’s send our message a bit further afield. This time we send the email to an external email account.

Keep following the log files on both hosts. On StudentVM1, send the following message. Please use your own external email account rather than mine, which I use for illustrative purposes.
# echo "Hello world from StudentVM1" | mailx -s "Test email 3 from StudentVM1" [email protected]
Here is the source of the message I received on my own email system.
Received: from studentvm2.example.com (wally1.both.org [192.168.0.254])
    by yorktown.both.org (8.15.2/8.15.2) with ESMTP id x5TDa0Ru011406
    for <[email protected]>; Sat, 29 Jun 2019 09:36:00 -0400
Received: from studentvm1.example.com ([192.168.56.21])
    by studentvm2.example.com (8.15.2/8.15.2) with ESMTPS id x5TDa0B9004335
    (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT)
    for <[email protected]>; Sat, 29 Jun 2019 09:36:00 -0400
Received: from studentvm1.example.com (localhost [127.0.0.1])
    by studentvm1.example.com (8.15.2/8.15.2) with ESMTPS id x5TDZxp8011175
    (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT)
    for <[email protected]>; Sat, 29 Jun 2019 09:35:59 -0400
Received: (from root@localhost)
    by studentvm1.example.com (8.15.2/8.15.2/Submit) id x5TDZw6c011174
    for [email protected]; Sat, 29 Jun 2019 09:35:58 -0400
From: Student User <[email protected]>
Message-Id: <[email protected]>
Date: Sat, 29 Jun 2019 09:35:58 -0400
Subject: Test email 3 from StudentVM1
User-Agent: Heirloom mailx 12.5 7/5/10
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-Spam-Status: No, score=-26.2 required=10.6 tests=BAYES_50,RDNS_NONE,USER_IN_WHITELIST
X-Scanned-By: MIMEDefang 2.84 on 192.168.0.52
Hello world from StudentVM1

Trace the route of the email through the various hosts using the headers and the mail logs on the virtual hosts.

We now have a working email system with a server and a simple client. Note that with the setup we currently have, the student user needs to login to the StudentVM2 host to retrieve email using mailx. We will discuss email clients and the server requirements to support them in more detail in Chapter 8 of this volume.

SMTP – The protocol

SMTP – Simple Mail Transfer Protocol – is an ASCII plain text conversation used to transfer email between servers and from a sending email client to a server and is defined in RFC821. SMTP uses TCP port 25. The SMTP protocol is well defined in the Internet RFCs so it is an open standard. SMTP servers are known as mail transfer agents (MTAs) because their function is to transfer email messages between one another.

Let’s watch this conversation.

Experiment 7-5

As the student user on StudentVM1, send an email using the -v option of the mailx command. The SMTP protocol commands are shown with preceding >>> characters. These lines are highlighted to enhance their visibility. The responses from the mail server are not highlighted and begin with message ID numbers.

We send the email from the terminal session.
[student@studentvm1 ~]$ echo "This is a test email." | mailx -v -s "Test email from StudentVM1" [email protected]
The mailx session connects to the MTA on the local host which responds with the 220 message.
[email protected]... Connecting to [127.0.0.1] via relay...
220 studentvm1.example.com ESMTP Sendmail 8.15.2/8.15.2; Sat, 29 Jun 2019 12:38:30 -0400
The MTA on StudentVM1 sends this line which is “hello – I am studentvm1.example.com.” The mail server on StudentVM2 responds with its side of the greeting and a list of features it supports.
>>> EHLO studentvm1.example.com
250-studentvm1.example.com Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH GSSAPI DIGEST-MD5 CRAM-MD5
250-STARTTLS
250-DELIVERBY
250 HELP
The local MTA has determined that TLS is supported and tells the remote MTA to start the TLS handshaking. TLS is an encryption protocol that is configured and enabled by default in current releases of Fedora and other Linux distributions. TLS ensures that the connection between the two MTAs is encrypted and that the data can be sent between them without being read by a casual observer to the conversation.
>>> STARTTLS
220 2.0.0 Ready to start TLS
We restart the conversation now that TLS is active.
>>> EHLO studentvm1.example.com
250-studentvm1.example.com Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH GSSAPI DIGEST-MD5 CRAM-MD5
250-DELIVERBY
250 HELP
The local MTA tells the remote MTA who the mail is from and a bit about it. The remote MTA responds by saying that the sender is OK. That means the sending domain has not been blocked by the remote MTA.
>>> MAIL From:<[email protected]> SIZE=253 [email protected]
250 2.1.0 <[email protected]>... Sender ok
The local MTA tells the remote MTA who the email is addressed to.
>>> RCPT To:<[email protected]>
We tell the remote MTA that we are ready to send the data which consists of the body of the email. The remote MTA returns a message that implies the recipient of the email has a valid mailbox on the server and that it is not full or otherwise blocked. It also sends a response of 354 which indicates that the local MTA can begin sending the body of the email.
>>> DATA
250 2.1.5 <[email protected]>... Recipient ok
354 Enter mail, end with "." on a line by itself
Sending the dot (.) on a line by itself to the remote MTA indicates that this is the end of the email. The remote MTA returns the message ID that it has assigned to the email and that the message was accepted by the remote MTA. It also indicates it is ready to close the connection from its end.
>>> .
250 2.0.0 x5TGcUtk013404 Message accepted for delivery
[email protected]... Sent (x5TGcUtk013404 Message accepted for delivery)
Closing connection to [127.0.0.1]
The local MTA sends QUIT to close the connection. The local MTA responds with a message to indicate that it is closing the connection.
>>> QUIT
221 2.0.0 studentvm1.example.com closing connection
SMTP return messages3 fall into the following categories shown in Figure 7-3.
../images/473483_1_En_7_Chapter/473483_1_En_7_Fig3_HTML.png
Figure 7-3

The SMTP return code classifications

Sometimes these messages, especially when they are error codes, are embedded in a returned email rejection. Other times the only way to see them is to use a tool like mailx and to observe the conversation for yourself.

Email-only accounts

Although the student user is a valid user in our experimental environment, it is a login account. Email servers need to be secure so that the owners of email accounts are unable to actually log in to the server. This is accomplished by creating nologin accounts for email-only users.

Experiment 7-6

As the root user on the server, StudentVM1, add an account with the username of email1 that can only be used as an email account. The -s option is used to specify the special nologin shell.
[root@studentvm2 ~]# useradd -c "Email only account" -s /sbin/nologin email1
[root@studentvm2 ~]# passwd email1
Changing password for user email1.
New password: <Enter the password>
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: <Enter the password again>
passwd: all authentication tokens updated successfully.

Create a password for this account. The password is used when an email client attempts to retrieve email from this account while the nologin shell prevents a login as a Linux user. Test to verify that you cannot login with this new account by attempting to do so as the user email1 using a virtual console.

As the user student, still on StudentVM1, send an email to the user email1.
[student@studentvm1 ~]$ echo "Test email to email1 email only account." | mailx -v -s "Test email" [email protected]
You cannot login as user email1 so you must retrieve this email with mailx a bit differently. Because root can do anything, you will have to issue the following command as root. You would get an error if you tried to do it as a non-root user.
[root@studentvm2 ~]# mailx -u email1
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/mail/email1": 1 message 1 new
>N  1 Student User          Sat Jun 29 21:10  25/1128  "Test email"
& 1
Message  1:
From [email protected]  Sat Jun 29 21:10:57 2019
Return-Path: <[email protected]>
From: Student User <[email protected]>
Date: Sat, 29 Jun 2019 21:10:51 -0400
Subject: Test email
User-Agent: Heirloom mailx 12.5 7/5/10
Content-Type: text/plain; charset=us-ascii
Status: R
Test email to email1 email only account.
&

Who gets email for root?

Many system level services can send email to root@localhost to notify the root user of the completion of an at job, for example, the daily LogWatch report, and more, depending upon the specific tools and their configuration. These emails can get missed and ignored on many hosts that the SysAdmin does not login to frequently. Even with only a few hosts to login to each day, I found it a chore to do so just to check root’s emails.

I found an easy way to fix that now that our internal StudentVM1 host can use StudentVM2 as a smart host. I use the /etc/aliases file to send the email to my personal email address.

The /etc/aliases file contains aliases for the system users that defines who gets email sent to them. Many system services have user accounts associated and some of those services send email notifications to root or to another user. Web sites also have nonspecific email accounts such as [email protected] or [email protected]. So if someone sends an email to [email protected], the aliases file tells SendMail to route that email to root. This email ends up in root's local mailbox on the local host. If that is not what you want, and it usually is not, we need to change the /etc/aliases file.

I like to get email that is addressed to root sent to me at one of my regular email accounts so that I will be sure to get it. This allows me to keep track of notifications that might indicate a problem of some sort.

Experiment 7-7

Start this experiment as the root user on StudentVM1. We will change a few things to send notifications intended for root to the student user instead.

First, copy the current version of the /etc/aliases file to /tmp for a short-term backup. Then open /etc/aliases with a text editor. Study the entries and notice that some like the ftp entry send emails to root, while further down, four other entries, ftpadm, ftpadmin, ftp-adm, and ftp-admin, all redirect email to ftp.

Down at the bottom of the file is a line that is commented out. It is an example of how to forward root’s email to another user.
#root:          marc
Below that, place the following line and save the file.
root:          [email protected]
Now run the newaliases command without any options or arguments to activate your changes.
[root@studentvm1 etc]# newaliases
/etc/aliases: 77 aliases, longest 19 bytes, 794 bytes total
As root on StudentVM1, send a test email to ftp without the FQDN. Verify that the email has been delivered to the user student on StudentVM1.
[root@studentvm1 etc]# echo "Test of /etc/aliases" | mailx -v -s "Test email for aliases" ftp

Now make the same change to the aliases file on StudentVM2 and test it with emails sent to root or one of the other aliases like ftp.

By making this one change in the aliases file, I do not need to change the default email address in many different services.

Things to remember

There are some things to remember about email.

It is not instant

One of the most common misconceptions that end users have about email is that it is instant. It is not. Email may get held up at one of the MTAs for various reasons. Heavy traffic can delay emails and anything marked as bulk in one of the headers will be placed at the bottom of the queue and only sent when all emails with higher precedence have been sent. Any email without a precedence header is considered to be normal. Bulk email is sent from listservs and may have many addressees at any one domain.

I had one situation when working in a government organization where a PHB tried to ream me out and threatened me with some sort of disciplinary action because an email he sent did not get to the people in his building immediately upon being sent. The email he sent was to warn of an imminent tornado which was, in fact, bearing down on that part of the city at the time. But the email was sent to a list, and between being bulk mail as well as having hundreds of recipients in an email system that received more than 20,000,000 (yes 20 million) emails per day, it took some time to process the delivery of all those emails.

And, as we have mentioned before, one must be sitting at their computer with the email client up and running and watching for new emails to come in for this asynchronous communication system to be effective. Email is just not an appropriate communication method for that type of imminent danger.

There is no delivery guarantee

Another problem is the misconception that email will always get delivered. It won’t. Many email systems drop emails that don’t conform to their anti-spam or bulk mail policies. They may reject emails for many reasons and there is nothing that we on the sending end can do about it. Sure, we can call or email the designated contact for the domain, but in most cases, they ignore this type of complaint.

Emails also get dropped when routers become overburdened and start dropping packets. In this case, the sending server may try to send the email again, but there is still no guarantee of its ultimate delivery.

Chapter summary

In this chapter, we have learned to use SendMail as an SMTP mail transfer agent. We have configured SendMail to be our mail server as well as to forward internal emails from our own network hosts to the mail server as a smart host. We have used the mailx email client on both hosts to retrieve and send emails. We have also added an MX record and a supporting record to our DNS server and added a rule to the firewall on the server to allow incoming SMTP packets on port 25.

Although we cannot receive email from the outside world on our email server, be assured that it would work. Once it can receive email from internal network hosts, and with configuration of SendMail to listen on the appropriate external network interface, we would also be able to receive emails from outside domains.

There is more to be done to make this into a fully functioning email system, but we are well on the way.

Exercises

Perform these exercises to complete this chapter:
  1. 1.

    Where are emails located in your inbox stored? Be specific with the host and the complete directory path.

     
  2. 2.

    Why do we need to masquerade the email sending addresses?

     
  3. 3.

    What TCP port does SMTP use?

     
  4. 4.

    Why does email on our virtual network get sent to our own instance of example.com and not to the outside world instance?

     
  5. 5.

    When sending email to an alias like www on StudentVM1, what is the To: address when the email arrives in the student email account on StudentVM2?

     
  6. 6.

    How does an email only account differ from a regular Linux user account?

     
  7. 7.

    What other things can you think of that we need to do to make our email server more functional and more secure?

     
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.161.251