Basic mailserver configuration on RHEL10: Difference between revisions
No edit summary |
|||
| (66 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
Quick and dirty (10 minutes) very basic configuration of mailserver with postfix, dovecot and mysql/mariadb.<br> | |||
It is the update of the previous [[basic_mailserver_configuration_on_RHEL_derivates]] | |||
===Prerequisites=== | |||
configure your DNS properly | |||
*A record matching the FQDN of this server | |||
*MX record for the domains to the IP of this server | |||
*ensure reverse IP is configured properly or some external servers can refuse your email | |||
*not mandatory: SPF record for your domains matching with the IP of your server | |||
===SSL certificates=== | |||
dnf install epel-release | |||
dnf install certbot | |||
Create cert with your FQDN server name (server08.vettore.org in the example) | |||
certbot certonly -d server08.vettore.org | |||
===install Mariadb and set up tables=== | ===install Mariadb and set up tables=== | ||
| Line 16: | Line 21: | ||
dnf install mariadb-server | dnf install mariadb-server | ||
systemctl enable mariadb --now | systemctl enable mariadb --now | ||
CREATE TABLE `users` ( `email` varchar(200) NOT NULL, | Enter mariadb console and: | ||
create database mailserver; | |||
use mailserver; | |||
PRIMARY KEY (`email`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 | ====USERS==== | ||
CREATE TABLE `users` ( | |||
`email` varchar(200) NOT NULL, | |||
`enabled` int(11) DEFAULT 1, | |||
`password` varchar(128) NOT NULL, | |||
`imap_enabled` int(11) DEFAULT 1, | |||
`smtp_enabled` int(11) NOT NULL DEFAULT 1, | |||
`smtp_username` varchar(45) DEFAULT NULL, | |||
PRIMARY KEY (`email`) | |||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 | |||
There are more fields than in usual tutorials you can retrieve online. | |||
*enabled: user can receive emails | |||
*imap_enabled: user can retieve email with IMAPs protocol | |||
*smtp_enabled: user can use smtp service to send email from a remote client | |||
*smtp_username: to authenticate SMTP, can be different from the email address | |||
DOMAINS | |||
====DOMAINS==== | |||
CREATE TABLE | CREATE TABLE | ||
| Line 31: | Line 52: | ||
ENGINE=MyISAM DEFAULT CHARSET=utf8 | ENGINE=MyISAM DEFAULT CHARSET=utf8 | ||
====ALIASES==== | |||
CREATE TABLE `aliases` ( `email` varchar(128) NOT NULL, | CREATE TABLE `aliases` ( `email` varchar(128) NOT NULL, | ||
| Line 38: | Line 59: | ||
PRIMARY KEY (`email`)) ENGINE=MyISAM DEFAULT CHARSET=utf8; | PRIMARY KEY (`email`)) ENGINE=MyISAM DEFAULT CHARSET=utf8; | ||
ADD a test user: | ADD a test user (enter in mariadb console): | ||
insert into users set email='paperino@274512.xyz', password='segretina412', | insert into users set email='paperino@274512.xyz', password='segretina412', smtp_username='paperino'; | ||
insert into domains set domain='274512.xyz'; | |||
Grant privileges: | Grant privileges: | ||
grant select on mailserver.* to postfix@localhost identified by 'yoursecretpassword' | grant select on mailserver.* to postfix@localhost identified by 'yoursecretpassword' | ||
=== | ===Postfix=== | ||
dnf install postfix postfix-mysql | dnf install postfix postfix-mysql | ||
groupadd -g150 vmail | groupadd -g150 vmail | ||
| Line 56: | Line 72: | ||
mkdir /var/vmail | mkdir /var/vmail | ||
chown vmail:vmail /var/vmail | chown vmail:vmail /var/vmail | ||
Edit /etc/postfix/main.cf and change/add the following line accordingly | Edit /etc/postfix/main.cf and change/add the following line accordingly (replace paths of your cerificates) | ||
inet_protocols = all | inet_protocols = all | ||
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-domains.cf | virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-domains.cf | ||
| Line 62: | Line 78: | ||
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-aliases.cf | virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-aliases.cf | ||
virtual_transport = dovecot | virtual_transport = dovecot | ||
smtpd_tls_cert_file = /etc/letsencrypt/live/server08.vettore.org/ | dovecot_destination_recipient_limit = 1 | ||
smtpd_tls_cert_file = /etc/letsencrypt/live/server08.vettore.org/fullchain.pem | |||
smtpd_tls_key_file = /etc/letsencrypt/live/server08.vettore.org/privkey.pem | smtpd_tls_key_file = /etc/letsencrypt/live/server08.vettore.org/privkey.pem | ||
smtp_tls_CApath = /etc/letsencrypt/live/ | smtpd_tls_security_level = may | ||
smtp_tls_CAfile = /etc/letsencrypt/live/server08.vettore.org/ | smtp_tls_CApath = /etc/letsencrypt/live/server08.vettore.org | ||
smtp_tls_CAfile = /etc/letsencrypt/live/server08.vettore.org/chain.pem | |||
smtpd_client_restrictions = permit_mynetworks, | |||
permit_sasl_authenticated, | |||
reject_unauth_destination, | |||
reject_unknown_sender_domain, | |||
reject_unknown_reverse_client_hostname, | |||
reject_rbl_client b.barracudacentral.org, | |||
reject_rbl_client blackholes.easynet.nl, | |||
reject_rbl_client proxies.blackholes.wirehub.net, | |||
reject_rbl_client bl.spamcop.net, | |||
#disabled for several reasons (be careful to enable again) | |||
# reject_rbl_client sbl.spamhaus.org, | |||
# reject_rbl_client zen.spamhaus.org, | |||
# reject_rhsbl_sender blackhole.securitysage.com, | |||
# reject_rbl_client cbl.abuseat.org, | |||
Setup the connectors configured above (virtual_xxx) | |||
/etc/postfix/mysql-virtual-domains.cf: | |||
user = postfix | |||
password = yuorsecretpassword | |||
hosts = 127.0.0.1 | |||
dbname = mailserver | |||
query = SELECT 1 FROM domains WHERE domain='%s' AND enabled=1 | |||
/etc/postfix/mysql-virtual-users.cf : | |||
<pre> | |||
user = postfix | |||
password = yoursecretpassword | |||
hosts = 127.0.0.1 | |||
dbname = mailserver | |||
query = SELECT 1 FROM users where email='%s'AND enabled=1 | |||
</pre> | |||
/etc/postfix/mysql-virtual-aliases.cf | |||
<pre> | |||
user = postfix | |||
password = yoursecretpassword | |||
hosts = 127.0.0.1 | |||
dbname = mailserver | |||
query = SELECT alias FROM aliases WHERE email='%s' AND enabled=1 | |||
</pre> | |||
You can check your configuration with postmap (1 returned in case of success) | |||
postmap q 274512.xyz mysql:/etc/postfix/mysql-virtual-domains.cf | |||
postmap -q paperino@274512.xyz mysql:/etc/postfix/mysql-virtual-users.cf | |||
Add this to your /etc/postfix/master.cf | |||
dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient} | |||
Enable & start service | |||
systemctl enable postfix --now | |||
<br> | <br> | ||
conf.d/10-mail.conf | ===Dovecot IMAP=== | ||
dnf install dovecot dovecot-mysql | |||
edit conf.d/10-mail.conf and add/uncomment this | |||
mail_location = maildir:/var/vmail/%d/%n/Maildir | mail_location = maildir:/var/vmail/%d/%n/Maildir | ||
edit /etc/dovecot/conf.d/auth-sql.conf.ext <br> | |||
comment out the first userdb section<br> | |||
remove comment from the last userdb section end edit as follows: | |||
userdb { | userdb { | ||
| Line 86: | Line 162: | ||
} | } | ||
Edit /etc/dovecot/conf.d/10-auth.conf:<br> | |||
Enable loading of the above file removing comment from | |||
!include auth-sql.conf.ext | |||
and comment out in order to disable PAM (otherwise you will get errors in /var/log/secure) | |||
#!include auth-system.conf.ext | |||
Verify path in the passdb section of the /etc/dovecot/conf.d/auth-sql.conf.ext file. Should be /etc/dovecot/dovecot-sql.conf.ext<br> | |||
You must create this file: | |||
driver=mysql | driver=mysql | ||
default_pass_scheme = PLAIN | default_pass_scheme = PLAIN | ||
connect= host=127.0.0.1 port=3306 dbname=mailserver user=postfix password= | connect= host=127.0.0.1 port=3306 dbname=mailserver user=postfix password=yoursecretpassword | ||
password_query = SELECT password, email as user FROM users where email='%u' AND | password_query = SELECT password, email as user FROM users where email='%u' AND imap_enabled=1 | ||
in | in conf.d/10-ssl.conf add the certifcate and key replacing with the path of the certificate created above | ||
ssl_cert = </etc/letsencrypt/live/server08.vettore.org/fullchain.pem | |||
ssl_key = </etc/letsencrypt/live/server08.vettore.org/privkey.pem | |||
#leave the following commented for normal configuration | |||
#ssl_ca = </etc/letsencrypt/live/server08.vettore.org/chain.pem | |||
in dovecot.conf remove comment from protocol. Remove pop3 if not needed. Remove submission if you wish to configure SMTP auth with a different service (see cirus-sasl section below). LMTP is optional (see SIEVE paragraph later) | |||
protocols = imap lmtp | protocols = imap lmtp | ||
Add to the bottom: | |||
mail_uid=vmail | mail_uid=vmail | ||
mail_gid=vmail | mail_gid=vmail | ||
first_valid_uid = 150 | first_valid_uid = 150 | ||
last_valid_uid = 150 | last_valid_uid = 150 | ||
| Line 122: | Line 203: | ||
} | } | ||
} | } | ||
Start end enable service | |||
systemctl enable dovecot --now | |||
===SMTP auth with cyrus-sasl=== | |||
Not the easiest way: you can use directly dovecot to authenticate SMTP users.</br> | |||
But the advantage of cyrus-sasl is you can configure different users for SMTP and IMAP or enable/disable SMTP for IMAP users. | |||
The table structure created above have fields for this purpose.</br> | |||
Setting smtp_enabled=0 means the users cannot use SMTP auth (cannot send email from outside using this server as relay) | |||
dnf install cyrus-sasl cyrus-sasl-plain cyrus-sasl-lib cyrus-sasl-sql | |||
edit /etc/sasl2/smtpd.conf | |||
<pre> | |||
pwcheck_method: auxprop | |||
mech_list: PLAIN LOGIN | |||
auxprop_plugin: sql | |||
sql_usessl: no | |||
sql_engine: mysql | |||
sql_hostnames: localhost | |||
sql_user: postfix | |||
sql_database: mailserver | |||
sql_passwd: yoursecretpassword | |||
sql_select: select password from users where username = '%u' AND smtp_enabled=1 | |||
log_level: 3 | |||
</pre> | |||
uncomment the following line in /etc/postfix/masters.cf | |||
submission inet n - n - - smtpd | |||
add the following to /etc/postfix/main.cf | |||
smtpd_use_tls = yes | |||
smtpd_sasl_path = smtpd | |||
smtpd_sasl_auth_enable = yes | |||
smtpd_sasl_type = cyrus | |||
smtpd_sasl_security_options = noanonymous | |||
smtpd_tls_auth_only = yes | |||
restart services and start (anable) saslauthd | |||
systemctl restart postfix | |||
systemctl restart dovecot | |||
systemctl enable saslauthd --now | |||
===Verify SSL connections=== | |||
====SMTP starttls==== | |||
openssl s_client -starttls smtp -servername server08.vettore.org -connect server08.vettore.org:587 | |||
====IMAP startls==== | |||
openssl s_client -starttls imap -servername server08.vettore.org -connect server08.vettore.org:143 | |||
==Sieve/pigeonhole (optional)== | |||
dnf install dovecot-pigeonhole | |||
edit ./conf.d/20-lmtp.conf & uncomment | |||
mail_plugins = $mail_plugins sievement | |||
edit ./conf.d/20-managesieve.conf and uncomment | |||
protocols = $protocols sieve | |||
and | |||
service managesieve-login { | |||
inet_listener sieve { | |||
port = 4190 | |||
} | |||
} | |||
restart dovecot</br> | |||
Try to telnet your local port 4190 to check if managesieve service is running</br> | |||
Enable LMTP in ./conf/10-master.conf | |||
service lmtp { | |||
unix_listener /var/spool/postfix/private/dovecot-lmtp { | |||
group = postfix | |||
mode = 0600 | |||
user = postfix | |||
} | |||
} | |||
in /etc/postfix/main.cf edit the virtual_transport | |||
virtual_transport = lmtp:unix:/var/spool/postfix/private/dovecot-lmtp | |||
restart both postfix and dovecot | |||
== SPF filtering (strongly suggested)== | |||
dnf install pypolicyd-spf | |||
create user | |||
adduser policyd-spf --user-group --no-create-home -s /bin/false | |||
Add to /etc/postfix/master.cf | |||
policyd-spf unix - n n - 0 spawn | |||
user=policyd-spf argv=/usr/libexec/postfix/policyd-spf | |||
Add to /etc/postfix/main.cf unde smtp_client_restrictions | |||
smtpd_client_restrictions = permit_mynetworks, | |||
permit_sasl_authenticated, | |||
reject_unauth_destination, | |||
reject_unknown_sender_domain, | |||
reject_unknown_reverse_client_hostname, | |||
........ | |||
check_policy_service unix:private/policyd-spf, | |||
Restart postfix | |||
Latest revision as of 15:03, 16 October 2025
Quick and dirty (10 minutes) very basic configuration of mailserver with postfix, dovecot and mysql/mariadb.
It is the update of the previous basic_mailserver_configuration_on_RHEL_derivates
Prerequisites
configure your DNS properly
- A record matching the FQDN of this server
- MX record for the domains to the IP of this server
- ensure reverse IP is configured properly or some external servers can refuse your email
- not mandatory: SPF record for your domains matching with the IP of your server
SSL certificates
dnf install epel-release dnf install certbot
Create cert with your FQDN server name (server08.vettore.org in the example)
certbot certonly -d server08.vettore.org
install Mariadb and set up tables
timedatectl set-timezone Europe/Rome dnf install mariadb dnf install mariadb-server systemctl enable mariadb --now
Enter mariadb console and:
create database mailserver; use mailserver;
USERS
CREATE TABLE `users` ( `email` varchar(200) NOT NULL, `enabled` int(11) DEFAULT 1, `password` varchar(128) NOT NULL, `imap_enabled` int(11) DEFAULT 1, `smtp_enabled` int(11) NOT NULL DEFAULT 1, `smtp_username` varchar(45) DEFAULT NULL, PRIMARY KEY (`email`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
There are more fields than in usual tutorials you can retrieve online.
- enabled: user can receive emails
- imap_enabled: user can retieve email with IMAPs protocol
- smtp_enabled: user can use smtp service to send email from a remote client
- smtp_username: to authenticate SMTP, can be different from the email address
DOMAINS
CREATE TABLE `domains` ( `domain` varchar(200) NOT NULL, `enabled` int(11) NOT NULL DEFAULT '1', PRIMARY KEY (`domain`)) ENGINE=MyISAM DEFAULT CHARSET=utf8
ALIASES
CREATE TABLE `aliases` ( `email` varchar(128) NOT NULL, `alias` varchar(255) NOT NULL, `enabled` int(11) DEFAULT '1', PRIMARY KEY (`email`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;
ADD a test user (enter in mariadb console):
insert into users set email='paperino@274512.xyz', password='segretina412', smtp_username='paperino'; insert into domains set domain='274512.xyz';
Grant privileges:
grant select on mailserver.* to postfix@localhost identified by 'yoursecretpassword'
Postfix
dnf install postfix postfix-mysql groupadd -g150 vmail useradd -r -u150 -d /var/vmail -s /sbin/nologin -g vmail vmail mkdir /var/vmail chown vmail:vmail /var/vmail
Edit /etc/postfix/main.cf and change/add the following line accordingly (replace paths of your cerificates)
inet_protocols = all
virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-users.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-aliases.cf
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1
smtpd_tls_cert_file = /etc/letsencrypt/live/server08.vettore.org/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/server08.vettore.org/privkey.pem
smtpd_tls_security_level = may
smtp_tls_CApath = /etc/letsencrypt/live/server08.vettore.org
smtp_tls_CAfile = /etc/letsencrypt/live/server08.vettore.org/chain.pem
smtpd_client_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
reject_unknown_sender_domain,
reject_unknown_reverse_client_hostname,
reject_rbl_client b.barracudacentral.org,
reject_rbl_client blackholes.easynet.nl,
reject_rbl_client proxies.blackholes.wirehub.net,
reject_rbl_client bl.spamcop.net,
#disabled for several reasons (be careful to enable again)
# reject_rbl_client sbl.spamhaus.org,
# reject_rbl_client zen.spamhaus.org,
# reject_rhsbl_sender blackhole.securitysage.com,
# reject_rbl_client cbl.abuseat.org,
Setup the connectors configured above (virtual_xxx)
/etc/postfix/mysql-virtual-domains.cf:
user = postfix password = yuorsecretpassword hosts = 127.0.0.1 dbname = mailserver query = SELECT 1 FROM domains WHERE domain='%s' AND enabled=1
/etc/postfix/mysql-virtual-users.cf :
user = postfix password = yoursecretpassword hosts = 127.0.0.1 dbname = mailserver query = SELECT 1 FROM users where email='%s'AND enabled=1
/etc/postfix/mysql-virtual-aliases.cf
user = postfix password = yoursecretpassword hosts = 127.0.0.1 dbname = mailserver query = SELECT alias FROM aliases WHERE email='%s' AND enabled=1
You can check your configuration with postmap (1 returned in case of success)
postmap q 274512.xyz mysql:/etc/postfix/mysql-virtual-domains.cf postmap -q paperino@274512.xyz mysql:/etc/postfix/mysql-virtual-users.cf
Add this to your /etc/postfix/master.cf
dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}
Enable & start service
systemctl enable postfix --now
Dovecot IMAP
dnf install dovecot dovecot-mysql
edit conf.d/10-mail.conf and add/uncomment this
mail_location = maildir:/var/vmail/%d/%n/Maildir
edit /etc/dovecot/conf.d/auth-sql.conf.ext
comment out the first userdb section
remove comment from the last userdb section end edit as follows:
userdb {
driver = static
args = uid=150 gid=150 home=/var/vmail/%d/%n allow_all_users=yes
}
Edit /etc/dovecot/conf.d/10-auth.conf:
Enable loading of the above file removing comment from
!include auth-sql.conf.ext
and comment out in order to disable PAM (otherwise you will get errors in /var/log/secure)
#!include auth-system.conf.ext
Verify path in the passdb section of the /etc/dovecot/conf.d/auth-sql.conf.ext file. Should be /etc/dovecot/dovecot-sql.conf.ext
You must create this file:
driver=mysql default_pass_scheme = PLAIN connect= host=127.0.0.1 port=3306 dbname=mailserver user=postfix password=yoursecretpassword password_query = SELECT password, email as user FROM users where email='%u' AND imap_enabled=1
in conf.d/10-ssl.conf add the certifcate and key replacing with the path of the certificate created above
ssl_cert = </etc/letsencrypt/live/server08.vettore.org/fullchain.pem ssl_key = </etc/letsencrypt/live/server08.vettore.org/privkey.pem #leave the following commented for normal configuration #ssl_ca = </etc/letsencrypt/live/server08.vettore.org/chain.pem
in dovecot.conf remove comment from protocol. Remove pop3 if not needed. Remove submission if you wish to configure SMTP auth with a different service (see cirus-sasl section below). LMTP is optional (see SIEVE paragraph later)
protocols = imap lmtp
Add to the bottom:
mail_uid=vmail
mail_gid=vmail
first_valid_uid = 150
last_valid_uid = 150
service stats {
unix_listener stats-reader {
group = vmail
mode = 0666
}
unix_listener stats-writer {
group = vmail
mode = 0666
}
}
Start end enable service
systemctl enable dovecot --now
SMTP auth with cyrus-sasl
Not the easiest way: you can use directly dovecot to authenticate SMTP users.
But the advantage of cyrus-sasl is you can configure different users for SMTP and IMAP or enable/disable SMTP for IMAP users.
The table structure created above have fields for this purpose.
Setting smtp_enabled=0 means the users cannot use SMTP auth (cannot send email from outside using this server as relay)
dnf install cyrus-sasl cyrus-sasl-plain cyrus-sasl-lib cyrus-sasl-sql
edit /etc/sasl2/smtpd.conf
pwcheck_method: auxprop mech_list: PLAIN LOGIN auxprop_plugin: sql sql_usessl: no sql_engine: mysql sql_hostnames: localhost sql_user: postfix sql_database: mailserver sql_passwd: yoursecretpassword sql_select: select password from users where username = '%u' AND smtp_enabled=1 log_level: 3
uncomment the following line in /etc/postfix/masters.cf
submission inet n - n - - smtpd
add the following to /etc/postfix/main.cf
smtpd_use_tls = yes smtpd_sasl_path = smtpd smtpd_sasl_auth_enable = yes smtpd_sasl_type = cyrus smtpd_sasl_security_options = noanonymous smtpd_tls_auth_only = yes
restart services and start (anable) saslauthd
systemctl restart postfix systemctl restart dovecot systemctl enable saslauthd --now
Verify SSL connections
SMTP starttls
openssl s_client -starttls smtp -servername server08.vettore.org -connect server08.vettore.org:587
IMAP startls
openssl s_client -starttls imap -servername server08.vettore.org -connect server08.vettore.org:143
Sieve/pigeonhole (optional)
dnf install dovecot-pigeonhole
edit ./conf.d/20-lmtp.conf & uncomment
mail_plugins = $mail_plugins sievement
edit ./conf.d/20-managesieve.conf and uncomment
protocols = $protocols sieve
and
service managesieve-login {
inet_listener sieve {
port = 4190
}
}
restart dovecot
Try to telnet your local port 4190 to check if managesieve service is running
Enable LMTP in ./conf/10-master.conf
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
group = postfix
mode = 0600
user = postfix
}
}
in /etc/postfix/main.cf edit the virtual_transport
virtual_transport = lmtp:unix:/var/spool/postfix/private/dovecot-lmtp
restart both postfix and dovecot
SPF filtering (strongly suggested)
dnf install pypolicyd-spf
create user
adduser policyd-spf --user-group --no-create-home -s /bin/false
Add to /etc/postfix/master.cf
policyd-spf unix - n n - 0 spawn user=policyd-spf argv=/usr/libexec/postfix/policyd-spf
Add to /etc/postfix/main.cf unde smtp_client_restrictions
smtpd_client_restrictions = permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
reject_unknown_sender_domain,
reject_unknown_reverse_client_hostname,
........
check_policy_service unix:private/policyd-spf,
Restart postfix
