Project

General

Profile

Support #653

Updated by Daniel Curtis over 8 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 

Back