{"id":316,"date":"2012-11-02T15:13:47","date_gmt":"2012-11-02T15:13:47","guid":{"rendered":"http:\/\/nicholshayes.co.uk\/blog\/?p=316"},"modified":"2015-04-10T09:01:21","modified_gmt":"2015-04-10T09:01:21","slug":"simple-local-only-mail","status":"publish","type":"post","link":"http:\/\/nicholshayes.co.uk\/blog\/?p=316","title":{"rendered":"Simple local only mail"},"content":{"rendered":"<p>I&#8217;m working on an application that needs to send notifications via email, and I want to be able to test it in the development environment. In the past, I&#8217;ve either been able to set up a small Windows mail server (<a href=\"http:\/\/www.hmailserver.com\/\">hMailServer<\/a> is great for this) or just use my standard email account. However, I&#8217;m a little restricted in my current environment, and working in a virtual machine. What I really need is a local-only mail solution that will work on my Xubuntu VM.<\/p>\n<p>In the past I&#8217;ve shied away from setting up a mail server on Linux. I failed miserably to set up sendmail in the past. Today I decided to try postfix, and found it very easy to set up a system to work the way I wanted it to.<\/p>\n<p>Being lazy, I just used the Ubuntu software centre to install postfix. The installation process popped up a config screen, and I selected the local only option. Looking at the <a href=\"http:\/\/www.postfix.org\/STANDARD_CONFIGURATION_README.html#local_network\">postfix documentation<\/a>, I came up with this configuration (etc\/postfix\/main.cf):<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><div class=\"text codecolorer\">myorigin = localhost<br \/>\n<br \/>\nsmtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)<br \/>\nbiff = no<br \/>\n<br \/>\n# appending .domain is the MUA's job.<br \/>\nappend_dot_mydomain = no<br \/>\n<br \/>\n# Uncomment the next line to generate &quot;delayed mail&quot; warnings<br \/>\n#delay_warning_time = 4h<br \/>\n<br \/>\nreadme_directory = no<br \/>\n<br \/>\n# TLS parameters<br \/>\nsmtpd_tls_cert_file=\/etc\/ssl\/certs\/ssl-cert-snakeoil.pem<br \/>\nsmtpd_tls_key_file=\/etc\/ssl\/private\/ssl-cert-snakeoil.key<br \/>\nsmtpd_use_tls=yes<br \/>\nsmtpd_tls_session_cache_database = btree:${data_directory}\/smtpd_scache<br \/>\nsmtp_tls_session_cache_database = btree:${data_directory}\/smtp_scache<br \/>\n<br \/>\n# See \/usr\/share\/doc\/postfix\/TLS_README.gz in the postfix-doc package for<br \/>\n# information on enabling SSL in the smtp client.<br \/>\n<br \/>\nmyhostname = localhost<br \/>\nalias_maps = hash:\/etc\/aliases<br \/>\nalias_database = hash:\/etc\/aliases<br \/>\nmydestination = robvm, localhost.localdomain, localhost<br \/>\nrelayhost =<br \/>\nmynetworks = 127.0.0.0\/8 [::ffff:127.0.0.0]\/104 [::1]\/128<br \/>\nmailbox_size_limit = 0<br \/>\nrecipient_delimiter = +<br \/>\ninet_interfaces = loopback-only<br \/>\ndefault_transport = error<br \/>\nrelay_transport = error<\/div><\/div>\n<p>I restarted postfix (&#8216;sudo postfix reload&#8217;) and was then able to test (see <a href=\"http:\/\/www.delouw.ch\/linux\/Postfix-Cyrus-Web-cyradm-HOWTO\/html\/test.html\">this<\/a>)<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">telnet localhost 25<br \/>\nTrying 127.0.0.1...<br \/>\nConnected to localhost.<br \/>\nEscape character is '^]'.<br \/>\n220 localhost ESMTP Postfix (Ubuntu)<br \/>\nhelo localhost<br \/>\n250 localhost<br \/>\nmail from: rob@localhost<br \/>\n250 2.1.0 Ok<br \/>\nrcpt to:rob@localhost<br \/>\n250 2.1.5 Ok<br \/>\ndata<br \/>\n354 End data with .<br \/>\nHello there<br \/>\n.<br \/>\n250 2.0.0 Ok: queued as E8B7960091C<br \/>\nquit<br \/>\n221 2.0.0 Bye<br \/>\nConnection closed by foreign host.<\/div><\/div>\n<p>That worked fine, but I wasn&#8217;t sure where the email was going. I needed a client.<\/p>\n<p>I first tried the default email client, which was Thunderbird. However, the configuration seemed to expect an internet mail server and I gave up on that idea pretty quickly.<\/p>\n<p><a href=\"http:\/\/www.claws-mail.org\/\">Claws<\/a> to the rescue. This mail client is easy to install via the software centre. The main issue was getting the basic settings right. These worked for me:<\/p>\n<div id=\"attachment_318\" style=\"width: 710px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/nicholshayes.co.uk\/blog\/wp-content\/uploads\/2012\/11\/claws_config_localhost.png\"><img aria-describedby=\"caption-attachment-318\" decoding=\"async\" loading=\"lazy\" class=\"size-full wp-image-318 \" title=\"claws_config\" src=\"http:\/\/nicholshayes.co.uk\/blog\/wp-content\/uploads\/2012\/11\/claws_config_localhost.png\" alt=\"\" width=\"700\" height=\"550\" \/><\/a><p id=\"caption-attachment-318\" class=\"wp-caption-text\">Claws mail client account preferences<\/p><\/div>\n<p>Hey presto, &#8220;get mail&#8221; retrieved the message I&#8217;d created while testing at the command line. With the configuration above, I was even able to send more messages to myself.<\/p>\n<p>Looking at this, it became obvious where the emails were being stored: \/var\/mail\/rob. A quick look there and I found a text file containing all my emails.<\/p>\n<p>Next step was to create an anonymous alias that I could use in my rails code. To do this I updated my etc\/aliases file by adding this to the end:<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">developer: rob<\/div><\/div>\n<p>At first this had no effect. I then found <a href=\"http:\/\/townx.org\/blog\/elliot\/adding_aliases_to_postfix_on_ubuntu\">this article by Elliot Smith<\/a>, which told me what I was missing:<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">sudo newaliases<\/div><\/div>\n<p>That command regenerates your alias database file. As soon as I did that, I found I was able to send emails to developer@localhost.<\/p>\n<p>Last but not least I needed to set up my rails app to work with this configuration. I added this to \/config\/environments\/development.rb:<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\">&nbsp; config.<span class=\"me1\">action_mailer<\/span>.<span class=\"me1\">smtp_settings<\/span> = <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"re3\">:address<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class=\"sy0\">=&gt;<\/span> <span class=\"st0\">&quot;localhost&quot;<\/span>,<br \/>\n&nbsp; &nbsp; <span class=\"re3\">:port<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sy0\">=&gt;<\/span> <span class=\"nu0\">25<\/span>,<br \/>\n&nbsp; &nbsp; <span class=\"re3\">:domain<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sy0\">=&gt;<\/span> <span class=\"st0\">'localhost'<\/span>,<br \/>\n&nbsp; &nbsp; <span class=\"re3\">:authentication<\/span> &nbsp; &nbsp; &nbsp; <span class=\"sy0\">=&gt;<\/span> <span class=\"st0\">'none'<\/span>,<br \/>\n&nbsp; &nbsp; <span class=\"re3\">:openssl_verify_mode<\/span> <span class=\"sy0\">=&gt;<\/span> <span class=\"st0\">'none'<\/span><br \/>\n&nbsp; <span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>And added this to the end of that file<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\"><span class=\"kw1\">class<\/span> OverrideMailReciptient<br \/>\n&nbsp; <span class=\"kw1\">def<\/span> <span class=\"kw2\">self<\/span>.<span class=\"me1\">delivering_email<\/span><span class=\"br0\">&#40;<\/span>mail<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; mail.<span class=\"me1\">to<\/span> = <span class=\"st0\">&quot;developer@localhost&quot;<\/span><br \/>\n&nbsp; <span class=\"kw1\">end<\/span><br \/>\n<span class=\"kw1\">end<\/span><br \/>\n<span class=\"re2\">ActionMailer::Base<\/span>.<span class=\"me1\">register_interceptor<\/span><span class=\"br0\">&#40;<\/span>OverrideMailReciptient<span class=\"br0\">&#41;<\/span><\/div><\/div>\n<p>Overriding the mail recipient causes all emails leaving your rails app, to be redirected to the given address. With that in place, I could play with things like devise sign up confirmation emails without anything leaving my virtual environment. Just what I wanted.<\/p>\n<p>It was all so simple, I don&#8217;t really know why I haven&#8217;t done this before.<\/p>\n<p><strong>Update: Catching all emails<\/strong><br \/>\nI&#8217;ve needed to update my settings so that I can send an email to any email address, and it will end up in the rob@localhost mailbox. To do this, I followed the instructions given <a href=\"http:\/\/www.tipcache.com\/tip\/Create_a_super_%22catch-all%22_email_address_in_Postfix_16.html\">here<\/a>.<\/p>\n<p>I created \/etc\/postfix\/virtual :<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">\/.*\/ &nbsp;rob@localhost<\/div><\/div>\n<p>I then added this to the bottom of etc\/postfix\/main.cf :<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\"># Set up rob@localhost to catch mail not directed to a specfic email address<br \/>\nvirtual_alias_maps = regexp:\/etc\/postfix\/virtual<br \/>\nvirtual_alias_domains =<\/div><\/div>\n<p>I then ran these two commands to create the mapping and restart postfix:<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"text codecolorer\">sudo postmap \/etc\/postfix\/virtual<br \/>\nsudo postfix reload<\/div><\/div>\n<p>Now all emails sent to localhost:25 end up in the rob@localhost mailbox.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m working on an application that needs to send notifications via email, and I want to be able to test it in the development environment. In the past, I&#8217;ve either been able to set up a small Windows mail server &hellip; <a href=\"http:\/\/nicholshayes.co.uk\/blog\/?p=316\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/316"}],"collection":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=316"}],"version-history":[{"count":15,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/316\/revisions"}],"predecessor-version":[{"id":525,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/316\/revisions\/525"}],"wp:attachment":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=316"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=316"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=316"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}