Install postfix + dovecot auth + tls + mysql + postfixadmin + postgrey + spamassassin and clamav on Centos 7
In this post we will install a mail server using virtual users with authentication using dovecot and ssl. After we are able to successfully send and retrieve e-mails we will securing the server with postgrey, spamassassin and clamav antivirus.
We will be using in this example a mysql backend. We will make sure that we have all the related packages installed. Will achieve that using yum:
#yum -y install postfix dovecot dovecot-mysql mariadb-server
When that's done we need to edit the /etc/postfix/main.cf
to match your needed configuration:
alias_database = hash:/etc/aliases
alias_maps = hash:/etc/aliases
broken_sasl_auth_clients = yes
command_directory = /usr/sbin
config_directory = /etc/postfix
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
debug_peer_level = 2
debugger_command = PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin$daemon_directory/$process_name $process_id & sleep 5
disable_vrfy_command = yes
html_directory = no
inet_interfaces = all
inet_protocols = all
mail_owner = postfix
mailq_path = /usr/bin/mailq.postfix
manpage_directory = /usr/share/man
milter_default_action = accept
mydestination = $myhostname, localhost.$mydomain, localhost
mydomain = example.com
myhostname = mail.example.com
myorigin = $myhostname
newaliases_path = /usr/bin/newaliases.postfix
queue_directory = /var/spool/postfix
readme_directory = /usr/share/doc/postfix-2.10.1/README_FILES
sample_directory = /usr/share/doc/postfix-2.10.1/samples
sendmail_path = /usr/sbin/sendmail.postfix
setgid_group = postdrop
smtpd_delay_reject = yes
smtpd_error_sleep_time = 1s
smtpd_hard_error_limit = 20
smtpd_helo_required = yes
smtpd_helo_restrictions = permit_mynetworks,
reject_non_fqdn_hostname,
reject_invalid_hostname,
permit
smtpd_recipient_restrictions = permit_sasl_authenticated,
permit_mynetworks,
check_policy_service unix:postgrey/socket,
reject_invalid_hostname,
reject_non_fqdn_hostname,
reject_unauth_destination,
reject_rbl_client list.dsbl.org,
reject_rbl_client sbl.spamhaus.org,
reject_rbl_client cbl.abuseat.org,
reject_rbl_client dul.dnsbl.sorbs.net,
permit
smtpd_sasl_auth_enable = yes
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_type = dovecot
smtpd_soft_error_limit = 10
smtpd_tls_CAfile = /etc/pki/tls/cert.pem
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/pki/tls/certs/mail.example.com.crt
smtpd_tls_key_file = /etc/pki/tls/private/mail.example.com.key
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes
smtpd_tls_security_level = may
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
unknown_local_recipient_reject_code = 550
virtual_alias_maps = mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf
virtual_gid_maps = static:12
virtual_mailbox_base = /home/vmail
virtual_mailbox_domains = mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_mailbox_limit = 51200000
virtual_mailbox_maps = mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 8
virtual_transport = virtual
virtual_uid_maps = static:8
virtual_maildir_limit_message=Sorry, Your maildir has overdrawn your diskspace quota, please free some space of your mailbox and try again.
virtual_mailbox_limit_maps=mysql:/etc/postfix/sql/mysql_virtual_mailbox_limit_maps.cf
virtual_mailbox_limit_override=yes
virtual_overquota_bounce=yes
virtual_create_maildirsize=yes
smptd_tls_session_cache_database=btree:/var/spool/postfix/smtpd_tls_cache
virtual_mailbox_extended=yes
smtpd_tls_note_starttls_offer=yes
You need to add create the following files:
/etc/postfix/sql/mysql_relay_domains_maps.cf
user = postfix
password = someotherpass
hosts = 127.0.0.1
dbname = mail
table = domain
select_field = domain
additional_conditions = and backupmx = '1'
/etc/postfix/sql/mysql_virtual_alias_maps.cf
user = postfix
password = someotherpass
hosts = 127.0.0.1
dbname = mail
table = alias
select_field = goto
where_field = address
/etc/postfix/sql/mysql_virtual_mailbox_limit_maps.cf
user = postfix
password = someotherpass
hosts = 127.0.0.1
dbname = virtual_mail
table = mailbox
select_field = quota
where_field = username
#additional_conditions = and active = '1'
/etc/postfix/sql/mysql_virtual_mailbox_maps.cf
user = postfix
password = someotherpass
hosts = 127.0.0.1
dbname = mail
table = mailbox
select_field = maildir
where_field = username
#additional_conditions = and active = '1'
/etc/postfix/sql/mysql_virtual_domains_maps.cf
user = postfix
password = someotherpass
hosts = 127.0.0.1
dbname = mail
table = domain
select_field = domain
where_field = domain
additional_conditions = and backupmx = '0' and active = '1'
To configure the smtps and submission for local delivery change the following in /etc/postfix/master.cf
submission inet n - n - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
smtps inet n - n - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated, reject
-o milter_macro_daemon_name=ORIGINATING
Next we start the mysql database and create a database for our installation. To start the database please run the following command:
#systemctl start mariadb.service
Make sure that your database will start upon startup:
#systemctl enable mariadb.service
Now it's time to create our database and the proper users with the needed privileges:
#mysql -u root
MariaDB> create database mail;
MariaDB> grant all privileges on mail.* to 'postfixadmin'@'localhost' identified by 'somepass';
MariaDB> grant select on mail.* to 'postfix'@'localhost' identified by 'someotherpass';
MariaDB> flush privileges;
We have created two users with different privileges. First the postfixadmin is the user which would be used by the webgui called postfixadmin which need write privileges into the database because you will be adding the domains, users and aliases which will be holded by this installation via it. The other user is postfix, which will be used by the postfix and dovecot to query the users from the database. These queries does not write to the database therefore this user will only have select right granted.
Now it's time to install nginx and the postfixadmin. First you need to add a new repo for nginx cause we want to use the latest version available. For that create a new file /etc/yum.repos.d/nginx.repo
with the following value in it.
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1
Now we need to add the epel repo so that we can install the full list of needed packages.
#yum -y install http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-2.noarch.rpm
Now we can install all the needed packages. To do so you will need to run the command:
#yum -y install php php-fpm php-common php-pdo php-mbstring php-imap php-cli php-mysql nginx
Edit the /etc/php-fpm.d/www.conf
and change the following entries:
;listen = 127.0.0.1:9000
listen = /var/run/php-fpm.sock
...
listen.owner = nginx
listen.group = nginx
listen.mode = 0666
...
user = nginx
group = nginx
Download the postfixadmin from here.
Unarchive the downloaded package and move it to /var/www/html
:
#tar -xzvf postfixadmin-2.91.tar.gz
#mv postfixadmin-2.91 /var/www/html/postfixadmin
Now it's time to set up the nginx and start the services. Edit the /etc/nginx/conf.d/default.conf
and change it to look like this:
server {
listen 80;
server_name 0.0.0.0;
error_log /var/log/nginx/error.log debug;
root /var/www/html/postfixadmin;
index index.php index.html index.htm;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Now go and edit the postfixadmin config file /var/www/potfixadmin/html/config.inc.php
. Change the value false to true at the line:
$CONF['configured'] = true;
Edit the entries in the config file related to the database:
$CONF['database_type'] = 'mysqli';
$CONF['database_host'] = 'localhost';
$CONF['database_user'] = 'postfixadmin';
$CONF['database_password'] = 'somepassword';
$CONF['database_name'] = 'mail';
Save the changes. Disable your selinux by editing the config file and change the SELINUX value from enforcing to permissive or disabled. To apply the change you will need to reboot your server. You will have to add a rule to the firewall to open the port 80 for web access. To do that you need to run the following command:
#firewall-cmd --zone=public --add-service=http --permanent
Then restart the firewall and start the php-fpm and nginx services:
#systemctl restart firewalld
#systemctl start php-fpm
#systemctl start nginx
Now you can open a browser and type the IP address of your system to get to the postfixadmin page.
It's time to create the self signed certificate for your domain in this example mail.example.com.
#genkey --days 3650 mail.example.com
This certificate is valid for 10 years.
Now it's time to configure the dovecot. First create a file called /etc/dovecot/dovecot-sql.conf.ext
driver = mysql
connect = host=localhost dbname=mail user=postfix password=P0stf1x
default_pass_scheme = CRAM-MD5
user_query = SELECT '/home/vmail/%n@%d' AS home, 8 AS uid, 12 AS gid FROM mailbox WHERE username = '%u'
password_query = SELECT password FROM mailbox WHERE username = '%u'
Next file to edit /etc/dovecot/conf.d/10-auth.conf
Change the values to match the following:
auth_mechanisms = plain login cram-md5
#!include auth-deny.conf.ext
#!include auth-master.conf.ext
#!include auth-system.conf.ext
!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-vpopmail.conf.ext
#!include auth-static.conf.ext
Next file to change is /etc/dovecot/conf.d/10-mail.conf
:
mail_location = maildir:/home/vmail/%d/%n/:INDEX=/home/vmail/%d/%n/indexes
mail_uid = 8
mail_gid = 12
first_valid_uid = 8
last_valid_uid = 8
first_valid_gid = 12
last_valid_gid = 12
Next file to change is /etc/dovecot/conf.d/10-master.conf
:
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}
service pop3-login {
inet_listener pop3 {
#port = 110
}
inet_listener pop3s {
#port = 995
#ssl = yes
}
}
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = mail
group = mail
}
}
Next file to change /etc/dovecot/conf.d/10-ssl.conf
:
ssl = required
ssl_cert = </etc/pki/tls/certs/mail.example.com.crt
ssl_key = </etc/pki/tls/private/mail.example.com.key
Next file on line: /etc/dovecot/conf.d/auth-sql.conf.ext
:
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
Note: There are only posted the values which need to be changed in the configuration files everything else should be left as it was on the config file by default.
Now before we start the services we would need to open the ports in the firewall. To do so run the following commands:
#firewall-cmd --zone=public --add-service=smtp --permanent
#firewall-cmd --zone=public --add-service=smtp --permanent
#firewall-cmd --zone=public --add-service=smtps --permanent
#firewall-cmd --zone=public --add-port=587/tcp --permanent
#firewall-cmd --zone=public --add-service=imaps --permanent
#firewall-cmd --zone=public --add-service=imap --permanent
#firewall-cmd --zone=public --add-service=pop3s --permanent
After we have added the ports we need to restart the firewall so that the rules would get applied.
#systemctl restart firewalld
Now we are ready to start up the service and enable them on boot.
#systemctl enable postfix
#systemctl restart postfix
#systemctl enable dovecot
#systemctl restart dovecot
We test the smtp by telneting into the domain on port 25
#telnet localhost 25
Connected to localhost.
Escape character is '^]'.
220 mail.example.com ESMTP Postfix
ehlo me
250-mail.example.com
250-PIPELINING
250-SIZE 10240000
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
First need to install the required software. For this we use yum:
#yum install -y postgrey spamassassin spamass-milter-postfix spamass-milter clamav-filesystem clamav-server clamav-update clamav-milter-systemd clamav-data clamav-server-systemd clamav-scanner-systemd clamav clamav-milter clamav-lib clamav-scanner
Once that is done it's time to configure the software. Let's start with the spamassassin. Fist edit the /etc/mail/spamassassin/local.cf
match your configuration with this:
required_hits 5.0
report_safe 0
required_score 5
#rewrite_header Subject *** SPAM ***
remove_header ham Status
remove_header ham Level
Next file to configure is /etc/sysconfig/spamassassin
:
# Options to spamd
SPAMDOPTIONS="-d -c -m5 -H"
and /etc/sysconfig/spamass-milter
:
EXTRA_FLAGS="-i 127.0.0.1 -m -r -1 -I "
and the last one for spamassassin is: /etc/sysconfig/spamass-milter-postfix
:
SOCKET="/run/spamass-milter/postfix/sock"
SOCKET_OPTIONS="-g postfix"
Next software to configure is clamav. First will edit the /etc/clamd.d/scan.conf
First thing to do is to comment or remove the Example in the cofiguration file. These are the configuration options which should be uncommented:
LogFile /var/log/clamd.scan
LogFileMaxSize 0
LogTime yes
LogSyslog yes
LogFacility LOG_MAIL
PidFile /var/run/clamd.scan/clamd.pid
TemporaryDirectory /var/tmp
DatabaseDirectory /var/lib/clamav
OfficialDatabaseOnly no
LocalSocket /var/run/clamd.scan/clamd.sock
LocalSocketGroup clamscan
LocalSocketMode 666
FixStaleSocket yes
TCPSocket 3310
TCPAddr 127.0.0.1
SelfCheck 600
User clamscan
AllowSupplementaryGroups yes
StatsEnabled yes
Next file to configure is /etc/mail/clamav-milter.conf
:
MilterSocket /var/run/clamav-milter/clamav-milter.socket
MilterSocket inet:7357
MilterSocketMode 777
FixStaleSocket yes
AllowSupplementaryGroups yes
PidFile /var/run/clamav-milter/clamav-milter.pid
TemporaryDirectory /var/tmp
ClamdSocket unix:/var/run/clamd.scan/clamd.sock
OnClean Accept
OnInfected Reject
OnFail Defer
RejectMsg Rejecting harmful email: %v found.
AddHeader Add
VirusAction /usr/local/bin/my_infected_message_handler
LogFileMaxSize 0
LogTime yes
LogSyslog yes
LogFacility LOG_MAIL
Now let's try and configure postgrey. For this you need to edit /etc/sysconfig/postgrey
:
POSTGREY_OPTS="--delay=60"
Last piece of software to install and configure is the opendkim to do this you need to run the following command:
#yum install -y libopendkim opendkim
Let's start to configure /etc/opendkim.conf
:
PidFile /var/run/opendkim/opendkim.pid
Mode sv
Syslog yes
SyslogSuccess yes
UserID opendkim:opendkim
Socket inet:8891@localhost
Umask 002
Canonicalization relaxed/simple
MinimumKeyBits 1024
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
Let's specify the TrustedHosts at /etc/opendkim/TrustedHosts
:
127.0.0.1
mail.example.com
example.com
#192.168.1.0/24
This file is used to define the internal ignore list and external ignore list. All emails which are orriginating from these hosts or domains will be automatically trusted and signed.
Now we create the keytable on /etc/opendkim/KeyTable
:
default._domainkey.example.com example.com:default:/etc/opendkim/keys/default.private
Next we create the signing table at /etc/opendkim/SigningTable
:
This file is used to declare the domains/email addresses and their selector
*@example.com default._domainkey.example.com
Now it's time to create the private and public keys. First change the directory to the /etc/opendkim/keys
and create a folder in there named as your domain for which you want to create the keys and fix the ownership of the folder:
#cd /etc/opendkim/keys
#mkdir example.com
#cd example.com
#chown -R opendkim.opendkim /etc/opendkim/keys/example.com
Now let's generate the keys for the domain and set the proper ownership:
#opendkim-genkey -s default -d example.com
#chown -R opendkim. /etc/opendkim/keys/
The -s option would give the name of the selector and the -d would give the domain of the keys.
Now open the /etc/opendkim/keys/example.com/mail.txt
and create a TXT entry on your domain DNS server according to what is in the file:
mail._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFRSHhfOAoqsF5t8dmpzuYGQAIP3JoLRVLQ5r8SsI6SrS90VGAsAByJsERImLxV68D3b+iDUhaw+PmQ/9L4atgnp3cbqgNRD++lAOvloGe+I1GlN6iKYNm4Xr3IYPPvaZYlT0JgawRZKGffP0l0bCqJT/36ZCcI+Shoq+l/H0LfwIDAQAB"
Now let's do the final changes in the postfix config file /etc/postfix/main.cf
. Add the following entries to the file:
milter_default_action = accept
smtpd_milters = unix:/var/run/clamav-milter/clamav-milter.socket,
unix:/var/run/spamass-milter/postfix/sock,
inet:127.0.0.1:8891
Once that is done it's time to enable the services for startup and start them and restart the postfix.
#systemctl enable spamassassin.service
#systemctl start spamassassin.service
#systemctl enable spamass-milter.service
#systemctl enable spamass-milter-root.service
#systemctl start spamass-milter.service
#systemctl start spamass-milter-root.service
#systemctl enable clamd@scan.service
#systemctl start clamd@scan.service
#systemctl enable clamav-milter.service
#systemctl start clamav-milter.service
#systemctl enable postgrey.service
#systemctl start postgrey.service
#systemctl enable opendkim.service
#systemctl start opendkim.service
#systemctl restart postfix.service