{"id":169,"date":"2014-11-22T21:05:21","date_gmt":"2014-11-22T20:05:21","guid":{"rendered":"http:\/\/www.lambiek.eu\/blog\/?p=169"},"modified":"2014-11-28T16:43:58","modified_gmt":"2014-11-28T15:43:58","slug":"copy-email-to-extra-recipient","status":"publish","type":"post","link":"https:\/\/www.lambiek.eu\/blog\/tutorial\/copy-email-to-extra-recipient\/","title":{"rendered":"Copy email to extra recipient"},"content":{"rendered":"<p>In my quest to have specific email copied to an additional recipient based on sender address I ended up in a combination of Postfix, Dovecot and Sieve.<\/p>\n<p>How I came to this configuration? Well, at first I thought it should be rather easy by doing it in Postfix itself. I read the manuals about sender_access_restrictions and configured the following:<\/p>\n<pre class=\"lang:default decode:true \" >\r\n\/etc\/postfix\/main.cf\r\nsmtpd_sender_restrictions = check_sender_access hash:\/etc\/postfix\/sender_access\r\n\r\n\/etc\/postfix\/sender_access\r\nsomedomain.com     redirect        recipient@anotherdomain.com\r\n\r\npostmap hash:\/etc\/postfix\/sender_access\r\nsystemctl reload postfix\r\n<\/pre>\n<p>Tried to send an email and this setup works pretty good.<\/p>\n<p>Then I realized that I would like two recipients for the redirected mails (keep a copy in my own mailbox for instance) and there the situation get interesting. The new configuration looks like:<\/p>\n<pre class=\"lang:default decode:true \" >\r\n\/etc\/postfix\/sender_access\r\nsomedomain.com     redirect        recipient@anotherdomain.com,second_recipient@somewhere.else\r\n\r\npostmap hash:\/etc\/postfix\/sender_access\r\nsystemctl reload postfix\r\n<\/pre>\n<p>In a lot of configuration directives you can specify multiple email addresses comma seperated but not in this case. The sender_access file is succesfully processed but when sending a test email the mail logs produce something like:<\/p>\n<pre class=\"lang:default decode:true \" >\r\nNov 22 19:29:52 server postfix\/error[15960]: A1F9D20BA2EF: to=&lt;recipient@anotherdomain.com, second_recipient&gt;, orig_to=&lt;original_recipient@here&gt;, relay=none, delay=2.1, delays=2\/0.02\/0\/0.01, dsn=5.1.3, status=bounced (bad address syntax)\r\n<\/pre>\n<p>Hmm, that is strange, the comma is completely overlooked and the email addresses are interpreted as one.<\/p>\n<p><strong>Note<\/strong>: I also tried to embrace the addresses with &#8221; and &#8216; characters but that does not help.<\/p>\n<p>Another approuch perhaps? What if I use the aliases file in between?<\/p>\n<pre class=\"lang:default decode:true \" >\r\n\/etc\/aliases\r\nredirect_map: recipient@anotherdomain.com, second_recipient@somewhere.else\r\n\r\n\/etc\/postfix\/sender_access\r\nsomedomain.com     redirect        redirect_map\r\n\r\nnewaliases\r\npostmap hash:\/etc\/postfix\/sender_access\r\nsystemctl reload postfix\r\n<\/pre>\n<p>When looking at the logs this time, Postfix does not like this:<\/p>\n<pre class=\"lang:default decode:true \" >\r\nNov 22 19:36:01 server postfix\/smtpd[16080]: warning: access table hash:\/etc\/postfix\/sender_access entry \"somedomain.com\" requires user@domain target\r\n<\/pre>\n<p>Apparently this needs the virtual map in the chain as well:<\/p>\n<pre class=\"lang:default decode:true \" >\r\n\/etc\/postfix\/virtual\r\nredirect@mydomain.com         redirect_map\r\n\r\n\/etc\/postfix\/sender_access\r\nsomedomain.com     redirect        redirect@mydomain.com\r\n\r\npostmap hash:\/etc\/postfix\/virtual\r\npostmap hash:\/etc\/postfix\/sender_access\r\nsystemctl reload postfix\r\n<\/pre>\n<p>So, this works, but I am not pretty comfortable with this solution. The chain is getting long to be easily maintained.<\/p>\n<p>I kept looking for easier alternatives&#8230;<\/p>\n<p>What&#8217;s a next approuch? Perhaps the redirect can be configured on additional lines?<\/p>\n<pre class=\"lang:default decode:true \" >\r\n\/etc\/postfix\/sender_access\r\nsomedomain.com     redirect        recipient@anotherdomain.com\r\nsomedomain.com     redirect        second_recipient@somewhere.else\r\n\r\npostmap hash:\/etc\/postfix\/sender_access\r\nsystemctl reload postfix\r\n<\/pre>\n<p>Unfortunately not, Postfix doesn&#8217;t like it:<\/p>\n<pre class=\"lang:default decode:true \" >\r\nNov 22 19:30:30 server postfix\/postmap[15970]: warning: \/etc\/postfix\/sender_access.db: duplicate entry: \"somedomain.com\"\r\n<\/pre>\n<p>At this point I am pretty done with Postfix. Let&#8217;s forget the Postfix configuration and try Sieve since I already have some filtering rules there.<\/p>\n<p>In this case we need the &#8220;copy&#8221; in the require line:<\/p>\n<pre class=\"lang:default decode:true \" >\r\n~\/.dovecot.sieve\r\nrequire [\"envelope\", \"fileinto\", \"imap4flags\", \"vacation\", \"copy\"];\r\n\r\nif envelope :contains \"from\" \"@somedomain.com\"\r\n{\r\n        redirect :copy \"recipient@anotherdomain.com\";\r\n        redirect :copy \"second_recipient@somewhere.else\";\r\n}\r\n<\/pre>\n<p>This setup works like a charm.<\/p>\n<p>Conclusion:<\/p>\n<p>My first thought was that by letting Postfix do the complete delivery of the mail it would be simpler and faster, but at the end the solution lies within multiple components and let Postfix just deliver the mail to it&#8217;s destination and hand over all the redirect work to sieve.<\/p>\n<p>If somebody knows of a better configuration I am glad to hear it&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my quest to have specific email copied to an additional recipient based on sender address I ended up in a combination of Postfix, Dovecot and Sieve. How I came to this configuration? Well, at first I thought it should be rather easy by doing it in Postfix itself. I read the manuals about sender_access_restrictions &#8230; <span class=\"more\"><a class=\"more-link\" href=\"https:\/\/www.lambiek.eu\/blog\/tutorial\/copy-email-to-extra-recipient\/\">[Read more&#8230;]<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4],"tags":[5,18,11,17,19],"_links":{"self":[{"href":"https:\/\/www.lambiek.eu\/blog\/wp-json\/wp\/v2\/posts\/169"}],"collection":[{"href":"https:\/\/www.lambiek.eu\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lambiek.eu\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lambiek.eu\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lambiek.eu\/blog\/wp-json\/wp\/v2\/comments?post=169"}],"version-history":[{"count":5,"href":"https:\/\/www.lambiek.eu\/blog\/wp-json\/wp\/v2\/posts\/169\/revisions"}],"predecessor-version":[{"id":178,"href":"https:\/\/www.lambiek.eu\/blog\/wp-json\/wp\/v2\/posts\/169\/revisions\/178"}],"wp:attachment":[{"href":"https:\/\/www.lambiek.eu\/blog\/wp-json\/wp\/v2\/media?parent=169"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lambiek.eu\/blog\/wp-json\/wp\/v2\/categories?post=169"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lambiek.eu\/blog\/wp-json\/wp\/v2\/tags?post=169"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}