Getting Postfix to Relay Through Gmail

3 February 2011
I have a home server running Fedora that I use as a media host. It's connected to my home LAN and is mainly used for playing songs from my MP3 collection or streaming music from Pandora. It's not a complex machine, but I like to be able to get reports from it in case something goes wrong. I have a Gmail account that I use to collect these sort of reports. Unfortunately my ISP blocks outbound port 25 connections so I can't use a traditional setup to e-mail myself using a local mail transport like Postfix (or Sendmail for that matter). Gmail, and other mail providers, do accept e-mail on the alternate port 587 but in order to utilize it safely you have to set up Gmail as a mail relay and Transport Layer Security (TLS) in order to protect your password (Gmail requires authentication for sending e-mail). I had Postfix already set up on my home machine, but configuring Postfix to use Gmail as a mail relay, and producing the right SSL certificates and keys was a real pain. In order to do all of this I had to create my own certificate signing authority (CA), generate my own certificate signing request (CSR) and finally my sign the request to create my own key. All of this is rather arcane, but uses the open source OpenSSL libraries. In order to do all of this you have to make sure openssl is installed on your system. The first steps are creating directories for your own CA so you can keep things separate. Needless to say you need to be root to do all of this. I crated the pki_madirish directory to complement the legitimate repository in /etc/pki like so:
# mkdir /etc/pki_madirish
Next change into that new directory so you can contain all your work.
# cd /etc/pki_madirish/
Once in this directory you have to create several sub directories and files so that the later steps will work. First create /etc/pki_madirish/myCA and then copy the regulary openssl configuration file in to that directory so it can be modified:
# mkdir /etc/pki_madirish/myCA

# mkdir /etc/pki_madirish/myCA/private

# mkdir /etc/pki_madirish/myCA/certs

# mkdir /etc/pki_madirish/myCA/newcerts

# cp /etc/pki/tls/openssl.cnf /etc/pki_madirish/myCA/openssl.my.cnf

# touch /etc/pki_madirish/myCA/index.txt

# echo '01' < /etc/pki_madirish/myCA/serial

# cd /etc/pki_madirish/myCA/
Now that the infrastructure is all set up you have to create your CA certificate and key:
# openssl req -config openssl.my.cnf -new -x509 -extensions v3_ca -keyout private/myca.key -out certs/myca.crt -days 1825
Once this is done you should alter the permissions on the new key:
# chmod 0400 private/myca.key 
Next you need to alter the configuration file so it points to the right directories:
# vi openssl.my.cnf 
Change the lines so they point to the right places:
[ CA_default ]

dir             = /etc/pki_madirish/myCA                # Where everything is kept
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file.
#unique_subject = no                    # Set to 'no' to allow creation of
                                        # several ctificates with same subject.
new_certs_dir   = $dir/newcerts         # default place for new certs.

certificate     = $dir/certs/myca.crt   # The CA certificate
serial          = $dir/serial           # The current serial number
crlnumber       = $dir/crlnumber        # the current crl number
                                        # must be commented out to leave a V1 CRL
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/private/myca.key # The private key
Next creat the new certificate signing request (CSR):
# openssl req -config openssl.my.cnf -new -nodes -keyout private/server.key -out server.csr -days 365
And change permissions on the the private key that results
# chmod 0400 /etc/pki_madirish/myCA/private/server.key 
Next you need to sign the CSR to create the new server certificate (server.crt):
# openssl ca -config openssl.my.cnf -policy policy_anything -out certs/server.crt -infiles server.csr
Finally you can remove the certificate signing request:
 
# rm server.csr 
Now all that is left to do is to modify the Postfix main.cf file (found at /etc/postfix/main.cf). Add the following lines to the end:
# Added to get outbound e-mail to work
# by Justin 2/3/11
relayhost = [smtp.gmail.com]:587

#auth
smtp_sasl_auth_enable=yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

#tls
smtp_use_tls = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous
smtp_tls_note_starttls_offer = yes
tls_random_source = dev:/dev/urandom
smtp_tls_scert_verifydepth = 5
smtp_tls_key_file=/etc/pki_madirish/myCA/private/server.key
smtp_tls_cert_file=/etc/pki_madirish/myCA/certs/server.crt
smtpd_tls_auth_only = no
smtpd_tls_ask_ccert = yes
smtpd_tls_req_ccert = no
smtp_tls_enforce_peername = no
Now you have to create the password file at /etc/postfix/sasl_passwd. Use an editor to create this file and add the single line:
smtp.gmail.com username@gmail.com:password
To the file. Change the 'username' and 'password' strings to the appropriate value for your account. Be sure to remove global read permissions from this file (and the sasl_passwd.db file that is generated using the below commands). Run the commands to create the Postfix database and restart Postfix:
# postmap /etc/postfix/sasl_passwd 

# /etc/init.d/postfix restart
Now you should be able to send mail through the Gmail relay.