Basic mailserver configuration on RHEL10: Difference between revisions

From Fvettore-WIKI
 
(26 intermediate revisions by the same user not shown)
Line 1: Line 1:
Dirty and quick (10 minutes) very basic configuration of mailserver with postfix, dovecot and mysql/mariadb.<br>
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 certificates===
  dnf install epel-release
  dnf install epel-release
  dnf install certbot
  dnf install certbot
Create cert with your FQN server name (server08.vettore.org in the example)
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


Line 19: Line 26:
  create database mailserver;
  create database mailserver;
  use mailserver;
  use mailserver;
====USERS====


USERS
CREATE TABLE `users` (
 
CREATE TABLE `users` (
   `email` varchar(200) NOT NULL,
   `email` varchar(200) NOT NULL,
   `enabled` int(11) DEFAULT 1,
   `enabled` int(11) DEFAULT 1,
Line 30: Line 36:
   `smtp_username` varchar(45) DEFAULT NULL,
   `smtp_username` varchar(45) DEFAULT NULL,
   PRIMARY KEY (`email`)
   PRIMARY KEY (`email`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
) 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 40: Line 52:
   ENGINE=MyISAM DEFAULT CHARSET=utf8  
   ENGINE=MyISAM DEFAULT CHARSET=utf8  
   
   
ALIAS:
====ALIASES====


  CREATE TABLE `aliases` ( `email` varchar(128) NOT NULL,
  CREATE TABLE `aliases` ( `email` varchar(128) NOT NULL,
Line 48: 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', username='paperino';
  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 66: 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/cert.pem
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/fullchain.pem
  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 129: 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
  }
  }
Rename the above file removing .ext extension


Verify path in the passdb section of the above file. Should be /etc/dovecot/dovecot-sql.conf.ext<br>
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 139: Line 176:
  password_query = SELECT password, email as user  FROM users where email='%u' AND imap_enabled=1
  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 (but not the CA)
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)
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


Line 162: Line 203:
   }
   }
  }
  }


Start end enable service
Start end enable service
Line 169: Line 211:
===SMTP auth with cyrus-sasl===
===SMTP auth with cyrus-sasl===
Not the easiest way: you can use directly dovecot to authenticate SMTP users.</br>
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 SMTPP for IMAP 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.</br>
The table structure created above have fields for this purpose.</br>


Line 206: Line 248:
  systemctl restart dovecot
  systemctl restart dovecot
  systemctl enable saslauthd --now
  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