The motivation to configure sendmail as a client for Simple Mail Transfer Protocol with SSL (SMTPS) came about when I switched ISP's and the new service required authentication as well as the use of port 465 to submit an email for delivery. In my case the ISP was AT&T U-verse powered by Yahoo! Mail. The old ISP permitted the use of port 25 as long as your IP address was part of their network, whereas the new service blocks that port to outgoing traffic. Setting up SMTPS is fairly easy to do using a client like Evolution, however, it is not quite as straightforward to configure sendmail to do the job. The reason why I needed sendmail was to allow my home server to send email using the PHP mail function from a web page. One of the uses of this server is as a platform for website development and testing. I will also show how it is possible to receive email on your home server using a dynamic dns provider.
When researching this topic I found a number of helpful sources on the internet. One of the problems though is that they didn't have all the pieces or something was a little off. Two very helpful sources where:
- Qiao Yang's Blog - Sendmail + AUTH +SSL tunnel -> ATT Yahoo! and AT&T Yahoo Email Address Verification and Sendmail
- SMTP AUTH in sendmail 8.10-8.13
Install and configure stunnel
The initial step to setting up the SSL connection on port 465 is to configure and run
stunnel. Stunnel provides a socket wrapper for ordinary programs to use SSL. Begin by installing stunnel as root using yum.
su -c "yum install stunnel"
Once installed, the easiest way to configure stunnel is to change to the directory /etc/stunnel and edit the file stunnel.conf. This is the default configuration file for stunnel. The contents of my configuration file is as follows:
client = yes foreground = no fips = no [smtps] accept=127.0.0.1:10025 connect=smtp.att.yahoo.com:smtps
The first two lines tell it we are running as a client in the background. The third line disables FIPS (Federal Information Processing Standards) which is on by default in stunnel. An error occured when stunnel started on my system unless FIPS was disabled. Line 5 begins the service name smtps. It will accept connections with the localhost on port 10025 and then connect to the ISP mail server smtp.att.yahoo.com on port 465. You can choose a port other than 10025 as long as it is an unused port and you use the same port when it comes time to configure the outgoing port in sendmail. Once installed and configured you can start stunnel by simply typing stunnel at the command line. Remember to run stunnel as root.
Begin by installing the sendmail-cf package. This package is needed to reconfigure and rebuild your sendmail.cf file. Install sendmail-cf as root using yum.
su -c "yum install sendmail-cf"
Create authinfo File
To allow sendmail to act as a client you will need to set up an authinfo file in /etc/mail. The authinfo file allows sendmail to login and authenticate with your ISP's SMTP server by passing it your username and password. Since the file contains your username and password it needs to be secure. As root it will be created with a user:group of root:root and privileges of -rw-r----- which should be sufficient.
The file /etc/mail/authinfo is a standard text file. My file contains the following:
AuthInfo:localhost.localdomain "U:root" "I:firstname.lastname@example.org" "P:password" "M:LOGIN PLAIN"
I had a few challenges getting this to work and will explain the entries as I understand them. After AuthInfo: is the name of the relay host. In this case, your server is relaying the login information using stunnel to smtp.att.yahoo.com port 465. That is why localhost.localdomain is used rather than going directly to smtp.att.yahoo.com. After U: is the user (authorization) id, root seems to work for me. The I: is the authentication id, the username on your ISP. P: password is self explanatory and M: tells sendmail to send this info in plain text format.
The last step with the authinfo file is to run makemap to make it available to sendmail.
makemap hash authinfo < authinfo
This command will create a file called authinfo.db.
The configuration file sendmail.cf is generated with m4 using macros contained in sendmail.mc. These configuration files are not very intuitive and I always create a backup of whatever is in place before making any changes.
cp sendmail.cf sendmail.cf.bkp
cp sendmail.mc sendmail.mc.bkp
Now we want to make a few changes in sendmail.mc so that it will relay messages to localhost.localdomain via port 10025 (remember to be consistent with how you configured stunnel if you changed the port). Add the following lines to your sendmail.mc after the line dnl define(
RELAY_MAILER_ARGS',TCP $h 10025')dnl
ESMTP_MAILER_ARGS',TCP $h 10025')dnl
The first line tells sendmail to use localhost.localdomain as the relay host. The next two tell it to use port 10025 and the last instructs it to use the authinfo feature.
Another change I made is to allow sendmail to receive mail from the internet and not just locally. We will need this later on for email address verification. This is accomplished by changing the line
dnl DAEMON_OPTIONS(Port=smtp,Addr=127.0.0.1, Name=MTA')dnl
Here is how my diff -u sendmail.mc.bkp sendmail.mc turned out.
diff -u sendmail.mc.bkp sendmail.mc --- sendmail.mc.bkp 2012-06-25 11:27:11.000000000 -0400 +++ sendmail.mc 2013-01-01 22:04:22.248132159 -0500 @@ -23,7 +23,10 @@ dnl # Uncomment and edit the following line if your outgoing mail needs to dnl # be sent out through an external mail server: dnl # -dnl define(`SMART_HOST', `smtp.your.provider')dnl +define(`SMART_HOST', `[localhost.localdomain]')dnl +define(`RELAY_MAILER_ARGS', `TCP $h 10025')dnl +define(`ESMTP_MAILER_ARGS', `TCP $h 10025')dnl +FEATURE(`authinfo', `hash /etc/mail/authinfo.db')dnl dnl # define(`confDEF_USER_ID', ``8:12'')dnl dnl define(`confAUTO_REBUILD')dnl @@ -72,8 +75,6 @@ dnl define(`confQUEUE_LA', `12')dnl dnl define(`confREFUSE_LA', `18')dnl define(`confTO_IDENT', `0')dnl -dnl # If you're operating in a DSCP/RFC-4594 environment with QoS -dnl define(`confINET_QOS', `AF11')dnl dnl FEATURE(delay_checks)dnl FEATURE(`no_default_msa', `dnl')dnl FEATURE(`smrsh', `/usr/sbin/smrsh')dnl @@ -115,7 +116,7 @@ dnl # 127.0.0.1 and not on any other network devices. Remove the loopback dnl # address restriction to accept email from the internet or intranet. dnl # -DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl +dnl DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl dnl # dnl # The following causes sendmail to additionally listen to port 587 for dnl # mail from MUAs that authenticate. Roaming users who can't reach their
The final step is to rebuild the sendmail configuration file using m4.
m4 sendmail.mc > /etc/mail/sendmail.cf
In order to receive messages from the internet it is necessary to open port 25. I won't go into the details of doing this here except to say that with iptables you will need to add a rule to accept incoming connections on port 25. This can be done on the command line or through system-config-firewall. With firewalld you will need to add either a persistent or direct rule with the command firewall-cmd. With iptables you will need to restart for the new rules to take effect. If you use firewalld persistant changes require a restart, but direct changes are immediate. No changes to the firewall are necessary for port 10025 since it is outgoing.
We are opening port 25 mainly for address verification. AT&T Yahoo! Mail for example will not allow us to send messages from an address different from my account unless it is a valid email address. Another way around this is to masquerade the sender's address as explained in Qiao Yang's Blog AT&T Yahoo Email Address Verification and Sendmail.
To receive messages via the internet on my home server I decided to establish an account with a Dynamic DNS service. The service provides a hostname and if the IP address changes the hostname will continue to be linked to the new IP address. This service also comes in handy if I need to access my home server from the internet for other reasons. For example, as a webserver or connecting to it via vpn. An internet search will provide a list of many free services to choose from. I am using noip.com for my dynamic dns service.
Email address verification on ISP
From the beginning of this page my main goal was to send messages using the php mail function via my webserver. While you can change the From: email address with the php mail function the user originating the message is apache because the server is running apache as the webserver. Therefore to send messages from another host via the ISP I need to verify the address email@example.com as a valid email address.
Instructions for adding and verifying an email address with AT&T Yahoo! Mail
- Log in to att.net and go to your email inbox.
- Select the gear icon in the upper-right corner of the page, and then select Settings.
- Select Accounts in the left sidebar.
- Select the Add button.
- Enter a description of the email account in the Description field (i.e. Server) and the account email address (ie. firstname.lastname@example.org) in Email Address.
- Remove the Reply-to address
- Select Save. A verification email will be sent your non-AT&T email account.
- Select the link within the email to verify this email address. You will now able to send and receive messages for this email address using your AT&T email account.
When the verification email gets delivered to your home server it will be directed to the root account since apache is an alias for root in /etc/aliases. Read the email and follow the instructions. Once completed you should be able to send an email from that address.
If you want to send email from other accounts they can be setup and verified the same way. The only difference would be that the verification email gets sent to that users account rather than root unless of course it has an alias. On my computer I setup my regular user to allow me to test the sendmail and stunnel configuration more easily.
Left To Do
- Double check security for any holes
- Look at the possibility of using submission Port 587