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.