{"id":292,"date":"2014-12-27T14:12:28","date_gmt":"2014-12-27T14:12:28","guid":{"rendered":"http:\/\/www.flat-planet.net\/?p=292"},"modified":"2014-12-27T14:12:28","modified_gmt":"2014-12-27T14:12:28","slug":"e-mail-server-setup-and-configuration","status":"publish","type":"post","link":"https:\/\/flat-planet.net\/?p=292","title":{"rendered":"E-Mail Server Setup and Configuration"},"content":{"rendered":"<p>Having your own mail server is very useful, though surprisingly hard to configure. Generally speaking there are actually two components in a standard linux mail server install. There is the Mail Transfer Agent [MTA] and the Mail Delivery Agent [MDA]. For this install I&#8217;ll be using Postfix as the MTA and Dovecot as the MDA<\/p>\n<p>The MTA handles relaying mail between different servers. It decides what to do with email from the outside world, and whether a particular user is allowed to send email using your server. It handles both incoming and outgoing SMTP. Postfix hands off local delivery (that is, the actual saving of the mail files on the server) to Dovecot\u2019s Local Mail Transfer Protocol service (LMTP). Postfix also lets Dovecot take care of authentication before users are allowed to send email from the server.<\/p>\n<p>The MDA is the part that end-users interact with. There are two main protocols in use by the MDA, POP3 and\/or IMAP (each have a secure variant, and have different pros\/cons). For this setup I&#8217;m ignoring the options and just configuring IMAPS &#8211; this is basically IMAP over an SSL\/TLS connection (and won&#8217;t be using SSL). The IMAP\/POP3 server handles requests from users who want to log in and check their email. Dovecot\u2019s LMTP service functions as the Mail Delivery Agent (MDA) by saving mail files on the server. Dovecot also handles all authorization.<\/p>\n<h1>Basic Requirements<\/h1>\n<ul>\n<li>A domain name &#8211; in this case flat-planet.net<\/li>\n<li>A hostname for the server e.g. mail.flat-planet.net<\/li>\n<li>An SSL certificate for the server hostname &#8211; see <a title=\"SSL Certificate Signing for Free with SAN\/UCC\" href=\"http:\/\/www.flat-planet.net\/?p=288\">this post<\/a> on the process for this<\/li>\n<\/ul>\n<h1>DNS Configuration<\/h1>\n<p>A specific type of DNS record is used for e-mail. This is known as the Mail Exchange [MX] record. The characteristic payload information of an MX record is the fully qualified domain name of a mail host and a preference value. The host name must map directly to one or more address record (A, or AAAA) in the DNS, and must not point to any CNAME records.<\/p>\n<p>Section 10.3 of <a title=\"RFC2181\" href=\"https:\/\/www.ietf.org\/rfc\/rfc2181.txt\" target=\"_blank\">RFC 2181<\/a> states:<\/p>\n<p style=\"padding-left: 60px;\">10.3. MX and NS records<\/p>\n<p style=\"padding-left: 60px;\">The domain name used as the value of a NS resource record, or part of the value of a MX resource record must not be an alias. Not only is the specification clear on this point, but using an alias in either of these positions neither works as well as might be hoped, nor well fulfills the ambition that may have led to this approach. This domain name must have as its value one or more address records. Currently those will be A records, however in the future other record types giving addressing information may be acceptable. It can also have other RRs, but <strong>never a CNAME RR<\/strong>.<\/p>\n<p style=\"padding-left: 60px;\">Searching for either NS or MX records causes &#8220;additional section processing&#8221; in which address records associated with the value of the record sought are appended to the answer. This helps avoid needless extra queries that are easily anticipated when the first was made.<\/p>\n<p style=\"padding-left: 60px;\">Additional section processing does not include CNAME records, let alone the address records that may be associated with the canonical name derived from the alias. Thus, if an alias is used as the value of an NS or MX record, no address will be returned with the NS or MX value. This can cause extra queries, and extra network burden, on every query.<\/p>\n<p>But since I&#8217;m hosting on a residential connection I don&#8217;t have a static IP, and so I&#8217;m using a CNAME record (not an uncommon practice, even among people who have static IPs and should know better).<\/p>\n<pre>Colin:~ $ <strong><span style=\"color: #0000ff;\">dig flat-planet.net MX<\/span><\/strong>\r\n\r\n; &lt;&lt;&gt;&gt; DiG 9.8.3-P1 &lt;&lt;&gt;&gt; flat-planet.net MX\r\n;; global options: +cmd\r\n;; Got answer:\r\n;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 32916\r\n;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0\r\n\r\n;; QUESTION SECTION:\r\n;flat-planet.net.\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0IN\u00a0\u00a0 \u00a0MX\r\n\r\n<strong><span style=\"color: #0000ff;\">;; ANSWER SECTION:<\/span><\/strong>\r\n<strong><span style=\"color: #0000ff;\">flat-planet.net.\u00a0\u00a0 \u00a01799\u00a0\u00a0 \u00a0IN\u00a0\u00a0 \u00a0MX\u00a0\u00a0 \u00a010 mail.flat-planet.net.<\/span><\/strong>\r\n\r\n;; Query time: 68 msec\r\n;; SERVER: 192.168.1.1#53(192.168.1.1)\r\n;; WHEN: Sat Dec 27 12:05:18 2014\r\n;; MSG SIZE\u00a0 rcvd: 54\r\n\r\nColin:~ $ <strong><span style=\"color: #0000ff;\">dig mail.flat-planet.net MX<\/span><\/strong>\r\n\r\n; &lt;&lt;&gt;&gt; DiG 9.8.3-P1 &lt;&lt;&gt;&gt; mail.flat-planet.net MX\r\n;; global options: +cmd\r\n;; Got answer:\r\n;; -&gt;&gt;HEADER&lt;&lt;- opcode: QUERY, status: NOERROR, id: 16794\r\n;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0\r\n\r\n;; QUESTION SECTION:\r\n;mail.flat-planet.net.\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0IN\u00a0\u00a0 \u00a0MX\r\n\r\n<strong><span style=\"color: #0000ff;\">;; ANSWER SECTION:<\/span><\/strong>\r\n<strong><span style=\"color: #0000ff;\">mail.flat-planet.net.\u00a0\u00a0 \u00a01402\u00a0\u00a0 \u00a0IN\u00a0\u00a0 \u00a0CNAME\u00a0\u00a0 \u00a0colinmacg.no-ip.info.<\/span><\/strong>\r\n\r\n;; AUTHORITY SECTION:\r\nno-ip.info.\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a059\u00a0\u00a0 \u00a0IN\u00a0\u00a0 \u00a0SOA\u00a0\u00a0 \u00a0nf1.no-ip.com. hostmaster.no-ip.com. 2107200777 600 300 604800 600\r\n\r\n;; Query time: 117 msec\r\n;; SERVER: 192.168.1.1#53(192.168.1.1)\r\n;; WHEN: Sat Dec 27 12:05:39 2014\r\n;; MSG SIZE\u00a0 rcvd: 132\r\n<\/pre>\n<p>At this point a 3rd query is required to resolve the no-ip.info domain to the actual IP address.<\/p>\n<p>It should be noted that the mail will be considered more likely to be spam (by spamassassin, amongst others) as the reverse DNS lookup on the IP address will show it as belonging to your ISP rather then your domain, but that alone is generally not enough.<\/p>\n<h1>Postfix<\/h1>\n<p>Postfix has two main config files: <strong>main.cf<\/strong>, which specifies what you would think of as config options, and <strong>master.cf<\/strong>, which specifies the services postfix should run.<\/p>\n<h2>master.cf<\/h2>\n<p>Here we have the smtp daemon enabled, and we are directing it through SpamAssassin as our content filter<\/p>\n<pre># ==========================================================================\r\n# service type private unpriv chroot wakeup maxproc command + args\r\n# (yes) (yes) (yes) (never) (100)\r\n# ==========================================================================\r\nsmtp inet n - - - - smtpd\r\n      -o content_filter=spamassassin\r\n\r\n...\r\n\r\nspamassassin unix - n n - - pipe user=debian-spamd argv=\/usr\/bin\/spamc -f -e \/usr\/sbin\/sendmail -oi -f ${sender} ${recipient}\r\n<\/pre>\n<h2>main.cf<\/h2>\n<p>Main points here are:<\/p>\n<ul>\n<li>Add in our cert and key for TLS<\/li>\n<li>Enable TLS<\/li>\n<li>Disable SSLv2 and SSLv3 &#8211; these are deprecated anyway, and with <a title=\"POODLE\" href=\"http:\/\/googleonlinesecurity.blogspot.ie\/2014\/10\/this-poodle-bites-exploiting-ssl-30.html\">POODLE (CVE-2014-3566)<\/a> we should explicitly disable these.<\/li>\n<li>The use of Mail Directories rather then the default<\/li>\n<li>Configuring the use of SASL<\/li>\n<li>Locking down smtpd and the HELO command<\/li>\n<\/ul>\n<pre style=\"padding-left: 30px;\"># TLS parameters\r\nsmtpd_tls_cert_file=\/etc\/ssl\/certs\/mail-cert.crt\r\nsmtpd_tls_key_file=\/etc\/ssl\/private\/mail-key.key\r\nsmtpd_use_tls=yes\r\nsmtpd_tls_session_cache_database = btree:${data_directory}\/smtpd_scache\r\nsmtp_tls_session_cache_database = btree:${data_directory}\/smtp_scache\r\nsmtpd_tls_protocols = !SSLv2, !SSLv3\r\n\r\nhome_mailbox = Maildir\/\r\nmailbox_transport = lmtp:unix:private\/dovecot-lmtp\r\n\r\n# SASL\u00a0 begins here\r\nsmtpd_sasl_type = dovecot\r\nsmtpd_sasl_path = private\/auth\r\nsmtpd_sasl_auth_enable = yes\r\nbroken_sasl_auth_clients = yes\r\nsmtpd_sasl_security_options = noanonymous\r\nsmtpd_sasl_local_domain = flat-planet.net\r\nsmtpd_tls_auth_only = yes\r\n\r\nsmtpd_recipient_restrictions =\r\n     permit_sasl_authenticated,\r\n     permit_mynetworks,\r\n     reject_unauth_destination\r\n\r\nsmtpd_helo_required = yes\r\nsmtpd_helo_restrictions =\r\n     permit_mynetworks,\r\n     permit_sasl_authenticated,\r\n     reject_invalid_helo_hostname,\r\n     reject_non_fqdn_helo_hostname,\r\n     reject_unknown_helo_hostname\r\ncheck_helo_access hash:\/etc\/postfix\/helo_access\r\n<\/pre>\n<h1>Dovecot<\/h1>\n<p>Dovecot allows users to log in and check their email using POP3 and IMAP. In this section, you\u2019ll configure Dovecot to force users to use SSL when they connect so that their passwords are never sent to the server in plain text. Users will have to connect using the standard SSL ports &#8211; 993 for IMAP and 995 for POP3 &#8211; and only those ports. Dovecot\u2019s LMTP service will function as the MDA and store incoming messages in the proper locations on the server. Dovecot will also be handling all user authentication for mail. In this case I&#8217;m only worried about IMAP over SSL\/TLS.<\/p>\n<p>Dovecot 2 uses a number of different configuration files. The primary configuration file contains a few directives, and then several inclusions of other configuration files. This helps to separate different configuration parameters logically so they\u2019re not all grouped together in one file. This is a major change from Dovecot 1, where virtually everything was configured in the same file.<\/p>\n<p>For my setup the following files are modified (in \/etc\/config\/dovecot\/conf.d):<\/p>\n<ul>\n<li>10-auth.conf<\/li>\n<li>10-mail.conf<\/li>\n<li>10-master.conf<\/li>\n<li>10-ssl.conf<\/li>\n<li>20-lmtp.conf<\/li>\n<li>90-sieve.conf<\/li>\n<\/ul>\n<h2>10-auth.conf<\/h2>\n<p>Some configuration for Sieve and LMTP later on. We need it to strip the domain from the username and look that part up:<\/p>\n<pre>auth_username_format = %Ln\r\n<\/pre>\n<h2>10-mail.conf<\/h2>\n<p>Rather then using mbox, I prefer the Maildir approach so modify the file like so:<\/p>\n<p>#mail_location = mbox:~\/mail:INBOX=\/var\/mail\/%u<br \/>\nmail_location = maildir:~\/Maildir<\/p>\n<h2>10-master.conf<\/h2>\n<p>Set Dovecot to listen to authentication requests from Postfix over unix sockets rather then network ports, and enable the imaps listener. I&#8217;m not opening IMAP to external networks so I&#8217;ll leave it enabled for now and disable once I&#8217;m sure all is working:<\/p>\n<pre>service imap-login {\r\n  inet_listener imap {\r\n    port = 143\r\n  } \r\n  inet_listener imaps {\r\n    port = 993\r\n    ssl = yes\r\n  }\r\n\r\nservice auth { \r\n        unix_listener \/var\/spool\/postfix\/private\/auth { \r\n                    mode = 0660 \r\n                    user = postfix \r\n                    group = postfix \r\n        } \r\n}\r\nservice lmtp {\r\n\u00a0       unix_listener \/var\/spool\/postfix\/private\/dovecot-lmtp {\r\n                    mode = 0666\r\n }\r\n}<\/pre>\n<h2>10-ssl.conf<\/h2>\n<p>Here I enable SSL, point it towards the keys (the &lt; is not a typo) and disable the ciphers and protocols I don&#8217;t want running (SSLv2 and v3).<\/p>\n<pre># SSL\/TLS support: yes, no, required. &lt;doc\/wiki\/SSL.txt&gt;\r\nssl = yes\r\n...\r\nssl_cert = &lt;\/etc\/ssl\/certs\/mail-cert.crt\r\nssl_key = &lt;\/etc\/ssl\/private\/mail-key.key\r\n\r\n...\r\n\r\n# SSL protocols to use\r\nssl_protocols = !SSLv3\r\n...\r\n# SSL ciphers to use\r\nssl_cipher_list = ALL:!LOW:!SSLv2:!SSLv3:!EXP:!aNULL\r\n<\/pre>\n<h2>20-lmtp.conf<\/h2>\n<p>Configure LMTP to allow the recipient address to include the detail of the mail folder you want to put it in, and to enable the sieve plugin (more on that later).<\/p>\n<pre># When recipient address includes the detail (e.g. user+detail), try to save\r\n# the mail to the detail mailbox. See also recipient_delimiter and\r\n# lda_mailbox_autocreate settings.\r\nlmtp_save_to_detail_mailbox = yes\r\n\r\nprotocol lmtp {\r\n# Space separated list of plugins to load (default is global mail_plugins).\r\n     mail_plugins = $mail_plugins sieve\r\n     postmaster_address = postmaster@flat-planet.net\r\n}\r\n<\/pre>\n<h2>90-sieve.conf<\/h2>\n<p>Configuration for sieve to allow sorting of the SpamAssassin tagged mails.<\/p>\n<pre>plugin {\r\n# The path to the user's main active script. If ManageSieve is used, this the\r\n# location of the symbolic link controlled by ManageSieve.\r\n     sieve = ~\/.dovecot.sieve\r\n\r\n...\r\n     recipient_delimiter = +\r\n<\/pre>\n<h1>SpamAssassin<\/h1>\n<p>SpamAssassin is a perl based e-mail filtering solution. It\u00a0 uses a variety of spam-detection techniques, that includes DNS-based and fuzzy-checksum-based spam detection, Bayesian filtering, external programs, blacklists and online databases.<\/p>\n<p>As usual, install with:<\/p>\n<pre>sudo apt-get update\r\nsudo apt-get install spamassassin\r\n<\/pre>\n<p>The configure with the file \/etc\/spamassassin\/local.cf and restart. Main configurations is:<\/p>\n<ul>\n<li>Rewrite the subject line to include the SPAM score<\/li>\n<li>Modify the headers only &#8211; don&#8217;t change the body<\/li>\n<li>Set the required score for something to be marked as SPAM (default is 5)<\/li>\n<li>Tell it to use Bayesian statistical analysis and enable auto-learning<\/li>\n<\/ul>\n<pre>rewrite_header Subject [***** SPAM _SCORE_ *****]\r\nreport_safe 0\r\nrequired_score 3.0\r\nuse_bayes 1\r\nbayes_auto_learn 1<\/pre>\n<p>And set ENABLED to 1 in \/etc\/defaults\/spamassassin and restart:<\/p>\n<p>sudo service spamassassin start<\/p>\n<h1>\u00a0Filtering and Sieve<\/h1>\n<p>Install lmtp and sieve<\/p>\n<pre>sudo apt-get update\r\nsudo apt-get install dovecot-sieve dovecot-lmtp\r\n<\/pre>\n<p>Restart Postfix and Dovecot<\/p>\n<pre>sudo service postfix reload\r\nsudo service dovecot reload\r\n<\/pre>\n<p>Add the filter to your home folder in ~\/.dovecot.sieve<\/p>\n<pre>require [\"fileinto\"];\r\n# Move spam to spam folder\r\nif header :contains \"X-Spam-Flag\" \"YES\" {\r\n         fileinto \"Spam\";\r\n         # Stop here so that we do not reply on spams\r\n         stop;\r\n}\r\n<\/pre>\n<p>When SpamAssassin marks emails as Spam it adds X-Spam-Flag: YES to the headers. This rule checks the headers and sends mail to the spam folder if that flag exists.<\/p>\n<h1>Does it work?<\/h1>\n<p>Apparently so &#8211; a fake FedEX mail was intercepted and placed in the SPAM folder. From looking at the mail header I can see the SpamAssassin analysis:<\/p>\n<p><tt><span style=\"color: #0000ff;\"><b>X-Spam-Flag:<\/b> YES<\/span><br \/>\n<\/tt><tt><b>X-Spam-Level:<\/b> **********<br \/>\n<\/tt><tt><b>X-Spam-Status:<\/b> Yes, <span style=\"color: #0000ff;\"><strong>score=10.3 required=3.0<\/strong> <\/span>tests=HTML_FONT_SIZE_LARGE,<br \/>\nHTML_MESSAGE,KB_DATE_CONTAINS_TAB,MIME_HTML_ONLY,MISSING_MID,\u00a0\u00a0\u00a0\u00a0 RCVD_IN_BL_SPAMCOP_NET,RCVD_IN_BRBL_LASTEXT,RCVD_IN_XBL,RDNS_NONE,TAB_IN_FROM<br \/>\nautolearn=no version=3.3.2<br \/>\n<\/tt><tt><b>X-Spam-Report:<\/b><br \/>\n* 1.2 RCVD_IN_BL_SPAMCOP_NET RBL: Received via a relay in bl.spamcop.net<br \/>\n* [Blocked - see &lt;http:\/\/www.spamcop.net\/bl.shtml?211.54.17.252&gt;]<br \/>\n* 1.6 RCVD_IN_BRBL_LASTEXT RBL: RCVD_IN_BRBL_LASTEXT<br \/>\n* [211.54.17.252 listed in bb.barracudacentral.org]<br \/>\n* 0.7 RCVD_IN_XBL RBL: Received via a relay in Spamhaus XBL<br \/>\n* [211.54.17.252 listed in zen.spamhaus.org]<br \/>\n* 3.8 KB_DATE_CONTAINS_TAB KB_DATE_CONTAINS_TAB<br \/>\n* 0.4 TAB_IN_FROM From starts with a tab<br \/>\n* 0.0 HTML_MESSAGE BODY: HTML included in message<br \/>\n* 0.0 HTML_FONT_SIZE_LARGE BODY: HTML font size is large<br \/>\n* 1.1 MIME_HTML_ONLY BODY: Message only has text\/html MIME parts<br \/>\n* 0.1 MISSING_MID Missing Message-Id: header<br \/>\n* 1.3 RDNS_NONE Delivered to internal network by a host with no rDNS<\/tt><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Having your own mail server is very useful, though surprisingly hard to configure. Generally speaking there are actually two components in a standard linux mail server install. There is the Mail Transfer Agent [MTA] and the Mail Delivery Agent [MDA]. For this install I&#8217;ll be using Postfix as the MTA and Dovecot as the MDA [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[84,55,63],"tags":[64,109,115,136,140,141,142,143,144],"series":[],"class_list":["post-292","post","type-post","status-publish","format-standard","hentry","category-spam","category-information-technology","category-raspberry-pi","tag-raspberry-pi-2","tag-setup","tag-config","tag-email","tag-spam","tag-internet","tag-postfix","tag-dovecot","tag-walkthrough"],"_links":{"self":[{"href":"https:\/\/flat-planet.net\/index.php?rest_route=\/wp\/v2\/posts\/292","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/flat-planet.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/flat-planet.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/flat-planet.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/flat-planet.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=292"}],"version-history":[{"count":3,"href":"https:\/\/flat-planet.net\/index.php?rest_route=\/wp\/v2\/posts\/292\/revisions"}],"predecessor-version":[{"id":296,"href":"https:\/\/flat-planet.net\/index.php?rest_route=\/wp\/v2\/posts\/292\/revisions\/296"}],"wp:attachment":[{"href":"https:\/\/flat-planet.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=292"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/flat-planet.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=292"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/flat-planet.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=292"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/flat-planet.net\/index.php?rest_route=%2Fwp%2Fv2%2Fseries&post=292"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}