I made it! Article Setting up a mail server - completed! Unbeliveable!
This commit is contained in:
parent
14187ee841
commit
7fb2fddbba
@ -5,10 +5,10 @@ block head_ext
|
|||||||
|
|
||||||
block article
|
block article
|
||||||
header
|
header
|
||||||
h2 Setting up a mail server (WIP)
|
h2 Setting up a mail server
|
||||||
div.menu
|
div.menu
|
||||||
a(href='/stuff#articles') Go back to articles list
|
a(href='/stuff#articles') Go back to articles list
|
||||||
time(datetime='2021-09-20') 20 September 2021
|
time(datetime='2022-05-21') 21 May 2022
|
||||||
nav
|
nav
|
||||||
h3 Contents
|
h3 Contents
|
||||||
ol
|
ol
|
||||||
@ -21,6 +21,21 @@ block article
|
|||||||
li #[a(href='#art-3-3') User aliases]
|
li #[a(href='#art-3-3') User aliases]
|
||||||
li #[a(href='#art-3-4') Starting Postfix]
|
li #[a(href='#art-3-4') Starting Postfix]
|
||||||
li #[a(href='#art-4') Dovecot POP3/IMAP server with Sieve mail filter]
|
li #[a(href='#art-4') Dovecot POP3/IMAP server with Sieve mail filter]
|
||||||
|
ol
|
||||||
|
li #[a(href='#art-4-1') Configuration files]
|
||||||
|
ol
|
||||||
|
li #[a(href='#art-4-1-1') dovecot.conf]
|
||||||
|
li #[a(href='#art-4-1-2') 10-auth.conf]
|
||||||
|
li #[a(href='#art-4-1-3') 10-logging.conf]
|
||||||
|
li #[a(href='#art-4-1-4') 10-mail.conf]
|
||||||
|
li #[a(href='#art-4-1-5') 10-master.conf]
|
||||||
|
li #[a(href='#art-4-1-6') 10-ssl.conf]
|
||||||
|
li #[a(href='#art-4-1-7') 15-lda.conf]
|
||||||
|
li #[a(href='#art-4-1-8') 15-mailboxes.conf]
|
||||||
|
li #[a(href='#art-4-1-9') 20-managesieve.conf]
|
||||||
|
li #[a(href='#art-4-1-10') 90-sieve.conf]
|
||||||
|
li #[a(href='#art-4-1-11') auth-system.conf.ext]
|
||||||
|
|
||||||
li #[a(href='#art-5') SpamAssassin spam filter]
|
li #[a(href='#art-5') SpamAssassin spam filter]
|
||||||
ol
|
ol
|
||||||
li #[a(href='#art-5-1') Updating built-in rule set]
|
li #[a(href='#art-5-1') Updating built-in rule set]
|
||||||
@ -43,57 +58,62 @@ block article
|
|||||||
li #[a(href='#art-9') Setting up a ClamAV antivirus]
|
li #[a(href='#art-9') Setting up a ClamAV antivirus]
|
||||||
|
|
||||||
h3#art-1 #[a(href='#art-1') 1. Introduction]
|
h3#art-1 #[a(href='#art-1') 1. Introduction]
|
||||||
p I use Postfix as a SMTP and Dovecot (with Pigeonhole (Sieve)) as an IMAP server. ClamAV for an antivirus. For antispam I use SpamAssassin. For DKIM and DMARC — OpenDKIM and OpenDMARC respectively.
|
p E-mail itself is a system consisting of several parts. A main E-mail protocol — SMTP is used for exchanging of mail between servers. For a user to manage his mail IMAP and POP3 protocols are used. Difference between IMAP and POP3 is that IMAP manages mail stored on a server, while POP3, once fetched mail, deletes it from server.
|
||||||
p It is vital to make the DKIM, DMARC and SPF DNS records. Also, if you want your mail server to be trusted by every other mail servers then you should get a static IP-address if you don't yet. And you have to ask your ISP to edit PTR DNS record for your static IP-address to point to your domain.
|
p As SMTP server I use Postfix. For IMAP (I don't use POP3 because I need access from multiple devices) I use Dovecot. Dovecot is also being used for SASL authentication in Postfix. And Dovecot supports Sieve protocol, through its implementation called Pigeonhole, that allows users to write their own message filtering rules.
|
||||||
p Unfortunately for me I don't have neither, and I'm afraid that even if I get the static IP-address, my ISP won't edit PTR record, because that's available only for bussiness customers. And about domains, there is such things as untrustworthy abused TLDs, and top TLD is in that list. That's definitely because it's a cheap TLD.
|
|
||||||
p Server is configured in a simple way using PAM (real system users) with user's passwords and with mail stored in ~/Maildir.
|
p Server is configured in a simple way using PAM (real system users) with user's passwords and with mail stored in ~/Maildir.
|
||||||
|
p But, as you know, there is a major problem called spam. And in order to withstand this problem there was mechanisms created. So that no one could impersonate you DKIM, DMARC and SPF were created. To ensure encrypted connection a MTA-STS (RFC8461) standard was made. To resist incoming spam anti-spam systems like SpamAssassin or spamd are used. Also it is good to check incoming mail for viruses, there are many antiviruses and I use one called ClamAV.
|
||||||
|
p I have mentioned DKIM (DomainKeys Identified Mail), it is used to sign mail going out that it is indeed comes from your server, and verify incoming mail. And for that I use OpenDKIM implementation.
|
||||||
|
p DMARC (Domain-based Message Authentication, Reporting and Conformance) is a policy that tells the server what to do if received mail failed some checks. To perform DMARC policy checks I use OpenDMARC implementation. OpenDMARC also performs SPF policy checks.
|
||||||
|
p SPF (Sender Policy Framework) allows the server to check that an incoming mail came from an IP address set in SPF DNS record for domain it originates from.
|
||||||
|
p Many servers will reject mail from a dynamic IP-address, so a static address is a must. But, from my experience, GMail, Yandex and Rambler will at least place my message to Junk directory. On Gmail I get to Inbox most of the time btw. There is such thing used against spam called block lists, and Spamhaus is the biggest player here. So, if a server uses such lists I get rejected at the stage of establishing a connection with no chance to get through anti-spam system.
|
||||||
|
p If you have a static address then in Spamhaus you can submit your address for deletion.
|
||||||
|
p Also, while not stated by RFCs, some servers will still reject your mail if your IP-address doesn't have a PTR DNS record set, and some will expect a PTR record to be a hostname of your server, like mail.example.org, or like my the.arav.top.
|
||||||
|
p There is another problem known as not trusted top level domain, like mine .top domain. :) Because of how cheap it is, it is popular among spammers.
|
||||||
|
|
||||||
h3#art-2 #[a(href='#art-2') 2. Installing]
|
h3#art-2 #[a(href='#art-2') 2. Installing]
|
||||||
p You need to install following packages: #[code postfix], #[code dovecot], #[code pidgeonhole] (or could be #[code dovecot-sieve]), #[code clamav], #[code opendkim], #[code opendmarc], and #[code spamassassin].
|
p You need to install following packages: #[code postfix], #[code dovecot], #[code pigeonhole] (or could be named as #[code dovecot-sieve]), #[code clamav], #[code opendkim], #[code opendmarc], and #[code spamassassin].
|
||||||
|
|
||||||
h3#art-3 #[a(href='#art-3') 3. Postfix SMTP server]
|
h3#art-3 #[a(href='#art-3') 3. Postfix SMTP server]
|
||||||
p Its configuration files are in directory #[code /etc/postfix]. There are two configuration files we'll work with. The first one is a #[code main.cf] file. Then we configure services in #[code master.cf]. Also I'll show you how to make aliases for users.
|
p Its configuration files are in directory #[code /etc/postfix]. There are two configuration files we'll work with. The first one is a #[code main.cf] file. Then we configure services in #[code master.cf]. Also I'll show you how to make aliases for users.
|
||||||
|
|
||||||
h4#art-3-1 #[a(href='#art-3-1') 3.1. main.cf]
|
h4#art-3-1 #[a(href='#art-3-1') 3.1. main.cf]
|
||||||
p Let's take a look at all base options that should be modified:
|
p So, you have #[code main.cf] opened, first we need to make changes in an existing configuration:
|
||||||
pre
|
pre
|
||||||
| myhostname = mail.example.org
|
| myhostname = mail.example.org
|
||||||
| mydomain = example.org
|
| mydomain = example.org
|
||||||
| myorigin = $mydomain
|
| myorigin = $mydomain
|
||||||
|
|
p #[code myhostname] should be a subdomain that points to an IP of a mail server. This hostname is usually an A DNS record even if you have only one IP-address it is discuraged making it a CNAME.
|
||||||
|
p #[code mydomain] is your domain. In #[code myorigin] we set a domain name from what sent mail appear. Yes, you can use other options as a variable to reduce copy-pasting.
|
||||||
|
pre
|
||||||
| inet_interfaces = all
|
| inet_interfaces = all
|
||||||
|
|
p In #[code inet_interfaces] we list interfaces we listen on. In this case we listen on all available interfaces.
|
||||||
|
pre
|
||||||
| mydestination = $myhostname, localhost, $mydomain, mail.$mydomain
|
| mydestination = $myhostname, localhost, $mydomain, mail.$mydomain
|
||||||
|
|
p #[code mydestination] is a list of domains our server deliver mail for.
|
||||||
|
pre
|
||||||
| local_recipient_maps = unix:passwd.byname $alias_maps
|
| local_recipient_maps = unix:passwd.byname $alias_maps
|
||||||
|
|
p Here we tell Postfix where to look for names of local recipients.
|
||||||
|
pre
|
||||||
| mynetworks = localhost, 192.168.0.0/24
|
| mynetworks = localhost, 192.168.0.0/24
|
||||||
|
p It is a list of trusted remote clients allowed to relay mail through our server.
|
||||||
|
|
pre
|
||||||
| alias_maps = hash:/etc/postfix/aliases
|
| alias_maps = hash:/etc/postfix/aliases
|
||||||
| alias_database = $alias_maps
|
| alias_database = $alias_maps
|
||||||
|
|
p For database of aliases we use #[code /etc/postfix/aliases] file in a special format we learn about later.
|
||||||
|
pre
|
||||||
| recipient_delimiter = +
|
| recipient_delimiter = +
|
||||||
|
|
p A symbol used to separate username and an extension.
|
||||||
|
pre
|
||||||
| home_mailbox = Maildir/
|
| home_mailbox = Maildir/
|
||||||
|
|
p Here we use a Maildir/ mailbox style when every message is stored in a separated file.
|
||||||
|
pre
|
||||||
| mailbox_transport = lmtp:unix:private/dovecot-lmtp
|
| mailbox_transport = lmtp:unix:private/dovecot-lmtp
|
||||||
|
|
p Here we tell Postfix what LMTP (Local Mail Transport Protocol) server to use.
|
||||||
|
pre
|
||||||
| inet_protocols = ipv4
|
| inet_protocols = ipv4
|
||||||
p Now let's clarify what are they doing.
|
p Here we leave only IPv4 support, if you have an IPv6 address then you may want to add #[code ipv6].
|
||||||
p Set #[code myhostname] to a hostname of a server (e.g. #[code mail.example.org]). Set #[code mydomain] to your domain name (e.g. #[code example.org]). Set #[code myorigin] to #[code $mydomain] to set origin of mail being sent from your server.
|
p So here we are done with an existing configuration and ready to make our additions to add encryption, milters, configure SASL authentication, restrictions and make some tweaks.
|
||||||
p #[code mydestination] is a list of domains that are delivered through a local transport. If server should go outside then this option must include #[code $mydomain] alongside names for the local machine. E.g. #[code $myhostname, localhost, $mydomain, mail.$mydomain].
|
p And we start with configuring milters. Milter stands for mail filter, a special protocol originated in Sendmail SMTP server.
|
||||||
p #[code local_recipient_maps] are lookup tables with all names and/or addresses of local recipients. In my case it set to #[code unix:passwd.byname $alias_maps].
|
|
||||||
p I have #[code inet_interfaces = all] to listen on all the interfaces.
|
|
||||||
p In #[code mynetworks], as stated in a Postfix's manual, we specify a list of “trusted” clients that have more privileges than “strangers”. In particular, such clients are allowed to relay mail through Postfix. I have it set to localhost and my LAN.
|
|
||||||
p In #[code alias_maps] we specify a list of lookup tables that contain aliases for existing users. And in #[code alias_database] just add #[code $alias_maps]. #[code alias_database] is, as stated in a manual, separate because not all the tables specified with #[code $alias_maps] have to be local files.
|
|
||||||
p #[code recipient_delimeter = +]. Here we set a delimeter to a plus sign (that's just a usual practice that I obeyed).
|
|
||||||
p I use a Maildir-style mailboxes, so #[code home_mailbox] is set to #[code Maildir/] (slash is necessary).
|
|
||||||
p We use Dovecot, so #[code mailbox_transport] should be set to #[code lmtp:unix:private/dovecot-lmtp]. Here we point to where Dovecot LMTP server listens, in our case it is a UNIX-socket.
|
|
||||||
p Optionaly, you can set #[code inet_protocols] to IP versions used by you, I set it just to #[code ipv4] for a quite legitimate reason of not having IPv6 address. :) It is a space-separated list, so to support both write #[code ipv4 ipv6].
|
|
||||||
|
|
||||||
p Next I'll cover how to make encryption working, set up milters (mail filters (i.e. OpenDKIM and OpenDMARC)), and restrictions.
|
|
||||||
p Next let's configure our milters:
|
|
||||||
pre
|
pre
|
||||||
| milter_default_action = accept
|
| milter_default_action = accept
|
||||||
| milter_protocol = 6
|
| milter_protocol = 6
|
||||||
@ -102,10 +122,10 @@ block article
|
|||||||
| unix:/var/spool/opendkim/opendkim.sock
|
| unix:/var/spool/opendkim/opendkim.sock
|
||||||
| inet 192.168.0.54:7357
|
| inet 192.168.0.54:7357
|
||||||
| non_smtpd_milters = $smtpd_milters
|
| non_smtpd_milters = $smtpd_milters
|
||||||
p #[code milter_default_action] specifies default action of a milter. Here we accept an e-mail message.
|
p #[code milter_default_action] specifies default action of a milter to accept messages.
|
||||||
p #[code milter_protocol] specifies protocol version used by milters, current is 6.
|
p #[code milter_protocol] specifies protocol version used by milters, current is 6.
|
||||||
p #[code smtpd_milters] is a list of milters the messages will go through. You can connect to milter with internet protocol with #[code inet:], with a unix socket #[code unix:]. The last one with port 7357 is a ClamAV by the way.
|
p #[code smtpd_milters] is a list of milters the messages will go through. You can connect to milter with internet protocol with #[code inet:], with a unix socket #[code unix:]. The last one with port 7357 is a ClamAV.
|
||||||
p Now lets do some tweaks:
|
p Now lets add some tweaks:
|
||||||
pre
|
pre
|
||||||
| biff = no
|
| biff = no
|
||||||
| strict_rfc821_envelopes = yes
|
| strict_rfc821_envelopes = yes
|
||||||
@ -115,11 +135,11 @@ block article
|
|||||||
|
|
|
|
||||||
| mailbox_size_limit = 0
|
| mailbox_size_limit = 0
|
||||||
| message_size_limit = 52428800
|
| message_size_limit = 52428800
|
||||||
p #[code biff] set to no, so the local service for new mail notifications disabled. We run on a server machine, we don't need them.
|
p #[code biff] set to no to disable local service for new mail notifications. It is a server, we don't need them here.
|
||||||
p #[code strict_rfc821_envelopes] set to yes require addresses to be enclosed with <>.
|
p #[code strict_rfc821_envelopes] set to yes require addresses to be enclosed with <>.
|
||||||
p Disabling VRFY command with #[code disable_vrfy_command] set to yes prevents some email addresses harvesting techniques.
|
p Disabling VRFY command with #[code disable_vrfy_command] prevents some email addresses harvesting techniques.
|
||||||
p #[code smtpd_helo_required] requires remote client to send HELO or EHLO command. This may stop some poorly written spam bots.
|
p #[code smtpd_helo_required] requires remote client to send HELO or EHLO command. This may stop some poorly written spam bots.
|
||||||
p #[code smtpd_delay_reject] makes Postfix wait until RCPT TO command before evaluating some restrictions.
|
p #[code smtpd_delay_reject] makes Postfix wait for RCPT TO command before evaluating some restrictions.
|
||||||
p #[code mailbox_size_limit] and #[code message_size_limit] sets maximum size of a whole mailbox and of each email. Here I set no limit for a mailbox, and max of 50MiB for an email message.
|
p #[code mailbox_size_limit] and #[code message_size_limit] sets maximum size of a whole mailbox and of each email. Here I set no limit for a mailbox, and max of 50MiB for an email message.
|
||||||
p And now it's time for SASL configuration:
|
p And now it's time for SASL configuration:
|
||||||
pre
|
pre
|
||||||
@ -129,12 +149,12 @@ block article
|
|||||||
| smtpd_sasl_security_options = noanonymous
|
| smtpd_sasl_security_options = noanonymous
|
||||||
| smtpd_sasl_local_domain = $mydomain
|
| smtpd_sasl_local_domain = $mydomain
|
||||||
| broken_sasl_auth_clients = no
|
| broken_sasl_auth_clients = no
|
||||||
p It's pretty clear. We chose dovecot as our SASL, set path to it withing /var/spool, and enable it. Then we set option to not allow anonymous connections. Set our domain for SASL, and wether let the clients with obsolete version of AUTH command in or not, we chose not to.
|
p It's pretty clear. We chose dovecot as our SASL server, set path to it that lies within /var/spool directory, and then enabled it. Then we prohibit anonymous connections. Add our domain for SASL authentication, and deny access for the clients with obsolete version of AUTH command.
|
||||||
p It's time for encryption, lets specify a list of high ciphers to use:
|
p It's time for encryption, lets specify a list of high (strong) ciphers to use:
|
||||||
pre
|
pre
|
||||||
| tls_high_cipherlist = ECDHE:DHE:kGOST:!aNULL:!eNULL:!RC4:!MD5:!3DES:!AES128:!CAMELLIA128:!ECDHE-RSA-AES256-SHA:!ECDHE-ECDSA-AES256-SHA
|
| tls_high_cipherlist = ECDHE:DHE:kGOST:!aNULL:!eNULL:!RC4:!MD5:!3DES:!AES128:!CAMELLIA128:!ECDHE-RSA-AES256-SHA:!ECDHE-ECDSA-AES256-SHA
|
||||||
p High means just that those ciphers are strong. I took this ciphers set from #[a(href="https://pub.nethence.com/security/ciphers") https://pub.nethence.com/security/ciphers].
|
p I took this ciphers set from #[a(href="https://pub.nethence.com/security/ciphers") https://pub.nethence.com/security/ciphers].
|
||||||
p Lets do client part of encryption.
|
p Now lets configure encryption for outgoing connections.
|
||||||
pre
|
pre
|
||||||
| smtp_use_tls = yes
|
| smtp_use_tls = yes
|
||||||
| smtp_tls_security_level = encrypt
|
| smtp_tls_security_level = encrypt
|
||||||
@ -145,11 +165,11 @@ block article
|
|||||||
| smtp_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
|
| smtp_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
|
||||||
| smtp_tls_protocols = $smtp_tls_mandatory_protocols
|
| smtp_tls_protocols = $smtp_tls_mandatory_protocols
|
||||||
| smtp_tls_mandatory_ciphers = high
|
| smtp_tls_mandatory_ciphers = high
|
||||||
p First we enable it with a #[code smtp_use_tls] option. Setting security level with (#[code smtp_tls_security_level]) to encrypt enforces use of encryption. Noting servers of our ability to use encryption with option #[code smtp_tls_note_starttls_offer]. Set to reuse connection instead of opening the new one each time.
|
p First we enable it with a #[code smtp_use_tls]. Enforce use of encryption with (#[code smtp_tls_security_level]) set to encrypt. Noting servers of our ability to use encryption with option #[code smtp_tls_note_starttls_offer]. Reuse connection instead of opening the new one each time.
|
||||||
p #[code smtp_tls_key_file] and #[code smtp_tls_cert_file] are paths to our encryption key and certificate.
|
p #[code smtp_tls_key_file] and #[code smtp_tls_cert_file] are paths to our TLS key and certificate.
|
||||||
p #[code smtp_tls_mandatory_protocols] and #[code smtp_tls_protocols] here we disallow old vulnerable protocols to use. Here only TLS version 1.2 and 1.3 are allowed.
|
p In #[code smtp_tls_mandatory_protocols] and #[code smtp_tls_protocols] we disallow old vulnerable protocols to use. Leave only TLS version 1.2 and 1.3 available.
|
||||||
p In #[code smtp_tls_mandatory_ciphers] we declare to use only good secure cyphers.
|
p In #[code smtp_tls_mandatory_ciphers] we declare to use only good secure cyphers we previously set.
|
||||||
p With server part everything is the same, just a few more options added:
|
p For incoming connections everything is the same, just a few more options added:
|
||||||
pre
|
pre
|
||||||
| smtpd_use_tls = yes
|
| smtpd_use_tls = yes
|
||||||
| smtpd_tls_security_level = encrypt
|
| smtpd_tls_security_level = encrypt
|
||||||
@ -163,10 +183,11 @@ block article
|
|||||||
| smtpd_tls_received_header = yes
|
| smtpd_tls_received_header = yes
|
||||||
| smtpd_tls_session_cache_timeout = 3600s
|
| smtpd_tls_session_cache_timeout = 3600s
|
||||||
| tls_random_source = dev:/dev/urandom
|
| tls_random_source = dev:/dev/urandom
|
||||||
p Security level is may, but for auth TLS is required. #[code smtpd_tls_loglevel] is for logging a summary of a TLS handshake.
|
p #[code smtpd_tls_auth_only] allows authorisation only on encrypted connections.
|
||||||
p #[code smtpd_tls_received_header] makes Postfix include information about the protocol and cypher used to a Received: header.
|
p #[code smtpd_tls_loglevel] set to 1 to log a summary of a TLS handshake.
|
||||||
|
p #[code smtpd_tls_received_header] makes Postfix include information about the protocol and cypher used to a #[code Received:] header.
|
||||||
p #[code smtpd_tls_session_cache_timeout] is for how long to store session. #[code tls_random_source] is for setting an entropy source.
|
p #[code smtpd_tls_session_cache_timeout] is for how long to store session. #[code tls_random_source] is for setting an entropy source.
|
||||||
p The final part is my "favorite". :) The restrictions! There is a set of them for each stage the message falls through. Here's the ones I configured:#[code smtpd_helo_restrictions], #[code smtpd_relay_restrictions], #[code smtpd_data_restrictions], #[code smtpd_sender_restrictions], and #[code smtpd_recipient_restrictions].
|
p The final part is my "favorite". :) The restrictions! There is a set of them for each stage the message falls through. Here are the ones I configured:#[code smtpd_helo_restrictions], #[code smtpd_relay_restrictions], #[code smtpd_data_restrictions], #[code smtpd_sender_restrictions], and #[code smtpd_recipient_restrictions].
|
||||||
p So lets roll. This my working restrictions setup:
|
p So lets roll. This my working restrictions setup:
|
||||||
pre
|
pre
|
||||||
| smtpd_helo_restrictions =
|
| smtpd_helo_restrictions =
|
||||||
@ -189,7 +210,7 @@ block article
|
|||||||
p In order to explain what every restriction does I'd have to copy-paste from #[code man 5 postconf]. :)
|
p In order to explain what every restriction does I'd have to copy-paste from #[code man 5 postconf]. :)
|
||||||
p The first set of restrictions are for HELO or EHLO command, that we force the client to send with priorly set option #[code smtpd_helo_required] to yes. Here #[code reject_unknown_helo_hostname] rejects hostnames that doesn't have DNS A or MX records. #[code reject_invalid_helo_hostname] rejects malformed hostnames, and #[code reject_non_fqdn_helo_hostname] ensures that the hostname is a fully-qualified domain name.
|
p The first set of restrictions are for HELO or EHLO command, that we force the client to send with priorly set option #[code smtpd_helo_required] to yes. Here #[code reject_unknown_helo_hostname] rejects hostnames that doesn't have DNS A or MX records. #[code reject_invalid_helo_hostname] rejects malformed hostnames, and #[code reject_non_fqdn_helo_hostname] ensures that the hostname is a fully-qualified domain name.
|
||||||
p The second one are for DATA command. And here man page is better than me at explaining it. Here is the link for #[a(href='http://www.postfix.org/postconf.5.html#reject_multi_recipient_bounce') reject_multi_recipient_bounce] and #[a(href='http://www.postfix.org/postconf.5.html#reject_unauth_pipelining') reject_unauth_pipelining]. All I can say is that it is better to have them than not to. :)
|
p The second one are for DATA command. And here man page is better than me at explaining it. Here is the link for #[a(href='http://www.postfix.org/postconf.5.html#reject_multi_recipient_bounce') reject_multi_recipient_bounce] and #[a(href='http://www.postfix.org/postconf.5.html#reject_unauth_pipelining') reject_unauth_pipelining]. All I can say is that it is better to have them than not to. :)
|
||||||
p The rest is simpler, #[code permit_sasl_authenticated] in #[code smtpd_sender_restrictions] accepts the senders that were authenticated by SALS (e.g. Dovecot or Cyrus). And all the #[code reject_unknown_*] and #[code reject_non_fqdn_*] has the same meaning as for theirs *_helo_* counterparts, just used in theirs specific places.
|
p The rest is simpler, #[code permit_sasl_authenticated] in #[code smtpd_sender_restrictions] accepts the senders that were authenticated by SASL (e.g. Dovecot or Cyrus). And all the #[code reject_unknown_*] and #[code reject_non_fqdn_*] has the same meaning as for theirs *_helo_* counterparts, just used in theirs specific places.
|
||||||
|
|
||||||
h4#art-3-2 #[a(href='#art-3-2') 3.2. master.cf]
|
h4#art-3-2 #[a(href='#art-3-2') 3.2. master.cf]
|
||||||
p The following services are needed: #[code smtp], #[code submission], #[code smtps], and we add #[code spamassassin] service. The rest in this file left untouchable.
|
p The following services are needed: #[code smtp], #[code submission], #[code smtps], and we add #[code spamassassin] service. The rest in this file left untouchable.
|
||||||
@ -215,12 +236,111 @@ block article
|
|||||||
p #[code smtp] is listening on port 25, and #[code smtps] on port 465. #[code submission] is listening on port 587 and is used by mail client to send mail.
|
p #[code smtp] is listening on port 25, and #[code smtps] on port 465. #[code submission] is listening on port 587 and is used by mail client to send mail.
|
||||||
|
|
||||||
h4#art-3-3 #[a(href='#art-3-3') 3.3. User aliases]
|
h4#art-3-3 #[a(href='#art-3-3') 3.3. User aliases]
|
||||||
p User aliases are in #[code aliases] file. They has a form "#[code <alias>: <username>]", e.g. #[code me: arav]. Where #[code username] may be other alias. After modifications you need to run #[code newaliases] program to update #[code aliases.db] database file.
|
p User aliases are in #[code aliases] file. They has a form "#[code <alias>: <username>]", e.g. #[code me: arav]. Where #[code username] may be other alias. After editing you need to run #[code newaliases] program to update #[code aliases.db] file.
|
||||||
|
|
||||||
h4#art-3-4 #[a(href='#art-3-4') 3.4. Starting Postfix]
|
h4#art-3-4 #[a(href='#art-3-4') 3.4. Starting Postfix]
|
||||||
p To start a Postfix service on systemd-based Linux distro run #[code systemctl start postfix]. To make Postfix run on every boot run #[code systemctl enable postfix].
|
p To start a Postfix service on systemd-based Linux distro run #[code systemctl start postfix]. To make Postfix run on every boot run #[code systemctl enable postfix].
|
||||||
|
|
||||||
h3#art-4 #[a(href='#art-4') 4. Dovecot POP3/IMAP server with Sieve mail filter]
|
h3#art-4 #[a(href='#art-4') 4. Dovecot POP3/IMAP server with Sieve mail filter]
|
||||||
|
p As I stated in the Introduction I use only IMAP, since it keeps mail on a server.
|
||||||
|
p First we need to create a #[code /etc/dovecot] directory and copy example configuration there, but we don't need everything. Example configuration lies in a #[code /usr/share/doc/dovecot/example-config] directory.
|
||||||
|
p Copy #[code dovecot.conf] file and #[code conf.d] directory.
|
||||||
|
p We will need #[code dovecot.conf] and files from a #[code conf.d] directory: 10-auth.conf, 10-mail.conf, 10-ssl.conf, 15-mailboxes.conf, 20-lmtp.conf, 90-sieve.conf, 10-logging.conf, 10-master.conf, 15-lda.conf, 20-managesieve.conf, auth-system.conf.ext.
|
||||||
|
p Here I will leave a brief necessary explanation of options, since you will see theirs documentation when will be editing configs.
|
||||||
|
|
||||||
|
h4#art-4-1 #[a(href='#art-4-1') 4.1. Configuration files]
|
||||||
|
|
||||||
|
h5#art-4-1-1 #[a(href='#art-4-1-1') 4.1.1. dovecot.conf]
|
||||||
|
pre
|
||||||
|
| protocols = imap lmtp sieve
|
||||||
|
p Here we activate IMAP for access to mailbox, LMTP for local message delivery from Postfix and Sieve protocol for user-defined custom filters.
|
||||||
|
pre
|
||||||
|
| listen = *
|
||||||
|
p Here we simply tell Dovecot to listen on all available interfaces.
|
||||||
|
pre
|
||||||
|
| base_dir = /var/run/dovecot
|
||||||
|
p Uncomment setting to set a base directory for runtime files.
|
||||||
|
pre
|
||||||
|
| instance_name = dovecot
|
||||||
|
p A new for this instance. In case you run multiple you can set a different names for them.
|
||||||
|
pre
|
||||||
|
| login_greeting = Dovecot ready.
|
||||||
|
p A greeting message for the clients.
|
||||||
|
pre
|
||||||
|
| login_trusted_networks = 192.168.0.0/24 192.168.1.0/24
|
||||||
|
p A list of trusted network ranges.
|
||||||
|
pre
|
||||||
|
| shutdown_clients = yes
|
||||||
|
p I chose to force closing client connections on master process shutdown.
|
||||||
|
p Here we are done with #[code dovecot.conf] file and let's go to #[code conf.d] directory.
|
||||||
|
|
||||||
|
h5#art-4-1-2 #[a(href='#art-4-1-2') 4.1.2. 10-auth.conf]
|
||||||
|
pre
|
||||||
|
| disable_plaintext_auth = yes
|
||||||
|
p It disables login without encryption.
|
||||||
|
pre
|
||||||
|
| auth_realms = example.org
|
||||||
|
p A list of realms for SASL authentication. Just leave here your domain.
|
||||||
|
pre
|
||||||
|
| auth_username_format = %Ln
|
||||||
|
p I chose to drop domain.
|
||||||
|
pre
|
||||||
|
| auth_mechanisms = plain
|
||||||
|
p I use a plain mechanism.
|
||||||
|
p And, finally, at the bottom leave #[code auth-system.conf.ext] include directive.
|
||||||
|
|
||||||
|
h5#art-4-1-3 #[a(href='#art-4-1-3') 4.1.3. 10-logging.conf]
|
||||||
|
p Simply uncomment #[code log_path = syslog] there.
|
||||||
|
|
||||||
|
h5#art-4-1-4 #[a(href='#art-4-1-4') 4.1.4. 10-mail.conf]
|
||||||
|
p In #[code 10-mail.conf] we set following:
|
||||||
|
pre
|
||||||
|
| mail_location = maildir:~/Maildir
|
||||||
|
p We use Maildir/ scheme and store it in user's home directory.
|
||||||
|
p Next set #[code mail_server_admin = admin@%d], or whatever name you want. Here #[code %d] will expand to a domain.
|
||||||
|
|
||||||
|
h5#art-4-1-5 #[a(href='#art-4-1-5') 4.1.5. 10-master.conf]
|
||||||
|
p In section #[code service imap-login] uncomment everything in #[code inet_listener] sub-sections for IMAP and IMAPS.
|
||||||
|
p If you want to use POP3 protocol, then do the same for #[code service pop3-login] section.
|
||||||
|
p Go to #[code service lmtp] section and add following sub-section to enable LMTP service on a UNIX socket:
|
||||||
|
pre
|
||||||
|
| unix_listener /var/spool/postfix/private/dovecot-lmtp {
|
||||||
|
| group = postfix
|
||||||
|
| user = postfix
|
||||||
|
| mode = 0666
|
||||||
|
| }
|
||||||
|
p Then go to #[code service auth] section and add following UNIX listener:
|
||||||
|
pre
|
||||||
|
| unix_listener /var/spool/postfix/private/auth {
|
||||||
|
| user = postfix
|
||||||
|
| mode = 0666
|
||||||
|
| }
|
||||||
|
|
||||||
|
h5#art-4-1-6 #[a(href='#art-4-1-6') 4.1.6. 10-ssl.conf]
|
||||||
|
p Set #[code ssl = required] to enable and enforce encryption.
|
||||||
|
p In #[code ssl_cert] and #[code ssl_key] set paths to your TLS certificate and key.
|
||||||
|
p Next you will see #[code ssl_key_password] where you type in your certificate's password if it is set.
|
||||||
|
p And if you run your own PKI then you can specify your CA cert in #[code ssl_ca].
|
||||||
|
p Next good thing to do is to generate Diffie-Hellmann parameters file and set it in #[code ssl_dh] option. How to do it is written in a help comment for this option.
|
||||||
|
p Next set a cipher list #[code ssl_cipher_list] to a list you previously specified in Postfix's #[code main.cf] file.
|
||||||
|
p And finally #[code ssl_prefer_server_ciphers = yes].
|
||||||
|
|
||||||
|
h5#art-4-1-7 #[a(href='#art-4-1-7') 4.1.7. 15-lda.conf]
|
||||||
|
p Here we simply uncomment and set #[code mail_plugins = $mail_plugins sieve] in #[code protocol lda] section.
|
||||||
|
|
||||||
|
h5#art-4-1-8 #[a(href='#art-4-1-8') 4.1.8. 15-mailboxes.conf]
|
||||||
|
p Here in a namespace inbox leave Drafts, Junk, Trash, and Sent mailboxes. Additionally, for every mailbox I added #[code auto = subscribe] options so they will appear in a mail client.
|
||||||
|
|
||||||
|
h5#art-4-1-9 #[a(href='#art-4-1-9') 4.1.9. 20-managesieve.conf]
|
||||||
|
p Uncomment #[code protocols] option, #[code service managesieve-login], and #[code service managesieve] sections.
|
||||||
|
p Within #[code service managesieve-login] section uncomment fully #[code inet_listener sieve] sub-section. And next you can tweak #[code service_count], #[code process_min_avail] and #[code vsz_limit] options to your taste.
|
||||||
|
|
||||||
|
h5#art-4-1-10 #[a(href='#art-4-1-10') 4.1.10. 90-sieve.conf]
|
||||||
|
p Here I just have #[code sieve_before = /var/lib/dovecot/sieve.d/] option uncommented, the rest is default.
|
||||||
|
|
||||||
|
h5#art-4-1-11 #[a(href='#art-4-1-11') 4.1.11. auth-system.conf.ext]
|
||||||
|
p Here is default except for in passdb I added #[code failure_show_msg=yes] in #[code args].
|
||||||
|
|
||||||
|
|
||||||
h3#art-5 #[a(href='#art-5') 5. SpamAssassin spam filter]
|
h3#art-5 #[a(href='#art-5') 5. SpamAssassin spam filter]
|
||||||
p Here we are working with a #[code local.cf] file to configure SpamAssassin.
|
p Here we are working with a #[code local.cf] file to configure SpamAssassin.
|
||||||
@ -239,14 +359,15 @@ block article
|
|||||||
|
|
||||||
h4#art-5-2 #[a(href='#art-5-2') 5.2. Bayesian classifier training]
|
h4#art-5-2 #[a(href='#art-5-2') 5.2. Bayesian classifier training]
|
||||||
p After you set up SpamAssassin for the first time you have to train Bayesian classifier. It will start to work after 200 messages will be examined.
|
p After you set up SpamAssassin for the first time you have to train Bayesian classifier. It will start to work after 200 messages will be examined.
|
||||||
p For training use #[code sa-learn] utility and use #[code --ham] and #[code --spam] to mark messages as normal mail and spam. I additionaly have to specify a path to database with #[code --dbpath /var/lib/spamassassin/.spamassassin] option, otherwise it will complain, so try first without it.
|
p For training use #[code sa-learn] utility and use #[code --ham] and #[code --spam] to mark messages as normal mail and spam. I additionaly have to specify a path to database with #[code --dbpath /var/lib/spamassassin/.spamassassin], otherwise it will complain, so try first without it.
|
||||||
|
|
||||||
|
|
||||||
h3#art-6 #[a(href='#art-6') 6. OpenDKIM signing and verifying filter]
|
h3#art-6 #[a(href='#art-6') 6. OpenDKIM signing and verifying filter]
|
||||||
p On ArchLinux OpenDKIM is unable to write in #[code /run], so I created #[code /var/spool/opendkim] directory for it.
|
p On ArchLinux I got a problem that OpenDKIM is unable to write in #[code /run], so I created #[code /var/spool/opendkim] directory for it.
|
||||||
|
p After configuring it, you need to add DNS record with your public key, it is covered in #[a href='#art-8-5'] section.
|
||||||
|
|
||||||
h4#art-6-1 #[a(href='#art-6-1') 6.1. opendkim.conf]
|
h4#art-6-1 #[a(href='#art-6-1') 6.1. opendkim.conf]
|
||||||
p Well, that's main config file
|
p Well, that's main config file:
|
||||||
pre
|
pre
|
||||||
| KeyTable refile:/etc/opendkim/keytable
|
| KeyTable refile:/etc/opendkim/keytable
|
||||||
| SigningTable refile:/etc/opendkim/signingtable
|
| SigningTable refile:/etc/opendkim/signingtable
|
||||||
@ -362,8 +483,9 @@ block article
|
|||||||
p In 5.2 we generated a key pair for our domain and now we'll take what's inside a #[code myselector.txt] file and add it to our DNS.
|
p In 5.2 we generated a key pair for our domain and now we'll take what's inside a #[code myselector.txt] file and add it to our DNS.
|
||||||
p DKIM DNS record looks like this:
|
p DKIM DNS record looks like this:
|
||||||
pre
|
pre
|
||||||
| myselector._domainkey IN TXT ( "v=DKIMv1; k=rsa; s=email; p=<public key goes here>" )
|
| myselector._domainkey IN TXT ( "v=DKIMv1; k=rsa; s=email; p=<public key goes here>"
|
||||||
p By the way, brackets are used in case a content of a record doesn't fit on one line.
|
| "<public key continues here>" )
|
||||||
|
p Brackets are used in case a content of a record doesn't fit on one line, and it won't fit.
|
||||||
|
|
||||||
h3#art-9 #[a(href='#art-9') 9. Setting up a ClamAV antivirus]
|
h3#art-9 #[a(href='#art-9') 9. Setting up a ClamAV antivirus]
|
||||||
p All you need to make it work together with Postfix is to add #[code /run/clamav/milter.sock] to #[code smtpd_milters] and #[code non_smtpd_milters] options in Postfix, also make some changes in configs of ClamAV.
|
p All you need to make it work together with Postfix is to add #[code /run/clamav/milter.sock] to #[code smtpd_milters] and #[code non_smtpd_milters] options in Postfix, also make some changes in configs of ClamAV.
|
||||||
@ -373,7 +495,7 @@ block article
|
|||||||
| ClamdSocket unix:/run/clamav/clamd.ctl
|
| ClamdSocket unix:/run/clamav/clamd.ctl
|
||||||
p Also, in case you need ClamAV to add headers also in case a message is free of viruses add #[code AddHeader Add] or #[code AddHeader Replace] option. The difference between them is detaily described in config file itself.
|
p Also, in case you need ClamAV to add headers also in case a message is free of viruses add #[code AddHeader Add] or #[code AddHeader Replace] option. The difference between them is detaily described in config file itself.
|
||||||
p Before starting ClamAV you need to update its virus definitions with #[code freshclam] util. Also, enable and start #[code clamav-freshclam] systemd service to keep definitions recent.
|
p Before starting ClamAV you need to update its virus definitions with #[code freshclam] util. Also, enable and start #[code clamav-freshclam] systemd service to keep definitions recent.
|
||||||
p I don't know how it is in other distros, but, for whatever reason, an Arch Linux's package doesn't have a systemd service file for the ClamAV milter. So I just copy it here from <a href="https://wiki.archlinux.org/index.php/ClamAV#Using_the_milter" rel="noopener noreferrer" target="_blank">ArchWiki</a>:
|
p I don't know how it is in other distros, but, for whatever reason, an Arch Linux's package doesn't come with a systemd service file for the ClamAV milter. So I just copy it here from <a href="https://wiki.archlinux.org/index.php/ClamAV#Using_the_milter" rel="noopener noreferrer" target="_blank">ArchWiki</a>:
|
||||||
pre
|
pre
|
||||||
| [Unit]
|
| [Unit]
|
||||||
| Description='ClamAV Milter'
|
| Description='ClamAV Milter'
|
||||||
|
Loading…
Reference in New Issue
Block a user