Postfix (with smtp.gmail.com as relayhost)
Most of us forget that postfix not only acts like a mail-server, but it can act like a smtp-client (like thunderbird, evolution).
This post is all about configuring postfix to work as mail-server for my local domain (drunkenmonk.org) at the same time forward any outside domain mails to smtp.google.com with my gmail account credentials. If you are curious about drunkenmonk.org, read my previous articles about dnsmasq and virtual home network. These two articles will explain how I setup my home network.
First things first, lets install postfix (Well I’m using sabayon)
$ sudo equo install mail-mta/postfix
BASIC MAIL SERVER
Postfix configuration is pretty simple and straight forward. You have to configure following parameters inside /etc/postfix/main.cf
mydomain = drunkenmonk.org myorigin = $mydomain inet_interfaces = all mydestination = localhost, localhost.$mydomain, $myhostname, $mydomain, mail.$mydomain mynetworks_style = subnet
‘mydomain’ tells postfix that it should serve as mail server for ‘drunkenmonk.org’ domain.
‘myorigin’ tells that postfix should append ‘drunkenmonk.org’ to any incoming mail’s address if the address don’t have domain part. Which means, when you do ‘mail someuser’ from commandline, postfix will append ‘drunkenmonk.org’ so that To address will become ‘email@example.com’.
‘inet_interfaces’ tells postfix to listen on all network interfaces.
‘mydestination’ tells postfix that it should be the final destination for ‘localhost’, ‘localhost.drunkenmonk.org’, ‘mokka.drunkenmonk.org’, ‘drunkenmonk.org’ and ‘mail.drunkenmonk.org’
‘mynetworks_style’ tells postfix that my local network is a ‘subnet’ type.
Thats all needed for postfix to get start. We can restart postfix with this configurations to send/receive mails between local users. However we want a little bit more from postfix. Lets configure it to use STARTTLS for its communication with its clients
BASIC MAIL SERVER WITH STARTTLS
If you wonder what is STARTTLS, its a simple method to establish communication in a secure way. Your server application (like Postfix listening on port 25) says “Hey client I have TLS support, If you want, we can communicate each other in TLS secure way within port 25 itself, If you don’t want, we can continue with plain-text, what you say?”, then your client (like Evolution or Thunderbird) will tell “OOh!! you offer TLS, then lets do TLS!!”. So the packets going between server and client will be encrypted using TLS.
Before STARTTLS, people used different port for secure smtp which is smtps(port 465). But nowadays it is changing, the regular smtp port itself been used for both plain-text and SSL/TLS communication.
We have to configure Postfix to talk in SSL/TLS way, for that we need Self Signed SSL certificate. Lets create one,
$ cd /etc/ssl/postfix $ sudo mkdir oldcerts $ sudo mv * oldcerts $ sudo openssl genrsa -out server.key.password -des3 1024 Generating RSA private key, 1024 bit long modulus .............................++++++ ..........................++++++ e is 65537 (0x10001) Enter pass phrase for server.key.password: Verifying - Enter pass phrase for server.key.password: $
Here you have to give a ‘pass phrase’ to generate RSA private key, but having a key with ‘pass phrase’ is asking for trouble. You have to manually type this password everytime postfix access this key. The following command will remove ‘pass phrase’ from a RSA key
$ sudo openssl rsa -in server.key.password -out server.key Enter pass phrase for server.key.password: writing RSA key $
Now you have a RSA private key file server.key without ‘pass phrase’. Its time to create certificate request,
$ sudo openssl req -out server.csr -new -key server.key You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:IN State or Province Name (full name) [Some-State]:TamilNadu Locality Name (eg, city) :Chennai Organization Name (eg, company) [Internet Widgits Pty Ltd]:DrunkenMonk Pvt Ltd Organizational Unit Name (eg, section) : Pattasarayam Generating Unit Common Name (e.g. server FQDN or YOUR name) :MokkaPandi Email Address :firstname.lastname@example.org Please enter the following 'extra' attributes to be sent with your certificate request A challenge password : An optional company name :
Don’t give any password when creating certificate request. Finally create a self signed ssl certificate using following command,
$ sudo openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt Signature ok subject=/C=IN/ST=TamilNadu/L=Chennai/O=DrunkenMonk Pvt Ltd/OU= Pattasarayam Generating Unit/CN=MokkaPandi/emailAddressemail@example.com Getting Private key $
Ok, thats it. You will have two files, one is /etc/ssl/postfix/server.crt and another is /etc/ssl/postfix/server.key, Now configure postfix to use these two for SSL/TLS communication, Add the following lines at the end of /etc/postfix/main.cf
# TLS Support smtpd_tls_cert_file = /etc/ssl/postfix/server.crt smtpd_tls_key_file = /etc/ssl/postfix/server.key smtpd_tls_security_level = may
Finally, start postfix
$ sudo eselect rc restart postfix
Check if postfix can operate with STARTTLS,
$ sudo openssl s_client -connect localhost:25 -starttls smtp
Above command will show the server certificate and all SSL stuffs. After this, whatever you send will be encrypted, now check if it can send mail,
250 DSN EHLO drunkenmonk.org 250-mokka.drunkenmonk.org 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN mail from: firstname.lastname@example.org 250 2.1.0 Ok rcpt to: email@example.com 250 2.1.5 Ok data 354 End data with . Subject: test mail test mail . 250 2.0.0 Ok: queued as E0E352C0091 quit 221 2.0.0 Bye closed $
Now see if root got a test mail
$ sudo mail >N 8 root@drunkenmonk Tue Aug 7 16:50 14/533 test mail &p From firstname.lastname@example.org Tue Aug 7 16:50:23 2012 X-Original-To: email@example.com Subject: test mail Date: Tue, 7 Aug 2012 16:49:48 +0530 (IST) From: firstname.lastname@example.org test mail &q $
We are not done yet. There is one more part. Lets make postfix to forward mails to gmail.
Till now, postfix can send/receive mails within drunkenmonk.org domain. But if someone from your subnet want to send a mail to a person who have mail address outside drunkenmonk.org domain (let say email@example.com), then your current postfix will try to contact mail server of yahoo.com. But, yahoo’s mail server will reject your mail because drunkenmonk.org is not a vaild registered domain.
But, If you have a gmail account, you can forward the mail first to smtp.gmail.com with your account credentials so that gmail will send your mail to firstname.lastname@example.org with your gmail account credentials. The person who owns email@example.com will receive a mail with from address as yours irrespective of whoever send within your local network.
To make postfix to know your credentials, we need to create a credential db with gmail account credentials, For that we need to add following line at the end of /etc/postfix/saslpass file
# run following command to generate hash password db # that can be used inside postfix's main.cf # # command: # postmap hash:saslpass # # #file content format: #remotehost username:password smtp.gmail.com foouser:barpassword
Now run the following command to create saslpass.db
$ cd /etc/postfix $ sudo postmap hash:saslpass
Now you can see saslpass.db created as a Berkeley DB file. We can now use this file inside main.cf to inform postfix about your gmail account credential. Before doing that, please remove /etc/postfix/saslpass file or change its access to 0600 for root. Because your credentials are in plaintext. We need to add following lines at the end of main.cf
# gmail smtp_sasl_auth_enable = yes smtp_sasl_password_maps = hash:/etc/postfix/saslpass smtp_sasl_security_options = noanonymous smtp_tls_security_level = encrypt smtp_tls_mandatory_ciphers = high smtp_tls_verify_cert_match = hostname, nexthop, dot-nexthop relayhost = smtp.gmail.com:587
Here ‘hash:/etc/postfix/saslpass’ actually makes postfix to access /etc/postfix/saslpass.db file. You can remove /etc/postfix/saslpass which have your gmail password as plaintext. It will not affect postfix and postfix doesn’t need it.
Thats it, we are done. Once you restart postfix, It becomes capable of sending mail to outside world but with your gmail account’s credentials. Thanks for reading all the way down to this line. Have a nice day!!