9
---------
Postfix mail server on CentOS 7 with virtual domains, management system, web access and many others
https://www.dmosk.ru/instruktions.php?object=postfix-centos
Terms on the topic: Postfix , POP3 , SMTP , IMAP , MariaDB , CentOS , PostfixAdmin , Dovecot , Roundcube
In this manual, you configure a full-fledged mail server. List of all features and capabilities:
Mail system based on Postfix;
Support for virtual domains;
Storing mail on the server;
Connection to mailboxes by POP3 and IMAP (Dovecot);
Encryption support;
Storing a part of the settings in MariaDB;
Protection from SPAM and viruses;
Access to mail using the web interface (Roundcube);
The ability to manage mailboxes using PostfixAdmin.
Content
1. Pre-installation of the system
2. Configuring the Web server: NGINX + PHP + MariaDB
3. Installing and configuring PostfixAdmin
7. Configuring Roundcube Webmail
1. Presetting the system
I remind you, this instruction is written under the Linux system CentOS version 7.
Setting the correct name to the server is an important step, since most antispam systems perform checks, referring to the server by name in anticipation of a response.
vi / etc / hostname
relay.dmosk.ru
* You must specify the FQDN name that will be available from the WAN. In this example, relay.dmosk.ru is specified .
After we enter the following command:
hostname relay.dmosk.ru
Install service packs (they will be needed during server configuration):
yum install ntp wget
* ntp for the ability to synchronize the time on the server; wget - client for downloading files.
Set the time zone (in this example, Moscow time):
\ cp / usr / share / zoneinfo / Europe / Moscow / etc / localtime
Synchronize time:
ntpdate en.pool.ntp.org
We update the system:
yum update
We open the ports in advance on the firewall :
firewall-cmd --permanent --add-port = 25 / tcp
firewall-cmd --permanent --add-port = 80 / tcp
firewall-cmd --permanent --add-port = 110 / tcp
firewall-cmd --permanent --add-port = 143 / tcp
firewall-cmd --permanent --add-port = 443 / tcp
firewall-cmd --permanent --add-port = 465 / tcp
firewall-cmd --permanent --add-port = 587 / tcp
firewall-cmd --permanent --add-port = 993 / tcp
firewall-cmd --permanent --add-port = 995 / tcp
firewall-cmd --reload
* where we will open the following ports:
25 - standard SMTP via STARTTLS;
80 - HTTP for Postfixadmin and Roundcube portals;
110 - standard POP3 via STARTTLS;
143 - standard IMAP via STARTTLS;
443 - secure HTTPS for Postfixadmin and Roundcube portals;
465 - Secure SMTP over SSL / TLS;
587 - Secure SMTP through STARTTLS;
993 - Secure IMAP over SSL / TLS;
995 - Secure POP3 over SSL / TLS.
2. Configuring the web server: NGINX + PHP + MariaDB
The PostfixAdmin control system operates as a web application developed in PHP , and stores information in the database. In our example, we will use the web server on NGINX , and the database will be MariaDB.
NGINX installation
Add the repository with the required package:
vi /etc/yum.repos.d/nginx.repo
[nginx]
name = nginx repo
baseurl = http: //nginx.org/packages/centos/$releasever/$basearch/
gpgcheck = 0
enabled = 1
Install nginx:
yum install nginx
We allow autostart service and start it:
systemctl enable nginx
systemctl start nginx
We check the working capacity of the web server by accessing it in the browser using the IP address . If you see the title "Welcome to nginx!", NGINX is configured correctly.
PHP + PHP-FPM + NGINX
Install php and php-fpm :
yum install php
yum install php-fpm
Configuring NGINX:
vi /etc/nginx/conf.d/default.conf
server {
listen 80 default_server;
set $ root_path / usr / share / nginx / html;
location / {
root $ root_path;
index index.php index.hml;
}
location ~ \ .php $ {
fastcgi_pass unix: /var/run/php-fpm/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $ root_path $ fastcgi_script_name;
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT $ root_path;
}
}
* where / usr / share / nginx / html - directory for posting the Postfix management portal.
Configure PHP-FPM:
vi /etc/php-fpm.d/www.conf
listen = /var/run/php-fpm/php5-fpm.sock
* here we changed the line 127.0.0.1:9000 .
Run the services:
systemctl enable php-fpm
systemctl start php-fpm
systemctl restart nginx
* If during the restart of nginx the nginx error pops up : [emerg] a duplicate default server , it is necessary to find the virtual domain setting, which also specifies the option default_server - the option should be removed. Or you can configure another virtual domain yourself.
For verification, create an index file in the site directory with the following content:
vi /usr/share/nginx/html/index.php
<? php phpinfo (); ?>
Open the site in the browser by its IP address. On the opened page we should see the detailed information on php:
MariaDB
Install the database server with the following command:
yum install mariadb mariadb-server
Enable the autostart service and run it:
systemctl enable mariadb
systemctl start mariadb
Set the password for the user sql root:
mysqladmin -u root password
3. Installing and Configuring PostfixAdmin
Install additional components for PHP:
yum install php-mysql php-mbstring php-imap
To apply installed packages, restart the script handler:
systemctl restart php-fpm
Download PostfixAdmin:
wget https://sourceforge.net/projects/postfixadmin/files/latest/download -O postfixadmin.tar.gz
In the directory of nginx sites we create a directory for postfixadmin and unpack the archive into it:
mkdir / usr / share / nginx / html / postfixadmin
tar -C / usr / share / nginx / html / postfixadmin -xvf postfixadmin.tar.gz --strip-components 1
We set the rights to the directory:
chown -R apache: apache / usr / share / nginx / html / postfixadmin
* despite the fact that we use the nginx web server, php-fpm by default, is run from the apache user.
Create the postfix database and the account in mariadb:
mysql -u root -p
CREATE DATABASE postfix DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
* where postfix is the name of the database.
GRANT ALL ON postfix. * TO 'postfix' @ 'localhost' IDENTIFIED BY 'postfix123';
* where postfix is the account name; postfix123 - password; localhost only allows connection from the local server.
Exit the MariaDB command shell:
\ q
Open the configuration file postfixadmin:
vi /usr/share/nginx/html/postfixadmin/config.inc.php
And we edit the following:
$ CONF ['configured'] = true;
$ CONF ['default_language'] = 'ru';
$ CONF ['database_password'] = 'postfix123';
$ CONF ['emailcheck_resolve_domain'] = 'NO';
Launch the browser and enter the address http: // <server IP address> /postfixadmin/setup.php
The process of verifying the configuration and installing the PostfixAdmin portal will begin. After it's finished, enter the password twice and generate a hash:
After reloading the page, we copy the hash:
Open the configuration file:
vi /usr/share/nginx/html/postfixadmin/config.inc.php
We find the line:
$ CONF ['setup_password'] = 'changeme';
And we change it to:
$ CONF ['setup_password'] = '7a8e14 ... c26';
* where '7a8e14 ... c26' is the copied hash.
After, on the same page where the hash is shown, add the superuser PostfixAdmin:
* where Setup password is the password that we entered on the previous page; Password - the new password for the account you are creating.
As a result, we will see the following:
And we go in the browser to the page http: // <IP-address of the server> / postfixadmin /
We enter login and password for the created user.
Done.
4. Configuring Postfix
By default, Postfix is already installed in CentOS 7. But if the server does not exist without it, let's perform the installation with a simple command:
yum install postfix
We create an account from which we will work with the virtual mailbox directory:
groupadd -g 1024 vmail
useradd -d / home / mail -g 1024 -u 1024 vmail -m
* First we create a group of vmail and guid 1024 , after - the user vmail with uid 1024 and home directory / home / mail . Note that on some systems, the group ID and user ID 1024 can be used. In this case, you must create another one, and in this manual, replace all 1024 with an alternative one.
Now open the configuration file of the mail server for editing:
vi /etc/postfix/main.cf
And we edit the following lines:
myorigin = $ mydomain
* This setting specifies which domain to substitute to the sender, if it is not specified in the FROM header.
mydestination = $ myhostname, localhost. $ mydomain, localhost, $ mydomain
* specify for which domains we receive incoming mail.
local_recipient_maps = unix: passwd.byname $ alias_maps
* indicate where to get the list of local users.
mynetworks = 127.0.0.0/8
* Permit to send messages to the local server.
alias_maps = hash: / etc / aliases
* indicate where to get the list of aliases.
inet_interfaces = all
* You need to make sure that postfix will listen on all necessary interfaces, in this case, at all.
Now at the end of the configuration file we will add the following:
virtual_mailbox_base = / home / mail
virtual_alias_maps = proxy: mysql: /etc/postfix/mysql_virtual_alias_maps.cf
virtual_mailbox_domains = proxy: mysql: /etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = proxy: mysql: /etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_minimum_uid = 1024
virtual_uid_maps = static: 1024
virtual_gid_maps = static: 1024
virtual_transport =
dovecot dovecot_destination_recipient_limit = 1
smtpd_sasl_auth_enable = yes
smtpd_sasl_exceptions_networks = $ mynetworks
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_sasl_type =
dovecot smtpd_sasl_path = private / auth
smtpd_tls_cert_file = /etc/ssl/mail/public.pem
smtpd_tls_key_file = /etc/ssl/mail/private.key
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_helo_required = yes
* where:
virtual_mailbox_base - the basic way to store mailboxes on a UNIX system.
virtual_alias_maps - format and path for storing aliases for virtual users.
virtual_mailbox_domains - the format and path for storing virtual user domains.
virtual_mailbox_maps - format and path for storing mailboxes for virtual users.
virtual_minimum_uid - from which number to assign IDs to users.
virtual_uid_maps - the identifier of the user from which messages are written.
virtual_gid_maps - identifier of the group from which messages are written.
virtual_transport - specifies the message delivery system.
dovecot_destination_recipient_limit - the transfer of messages from Postfix to Dovecot is performed according to the specified number (in our example, 1 piece).
smtpd_sasl_auth_enable - allows sasl authentication.
smtpd_sasl_exceptions_networks - excluding networks from using encryption.
smtpd_sasl_security_options - additional options for setting sasl.
broken_sasl_auth_clients - this option is prescribed for MS Outlook clients.
smtpd_sasl_type - indicates the type of authentication.
smtpd_sasl_path - the path to the temporary information exchange files with Dovecot. It specifies either an absolute path or a relative queue_directory.
smtpd_tls_cert_file - the full path to the public certificate.
smtpd_tls_key_file - the full path to the private certificate.
smtpd_use_tls - indicates to clients that TLS support is available.
smtpd_tls_auth_only - use only TLS.
smtpd_helo_required - request to start the session with a greeting.
Create a file with the settings for accessing the database with aliases:
vi /etc/postfix/mysql_virtual_alias_maps.cf
user = postfix
password = postfix123
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address = '% s' AND active = '1'
* where user and password - login and password to connect to MySQL; hosts - the name of the database server (in this case, the local server); dbname - the name of the database; query - a query template for data.
Create a file with instructions for obtaining data on virtual domains:
vi /etc/postfix/mysql_virtual_domains_maps.cf
user = postfix
password = postfix123
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain = '% u'
And a file with mailboxes:
vi /etc/postfix/mysql_virtual_mailbox_maps.cf
user = postfix
password = postfix123
hosts = localhost
dbname = postfix
query = SELECT CONCAT (domain, '/', maildir) FROM mailbox WHERE username = '% s' AND active = '1'
Open the file master.cf and add to the very end:
vi /etc/postfix/master.cf
submission inet n - n - - smtpd
-o smtpd_tls_security_level = may
-o smtpd_sasl_auth_enable = yes
-o smtpd_sasl_type = dovecot
-o smtpd_sasl_path = / var / spool / postfix / private / auth
-o smtpd_sasl_security_options = noanonymous
-o smtpd_sasl_local_domain = $ myhostname
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
dovecot unix - n n - - pipe
flags = DRhu user = vmail: vmail argv = / usr / libexec / dovecot / deliver -d $ {recipient}
* Need to make sure that the contents of the file are no other options uncommented for submission, smtps and dovecot (by default, they are not). In this case, we configured postfix on ports 25, 465 and 587.
Restart postfix:
systemctl restart postfix
5. Configuring Dovecot
Install Dovecot with the component to work with the DBMS:
yum install dovecot dovecot-mysql
We configure the way messages are stored:
vi /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir: / home / mail /% d /% u /
first_valid_gid = 1024
* In this example, the messages will be stored in the advanced maildir format .
Configure the listener for authentication:
vi /etc/dovecot/conf.d/10-master.conf
service auth {
unix_listener / var / spool / postfix / private / auth {
mode = 0666
user = postfix
group = postfix
}
unix_listener auth-userdb {
mode = 0600
user = vmail
group = vmail
}
}
* Please note that / var / spool / postfix / private / auth is the same private / auth that was registered by us in postfix.
Configure authentication in Dovecot:
vi /etc/dovecot/conf.d/10-auth.conf
#! include auth-system.conf.ext
! include auth-sql.conf.ext
* in this case, we just comment on the usual authentication and remove the comment for using sql-auttification.
Configure the use of encryption:
vi /etc/dovecot/conf.d/10-ssl.conf
ssl = required
ssl_cert = </etc/ssl/mail/public.pem
ssl_key = </etc/ssl/mail/private.key
* This setting will tell dovecot to require clients to use encryption.
Let's configure automatic creation of directories when the user first connects to the mailbox:
vi /etc/dovecot/conf.d/15-lda.conf
lda_mailbox_autocreate = yes
We configure the connection to our database:
vi /etc/dovecot/conf.d/auth-sql.conf.ext
passdb {
...
args = /etc/dovecot/sql.conf
}
userdb {
...
args = /etc/dovecot/sql.conf
}
* In this example, we have specified a file that will contain the settings for retrieving users and passwords from the database.
Create a file with the settings for working with mysql:
vi /etc/dovecot/sql.conf
driver = mysql
connect = host = localhost dbname = postfix user = postfix password = postfix123
default_pass_scheme = MD5-CRYPT
password_query = SELECT password FROM mailbox WHERE username = '% u'
user_query = SELECT maildir, 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '% u'
user_query = SELECT CONCAT ('/ home / mail /', LCASE (`domain`), '/', LCASE (` maildir`)), 1024 AS uid, 1024 AS gid FROM mailbox WHERE username = '% u'
And, finally, configure the protocols and interface, which will listen to dovecot:
vi /etc/dovecot/dovecot.conf
protocols = imap imaps pop3 pop3s
listen = *
* By default, dovecot also listens on ipv6 ( listen = *, ::) . If the server does not use the 6th version of the TCP / IP protocol, errors will appear in the dovecot logs:
master: Error: service (imap-login): listen (::, 143) failed
: service (imap-login): listen (::, 993) failed: Address
Generate security certificates
Create a catalog in which to place the certificates:
mkdir -p / etc / ssl / mail
And we will generate them with the following command:
openssl req -new -x509 -days 1461 -nodes -out /etc/ssl/mail/public.pem -keyout /etc/ssl/mail/private.key -subj "/ C = RU / ST = SPb / L = SPb / O = Global Security / OU = IT Department / CN = relay.dmosk.ru "
* the certificate is generated for 1461 days, subj keys can be arbitrary, CN must be specified in accordance with the name of the server by which we will connect to the mail.
Run the dovecot:
systemctl start dovecot
6. Create the first mailbox and check the server operation
In the browser, enter the path to Postfixadmin in the address bar - http: // <server IP address> / postfixadmin /.
We enter login and password from the administrative account that we created in step 3. We will see the account management page.
Let's move on to the Domain List - New Domain:
Fill out the forms and click on Add Domain:
Now go to Overview - Create a box:
Enter the data for the new user and click on Create a box:
Now you can connect to the server using any email program, for example, Mozilla Thunderbird.
Connection parameters:
Server : the name of the server or its IP address (not desirable, since the certificate is issued by domain name).
IMAP : 143 STARTTLS or 993 SSL / TLS
POP3 : 110 STARTTLS or 995 SSL / TLS
SMTP : 25 STARTTLS or 465 SSL / TLS or 587 STARTTLS
7. Install and configure Roundcube Webmail
On the official site go to the download page of Roundcube. See the link to the latest stable version of the product:
Use the link to download the program archive:
wget https://github.com/roundcube/roundcubemail/releases/download/1.1.9/roundcubemail-1.1.9.tar.gz
Create a directory where the portal files will be located:
mkdir / usr / share / nginx / html / webmail
And unpack the downloaded archive:
tar -C / usr / share / nginx / html / webmail -xvf roundcubemail-1.1.9.tar.gz --strip-components 1
Copy the config template:
cp /usr/share/nginx/html/webmail/config/config.inc.php.sample /usr/share/nginx/html/webmail/config/config.inc.php
And we open it for editing:
vi /usr/share/nginx/html/webmail/config/config.inc.php
$ config ['db_dsnw'] = 'mysql: // roundcube: roundcube123 @ localhost / roundcubemail';
$ config ['enable_installer'] = true;
* We edit the first line, and add the second one. In the first line of the roundcube: roundcube123 - login and password for accessing the database; localhost - the database server; roundcubemail - the name of the database.
We set the apache owner to the portal folder:
chown -R apache: apache / usr / share / nginx / html / webmail
Create a base in MariaDB for the roundcubemail:
mysql -uroot -p
> CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
> GRANT ALL PRIVILEGES ON roundcubemail. * TO roundcube @ localhost IDENTIFIED BY 'roundcube123';
> quit
And load the data into the created database:
mysql -uroot -p roundcube </ usr/share/nginx/html/webmail/SQL/mysql.initial.sql
Install the components necessary for the work of Roundcube:
yum install php-pear php-php-php-php-php-php-pear-Net-SMTP php-pear-Net-IDNA2 php-pear-Mail-Mime
Let's configure php:
vi /etc/php.ini
date.timezone = "Europe / Moscow"
Reboot php-fpm:
systemctl restart php-fpm
Now open the browser and go to http: // <server IP address> / webmail / installer /. At the very bottom click on the Next button . If the button is inactive, check that there are no errors ( NOT OK ).
We check that all items are in the OK state .
After removing the folder with the installation scripts:
\ rm -R / usr / share / nginx / html / webmail / installer
And go to the browser at http: // <server IP address> / webmail /.
8. Protect yourself from viruses
Installing and Configuring ClamAV
Install the antivirus:
yum install clamav clamsmtp clamav-scanner-systemd clamav-update
Configuring postfix:
vi /etc/postfix/main.cf
content_filter = scan: [127.0.0.1]: 10025
receive_override_options = no_address_mappings
* where content_filter points to an application that will scan messages; receive_override_optionsallows you to see the original email addresses of emails with viruses.
Now edit master.cf:
vi /etc/postfix/master.cf
We add the following:
scan unix - - n - 16 smtp
-o smtp_send_xforward_command = yes
-o smtp_enforce_tls = no
127.0.0.1:10026 inet n - n - 16 smtpd
-o content_filter =
-o receive_override_options = no_unknown_recipient_checks, no_header_body_checks
-o smtpd_helo_restrictions =
-o smtpd_client_restrictions =
- o smtpd_sender_restrictions =
-o smtpd_recipient_restrictions = permit_mynetworks, reject
-o mynetworks_style = host
-o smtpd_authorized_xforward_hosts = 127.0.0.0 / 8
Restart postfix:
systemctl restart postfix
Configure clamsmtpd:
vi /etc/clamsmtpd.conf
ClamAddress: /var/run/clamd.scan/clamd.sock
TempDirectory: /var/run/clamd.scan
* Where ClamAddress is pointing to the path to the socket file - it must match the path in the configuration file for clam scan; TempDirectory - the path for storing temporary files.
Editing the configuration file for clam scan:
vi /etc/clamd.d/scan.conf
PidFile /var/run/clamd.scan/clamd.pid
LocalSocket /var/run/clamd.scan/clamd.sock
User clamsmtp
* where PidFile is the path for the service pid file; LocalSocket - the path to the socket file for interaction with clamsmtp; User - the user from which clamd will be launched.
Let's edit the owner on the directory for the socket file:
chown clamsmtp: clamscan /var/run/clamd.scan
Now let's run the antivirus and run it:
systemctl enable clamsmtpd
systemctl start clamsmtpd
systemctl enable clamd @ scan
systemctl start clamd @ scan
Update
Open the config freshclam and put a comment opposite Example:
vi /etc/freshclam.conf
#Example
We resolve and start the service:
systemctl enable clamd @ freshclam
systemctl start clamd @ freshclam
Run the update:
freshclam
To configure the automatic update, we edit cron:
crontab -e
15 3 * * * / bin / freshclam
* In this example, every day at 03:15 the clamav update process will be started.
Checking
To check, we send a message with the following content:
X5O! P% @ AP [4 \ PZX54 (P ^) 7CC) 7} $ EICAR-STANDARD-ANTIVIRUS-TEST-FILE! $ H + H *
The letter should not reach.
9. Fighting with SPAM
Checking content with Spamassassin
Install spamassassin
yum install spamassassin
Edit master.cf:
vi /etc/postfix/master.cf
For smtp, add the following option:
smtp inet n - n - - smtpd
-o content_filter = spamassassin
And add the following:
spamassassin unix - n n - - pipe
flags = R user = spamd argv = / usr / bin / spamc -u spamd -e / usr / sbin / sendmail -f $ sender $ recipient
Updating spamassassin:
sa-update --nogpg
Let's start it and start the service:
systemctl enable spamassassin
systemctl start spamassassin
Restart postfix:
systemctl restart postfix
For automatic updates, add the following to cron:
crontab -e
30 3 * * * / bin / sa-update
* The update will occur every day at 03:30 .
To check the operation of the content antispam, send a message with the following content:
XJS * C4JDBQADN1.NSBN3 * 2IDNEN * GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL * C.34X
Antispam tools Postfix
MTA Postfix has its own mechanism for checking the headers of incoming messages. The rules are placed in 6 sections, which are processed in the following order:
client -> helo -> sender -> relay -> recipient -> data
And so, to configure the antispam in the main.cf configuration file, add:
vi /etc/postfix/main.cf
= smtpd_client_restrictions
permit_mynetworks
permit_sasl_authenticated
reject_unauth_pipelining
permit
smtpd_helo_restrictions =
permit
smtpd_sender_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_non_fqdn_sender
reject_unknown_sender_domain
permit
smtpd_relay_restrictions =
permit
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_non_fqdn_recipient
reject_unauth_destination
reject_unknown_recipient_domain
reject_unverified_recipient
permit
smtpd_data_restrictions =
permit
smtpd_end_of_data_restrictions =
permit
* these are more or less mild rules. They can be used for the first time while testing the server.
To strengthen the protection we add:
smtpd_recipient_restrictions =
...
reject_unknown_client_hostname
reject_invalid_helo_hostname
reject_non_fqdn_helo_hostname
reject_unknown_helo_hostname
reject_rbl_client bl.spamcop.net
reject_rbl_client cbl.abuseat.org
reject_rbl_client dul.ru
reject_rbl_client dnsbl.abuse.ch
permit
* where:
reject_unknown_client_hostname - checks the presence of the PRT record of the sender and the availability of the working A-record in accordance with the PTR.
reject_invalid_helo_hostname - Checks the HELO greeting syntax.
reject_non_fqdn_helo_hostname - requires the correct FQDN name during the HELO greeting.
reject_unknown_helo_hostname - forbids to be represented by names for which there is no A-record or MX.
reject_rbl_client - checks the presence of the sender in blacklists.
After making all edits, you need to restart Postfix:
systemctl restart postfix