Support #653
Updated by Daniel Curtis over 9 years ago
{{>toc}} This is a guide on installing Dovecot and Postfix with Nginx, PostgreSQL, and SpamAssassin on FreeBSD. This guide is adapted from the mail server setup at "purplehat.org":http://www.purplehat.org/?page_id=4 h2. Prepare the System * Make sure the system is up to date: <pre> pkg update && pkg upgrade </pre> * Install portmaster and screen: <pre> pkg install portmaster screen </pre> * Update the ports tree: <pre> portsnap fetch extract pkg2ng </pre> h2. Configure the Ports * This builds ClamAV to allow our “vscan” user access to it. Add ClamAV build options to @/etc/make.conf@ file: <pre> echo "CLAMAVUSER=vscan" >> /etc/make.conf echo "CLAMAVGROUP=vscan" >> /etc/make.conf </pre> * Add BATCH option to @/etc/make.conf@ file: <pre> echo "BATCH=yes" >> /etc/make.conf </pre> * Edit pear-Net_SMTP installation menu: <pre> cd /usr/ports/net/pear-Net_SMTP make config </pre> #* *NOTE*: Make sure *[X]PEAR_AUTH_SASL* is selected. * Edit pear-Auth Options installation menu: <pre> cd /usr/ports/security/pear-Auth make config </pre> #* *NOTE*: Make sure *[X]PEAR_DB* and *[X]PEAR_LOG* are selected. * Edit pear-Log installation menu: <pre> cd /usr/ports/sysutils/pear-Log make config </pre> #* *NOTE*: Make sure *[X]PEAR_DB* is selected. * Edit Dovecot installation menu: <pre> cd /usr/ports/mail/dovecot2 make config </pre> #* *NOTE*: Make sure *[X]PGSQL* is selected. * Edit Postfix installation menu: <pre> cd /usr/ports/mail/postfix make config </pre> #* *NOTE*: Make sure *[X]BDB*, *[X]PGSQL*, *[X]TLS*, *[X]VDA* and *[X]DOVECOT2* are selected. * Edit Postfixadmin installation menu: <pre> cd /usr/ports/mail/postfixadmin make config </pre> *NOTE*: Make sure *[X]PGSQL* is selected. * Edit SpamAssassin installation menu: <pre> cd /usr/ports/mail/spamassassin make config </pre> #* *NOTE*: Make sure *[X]PGSQL*, *[X]DKIM*, *[X]RAZOR*, *[X]RELAY_COUNTRY* and *[X]SPF_QUERY* are selected. * Edit Maia-Mailguard installation menu: <pre> cd /usr/ports/security/maia make config </pre> #* *NOTE*: Make sure the *[X]DOVECOT2*, *[X]FUZZYOCR*, *[X]PGSQL*, *[X]PFA*, *[X]POSTFIX* and *[X]WEBHOST* options are selected. Also make sure to unset the *[ ]MYSQL* option. Feel free to select any additional options you may want. h2. Install Maia Mailguard * Install Maia-Mailguard: <pre> portmaster security/maia </pre> * Set password for “vscan” user to *SuperSecretPassword*: <pre> passwd vscan </pre> h2. Install PostgreSQL * This environment will be setup with PostgreSQL 9.4: <pre> portmaster databases/postgresql94-server </pre> * Login to PostgreSQL: <pre> sudo -u postgres psql -d template1 </pre> * Create a user for maiauser: <pre> CREATE USER maiauser CREATEDB; ALTER ROLE maiauser WITH PASSWORD 'SuperSecretPassword'; </pre> * Create the maiadb database & grant all privileges on database <pre> CREATE DATABASE maiadb OWNER maiauser; </pre> * Quit the database session <pre> \q </pre> * Try connecting to the new database with the new user <pre> sudo -u maiauser -H psql -d maiadb </pre> * Quit the database session <pre> \q </pre> * Populate the database: <pre> cd /usr/local/share/doc/maia psql -h pg.example.com -U maiauser -W maiadb < maia-pgsql.sql </pre> h2. Configure Dovecot * Install Dovecot Pigeonhole: <pre> cd /usr/ports/mail/dovecot2-pigeonhole portmaster mail/dovecot2-pigeonhole security/bcrypt </pre> * Edit /etc/rc.conf so Dovecot starts at boot: <pre> echo 'dovecot_enable="YES"' >> /etc/rc.conf </pre> * Copy Dovecot configuration files: <pre> cd /usr/local/etc/dovecot/example-config cp -Rp * ../ </pre> * Edit the dovecot auth config file: <pre> vi /usr/local/etc/dovecot/conf.d/10-auth.conf </pre> #* And edit the following: <pre> ... disable_plaintext_auth = no ... auth_mechanisms = plain login ... #!include auth-system.conf.ext !include auth-sql.conf.ext </pre> * Edit the dovecor mail config file: <pre> vi /usr/local/etc/dovecot/conf.d/10-mail.conf </pre> #* And modify the following: <pre> ... mail_location = maildir:/usr/local/virtual/%d/%n ... namespace inbox { type = private separator = / mailbox Sent { auto = subscribe special_use = \Sent } mailbox Drafts { auto = subscribe special_use = \Drafts } mailbox Trash { auto = subscribe special_use = \Trash } mailbox Spam { auto = subscribe special_use = \Junk } ... first_valid_uid = 110 last_valid_uid = 110 ... first_valid_gid = 110 last_valid_gid = 110 ... mail_plugins = mail_log notify ... </pre> * Edit the dovecot master config file: <pre> vi /usr/local/etc/dovecot/conf.d/10-master.conf </pre> #* And modify the following <pre> ... unix_listener auth-userdb { mode = 0660 user = vscan group = vscan } #Postfix smtp-auth unix_listener /var/spool/postfix/private/auth { mode = 0660 user = postfix group = postfix } ... </pre> * Edit the dovecot ssl config file: <pre> vi /usr/local/etc/dovecot/conf.d/10-ssl.conf </pre> #* And modify the following: <pre> ... ssl = yes ... ssl_cert = </usr/local/etc/ssl/mail.example.com.crt </usr/local/etc/ssl/dovecot/cert.pem ssl_key = </usr/local/etc/ssl/mail.example.com.key </usr/local/etc/ssl/dovecot/key.pem ... ssl_ca = </usr/local/etc/ssl/mail.example.com.crt </usr/local/etc/ssl/dovecot/cert.pem ... ssl_verify_client_cert = yes ... ssl_protocols = !SSLv2 !SSLv3 ... </pre> * Edit the dovecot lda config file: <pre> vi /usr/local/etc/dovecot/conf.d/15-lda.conf </pre> #* And modify the following: <pre> ... postmaster_address = postmaster@example.com ... hostname = mail.example.com ... sendmail_path = /usr/local/sbin/sendmail ... lda_mailbox_autocreate = yes ... protocol lda { # Space separated list of plugins to load (default is global mail_plugins). mail_plugins = $mail_plugins sieve ... </pre> * Edit the dovecot imap config file: <pre> vi /usr/local/etc/dovecot/conf.d/20-imap.conf </pre> #* And modify the following: <pre> ... protocol imap { # Space separated list of plugins to load (default is global mail_plugins). mail_plugins = $mail_plugins quota imap_quota zlib ... </pre> * Edit the dovecot pop3 config file: <pre> vi /usr/local/etc/dovecot/conf.d/20-pop3.conf </pre> #* And modify the following: <pre> ... pop3_client_workarounds = outlook-no-nuls oe-ns-eoh ... mail_plugins = $mail_plugins ... </pre> * Edit the dovecot plugin config file: <pre> vi /usr/local/etc/dovecot/conf.d/90-plugin.conf </pre> #* And modify the following: <pre> ... plugin { #setting_name = value expire = Trash mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename mail_log_fields = uid box msgid size } plugin { sieve = /usr/local/virtual/home/%d/%n/.dovecot.sieve sieve_dir = /usr/local/virtual/home/%d/%n/sieve sieve_global_path = /usr/local/virtual/home/default.sieve mail_home = /usr/local/virtual/home/%d/%n } ... </pre> * Edit the dovecot quota config file: <pre> vi /usr/local/etc/dovecot/conf.d/90-quota.conf </pre> #* And modify the following: <pre> ... service quota-warning { executable = script /usr/local/bin/quota-warning.sh user = dovecot unix_listener quota-warning { user = vscan } } ... (Add to end of file...) plugin { #Where is quota applied ? quota = maildir:User quota # the default quota storage bytes, overrides are fetched from userdb [userdb_quota_ruleX] quota_rule = *:storage=1G #Storage bytes overrides quota_rule2 = Trash:storage=+30%% quota_rule3 = Sent:storage=+30%% quota_warning = storage=90%% quota-warning 90 %u quota_warning2 = storage=75%% quota-warning 75 %u #What message to send to IMAP clients (and SMTP senders) when quota is exceeded? quota_exceeded_message = Storage quota for this account has been exceeded, please try again later. } ... </pre> * Create Sieve home directory: <pre> mkdir -p /usr/local/virtual/home </pre> * Create the default.sieve file: <pre> vi /usr/local/virtual/home/default.sieve </pre> #* And add the following: <pre> require ["fileinto"]; # rule:[Spam] if header :contains "X-Spam-Status" "Yes" { fileinto "Spam"; stop; } </pre> * Run the sievec command against our default sieve file: <pre> sievec /usr/local/virtual/home/default.sieve </pre> * Set proper permissions on our virtual directory: <pre> chown -R vscan:vscan /usr/local/virtual chmod 0750 /usr/local/virtual </pre> * Edit the dovecot sql config file: <pre> vi /usr/local/etc/dovecot/dovecot-sql.conf.ext </pre> #* And modify the following: <pre> ... driver = pgsql ... connect = host=pg.example.com dbname=postfix user=postfix password=postfix_sql_password ... default_pass_scheme = BLF-CRYPT MD5 ... password_query = SELECT password, CONCAT('*:bytes=', quota) AS userdb_quota_rule FROM mailbox WHERE username = '%u' AND active = '1' ... user_query = SELECT CONCAT('/usr/local/virtual/', maildir) as home, 110 AS uid, 110 AS gid, CONCAT('*:bytes=', quota) AS quota_rule \ FROM mailbox WHERE username = '%u' AND active = '1' ... </pre> #* *NOTE*: The user_query line contains a bit in the query to allow Dovecot to return quota usage. If you don’t want or don’t need quota usage returned, you can just remove that bit from the query… * Edit the main dovecot config file: <pre> vi /usr/local/etc/dovecot/dovecot.conf vi/usr/local/etc/dovecot/dovecot.conf </pre> #* And modify the following: <pre> ... protocols = imap pop3 sieve ... login_greeting = example.com Mail Server Ready... ... </pre> * Add the dovecot user to vscan group for LDA/delivery: <pre> pw usermod dovecot -G vscan </pre> * Create SSL/TLS key and CSR to have signed for a certificate for secure connections: <pre> mkdir -p /usr/local/etc/ssl/dovecot cd /usr/local/etc/ssl /usr/local/etc/ssl/dovecot openssl req -sha512 -out mail.example.com.csr -new -newkey rsa:4096 -nodes -keyout mail.example.com.key </pre> h2. Configure Postfix * Disable Sendmail and start Postfix at boot: <pre> echo 'sendmail_enable="NO"' >> /etc/rc.conf echo 'sendmail_submit_enable="NO"' >> /etc/rc.conf echo 'sendmail_outbound_enable="NO"' >> /etc/rc.conf echo 'sendmail_msp_queue_enable="NO"' >> /etc/rc.conf echo 'postfix_enable="YES"' >> /etc/rc.conf </pre> * Create and add Postfix stuffs to the /etc/periodic.conf file: <pre> echo 'daily_clean_hoststat_enable="NO"' >> /etc/periodic.conf echo 'daily_status_mail_rejects_enable="NO"' >> /etc/periodic.conf echo 'daily_status_include_submit_mailq="NO"' >> /etc/periodic.conf echo 'daily_submit_queuerun="NO"' >> /etc/periodic.conf </pre> * Edit the main postfix config file: <pre> vi /usr/local/etc/postfix/main.cf </pre> #* And modify the following: <pre> ... soft_bounce = no # SASL CONFIG broken_sasl_auth_clients = yes smtpd_sender_restrictions = permit_sasl_authenticated, permit_mynetworks smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_non_fqdn_hostname, reject_non_fqdn_sender, reject_non_fqdn_recipient, reject_unauth_destination, reject_unauth_pipelining, reject_invalid_hostname, reject_rbl_client bl.spamcop.net, reject_rbl_client sbl-xbl.spamhaus.org, reject_rbl_client zen.spamhaus.org, reject_rbl_client dnsbl.sorbs.net, reject_rbl_client rhsbl.sorbs.net, reject_rbl_client db.wpbl.info, reject_rbl_client cbl.abuseat.org, reject_rbl_client proxies.blackholes.wirehub.net, reject_rbl_client query.bondedsender.org smtpd_sasl_auth_enable = yes smtpd_sasl_authenticated_header = yes smtpd_sasl_local_domain = $myhostname smtpd_sasl_security_options = noanonymous smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth # TLS CONFIG smtp_use_tls = yes smtpd_use_tls = yes smtp_tls_note_starttls_offer = yes smtpd_tls_key_file = /usr/local/etc/ssl/postfix/smtpd.pem smtpd_tls_cert_file = /usr/local/etc/ssl/postfix/smtpd.pem smtpd_tls_CAfile = /usr/local/etc/ssl/postfix/smtpd.pem smtpd_tls_loglevel = 0 smtpd_tls_received_header = yes smtpd_tls_session_cache_timeout = 3600s smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3 tls_random_source = dev:/dev/urandom #PostgreSQL Configuration virtual_alias_maps = proxy:mysql:/usr/local/etc/postfix/mysql_virtual_alias_maps.cf virtual_gid_maps = static:125 virtual_mailbox_base = /usr/local/virtual virtual_mailbox_domains = proxy:mysql:/usr/local/etc/postfix/mysql_virtual_domains_maps.cf virtual_mailbox_limit = 51200000 virtual_mailbox_maps = proxy:mysql:/usr/local/etc/postfix/mysql_virtual_mailbox_maps.cf virtual_minimum_uid = 125 virtual_transport = dovecot virtual_uid_maps = static:125 # Additional for quota support virtual_mailbox_limit_maps = proxy:mysql:/usr/local/etc/postfix/mysql_virtual_mailbox_limit_maps.cf proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps virtual_mailbox_limit_override = yes virtual_maildir_limit_message = Sorry, this user has overdrawn their diskspace quota. Please try again later. virtual_overquota_bounce = yes maximal_queue_lifetime = 4h bounce_queue_lifetime = 4h # Adjusted message size limit. message_size_limit = 25600000 ... myhostname = host.domain.tld ... mydomain = domain.tld ... mydestination = localhost.$mydomain, localhost ... relay_domains = proxy:mysql:/usr/local/etc/postfix/mysql_relay_domains_maps.cf ... relay_recipient_maps = proxy:mysql:/usr/local/etc/postfix/mysql_virtual_mailbox_maps.cf ... # TRANSPORT MAP # # See the discussion in the ADDRESS_REWRITING_README document. dovecot_destination_recipient_limit = 1 ... </pre> * Edit the master postfix config file: <pre> /usr/local/etc/postfix/master.cf </pre> #* And modify the following: <pre> ... submission inet n - n - - smtpd -o smtpd_enforce_tls=yes ... -o smtpd_sasl_auth_enable=yes ... -o smtpd_client_restrictions=permit_sasl_authenticated,reject ... -o smtpd_relay_restrictions=permit_sasl_authenticated,reject ... smtps inet n - n - - smtpd ... -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes ... -o smtpd_client_restrictions=permit_sasl_authenticated,reject ... -o smtpd_relay_restrictions=permit_sasl_authenticated,reject ... (At the end of the file, add) dovecot unix - n n - - pipe flags=DRhu user=vscan:vscan argv=/usr/local/libexec/dovecot/deliver -f ${sender} -d ${recipient} ... </pre> * Create and edit postgresql virtual alias map file: <pre> vi /usr/local/etc/postfix/pgsql_virtual_alias_maps.cf </pre> #* And add the following: <pre> user = postfix password = postfix_sql_password hosts = localhost dbname = postfix query = SELECT goto FROM alias WHERE address='%s' AND active = '1' </pre> * Create and edit postgresql virtual domain map file: <pre> vi /usr/local/etc/postfix/pgsql_virtual_domains_maps.cf </pre> #* And add the following: <pre> user = postfix password = postfix_sql_password hosts = localhost dbname = postfix query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '0' and active = '1' </pre> * Create and edit postgresql virtual mailbox map file: <pre> vi /usr/local/etc/postfix/pgsql_virtual_mailbox_maps.cf </pre> #* And add the following: <pre> user = postfix password = postfix_sql_password hosts = localhost dbname = postfix query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1' </pre> * Create and edit file: <pre> vi /usr/local/etc/postfix/pgsql_virtual_mailbox_limit_maps.cf </pre> #* And add the following: <pre> user = postfix password = postfix_sql_password hosts = localhost dbname = postfix query = SELECT quota FROM mailbox WHERE username='%s' </pre> * Create and edit the postgresql relay domain map file: <pre> vi /usr/local/etc/postfix/pgsql_relay_domains_maps.cf </pre> #* And add the following: <pre> user = postfix password = postfix_sql_password hosts = localhost dbname = postfix query = SELECT domain FROM domain WHERE domain='%s' and backupmx = '1' </pre> * Secure Postfix’s PostgreSQL files: <pre> chmod 640 /usr/local/etc/postfix/pgsql_* chgrp postfix /usr/local/etc/postfix/pgsql_* </pre> * Create the transport file and update the transport map database: <pre> touch /usr/local/etc/postfix/transport postmap /usr/local/etc/postfix/transport </pre> * Edit aliases file, uncomment and change “root” to an email address you want system messages to be mailed to: <pre> vi /etc/aliases </pre> #* And modify the following: <pre> root: user@example.com </pre> * Create aliases.db file: /usr/bin/newaliases h2. Resources * http://www.purplehat.org/?page_id=4 * http://www.maiamailguard.com/maia/wiki/Install