How to check MX records

First you can check that the declaration is correct, using dig:

# dig foobar.com MX

; <<>> DiG 9.7.3 <<>> foobar.com MX
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32034
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;foobar.com.                    IN      MX

;; ANSWER SECTION:
foobar.com.             14400   IN      MX      0 foobar.com.

;; ADDITIONAL SECTION:
foobar.com.             14400   IN      A       69.89.31.56

;; Query time: 198 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri Jun 23 18:56:51 2017
;; MSG SIZE  rcvd: 60

Next you can use an online tool, like mxtoolbox to check others requirements and make sure the server's IP isn't already included into a commonly use blacklist.

Fix EHLO for multi-front platform

First verify that the VIP used for outgoing traffic has a correct reverse DNS record:

host 195.54.62.XX

Fix it if necessary. Next, change the /etc/mailname on every VM. Value should be strictly identical to the reverse.

Last step, indicate to every MTA’s VM to use a custom EHLO value instead of the hostname. For exim simple create a file /etc/exim4/exim4.conf.localmacros with the following content:

REMOTE_SMTP_HELO_DATA=<reverse_value>

Mailx command examples

mailx is an evolution of the original mail command line utility for sending and receiving mail. It a very useful tool to test mail setup.

How the mail command works

The mail command invokes the “standard” sendmail command which in turns connects to the local MTA (mail transfert agent). In most modern distribution the sendmail binary isn’t used anymore, and it’s just a symbolic link to the MTA.

The local MTA (exim, postfix, etc..) run an SMTP server that accept connection on the port TCP 25.

Install the mail command

On Debian three packages provide the mailx command. I suggest you to install the heirloom-mailx package, because this version has more features and options.

Sending mails

You can use mailx interactively. You can hit enter for new lines, and when done typing the message press Ctrl+D and mailx would display an EOT:

$ mail -s "This is the subject" someone@foobar.com
I'm batman!
EOT

1. Body content from a file

The message body of the email can be taken from a file:

$ mail -s "This is Subject" someone@foobar.com < /path/to/file

The message can also be piped:

$ echo "This is message body" | mail -s "This is Subject" someone@foobar.com

2. Multiple recipients

To send the mail to multiple recipients, specify all the emails separated by a comma:

$ echo "This is message body" | mail -s "This is Subject" someone@foobar.com,someone2@foobar.com

3. CC and BCC

The -c and -b options can be used to add CC and BCC addresses respectively:

$ echo "This is message body" | mail -s "This is Subject" -c user@foobar.com someone@foobar.com

4. Specify From name and address

To specify a “FROM” name and address, use the -r option:

$ echo "This is message body" | mail -s "This is Subject" -r "ThePope<thepope@vactican.com>" someone@foobar.com

5. Specify “Reply-To” address

The reply to address is set with the internal option variable “replyto” using the -S option:

$ echo "This is message" | mail -s "Testing replyto" -S replyto="batman@foobar.com" someone@foobar.com

6. Attachments

Attachments can be added with the -a option:

$ echo "This is message body" | mail -s "This is Subject" -r "ThePope<thepope@vactican.com>" -a /path/to/file someone@foobar.com

Sending email using telnet

Every admin knows as to use telnet to test remote port connectivity. But did you know that you can use this command in more ‘creative’ manners ?

For example to send mail in a fully manual mode:

# telnet localhost smtp
Connected to localhost.
Escape character is '^]'.
220 sd-35049.dedibox.fr ESMTP Exim 4.72 Mon, 16 Jan 2012 12:56:06 +0100
HELO sd-35049.dedibox.fr
250 sd-35049.dedibox.fr Hello localhost [::1]
mail from: megamind@secretbase.com
250 OK
rcpt to: foobar@yopmail.com
250 Accepted
data
354 Enter message, ending with "." on a line by itself
Hey genius buddy
This is a test!
.
250 OK id=1cT5uM-0001oK-Dm
quit
221 sd-35049.dedibox.fr closing connection
Connection closed by foreign host.

[Exim] Smarthost configuration

Let say we already have a functional SMTP server that is responsible for routing all mail for a given domain. Now we add a new server into this network that must be able to send its own emails, for example for administrative purposes (alerts, crontab, logs, emails generated by the applications, etc …). This new MTA doesn’t have to manage mail for users.

The clean way to do this is to configure our exim daemon to send mail via the “official” SMTP server. For this, just modify the /etc/exim4/update-exim4.conf.conf file like this:

dc_eximconfig_configtype='satellite'
dc_other_hostnames=''
dc_local_interfaces='127.0.0.1 ; ::1'
dc_readhost='mydebian.mydomain.com'
dc_relay_domains=''
dc_minimaldns='false'
dc_relay_nets=''
dc_smarthost='myrelay.mydomain.com::25'
CFILEMODE='644'
dc_use_split_config='false'
dc_hide_mailname='true'
dc_mailname_in_oh='true'
dc_localdelivery='mail_spool'

Now the host mydebian.mydomain.com can send emails using myrelay.mydomain.com‘s MTA.

[Exim] cheatsheet

This post is a partial copy of this article.

—————————————————————————————————————

Message-IDs and spool files

The message-IDs that Exim uses to refer to messages in its queue are mixed-case alpha-numeric, and take the form of: XXXXXX-YYYYYY-ZZ. Most commands related to managing the queue and logging use these message-ids. There are three files for each message in the spool directory. If you’re dealing with these files by hand, instead of using the appropriate exim commands as detailed below, make sure you get them all and don’t leave Exim with remnants of messages in the queue.

Files in /var/spool/exim/msglog contain logging information for each message and are named the same as the message-id. Files in /var/spool/exim/input are named after the message-id, plus a suffix denoting whether it is the envelope header (-H) or message data (-D). These directories may contain further hashed subdirectories to deal with larger mail queues.

Basic information

Print a count of the messages in the queue:

# exim -bpc

Print a listing of the messages in the queue (time queued, size, message-id, sender, recipient):

# exim -bp

Print a summary of messages in the queue (count, volume, oldest, newest, domain, and totals):

# exim -bp | exiqsumm

Print what Exim is doing right now:

# exiwhat

Test how exim will route a given address:

# exim -bt alias@localdomain.com

Run a pretend SMTP transaction for a given IP:

# exim -bh 192.168.11.22

This will display Exim’s checks, ACLs, and filters as they are applied. The message will NOT actually be delivered.

Display all of Exim’s configuration settings:

# exim -bP

Searching the queue with exiqgrep

For messages from a specific sender:

# exiqgrep -f [luser]@domain

For messages for a specific recipient/domain:

# exiqgrep -r [luser]@domain

Print messages older than than 1 day:

# exiqgrep -o 86400 [...]

For messages less than an hour old:

# exiqgrep -y 3600 [...]

There are also a few flags that control the display of the output. Use -i to print just the message-id. Use -c to print a count of messages matching the condition.

Managing the queue

Remove a message from the queue:

# exim -Mrm <message-id>

Freeze a message:

# exim -Mf <message-id>

Thaw a message:

# exim -Mt <message-id>

Deliver a message, whether it’s frozen or not, whether the retry time has been reached or not:

# exim -M <message-id>

Deliver a message, but only if the retry time has been reached:

# exim -Mc <message-id>

Remove all frozen messages:

# exiqgrep -z -i | xargs exim -Mrm

Remove all messages older than five days (86400 * 5 = 432000 seconds):

# exiqgrep -o 432000 -i | xargs exim -Mrm

Freeze all queued mail from a given sender:

# exiqgrep -i -f luser@example.tld | xargs exim -Mf

View a message’s headers:

# exim -Mvh <message-id>

View a message’s body:

# exim -Mvb <message-id>

View a message’s logs:

# exim -Mvl <message-id>

[Exim] Block all outgoing mails except for specific domains

The common practice on preproduction environment, is to block all outgoing mails except for a given whitelist domain. To do that in exim you must modify the router section.

Edit your exim4.conf.template just after the “begin routers” line, add the following snippet:

catch_otherdomains:
        driver = redirect
        domains = !foobar.com:!example.fr
        data = :blackhole: