Differences

This shows you the differences between two versions of the page.

Link to this comparison view

tech:linux:mail_server_setup [2020/02/11 06:26]
tech:linux:mail_server_setup [2023/10/19 06:33] (current)
Line 1: Line 1:
 +====== Mail Server Setup ======
 +This is how I set up my mail server on
 +  * Ubuntu Ubuntu 14.04.5 LTS
 +  * Dovecot 2.2.9 (dovecot --version)
 +  * Postfix 2.11.0 (postconf mail_version)
 +  * Postfix Admin 2.3.5
 +  * Squirrel Mail 1.4.22 ​
 +  * MySQL Ver 14.14 Distrib 5.5.57 (mysql --version)
 +  * PHP 5.5.9 (php --version)
 +  * pflogsumm.pl - Produce Postfix MTA logfile summary
 +  * Fail2Ban v0.8.11 (/​usr/​bin/​fail2ban-server --version)
 +  * [[doveadm_scripting|Automatic email processing using Doveadm]]
  
 +===== Supporting Packages to Install =====
 +  * postfix-mysql
 +  * dovecot-core
 +  * dovecot-postfix (not valid anymore in 2022)
 +  * dovecot-mysql
 +  * dovecot-imapd
 +  * php5-mysql
 +
 +===== Server configuration =====
 +==== vmail user configuration ====
 +<code bash>
 +groupadd -g 5000 vmail
 +useradd -d /home/vmail -g 5000 -m -s /bin/bash -u 5000 -p somepassword vmail
 +id vmail
 +</​code>​
 +uid=5000(vmail) gid=5000(vmail) groups=5000(vmail)
 +
 +===== Postfix configuration =====
 +/​etc/​postfix/​main.cf
 +
 +<file ini main.cf>
 +# See /​usr/​share/​postfix/​main.cf.dist for a commented, more complete version
 +
 +
 +# Debian specific: ​ Specifying a file name will cause the first
 +# line of that file to be used as the name.  The Debian default
 +# is /​etc/​mailname.
 +myorigin = /​etc/​mailname
 +
 +smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
 +biff = no
 +
 +# appending .domain is the MUAs job.
 +append_dot_mydomain = no
 +
 +# Uncomment the next line to generate "​delayed mail" warnings
 +delay_warning_time = 4h
 +
 +readme_directory = no
 +
 +# TLS parameters
 +smtpd_tls_cert_file = /​etc/​ssl/​certs/​ssl-mail.pem
 +smtpd_tls_key_file = /​etc/​ssl/​private/​ssl-mail.key
 +smtpd_tls_loglevel = 1
 +smtpd_tls_security_level = may
 +smtpd_tls_session_cache_database = btree:​${data_directory}/​smtpd_scache
 +smtp_tls_session_cache_database = btree:​${data_directory}/​smtp_scache
 +tls_random_source = dev:/​dev/​urandom
 +tls_random_bytes = 32
 +tls_random_reseed_period = 3600s
 +#
 +home_mailbox = Maildir/
 +smtpd_sasl_auth_enable = yes
 +smtpd_sasl_type = dovecot
 +smtpd_sasl_path = private/​dovecot-auth
 +smtpd_sasl_authenticated_header = yes
 +smtpd_sasl_security_options = noanonymous
 +smtpd_sasl_local_domain = $myhostname
 +broken_sasl_auth_clients = yes
 +smtpd_use_tls = yes
 +smtpd_tls_received_header = yes
 +smtpd_tls_mandatory_protocols = SSLv3, TLSv1
 +smtpd_tls_mandatory_ciphers = medium
 +#​smtpd_tls_auth_only = yes
 +#
 +smtp_tls_cert_file=/​etc/​postfix/​ssl/​smtpd.pem
 +smtp_tls_key_file=$smtp_tls_cert_file
 +smtp_tls_loglevel = 1
 +smtp_tls_security_level = may
 +smtp_tls_note_starttls_offer = yes
 +smtp_use_tls = yes
 +#
 +
 +# See /​usr/​share/​doc/​postfix/​TLS_README.gz in the postfix-doc package for
 +# information on enabling SSL in the smtp client.
 +
 +myhostname = example.org
 +alias_maps = hash:/​etc/​aliases
 +alias_database = hash:/​etc/​aliases
 +myorigin = /​etc/​mailname
 +#​mydestination = example.org,​ www.example.org,​ example.cc, www.example.cc,​ myserverhostname,​ localhost.localdomain,​ localhost
 +mydestination =
 +relayhost = smtp-server.example.com
 +# This was commented out as it gives a "​unused parameter"​ warning on Precise - works on Hardy
 +#​relay_domain = $mydestination
 +mynetworks_style = subnet
 +#mynetworks = 127.0.0.0/8 [::​ffff:​127.0.0.0]/​104 [::1]/128
 +mailbox_command = /​usr/​lib/​dovecot/​deliver -c /​etc/​dovecot/​conf.d/​01-mail-stack-delivery.conf -m "​${EXTENSION}"​
 +mailbox_size_limit = 0
 +recipient_delimiter = +
 +inet_interfaces = all
 +owner_request_special = no
 +message_size_limit = 32768000
 +#
 +# Virtual Mailbox Domain Settings
 +virtual_alias_maps = mysql:/​etc/​postfix/​mysql/​alias_maps.cf,​ mysql:/​etc/​postfix/​mysql/​alias_alias_maps.cf
 +virtual_mailbox_domains = mysql:/​etc/​postfix/​mysql/​domains_maps.cf
 +virtual_mailbox_maps = mysql:/​etc/​postfix/​mysql/​mailbox_maps.cf,​ mysql:/​etc/​postfix/​mysql/​mailbox_alias_maps.cf
 +virtual_mailbox_limit = 51200000
 +virtual_minimum_uid = 5000
 +virtual_uid_maps = static:5000
 +virtual_gid_maps = static:5000
 +virtual_mailbox_base = /home/vmail
 +virtual_transport = virtual
 +# Additional for quota support
 +# This was commented out as it gives a "​unused parameter"​ warning on Precise - works on Hardy
 +#​virtual_create_maildirsize = yes
 +#​virtual_mailbox_extended = yes
 +#​virtual_mailbox_limit_maps = mysql:/​etc/​postfix/​mysql/​mailbox_limit_maps.cf
 +#​virtual_mailbox_limit_override = yes
 +#​virtual_maildir_limit_message = Sorry, the your maildir has overdrawn your diskspace quota, please free up some of spaces of your mailbox try again.
 +#​virtual_overquota_bounce = yes
 +#
 +# Spam reduction parameters. May be aggresive for some, but seems to work well.
 +access_map_reject_code = 554
 +invalid_hostname_reject_code = 554
 +maps_rbl_reject_code = 554
 +multi_recipient_bounce_reject_code = 554
 +non_fqdn_reject_code = 554
 +plaintext_reject_code = 554
 +reject_code = 554
 +relay_domains_reject_code = 554
 +unknown_local_recipient_reject_code = 550
 +unknown_address_reject_code = 550
 +unknown_client_reject_code = 550
 +unknown_hostname_reject_code = 550
 +unknown_relay_recipient_reject_code = 550
 +unknown_virtual_alias_reject_code = 550
 +unknown_virtual_mailbox_reject_code = 550
 +unverified_recipient_reject_code = 550
 +unverified_sender_reject_code = 550
 +#
 +default_process_limit = 20
 +smtpd_client_connection_count_limit = 10
 +# Value of 60 should translate to 1 per second limit
 +smtpd_client_connection_rate_limit = 60
 +smtpd_client_message_rate_limit = 60
 +smtpd_client_new_tls_session_rate_limit = 60
 +#
 +smtpd_helo_required = yes
 +smtpd_delay_reject = yes
 +address_verify_map = btree:​${data_directory}/​verify_cache
 +smtpd_reject_unlisted_sender=yes
 +#
 +smtpd_recipient_restrictions =
 +    check_client_access hash:/​etc/​postfix/​white_lists,​
 +    permit_sasl_authenticated,​
 +    permit_mynetworks,​
 +#   ​permit_tls_clientcerts,​
 +    reject_invalid_hostname,​
 +    reject_non_fqdn_hostname,​
 +    reject_non_fqdn_sender,​
 +    reject_non_fqdn_recipient,​
 +    reject_unknown_sender_domain,​
 +    reject_unknown_recipient_domain,​
 +    reject_unverified_sender,​
 +    reject_unauth_destination,​
 +    reject_rbl_client zen.spamhaus.org,​
 +    reject_rbl_client cbl.abuseat.org,​
 +    check_client_access hash:/​etc/​postfix/​white_lists,​
 +    permit
 +smtpd_data_restrictions =
 +    permit_sasl_authenticated,​
 +    permit_mynetworks,​
 +    reject_unauth_pipelining,​
 +    permit
 +# Added for trying to send email from PDA
 +smtpd_client_restrictions =
 +    permit_sasl_authenticated
 +smtpd_helo_restrictions =
 +    check_helo_access hash:/​etc/​postfix/​check_helo_access,​
 +    permit_mynetworks,​
 +    permit_sasl_authenticated,​
 +    reject_non_fqdn_hostname,​
 +    reject_invalid_hostname,​
 +    permit
 +#
 +</​file>​
 +
 +
 +/​etc/​postfix/​mailname
 +<file ini mailname>​
 +example.org
 +</​file>​
 +
 +==== Client TLS Support ====
 +Follow this for [[postfix_client_tls|Postfix Client TLS Support]] setup
 +
 +===== Postfix MySql (maps) configuration =====
 +  * Create directory /​etc/​postfix/​mysql
 +  * Please the following files under /​etc/​postfix/​mysql
 +
 +<file ini mysql_uid.cf>​
 +user=<​mysql_db_user>​
 +password=<​mysql_db_password>​
 +dbname=<​mysql_db_name>​
 +table=mailbox
 +select_field=username
 +where_field=username
 +hosts=127.0.0.1:<​mysql_db_port>​
 +</​file>​
 +
 +<file ini mysql_gid.cf>​
 +user=<​mysql_db_user>​
 +password=<​mysql_db_password>​
 +dbname=<​mysql_db_name>​
 +table=mailbox
 +select_field=username
 +where_field=username
 +hosts=127.0.0.1:<​mysql_db_port>​
 +</​file>​
 +
 +<file ini mailbox_maps.cf>​
 +user=<​mysql_db_user>​
 +password=<​mysql_db_password>​
 +dbname=<​mysql_db_name>​
 +table=mailbox
 +select_field=maildir
 +where_field=username
 +hosts=127.0.0.1:<​mysql_db_port>​
 +additional_conditions = and active = 1
 +</​file>​
 +
 +<file ini mailbox_limit_maps.cf>​
 +user=<​mysql_db_user>​
 +password=<​mysql_db_password>​
 +dbname=<​mysql_db_name>​
 +table=mailbox
 +select_field=quota
 +where_field=username
 +hosts=127.0.0.1:<​mysql_db_port>​
 +additional_conditions = and active = 1
 +</​file>​
 +
 +<file ini alias_maps.cf>​
 +user=<​mysql_db_user>​
 +password=<​mysql_db_password>​
 +dbname=<​mysql_db_name>​
 +table=alias
 +select_field=goto
 +where_field=address
 +hosts=127.0.0.1:<​mysql_db_port>​
 +additional_conditions = and active = 1
 +</​file>​
 +
 +<file ini domains_maps.cf>​
 +user=<​mysql_db_user>​
 +password=<​mysql_db_password>​
 +dbname=<​mysql_db_name>​
 +table=domain
 +select_field=domain
 +where_field=domain
 +hosts=127.0.0.1:<​mysql_db_port>​
 +additional_conditions = and backupmx = 0 and active = 1 and transport = '​virtual'​ and domain = '​%s'​
 +</​file>​
 +
 +<file ini relay_domains.cf>​
 +user=<​mysql_db_user>​
 +password=<​mysql_db_password>​
 +dbname=<​mysql_db_name>​
 +table=domain
 +select_field=domain
 +where_field=domain
 +hosts=127.0.0.1:<​mysql_db_port>​
 +additional_conditions = and active = 1 and backupmx = 0 and transport = '​relay'​ and domain = '​%s'​
 +</​file>​
 +
 +The below two settings (alias_alias_maps.cf & mailbox_alias_maps.cf) are for alias domains:
 +<file ini alias_alias_maps.cf>​
 +user=<​mysql_db_user>​
 +password=<​mysql_db_password>​
 +dbname=<​mysql_db_name>​
 +hosts=127.0.0.1:<​mysql_db_port>​
 +query = SELECT goto FROM alias,​alias_domain
 +  WHERE alias_domain.alias_domain = '​%d'​
 +  AND alias.address=concat('​%u',​ '​@',​ alias_domain.target_domain)
 +  AND alias.active = 1 AND alias_domain.active = 1
 +</​file>​
 +
 +<file ini mailbox_alias_maps.cf>​
 +user=<​mysql_db_user>​
 +password=<​mysql_db_password>​
 +dbname=<​mysql_db_name>​
 +hosts=127.0.0.1:<​mysql_db_port>​
 +query = SELECT maildir FROM mailbox, alias_domain
 +  WHERE alias_domain.alias_domain = '​%d'​
 +  AND mailbox.username=concat('​%u',​ '​@',​ alias_domain.target_domain )
 +  AND mailbox.active = 1 AND alias_domain.active = 1
 +</​file>​
 +===== Dovecot Configuration =====
 +Change the following files at /​etc/​dovecot & /​etc/​dovecot/​conf.d
 +
 +The files in /​etc/​dovecot need NO changes from default
 +  * dovecot.conf
 +  * dovecot-db.conf.ext
 +  * dovecot-dict-sql.conf.ext
 +  * dovecot-sql.conf.ext
 +
 +File(s) requiring change
 +
 +<file ini dovecot-sql.conf.ext>​
 +driver = mysql
 +connect = host=127.0.0.1 port=3306 user=root password=rootpassword dbname=postfixadmindbname
 +default_pass_scheme = CRAM-MD5
 +user_query = \
 + ​SELECT \
 +        concat('/​home/​vmail/',​ maildir) as home, \
 +        5000 as uid, 5000 as gid \
 +        FROM mailbox \
 +        WHERE username = '​%u'​ AND active = '​1'​
 +password_query = \
 + ​SELECT username as user, password, \
 +        concat('/​home/​vmail/',​ maildir) as userdb_home,​ \
 +        concat('​maildir:/​home/​vmail/',​ maildir) as userdb_mail,​ \
 +        5000 as userdb_uid, 5000 as userdb_gid \
 +        FROM mailbox \
 +        WHERE username = '​%u'​ AND active = '​1'​
 +</​file>​
 +
 +
 +The following files in /​etc/​dovecot/​conf.d do NOT require change as well
 +  *  01-mail-stack-delivery.conf
 +  *  10-director.conf
 +  *  10-master.conf
 +  *  10-ssl.conf
 +  *  15-lda.conf
 +  *  20-imap.conf
 +  *  20-managesieve.conf
 +  *  20-pop3.conf
 +  *  90-acl.conf
 +  *  90-plugin.conf
 +  *  90-quota.conf
 +  *  90-sieve.conf
 +  *  auth-deny.conf.ext
 +  *  auth-master.conf.ext
 +  *  auth-passwdfile.conf.ext
 +  *  auth-static.conf.ext
 +  *  auth-vpopmail.conf.ext
 +
 +
 +File(s) requiring change
 +
 +<file ini 10-logging.conf>​
 +auth_verbose = yes
 +auth_debug = yes
 +plugin {
 +  # Events to log. Also available: flag_change append
 +  #​mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename
 +  # Available fields: uid, box, msgid, from, subject, size, vsize, flags
 +  # size and vsize are available only for expunge and copy events.
 +  #​mail_log_fields = uid box msgid size
 +}
 +
 +</​file>​
 +
 +<file ini 10-auth.conf>​
 +auth_mechanisms = plain cram-md5
 +!include auth-system.conf.ext
 +</​file>​
 +
 +<file ini auth-system.conf.ext>​
 +passdb {
 +  driver = sql
 +  args = /​etc/​dovecot/​dovecot-sql.conf.ext
 +  # [session=yes] [setcred=yes] [failure_show_msg=yes] [max_requests=<​n>​]
 +  # [cache_key=<​key>​] [<​service name>]
 +  #args = dovecot
 +}
 +userdb {
 +  # <​doc/​wiki/​AuthDatabase.Passwd.txt>​
 +  driver = sql
 +  args = /​etc/​dovecot/​dovecot-sql.conf.ext
 +  # [blocking=no]
 +  #args =
 +}
 +</​file>​
 +
 +<file ini 10-mail.conf>​
 +mail_location = maildir:/​home/​vmail/​%d/​%u
 +mail_uid = vmail
 +mail_gid = vmail
 +maildir_copy_with_hardlinks = yes
 +</​file>​
 +
 +===== Postfix Admin =====
 +All changes from the default go in config.local.php
 +<file ini config.local.php>​
 +$CONF['​postfix_admin_url'​] = '​http://​pfa.example.org';​
 +
 +$CONF['​domain_path'​] = '​YES';​
 +
 +$CONF['​database_type'​] = '​mysql';​
 +$CONF['​database_host'​] = '​localhost';​
 +$CONF['​database_user'​] = '​upostfixadmin';​
 +$CONF['​database_password'​] = '​somepassword';​
 +$CONF['​database_name'​] = '​postfixadmin';​
 +
 +$CONF['​admin_email'​] = '​postmaster@example.com';​
 +
 +$CONF['​smtp_server'​] = '​smtp-server.example.com';​
 +
 +$CONF['​encrypt'​] = '​dovecot:​CRAM-MD5';​
 +
 +$CONF['​dovecotpw'​] = "/​usr/​bin/​doveadm pw";
 +
 +$CONF['​page_size'​] = '​100';​
 +
 +$CONF['​default_aliases'​] = array (
 +    '​abuse'​ => '​abuse@example.com',​
 +    '​hostmaster'​ => '​hostmaster@example.com',​
 +    '​postmaster'​ => '​postmaster@example.com',​
 +    '​webmaster'​ => '​webmaster@example.com'​
 +);
 +
 +$CONF['​aliases'​] = '​10000';​
 +$CONF['​mailboxes'​] = '​10000';​
 +$CONF['​maxquota'​] = '​10000';​
 +
 +$CONF['​transport'​] = '​YES';​
 +
 +$CONF['​vacation_domain'​] = '​autoreply.example.com';​
 +
 +$CONF['​user_footer_link'​] = "​http://​example.com/";​
 +$CONF['​footer_text'​] = '​Return to example.com'; ​
 +$CONF['​footer_link'​] = '​http://​example.com';​
 +
 +$CONF['​create_mailbox_subdirs_prefix'​]='';​
 +$CONF['​new_quota_table'​] = '​YES';​
 +</​file>​
 +
 +===== Migration from Courier to Postfix =====
 +If you are moving to a new machine make sure that you tar and untar files to preserver permissions and most importantly timestamps. Or all your old mail will have the same date/time!
 +==== Resource ====
 +[[http://​wiki.dovecot.org/​Migration/​Courier|Migration-Courier - Dovecot Wiki]]
 +==== Command ====
 +<​code>​
 +/​home/​vmail/​courier-dovecot-migrate.pl --to-dovecot --recursive --convert --overwrite /​home/​vmail/​example.org/​
 +</​code>​
 +Sample output:
 +<​code>​
 +Converting to Dovecot format
 +Finding maildirs under /​home/​vmail/​example.org/​
 +
 +Total: 70 mailboxes / 38 users
 +       0 errors
 +46 dovecot-uidlist files written
 +
 +WARNING: Badly done migration will cause your IMAP and/or POP3 clients to re-download all mails. Read http://​wiki.dovecot.org/​Migration carefully.
 +</​code>​
 +==== Folder between courier and dovecot ====
 +One way to get the courier subfolders to show up in dovecot is to add this to the configuration:​
 +<file ini 10-mail.conf>​
 +namespace private {
 +  prefix = INBOX.
 +  separator = .
 +  inbox = yes
 +}
 +</​file>​
 +Alternatively,​ I created the subfolders (from squirrel mail) and then delete the newly created folders from the Linux file folders and renamed the existing file folders to the name I just deleted. ​ So here goes for example:
 +<​code>​
 +mv .INBOX.SomeSubFolder/​ junk
 +mv .SomeSubFolder .INBOX.SomeSubFolder
 +</​code>​
 +Here I moved the newly created folder to a "​junk"​ location (an alternative to just deleting it). Then renamed the original folder to the new folder name.
 +
 +===== Squirrel Mail configuration =====
 +Follow this [[tech:​linux:​sq_config|link]].
 +
 +===== Some dovecot commands =====
 +<​code>​
 +dovecot --build-options
 +find /​usr/​lib/​dovecot/​modules/​
 +doveconf -a
 +</​code>​
 +
 +===== pflogsumm.pl - Produce Postfix MTA logfile summary =====
 +The pflogsumm.pl produces a daily summary of mail activity.  ​
 +
 +Install ''​pflogsumm''​ at ''/​usr/​local/​bin/​pflogsumm''​. Install the below script as a Daily cron.  Make sure the /​etc/​cron.daily has the shell script above the daily ''​log-rotate''​ script and the Daily cron runs at midnight. To change the timing of the daily cron run, update the run time at ''/​etc/​crontab''​.
 +
 +Daily cron job shell wrapper
 +<code bash>
 +#!/bin/bash
 +#
 +# Daily Postfix Log report
 +#
 +TS=$(date +%Y%m%d_%H%M%S);​
 +LOGFILEDIR="/​var/​log/​postfixrep"​
 +LOGFILE="​$LOGFILEDIR/​pfrep_$TS.txt"​
 +PFLOGSUMM="/​usr/​local/​bin/​pflogsumm"​
 +PFMAILINF="/​var/​log/​mail.info"​
 +PFMAILINF="/​var/​log/​mail.log"​
 +REMAIL="​report@example.org"​
 +REPSUB="​Postfix Report"​
 +#
 +#$PFLOGSUMM $PFMAILINF > $LOGFILE
 +$PFLOGSUMM --detail 10 --problems_first --verbose_msg_detail $PFMAILINF > $LOGFILE
 +cat $LOGFILE | mailx -s "​$REPSUB"​ $REMAIL
 +#
 +# Delete log files older than 40 days
 +/​usr/​bin/​find $LOGFILEDIR/​pfrep* -mtime +40 -exec rm {} \;
 +#
 +exit 0
 +</​code>​
 +
 +
 +===== Fail2ban configuration =====
 +Fail2ban is optional but highly recommended to reduce thrashing of the servers from brute-force attempts
 +
 +  * Install fail2ban (and iptables) using apt-get (I use aptitude!)
 +  * Changes to ''/​etc/​fail2ban/​jail.conf''​
 +    * Enable postfix, sasl, dovecot by setting ''​enabled ​ = true''​
 +      * Optionally also enable ''​recidive''​
 +    * Enable dovecot for IMAP login attemps
 +    * Add local LAN to ''​ignoreip''​ (e.g. ignoreip = 127.0.0.1/8 192.168.0.0/​16)
 +      * Believe you may also want to include your WAN IP as I sometimes see it in the logs
 +    * Optionally increase bantime from 60 to 3600
 +    * Optionally increase findtime from 60 to 3600
 +    * Optionally decrease maxretry from 3 to 2
 +    * Set destemail to a valid email
 +  * Update Files in /​etc/​fail2ban/​filter.d as below
 +
 +Notice the ''​journalmatch = _SYSTEMD_UNIT=postfix@-.service''​ line. The default ''​journalmatch = _SYSTEMD_UNIT=postfix.service''​ does not work. Not sure if this is an issue with Debian/​Bookworm or fail2ban configuration. ​
 +
 +==== SMTP Configuration ====
 +
 +<file ini postfix.conf>​
 +# Fail2Ban filter for selected Postfix SMTP rejections
 +#
 +#
 +
 +[INCLUDES]
 +
 +# Read common prefixes. If any customizations available -- read them from
 +# common.local
 +before = common.conf
 +
 +[Definition]
 +
 +_daemon = postfix/​smtpd
 +
 +failregex = ^%(__prefix_line)sNOQUEUE:​ reject: RCPT from \S+\[<​HOST>​\]:​ 554 5\.7\.1 .*$
 +            ^%(__prefix_line)sNOQUEUE:​ reject: RCPT from \S+\[<​HOST>​\]:​ 554 5\.5\.2 .*$
 +            ^%(__prefix_line)sNOQUEUE:​ reject: RCPT from \S+\[<​HOST>​\]:​ 450 4\.7\.1 : Helo command rejected: Host not found; from=<>​ to=<> proto=ESMTP helo= *$
 +            ^%(__prefix_line)s\S+\:​ reject: RCPT from \S+\[<​HOST>​\]:​ 550 5\.1\.1 <​\S*>:​ Recipient address rejected:​.*$
 +            ^%(__prefix_line)sNOQUEUE:​ reject: RCPT from \S+\[<​HOST>​\]:​ 454 4\.7\.1 <​\S*>:​ Relay access denied;.*$
 +            ^%(__prefix_line)swarning:​ \S+\[<​HOST>​\]:​ SASL LOGIN authentication failed: Invalid authentication mechanism$
 +            ^%(__prefix_line)swarning:​ Recipient address rate limit exceeded: \S+\ from unknown\[<​HOST>​\] for service smtp$
 +
 +ignoreregex =
 +
 +[Init]
 +
 +journalmatch = _SYSTEMD_UNIT=postfix@-.service
 +
 +</​file>​
 +
 +
 +<file ini postfix-sasl.conf>​
 +# Fail2Ban filter for postfix authentication failures
 +#
 +
 +[INCLUDES]
 +
 +before = common.conf
 +
 +[Definition]
 +
 +_daemon = postfix/​smtpd
 +
 +failregex = ^%(__prefix_line)swarning:​ [-._\w]+\[<​HOST>​\]:​ SASL (?:​LOGIN|PLAIN|(?:​CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/​]*={0,​2})?​\s*$
 +
 +ignoreregex =
 +
 +[Init]
 +
 +journalmatch = _SYSTEMD_UNIT=postfix@-.service
 +
 +</​file>​
 +
 +''​dovecot.conf''​ did not require any changes from the default install
 +
 +==== Dovecot/​IMAP Configuration ====
 +Below are the list of failures that need to be checked
 +<​code>​
 +Jul  9 07:19:39 inthostname dovecot: imap-login: Disconnected:​ Too many invalid commands (no auth attempts in 0 secs): user=<>,​ rip=<​hackerip>,​ lip=internalip,​ session=<​MGpJ4QwAJgCn+IV+>​
 +Jul  9 00:23:02 inthostname dovecot: imap-login: Aborted login (no auth attempts in 4 secs): user=<>,​ rip=<​hackerip>,​ lip=internalip,​ TLS, session=<​g2xYDwcAcwBX7LCo>​
 +Jul  9 07:57:35 inthostname dovecot: imap-login: Disconnected (no auth attempts in 0 secs): user=<>,​ rip=<​hackerip>,​ lip=internalip,​ TLS: Disconnected,​ session=<​wqHyaA0AHgCrQ0bl>​
 +Jul  9 11:15:15 inthostname dovecot: imap-login: Disconnected (auth failed, 1 attempts in 2 secs): user=<​someone@example.org>,​ method=PLAIN,​ rip=<​hackerip>,​ lip=internalip,​ TLS, session=<​mN+5KxAACACr92MJ>​
 +Jul  9 14:37:38 inthostname dovecot: imap-login: Disconnected (tried to use disallowed plaintext auth): user=<>,​ rip=<​hackerip>,​ lip=internalip,​ session=<​HXSc/​xIAuAAl7S4R>​
 +Oct  6 23:17:35 inthostname dovecot: imap-login: Disconnected (disconnected before auth was ready, waited 0 secs): user=<>,​ rip=<​hackerip>,​ lip=internalip,​ TLS handshaking:​ SSL_accept() failed: error:​140760FC:​SSL routines:​SSL23_GET_CLIENT_HELLO:​unknown protocol, session=<​HTcFoxgHmgBrquET>​
 +Oct  5 04:33:07 inthostname dovecot: imap-login: Disconnected (tried to use unsupported auth mechanism): user=<>,​ method=NTLM,​ rip=<​hackerip>,​ lip=internalip,​ session=<​MK/​Dz/​QGMAClmnge>​
 +Sep 25 04:55:41 inthostname dovecot: imap-login: Disconnected (client didn't finish SASL auth, waited 19 secs): user=<>,​ method=PLAIN,​ rip=<​wanip>,​ lip=internalip,​ TLS: SSL_read() syscall failed: Connection reset by peer, session=<​9yvt9CsGOQAYNzGR>​
 +
 +
 +hackerip=x.x.x.x
 +internalip=y.y.y.y
 +</​code>​
 +
 +==== Testing Fail2ban configuration ====
 +<code bash>
 +fail2ban-regex systemd-journal /​etc/​fail2ban/​filter.d/​postfix.conf
 +fail2ban-regex systemd-journal /​etc/​fail2ban/​filter.d/​postfix-sasl.conf
 +</​code>​
 +
 +==== Other Fail2ban related configuration ====
 +rsyslog filters duplicate messages as ''​last message repeated X times''​. This causes Fail2ban to not get the actual count of failed attempts. To change the configuration:​
 +
 +Edit ''/​etc/​rsyslog.conf''​ to update ''​$RepeatedMsgReduction''​ from on to off
 +<​code>​
 +$RepeatedMsgReduction off
 +</​code>​
 +
 +Restart rsyslog
 +<code bash>
 +service rsyslog restart
 +</​code>​
 +
 +==== Other Fail2ban related commands ====
 +== Currently banned IPs ==
 +Run as root:
 +<code bash>
 +fail2ban-client status | grep "Jail list:" | sed "s/ //g" | awk '​{split($2,​a,","​);​for(i in a) system("​fail2ban-client status " a[i])}'​
 +</​code>​
 +
 +=== Permanently ban ==
 +Refer [[senthil:​tech:​linux:​fail2ban_maintain|here]] to permanently ban!
 +==== Other Fail2ban resources ====
 +https://​www.the-art-of-web.com/​system/​fail2ban-howto/​
 +
 +===== Post Configuration Steps =====
 +==== white_lists file ====
 +To avoid error that there is no white list file.  ​
 +
 +The ''​check_helo_access''​ allows helo specific white lists. ​ For e.g. use when you an error such as ''​Helo command rejected: Host not found;''​.
 +<code bash>
 +cd /​etc/​postfix
 +touch white_lists
 +postmap white_lists
 +#
 +touch check_helo_access
 +postmap check_helo_access
 +</​code>​
 +
 +==== Restart ====
 +<​code>​
 +service postfix restart
 +service dovecot restart
 +</​code>​
 +
 +===== Dovecot debug =====
 +To turn on auth debug in dovecot. ​ Update ''​dovecot/​conf.d/​10-logging.conf''​ file with
 +<​code>​
 +auth_verbose = no
 +auth_debug = no
 +</​code>​
 +Remember to turn if off once done.
 +
 +===== /​etc/​aliases =====
 +Optionally update aliases so mail delivered to root (or someuser) at localhost can be forwarded to a remote mail user.
 +<​code>​
 +# See man 5 aliases for format
 +postmaster: ​   root
 +someuser:​someuser@example.org
 +root:​someuser@example.org
 +</​code>​
 +Run the below after changing ''/​etc/​aliases''​
 +<code bash>
 +postalias /​etc/​aliases
 +# Alternative to postalias you can also run '​newaliases'​ command
 +service postfix restart
 +</​code>​
 +
 +===== Logs =====
 +Update ''​logrotate''​ configuration at ''/​etc/​logrotate.d/​rsyslog''​ to increase the retention period. ​ Typically mail logs have a 4 week retention period (parameter ''​rotate''​). ​ Increase it to 13 weeks or more as desired.
 +
 +===== Satellite hosts =====
 +The above setup is for Postfix smart host.  For the rest of the servers in the network, it is preferred to set them up as a Satellite host and route mail through the local host. The Postfix main.cf configuration for Postfix Satellite host aka Send-only, Relay, Forwarded host is below.
 +Note: 
 +  * Replace ''​your-host-name''​ with your hostname ​
 +  * ''​example.org''​ with the smart-host domain name
 +  * ''​mainsmtp''​ with the hostname/IP of the smart-host
 +
 +/​etc/​postfix/​main.cf
 +<file ini main.cf>
 +# See /​usr/​share/​postfix/​main.cf.dist for a commented, more complete version
 +
 +# Debian specific: ​ Specifying a file name will cause the first
 +# line of that file to be used as the name.  The Debian default
 +# is /​etc/​mailname.
 +myorigin = /​etc/​mailname
 +
 +smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
 +biff = no
 +
 +# appending .domain is the MUA's job.
 +append_dot_mydomain = no
 +
 +# Uncomment the next line to generate "​delayed mail" warnings
 +#​delay_warning_time = 4h
 +
 +readme_directory = no
 +
 +# TLS parameters
 +smtpd_tls_cert_file=/​etc/​ssl/​certs/​ssl-cert-snakeoil.pem
 +smtpd_tls_key_file=/​etc/​ssl/​private/​ssl-cert-snakeoil.key
 +smtpd_use_tls=yes
 +smtpd_tls_session_cache_database = btree:​${data_directory}/​smtpd_scache
 +smtp_tls_session_cache_database = btree:​${data_directory}/​smtp_scache
 +
 +# See /​usr/​share/​doc/​postfix/​TLS_README.gz in the postfix-doc package for
 +# information on enabling SSL in the smtp client.
 +
 +smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
 +myhostname = your-host-name
 +alias_maps = hash:/​etc/​aliases
 +alias_database = hash:/​etc/​aliases
 +mydomain = example.org
 +mydestination = $myhostname.$mydomain,​ localdomain,​ $myhostname,​ localhost.localdomain,​ localhost
 +relayhost = mainsmtp
 +smtp_host_lookup = native
 +mynetworks = 127.0.0.0/8 [::​ffff:​127.0.0.0]/​104 [::1]/128
 +mailbox_size_limit = 0
 +recipient_delimiter = +
 +inet_interfaces = loopback-only
 +# Address rewriting
 +#​smtp_generic_maps = hash:/​etc/​postfix/​generic
 +</​file>​
 +
 +/​etc/​postfix/​mailname
 +<file ini mailname>​
 +your-host-name.example.org
 +</​file>​
 +
 +/​etc/​aliases
 +<file ini aliases>
 +# See man 5 aliases for format
 +postmaster: ​   root
 +user:​system@example.org
 +root:​system@example.org
 +</​file>​
 +
 +===== Related =====
 +  * [[squirrelmail|Additional SquirrelMail Notes]]
 +  * [[setup_postfix_relay|Setup Postfix to act as Relay Host]]
 +  * [[postfix_client_tls|Postfix Client TLS Support]]
 +  * [[postfix_important_settings|Important Postfix settings]]
 +  * [[postfix_relay_on_recipient_domain|Postfix - Choose a different SMTP relay based on sender domain]]

QR Code
QR Code tech:linux:mail_server_setup (generated for current page)