The problem I’m facing is that emails from my Debian box are not sent outside of my local network. Glad I found the solution, and here is how to go about it. This solution applies to the following issues
- Setting up a smarthost to send emails using an authenticated SMTP server (like Gmail, AOL & Yahoo!)
- You have a *nix box and want to backup status emails to be sent to an external (outside your LAN) email address.
Assumptions:
- I am using the box standard binaries of my preferred distribution (Debian 6.0)
- You have the necessary SSL certificates in place. Most distributions’ installers would have created all the necessary SSL certificates during the first boot of your OS.
Debian/Ubuntu package Exim4 as the default MTA (Mail Transfer Agent), since I’m not a full-time administrator, I prefer a quick, easy, understandable, & secure solution and found Postfix as a quick win. First thing to do is to uninstall Exim4 and install Postfix. Below is one way to go about it using apt.
# i have used --purge to remove any configurations that exim4 came with.
# if you are not sure, drop --purge from the command.
$ sudo apt-get remove --purge exim4 exim4-base exim4-config exim4-daemon-light`
# installing postfix
$ sudo apt-get install postfix
During the installation of Postfix, you will be asked a series of questions.
Mark them as below
Please select the mail server configuration type that best meets your needs.
- Internet with smarthost
The “mail name” is the domain name used to “qualify” ALL mail addresses without a domain name.
- hostname of your machine with FQDN (Fully Qualified Domain Name)
Please specify a domain, host, host:port, [address] or [address]:port. Use the form [destination] to turn off MX lookups.
- your SMTP service provider (like smtp.gmail.com:587)
Mail for the ‘postmaster’, ‘root’, and other system accounts needs to be redirected to the user account of the actual system administrator.
- Leave it blank, will come back to it in a little while
Please give a comma-separated list of domains for which this machine should consider itself the final destination.
- hostname of your machine with FQDN and localhost
If synchronous updates are forced, then mail is processed more slowly.
- No
Please specify the network blocks for which this host should relay mail.
- 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 (This is the security bit I was referring to earlier; if you leave it blank, it will accept emails from everyone in your subnet, which is not always right)
Please choose whether you want to use procmail to deliver local mail.
- Yes
Please specify the limit that Postfix should place on mailbox files to prevent runaway software errors.
- This is up to you, but this setting can always be changed, so be on the safer side, leave it as default, which is “0”, meaning no limit
Please choose the character that will be used to define a local address extension.
- Choose default which is “+” or leave it blank
Internet protocols to use
- If you know what you are doing, then choose appropriately, else leave it at default, which is “ipv4”
Once installation is complete, Postfix MTA is started up automatically as a service. Stop the service as we still need to configure some vital options. To begin with, all configuration files of Postfix in Debian/Ubuntu are stored under /etc/postfix
. One file we would be most interested in is /etc/postfix/main.cf
. It’s the main configuration file for Postfix, and this is how it looks just after installation.
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# Debian specific: Specifying a filename will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no # appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no # TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.keys
mtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.
myhostname = saraswathi.om.loc
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = saraswathi.om.loc, localhost.om.loc, localhost
relayhost = smtp.gmail.com:587
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = ipv4
The next step is to configure your service provider’s SMTP credentials, which will be kept in a separate file and will be hashed. Later, you might wish to remove the plain text file for additional security. To achieve this, follow the steps below
# if the folder "sasl" doesn't exist, create it
$ cd /etc/postfix/sasl
# your smtp configuration should match exactly as it's described
# in main.cf file
$ sudo sh -c "echo 'smtp.gmail.com:587 username:password' >> passwd"
# make the file "passwd" root read/write
$ sudo chmod 600 ./passwd
# let's hash the file
$ sudo postmap hash:passwd
# you should see a second file in the folder named "passwd.db"
# to test if the file was created correctly, you can delete the normal text
# file and run this command, note it would print username:password
$ sudo postmap -q smtp.gmail.com:587 username:password
After we have added SMTP credentials, we have to configure Postfix to use those credentials to send your emails. Append /etc/postfix/main.cf
like
### BEGIN NON DEBCONF ENTRIES ###
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl/passwd
smtp_sasl_security_options = noanonymous
....
As most of the SMTP service providers use TLS security, we need to configure it in /etc/postifx/main.cf
as
...
# TLS
smtp_sasl_tls_security_options = noanonymous
smtp_use_tls = yes
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
...
Hang on, I know it’s been a long journey, we are almost there. When your server sends an email, it sends from the logged-in user. So in my case if I am logged in as “natarajmb” to box “saraswathi.om.loc” any mail that’s sent from me will be sent as “[email protected]” which is correct but, SMTP servers (outside Gmail, AOL or Yahoo!! and so on) don’t accept emails sent from other user or domain apart from the logged in SMTP user. Hence, before the mail is left by Postfix, it needs to rewrite the email headers, mostly the “From” field, to satisfy SMTP servers. Note: Most MTAs offer this functionality.
# create a file named "generic" to hold user / domain mapping
$ cd /etc/postfix
$ sudo sh -c "echo '[email protected] [email protected]' >> generic"
# hash the file
$ sudo postmap hash:generic
Now we need to configure this mapping file in the main.cf, which is done by adding the “smtp_generic_maps” property.
...
smtp_generic_maps = hash:/etc/postfix/generic
...
Last but not least, most SMTP servers block accounts if they are sending emails continuously, so to avoid any such incidents, you’d better prepare Postfix to behave by adding these lines to the main.cf
...
smtp_destination_rate_delay = 60
relay_destination_rate_delay = 60
...
We are at the end of the tunnel. Start your Postfix server and fire some emails to test. You might be interested in the following commands to do your tests.
# to send some test mails
$ mail -s "Syslog file" [email protected] < /var/log/syslog
# check mail queue
$ sudo mailq
# postfix log to troubleshoot errors
$ sudo tail -f /var/log/mail.log