Ga naar de inhoud
Home » Mail Server op OCI

Mail Server op OCI

Oracle Cloud Blog Header

Basis: https://computingforgeeks.com/setup-mail-server-on-centos-with-postfix-dovecot-mysql-roundcube/

We gaan een mail server in de lucht brengen. In dit voorbeeld voor het domein famtenhoopen.nl. Het domain famtenhoopen.nl is in mijn bezit (beetje essentieel 🙂 )

Maak een VCN mynetwork (10.0.0.0/16) met daarin een public subnetwerk public (10.0.0.0/24) daarin een CentOS 8 instantie met een public IPv4 adres met de hostnaam lpa. Download de gegeneerde key, of hergebruik een bestaand key pair. Mocht je later in deze tanant nog een instance maken, hergebruik dan deze key.

Security List voor lpa

Zog ervoor dat de volgende poorten open staan voor statefull ingress verkeer. Dit kun je doen door de default security list aan te passen of een nieuwe te maken en die toe te voegen naast de default security list.

  • SSH 22
  • HTTPS: 443
  • HTTP: 80 (voor Lets Encrypt)
  • SMTP: 25
  • POP3: 110
  • IMAP: 143
  • SMTP Secure: 465
  • MSA: 587
  • IMAP Secure: 993
  • POP3 Secure: 995
  • Cockpit: 9090

Zog ervoor dat de volgende poorten open staan voor statefull egress verkeer. Dit kun je doen door de default security list aan te passen of een nieuwe te maken en die toe te voegen naast de default security list.

  • SMTP: 25

Je kunt ook al het verkeer naar het internet (0.0.0.0/0) voor All Protocols toestaan 🙂

Routetable voor lpa

Zorg ervoor dat al het verkeer naar 0.0.0.0/0 naar de Internet Gateway verzonden wordt.

Inloggen

Inloggen gaat via ssh, een ssh key heb je gemaakt tijdens de creatie van de instanties. Zorg dat je deze download de eerste keer en hergebruik dit paar voor alle instanties die daar na komen.

Via ssh -i <privatekey> user@ip-adress …. in mijn geval iets in de geest van:

ssh -i ~/Documenten/Oracle/Cloud/arjan-instance/PKI/host-web/user-opc/opc opc@130.61.161.240

Zelf doe ik het via Remmina Remote Desktop Client, maar dat is eigenlijk om het even.

Zorg ervoor dat je op beide instanties bent ingelogd

Cockpit & SELinux

Cockpit maakt het onderhoud van de server makkelijker, activeer haar. Voor meer info zie CentOS en Cockpit

Doe het volgende om SELinux uit te zetten:

# wat is de status van SELinux
sudo sestatus
# als ze enabled is passen we /etc/sysconfig/selinux aan
cd /etc/sysconfig
sudo vi selinux 
# zet SELINUX op disabled en save file en exit
# sudo systemctl reboot

Na de reboot is SELinux disabled.

Installeren van alle benodigde software

In de tekst hieronder is alle data/gegevens/instellingen die gerelateerd zijn aan mijn omgeving en mijn domein rood gemaakt. Dit moet bij jou dus anders zijn.

We gaan het mail verkeer beveiligen met certificaten (keys) van Lets Encrypt. Voordat je dat kunt doen moet je er voor zorgen dat in DNS een A record is gemaakt voor mail.famtenhoopen.nl

Installeer snapd, volg de instructies op die vermeld staan op: https://snapcraft.io/docs/installing-snapd

Nadat je snapd hebt geinstalleerd en het systeem hebt gereboot ga je naar https://certbot.eff.org/

Beantwoord de vraag My HTTP website is running:

Vervolges krijg je instructies in het tabblad Default Onthou je hebt snapd al geinstalleerd 🙂

Dus je begint bij stap 3 (Controle of je de laatste snapd hebt).

In stap 4 ruim je oude troep op (kun je overslaan als je dat niet hebt)

In Stap 5 installeer je Certbot

In Stap 6 “Prepare” je de Certbot

Stap 7 doe je niet, maar je doet:

sudo certbot certonly --standalone -d mail.famtenhoopen.nl

De certificaten worden geplaatst in /etc/letsencrypt/live/mail.famtenhoopen.nl

De certificaten van Lets Encrypt zijn niet zo lang geldig, dus je moet ze regelmatig vernieuwen. Regel dit in de cron van root:

De certificaten verlopen na (geloof) 3 maanden, dus automatisch updaten via de cron van root. Voeg de volgende regel toe aan de cron van root:

sudo crontab -e
# voeg de volgende regel toe
0 0,12 * * * /bin/certbot renew -q

De firewalld(aemon) kan ook uit:

sudo systemctl stop firewalld
sudo systemctl disable firewalld

Nu de benodigde pakketten installeren

sudo yum install whois telnet nmap # deze zijn eigenlijk niet nodig maar heel handig bij debuggen!
sudo yum install postfix dovecot mariadb-server postfix-mysql policycoreutils-python-utils dovecot-mysql
sudo systemctl start mariadb 
sudo systemctl enable mariadb 
sudo mysql_secure_installation

Onthou het root wachtwoord dat je opgegeven hebt voor root bij mariadb!

Postfix Configureren

Maak een database aan voor postfix

sudo mysql -u root -p
create database postfix_accounts;
grant all on postfix_accounts.* to 'postfix_admin'@'localhost' identified by 'StrongPassword';
flush privileges;
#
# Maak een tabel aan met alle postfix accounts
#
CREATE TABLE `postfix_accounts`.`domains_table` ( `DomainId` INT NOT NULL AUTO_INCREMENT , `DomainName` VARCHAR(50) NOT NULL , PRIMARY KEY (`DomainId`)) ;
#
# Maak een tabel met alle user accounts
#
CREATE TABLE `postfix_accounts`.`accounts_table` ( `AccountId` INT NOT NULL AUTO_INCREMENT, `DomainId` INT NOT NULL, `password` VARCHAR(300) NOT NULL, `Email` VARCHAR(100) NOT NULL, PRIMARY KEY (`AccountId`), UNIQUE KEY `Email` (`Email`), FOREIGN KEY (DomainId) REFERENCES domains_table(DomainId) ON DELETE CASCADE );
#
# Maak een tabel voor de aliassen.
# Een alias zorgt ervoor dat mail naar b.v. sales@example.com doorgezonden wordt naar jan.de.verkoper@example.com
#
CREATE TABLE `postfix_accounts`.`alias_table` ( `AliasId` INT NOT NULL AUTO_INCREMENT, `DomainId` INT NOT NULL, `Source` varchar(100) NOT NULL, `Destination` varchar(100) NOT NULL, PRIMARY KEY (`AliasId`), FOREIGN KEY (DomainId) REFERENCES domains_table(DomainId) ON DELETE CASCADE );
#
# Voeg rijen toe aan de tabellen
#
INSERT INTO `postfix_accounts`.`domains_table` (DomainName) VALUES ('famtenhoopen.nl');  
INSERT INTO `postfix_accounts`.`accounts_table` (DomainId, password, Email) VALUES (1, ENCRYPT('StrongPassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'arjan@famtenhoopen.nl');  
INSERT INTO `postfix_accounts`.`accounts_table` (DomainId, password, Email) VALUES (1, ENCRYPT('StrongPassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'deleteme@famtenhoopen.nl');  
INSERT INTO `postfix_accounts`.`alias_table` (DomainId, Source, Destination) VALUES (1, 'contact@famtenhoopen.nl', 'arjan@famtenhoopen.nl');
quit

Configure the master configuration file

sudo vim /etc/postfix/master.cf

Haal het commentaar teken weg bij de volgende regels en zorg ervoor dat de regels die beginnen met -o op de juiste manier inspringen en de juiste waardes bevatten!

submission inet n       -       n       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_tls_security_level=encrypt   ## Comment this if you have no SSL(not recommended)
  -o smtpd_tls_auth_only=yes            ## Comment this if you have no SSL(not recommended)
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
  -o smtpd_reject_unlisted_recipient=no
pickup    unix  n       -       n       60      1       pickup
cleanup   unix  n       -       n       -       0       cleanup
qmgr      unix  n       -       n       300     1       qmgr
tlsmgr    unix  -       -       n       1000?   1       tlsmgr
rewrite   unix  -       -       n       -       -       trivial-rewrite
bounce    unix  -       -       n       -       0       bounce
defer     unix  -       -       n       -       0       bounce
trace     unix  -       -       n       -       0       bounce
verify    unix  -       -       n       -       1       verify
flush     unix  n       -       n       1000?   0       flush
proxymap  unix  -       -       n       -       -       proxymap
proxywrite unix -       -       n       -       1       proxymap
smtp      unix  -       -       n       -       -       smtp
relay     unix  -       -       n       -       -       smtp
        -o syslog_name=postfix/$service_name
showq     unix  n       -       n       -       -       showq
error     unix  -       -       n       -       -       error
retry     unix  -       -       n       -       -       error
discard   unix  -       -       n       -       -       discard
local     unix  -       n       n       -       -       local
#virtual   unix  -       n       n       -       -       virtual
lmtp      unix  -       -       n       -       -       lmtp
anvil     unix  -       -       n       -       1       anvil
scache    unix  -       -       n       -       1       scache
dovecot   unix  -       n       n       -       -       pipe
    flags=DRhu user=vmail:vmail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}

Sla het bestand op.

Aanpassen van de main.cf file

sudo vi /etc/postfix/main.cf

Maak de volgende aanpassingen:

Haal het commentaar teken web bij myhostname en vervang host.domain.tld hostname van de server zoals de buitenwereld haar aanspreekt.

myhostname = mail.famtenhoopen.nl

Voeg je domeinnaam toe:

mydomain = famtenhoopen.nl   ## Input your unique domain here

Haal het commentaar teken weg bij de volgende regels. Als de regel er nog niet is, voeg haar dan toe:

myorigin = $myhostname
inet_interfaces = all
inet_protocols = all
mydestination = $myhostname, localhost.$mydomain, localhost
smtpd_recipient_restrictions = permit_mynetworks
home_mailbox = Maildir/

Voeg de volgende regels toe aan het eind:

append_dot_mydomain = no
biff = no
config_directory = /etc/postfix
dovecot_destination_recipient_limit = 1
message_size_limit = 4194304
smtpd_tls_key_file = /etc/letsencrypt/live/mail.famtenhoopen.nl/privkey.pem     ##SSL Key
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.famtenhoopen.nl/fullchain.pem  ##SSL Cert
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_security_level=may
virtual_transport = dovecot
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

Ben je wat bang voor spammers dan kun je je via de volgende 3 settings wat beschermen

  • smtpd_error_sleep_time – The SMTP server response delay after a client has made more than $smtpd_soft_error_limit errors, and fewer than smtpd_hard_error_limit errors, without delivering mail
  • smtpd_soft_error_limit : The number of errors a remote SMTP client is allowed to make without delivering mail before the Postfix SMTP server slows down all its responses
  • smtpd_hard_error_limit : The maximal number of errors a remote SMTP client is allowed to make without delivering mail. The Postfix SMTP server disconnects when the limit is exceeded.

Voeg in dat geval de volgende regels toe:

smtpd_error_sleep_time = 1s
smtpd_soft_error_limit = 10
smtpd_hard_error_limit = 20

Voeg de volgende regels toe aan het eind:

virtual_mailbox_domains = mysql:/etc/postfix/database-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/database-users.cf
virtual_alias_maps = mysql:/etc/postfix/database-alias.cf

Sla het bestand op.

De laatste drie regels aan bestanden die er nog niet zijn. Deze gaan we nu maken.

Bestand dat zorgt dat Postfix de domeinen uit de database kan lezen

sudo vim /etc/postfix/database-domains.cf

user = postfix_admin
password = StrongPassword
hosts = 127.0.0.1
dbname = postfix_accounts
query = SELECT 1 FROM domains_table WHERE DomainName='%s'

Bestand dat zorgt dat Postfix de user accounts uit de database kan lezen

sudo vim /etc/postfix/database-users.cf

user = postfix_admin
password = StrongPassword
hosts = 127.0.0.1
dbname = postfix_accounts
query = SELECT 1 FROM accounts_table WHERE Email='%s'

Bestand dat zorgt dat Postfix de email aliassen uit de database kan lezen

sudo vim /etc/postfix/database-alias.cf

user = postfix_admin
password = StrongPassword
hosts = 127.0.0.1
dbname = postfix_accounts
query = SELECT Destination FROM alias_table WHERE Source='%s'

Permissies en eigenaar goed zetten:

sudo chmod 640 /etc/postfix/database-domains.cf
sudo chmod 640 /etc/postfix/database-users.cf
sudo chmod 640 /etc/postfix/database-alias.cf
sudo chown root:postfix /etc/postfix/database-domains.cf
sudo chown root:postfix /etc/postfix/database-users.cf
sudo chown root:postfix /etc/postfix/database-alias.cf

We hebben aanpassingen gemaakt aan de Postfix configuratie, dus herstarten en zorgen dat ze bij een reboot automatisch gestart wordt:

sudo systemctl restart postfix
sudo systemctl enable postfix

Nu kijken of het werkt 🙂 Voer onderstaande commando’s uit, de output van het commando moet zijn zoals hieronder aangegeven:

sudo postmap -q famtenhoopen.nl mysql:/etc/postfix/database-domains.cf
1
sudo postmap -q arjan@famtenhoopen.nl mysql:/etc/postfix/database-users.cf
1
sudo postmap -q marike@famtenhoopen.nl mysql:/etc/postfix/database-users.cf
1
sudo postmap -q contact@famtenhoopen.nl mysql:/etc/postfix/database-alias.cf
arjan@famtenhoopen.nl

Dovecot Configureren

De user vmail in de groep vmail is verantwoordelijk voor het afhandelen van de mail. Die moeten we nog maken:

sudo groupadd -g 6000 vmail 
sudo useradd -g vmail -u 6000 vmail -d /home/vmail -m

Open de dovecot configuratie file en zorg ervoor dat ondersaande regels NIET beginnen met een #

sudo vim /etc/dovecot/dovecot.conf

listen = *, ::
protocols = imap pop3 lmtp
!include conf.d/*.conf
!include_try local.conf
log_path = /var/log/dovecot.log  ##Add this for logs

Zorg ervoor dat de log er is engeschreven kan worden

sudo touch /var/log/dovecot.log
sudo chown vmail:vmail /var/log/dovecot.log

Open /etc/dovecot/conf.d/10-auth.conf file en zorg ervoor dat onderstaande regels NIET beginnen met een #-je EN de regel !include auth-system.conf.ext is standaard zonder # aan het begin. Plaats er een # voor zodat alleen !include auth-sql.conf.ext is enabled.

sudo vim /etc/dovecot/conf.d/10-auth.conf

disable_plaintext_auth = yes
auth_mechanisms = plain login
!include auth-sql.conf.ext     ## Only enable authentication through SQL and leave other authentication methods disabled

# zet een hekje voor
!include auth-system.conf.ext

We gaan nu het bestand /etc/dovecot/conf.d/auth-sql.conf.ext aanpassen/maken.

Er zijn een paar speciale variabelen

  • %u – username
  • %n – user part in user@domain, same as %u if there’s no domain
  • %d – domain part in user@domain, empty if there’s no domain
  • %h – home directory

We gaan de emails opslaan in een structuur onder de map /home/vmail/ zorg ervoor dat het eruitziet als hieronder:

sudo vim /etc/dovecot/conf.d/auth-sql.conf.ext

passdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
  driver = static     ## Don't forget to change this
  args = uid=vmail gid=vmail home=/home/vmail/%d/%n/Maildir
}

Maak de map /home/vmail/domain  (/home/vmail/%d/)

sudo mkdir /home/vmail/famtenhoopen.nl

De argumenten (args) zoals hierboven beschreven in bovenstaand bestand moeten we nog uit de database halen:

sudo vi /etc/dovecot/dovecot-sql.conf.ext

driver = mysql
connect = "host=127.0.0.1 dbname=postfix_accounts user=postfix_admin password=StrongPassword"
default_pass_scheme = SHA512-CRYPT
password_query = SELECT Email as User, password FROM accounts_table WHERE Email='%u';

Config van de mailbox locaties. Open het bestand /etc/dovecot/conf.d/10-mail.conf en zorg ervoor dat de instellingen overeenkomen met wat hiernonder staat:

sudo vi /etc/dovecot/conf.d/10-mail.conf

mail_location = maildir:/home/vmail/%d/%n/Maildir
namespace inbox {
  inbox = yes
}
mail_privileged_group = mail
mbox_write_locks = fcntl

Open nu /etc/dovecot/conf.d/10-master.conf en maak onderstaande aanpassingen:

sudo vi /etc/dovecot/conf.d/10-master.conf
service imap-login {
  inet_listener imap {
    port = 143
  }
  inet_listener imaps {
  }
}
service pop3-login {
  inet_listener pop3 {
    port = 110
  }
  inet_listener pop3s {
  }
}
service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
   mode = 0600
   user = postfix
   group = postfix
  }
}
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
  unix_listener auth-userdb {
   mode = 0600
   user = vmail
  }
  user = dovecot
}
service auth-worker {
  user = vmail
}
service dict {
  unix_listener dict {
  }
}

service stats {
  unix_listener stats-reader {
    group = vmail
    mode = 0666
  }
  unix_listener stats-writer {
    group = vmail
    mode = 0666
  }
}

service anvil {
  unix_listener anvil {
    group = vmail
    mode = 0666
  }
}

De vmail gebruiker is verantwoordeijk voor het afhandelen van de mail, ze moet er natuurijk wel toegang toe hebben:

sudo chown -R vmail:vmail /home/vmail

Geef vmail and dovecot users toegang tot de configuratie bestanden:

sudo chown -R vmail:dovecot /etc/dovecot 
sudo chmod -R o-rwx /etc/dovecot

In /etc/dovecot/conf.d/10-ssl.conf, zit de SSL configuratie. Wil je geen SSL zet haar dan op no (wel eenheel slecht idee !!!)

sudo vim /etc/dovecot/conf.d/10-ssl.conf
ssl = no

Behoor je tot het verstandig deel van deze wereld, dan zet je haar op  required en geef je de keys op die je al gemaakt had met Lets Encrypt:

sudo vim /etc/dovecot/conf.d/10-ssl.conf

ssl = required
ssl_cert = </etc/letsencrypt/live/mail.famtenhoopen.nl/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.famtenhoopen.nl/privkey.pem

Nu Dovecot starten en zorgen dat ze bij reboot ook weer gestart wordt:

sudo systemctl start dovecot
sudo systemctl enable dovecot

Ga kijken of alles wekt door je mail client te verbinden, mail verzenden en mail ontvangen.

Toevoegen van Domeinen, Users en Aliassen

Ben niet zo’n grote database held, dus hier wat sql geknutsel dat van pas kan komen 🙂 We gaan uit van de toestand die er nu is. Alles voer je uit vanuit mysql

Nieuwe user van bestaand domein toevoegen:

INSERT INTO `postfix_accounts`.`accounts_table` (DomainId, password, Email) VALUES (1, ENCRYPT('StrongPassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'vincent@famtenhoopen.nl');

Bestaande user van een bestaand domein weggooien:

DELETE FROM `postfix_accounts`.`accounts_table` WHERE Email = 'arjan@famtenhoopen.nl' ;

Nieuw domein toevoegen (vb: hatseflats.nl).

LET OP:

Hiervoor heb je postfix >= 3.4 nodig. Deze versie heeft support voor SNI, oudere versies hebben dat niet!! Dus onmogelijk om het aan de praat te krijgen. Succes, ik had postfix 3.3.1 🙁

Om alles ook goed beveiligen moet je voor alle domeinen ook certificaten hebben. Deze kun je genereren met sudo certbot certonly –standalone -d mail.hatseflats.nl net zo als in het begin uitgevoerd voor mail.famtenhoopen.nl

Het zou als volgt moeten gaan 🙂 🙂 🙂

  • Zorg dat je het domein in je bezit hebt
  • Zorg dat dit domein een MX record heeft (b.v. mail)
  • Zorg dat het MX record (mail.hatseflats.nl) verwijst naar het IP van deze mail server (mail.famtenhoopen.nl)
  • Zorg ervoor dat mail.hatseflats.nl geresolved kan worden (beetje langer wachten is vaak een goede remedie)
  • Nu het nieuwe domein toevoegen via:
INSERT INTO `postfix_accounts`.`domains_table` (DomainName) VALUES ('hatseflats.nl');

Nu moet je de postfix configuratie aanpassen, zie https://serverfault.com/questions/928926/postfix-multi-domains-and-multi-certs-on-one-ip Succes!!!

Nieuwe gebruiker van een nieuw domein toevoegen (vb fotograaf@hatseflats.nl)

Achterhaal wat het DomainId is van het domein in de domains tabel via:

SELECT * FROM `postfix_accounts`.`domains_table`;

Stel dat het ‘2‘ blijkt te zijn, onthou dit. Voeg gebruiker toe via:

INSERT INTO `postfix_accounts`.`accounts_table` (DomainId, password, Email) VALUES (2, ENCRYPT('StrongPassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), 'fotograaf@hatseflats.nl');

Nieuwe alias voor een nieuw domein toevoegen

Achterhaal wat het DomainId is van het domein in de domains tabel via:

SELECT * FROM `postfix_accounts`.`domains_table`;

Stel dat het ‘2‘ blijkt te zijn, onthou dit. Voeg de alias toe via:

INSERT INTO `postfix_accounts`.`alias_table` (DomainId, Source, Destination) VALUES (2, 'contact@hatseflats.nl', 'fotograaf@hatseflats.nl');

Klaar.