Basic mailserver configuration on RHEL10: Difference between revisions
No edit summary |
|||
| (53 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]] | 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=== | |||
===SSL | |||
dnf install epel-release | dnf install epel-release | ||
dnf install certbot | dnf install certbot | ||
Create cert with your | Create cert with your FQDN server name (server08.vettore.org in the example) | ||
certbot certonly -d server08.vettore.org | certbot certonly -d server08.vettore.org | ||
===install Mariadb and set up tables=== | ===install Mariadb and set up tables=== | ||
| Line 27: | Line 22: | ||
systemctl enable mariadb --now | systemctl enable mariadb --now | ||
Enter | Enter mariadb console and: | ||
create database mailserver; | create database mailserver; | ||
use 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==== | |||
DOMAINS | |||
CREATE TABLE | CREATE TABLE | ||
| Line 47: | 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 55: | Line 60: | ||
ADD a test user (enter in mariadb console): | 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'; | insert into domains set domain='274512.xyz'; | ||
| Line 61: | Line 66: | ||
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 67: | 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 73: | 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 | Setup the connectors configured above (virtual_xxx) | ||
/etc/postfix/mysql-virtual-domains.cf: | /etc/postfix/mysql-virtual-domains.cf: | ||
| Line 86: | Line 111: | ||
hosts = 127.0.0.1 | hosts = 127.0.0.1 | ||
dbname = mailserver | dbname = mailserver | ||
query = SELECT 1 FROM domains WHERE domain='%s' AND enabled=1 | query = SELECT 1 FROM domains WHERE domain='%s' AND enabled=1 | ||
/etc/postfix/mysql-virtual-users.cf : | /etc/postfix/mysql-virtual-users.cf : | ||
| Line 94: | Line 119: | ||
hosts = 127.0.0.1 | hosts = 127.0.0.1 | ||
dbname = mailserver | dbname = mailserver | ||
query = SELECT 1 FROM users where email='%s' | query = SELECT 1 FROM users where email='%s'AND enabled=1 | ||
</pre> | |||
/etc/postfix/mysql-virtual-aliases.cf | /etc/postfix/mysql-virtual-aliases.cf | ||
<pre> | <pre> | ||
| Line 101: | Line 127: | ||
hosts = 127.0.0.1 | hosts = 127.0.0.1 | ||
dbname = mailserver | dbname = mailserver | ||
query = SELECT alias FROM aliases WHERE email='%s' | 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) | You can check your configuration with postmap (1 returned in case of success) | ||
| Line 111: | Line 138: | ||
dovecot unix - n n - - pipe flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient} | 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 | systemctl enable postfix --now | ||
<br> | <br> | ||
=== | |||
===Dovecot IMAP=== | |||
dnf install dovecot dovecot-mysql | dnf install dovecot dovecot-mysql | ||
| Line 133: | Line 161: | ||
args = uid=150 gid=150 home=/var/vmail/%d/%n allow_all_users=yes | args = uid=150 gid=150 home=/var/vmail/%d/%n allow_all_users=yes | ||
} | } | ||
Verify path in the passdb section of the | 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: | You must create this file: | ||
| Line 141: | Line 174: | ||
default_pass_scheme = PLAIN | default_pass_scheme = PLAIN | ||
connect= host=127.0.0.1 port=3306 dbname=mailserver user=postfix password=yoursecretpassword | 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 conf.d/10-ssl.conf add the certifcate and key replacing with the path of the certificate created above | 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 | 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: | Add to the bottom: | ||
| Line 166: | Line 203: | ||
} | } | ||
} | } | ||
Start end enable service | Start end enable service | ||
| Line 172: | Line 210: | ||
===SMTP auth with cyrus-sasl=== | ===SMTP auth with cyrus-sasl=== | ||
Not the | Not the easiest way: you can use directly dovecot to authenticate SMTP users.</br> | ||
But the advantage of cyrus-sasl is you can | 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 | dnf install cyrus-sasl cyrus-sasl-plain cyrus-sasl-lib cyrus-sasl-sql | ||
| Line 189: | Line 229: | ||
sql_database: mailserver | sql_database: mailserver | ||
sql_passwd: yoursecretpassword | sql_passwd: yoursecretpassword | ||
sql_select: select password from users where username = '%u' | sql_select: select password from users where username = '%u' AND smtp_enabled=1 | ||
log_level: 3 | log_level: 3 | ||
</pre> | </pre> | ||
| Line 202: | Line 242: | ||
smtpd_sasl_type = cyrus | smtpd_sasl_type = cyrus | ||
smtpd_sasl_security_options = noanonymous | smtpd_sasl_security_options = noanonymous | ||
smtpd_tls_auth_only = | 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 { | |||
service | inet_listener sieve { | ||
inet_listener | port = 4190 | ||
port = | |||
} | } | ||
} | } | ||
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
