Een eigen mailserver opzetten met OpenBSD
Introductie
E-mail heeft geen introductie nodig, aangezien bijna iedereen tegenwoordig het wel gebruikt. Veel mensen zijn dan ook gestart met een gratis account van hun internetprovider of hebben een account bij Gmail of Hotmail. Je zou ook zelf een mailserver kunnen opzetten, om digitaal onafhankelijker te worden. Dit artikel is dan ook gericht op dit doel, zelf een mailserver opzetten voor de ultieme controle over jouw e-mail.
E-mail is een mooi voorbeeld van een decentrale dienst. Je hebt veel invloed over de inrichting van een systeem en vergroot dus je onafhankelijkheid. De data in jouw e-mails gaat ook langs minder partijen en dat is weer goed voor je privacy. Ook biedt het meer mogelijkheden.
Kortom, zelf e-mail in beheer hebben heeft een aantal voordelen. Er zijn ook goede redenen om het zelf niet te doen, zoals gemak en de bekende blokkades door de grote techgiganten. Daarom zijn er wel wat aandachtspunten voordat je enthousiast aan de slag gaat.
Vereiste kennis en benodigdheden
Een eigen mailserver opzetten is relatief eenvoudig, maar komt toch wel met de nodige aandachtspunten. Daarom is het verstandig om het geheel meteen vanaf dag 1 goed in te richten. Half werk zal afgestraft worden, zoals e-mails die niet aankomen bij de ontvanger, in de spammap belanden of zelfs dat je op een zogeheten blacklist komt. Kortom, goed nadenken én vooruitdenken is gaat je achteraf helpen.
Om te beginnen met de vereiste voorkennis: ervaring met Linux en de terminal is minimaal nodig. Ervaring met FreeBSD, NetBSD, of nog liever OpenBSD, maakt het helemaal compleet. Daarnaast algemene kennis van DNS en de algemene concepten van een mailserver en mailboxen is ook handig.
Mis je bovenstaande kennis? Geen probleem, dit artikel is zo geschreven dat je toch een werkende configuratie zou moeten kunnen maken. Er zal dan wel wat meer tijd gaan zitten in de installatie. Ook is het dan aan te raden om aanvullende tijd te stoppen in het algemene systeembeheer. Die stappen zijn namelijk niet hier in detail beschreven. Denk aan zaken zoals het bijwerken van software, het toekennen van rechten aan lokale gebruikers en het maken van back-ups
De benodigdheden:
- Minimaal één domeinnaam
- Een (virtuele) machine
- Toegang tot de DNS-gegevens van je domeinnaam of domeinnamen
- Tijd
Domeinnaam
Als je nog geen domeinnaam hebt, dan is dit de eerste stap: een domeinnaam registreren. Dat doe je bij een registrar, vaak een hostingprovider. Ook zijn er bedrijven die zich specifiek richten op domeinregistraties.
De naam van je domein maakt niet veel uit, maar kortere namen komen vaak vriendelijker over dan bijvoorbeeld ikgazelfmijnemailhosten.nl.
Heb je een domeinnaam op het oog? Test of hij beschikbaar is en registreer hem dan meteen. Als je wacht, kan het zijn dat de gezochte naam uitlekt en iemand hem voor je neus wegkaapt.
Zelf ben ik tevreden over ShockMedia voor de domeinregistraties. De eigenaar ken ik van lang geleden, maar belangrijker is de goede en vriendelijke ondersteuning die ik heb ervaren over de jaren heen.
Hosting voor virtuele machine
Een mailserver kun je thuis hosten, maar is wellicht niet zo verstandig. Ook al heb je een vast IP-adres op je internetverbinding, vaak zijn deze IP-adressen gemarkeerd als “consumer internet”. Vaak zal je internetprovider het uitsturen van e-mail standaard ook blokkeren, voornamelijk om spam tegen te gaan. Ook als je een uitzondering vraagt bij je provider, kan het nog steeds zijn dat grote partijen gehele netwerkblokken van internetverbindingen blokkeren of als verdacht markeren. Kortom, je mailserver draaien op een consumenteninternetverbinding is niet aan te raden.
Voor de hosting van mijn eigen mailserver heb ik daarom gekozen voor OpenBSD Amsterdam. Ik wil namelijk graag mijn mailserver zo veilig en stabiel mogelijk maken en dan is OpenBSD bij uitstek het besturingssysteem voor die taak. Andere voordelen zijn de gunstige prijs, dat het gehost wordt in Nederland, vele positieve ervaringen van mensen uit de wereld van BSD en dat ik toevallig de beheerder van de dienst ook nog een bekende van me is.
Disclaimer: er is geen sprake van sponsoring, de beheerder wist voorheen niet dat ik er ging hosten en heeft geen invloed op dit artikel. Als de dienstverlening me niet bevalt, dan laat ik het ook weten.
Na het bestellen van een virtuele machine (VM) bij OpenBSD Amsterdam, kreeg ik al snel een welkomstbericht met daarin alle benodigde gegevens zoals IP-adressen, hostnamen en wat tips. Helder en duidelijk, daar kunnen meer partijen een voorbeeld aan nemen.
OpenBSD Amsterdam geeft je standaard toegang tot je virtuele machine via SSH. Aanvullend ook toegang tot de console. Dat is een fijne gedachte, zeker bij het inrichten van bijvoorbeeld je firewall. Je zult de eerste niet zijn die na het activeren van de firewall geen toegang meer heeft.
DNS-beheer
Voor het inrichten van diensten binnen je domeinnaam, dien je toegang te hebben tot de DNS-records. Er zijn verschillende types, zoals:
- A: koppel een hostnaamnaam aan een IP-adres
- AAAA: koppen een naam aan een IP-adres voor IPv6
- MX: benoem welke servers mail voor jouw domein accepteren
- TXT: bevat informatie en wordt gebruikt voor diverse toepassingen
- PTR: het omzetten van een IP-adres naar een hostnaam
- CAA: welke entititeiten mogen een certificaat aanmaken voor het domein
Op het moment dat we DNS-records configureren, benoemen we meestal de naam, type en de bijbehorende waarde. Indien er geen naam van toepassing is, omdat we bijvoorbeeld willen verwijzen naar het domein zelf, dan gebruiken we hiervoor het apenstaartje (@).
Inventarisatie en controles vooraf
De eerste stap is controleren van diverse zaken:
- Heeft de hoster een bekend reputatie van spam?
- Hebben we een IP-adres dat alleen voor jou is, oftewel niet gedeeld wordt met anderen?
- Staat het IP-adres nu al op een blacklist?
- Kunnen we de reverse DNS ook aanpassen?
De doelgroep bij OpenBSD Amsterdam zijn techneuten. Zij hebben, net als ik, er baat bij dat zaken netjes zijn ingericht en we geen overlast veroorzaken. Kortom, ik maak me niet zo zorgen om mijn digitale buurmannen en -vrouwen. Het netwerkblok waarin mijn IP-adres valt, daar heb ik natuurlijk minder kijk op. Het kan natuurlijk zijn dat de hoster dit netwerkblok heeft gekocht van een partij die er graag vanaf wilde, juist vanwege de reputatie. Hoe dan ook, als wij netjes zijn en blijven, dan loopt het gehele blok minder risico.
Via verschillende websites kun je testen of jouw IP-adres op een blacklist staat. Zo is MXToolBox er eentje van. Controleer zowel het IPv4-adres als IPv6. Ook de website van Talos Intelligence kan helpen bij het beoordelen van je IP-adres.
Basisconfiguratie systeem
OpenSSH aanpassen
Aangezien SSH-toegang verloopt via een sleutelpaar (public key authentication) is de eerste stap na het inloggen om meteen authenticatie via wachtwoorden uit te schakelen.
rcctl set sshd flags -o PasswordAuthentication=no
Aan /etc/ssh/sshd_config voeg ik een regel toe Port met een zelfgekozen poort. Het aanpassen van de poort maakt het systeem niet veiliger, maar scheelt een hoop vervuiling van de logbestanden.
Overigens is de aanpassing van de poort ook te doen met een flag zoals bovenstaand is gedaan voor PasswordAuthentication. In mijn geval maakt het weinig verschil, aangezien de firewall toegang tot poort 22 blokkeert, tenzij het van een set van bekende en vertrouwde IP-adressen af komt.
Na het aanpassen, herstarten we de SSH daemon:
rcctl restart sshd
In een nieuw scherm even testen of de verbinding op de nieuw ingestelde poort werkt en we kunnen aan de slag!
Zeker weten dat authenticatie met behulp van wachtwoorden uit staat?
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password -p POORT GEBRUIKER@HOSTNAAM
Firewall instellen: pf
Nu er nog niks draait op het systeem, is dit ook een mooi moment om meteen vanaf het eerste moment de firewall volledig dicht te zetten. Uiteraard met wat uitzonderingen, zodat het systeem wel functioneel blijft, inclusief toegang via SSH. Pas na het uitrollen van de andere diensten, zoals SMTP en IMAP, prikken we dan wat extra gaatjes in de firewall.
Waarom meteen een firewall-configuratie maken? Bij sommige hostingproviders kun je gebruik maken van hun firewall. Deze draait op het netwerk zelf, dus VOOR de virtuele machine. Echter in dit geval zit er niks tussen, dus is een strenge set met firewall-regels een mooie manier om het verkeer te beperken. Geen overbodige luxe, want er komt een hele boel “digitale troep” langs. Die kunnen we meteen vanaf het begin blokkeren.
OpenBSD maakt gebruik van pf, een zeer krachtige oplossing. Vaak met een beperkt aantal firewall-regels biedt het al een zeer functioneel filter voor (ongewenst) netwerkverkeer.
Meer weten over pf? Daar komt later een ander diepgaand artikel van.
Handig om te controleren:
- tijdsynchronisatie:
ntpctl -s all - ophalen van softwarepakketten en updates:
syspatch -c - het omzetten van namen en IP-adressen:
host -t txt openbsd.org
DNS-caching met unbound en unwind
Op OpenBSD is er de mogelijkheid om met unwind te werken. Dit zeer lichte proces helpt met het cachen (onthouden) van alle DNS-verzoeken. DNS is het adresboek om IP-adressen en namen die bij elkaar horen, om te zetten. Het opzoeken kost steeds wat tijd en door de antwoorden te onthouden, hoeven we minder netwerkverkeer uit te sturen en gaat de snelheid van verwerking van e-mail en spamdetectie omhoog.
Open /etc/unwind.conf en configureer de DNS-servers die de resolving moeten gaan doen. Een voorbeeldje:
forwarder { 2620:fe::fe DoT 2620:fe::9 DoT }
preference { DoT }
Controleer je configuratie met unwind -n om te zien of alles goed is. Daarna kunnen we unwind activeren en starten.
rcctl enable unwind
Om te starten:
rcctl start unwind
Bekijk nu /etc/resolv.conf om te zien of deze naar unwind verwijst. Voorbeeld:
nameserver 127.0.0.1 # resolvd: unwind
lookup file bind
Voor de techneut die een stapje verder wil gaan: voor een mailserver zou je ook met unbound kunnen werken. Deze kunnen we dan lokaal op poort 5353 draaien, zodat deze niet in de weg van unwind zit.
In /etc/unwind.conf configureer je dan de instance die op poort 5353 draait op localhost (IPv6 in dit geval):
forwarder {
::1 port 5353
}
Uiteraard dient unbound hiervoor goed geconfigureerd te worden. Dat komt wellicht nog aan bod in een losstaand artikel. Bij het gebruik van alleen unbound, dien je meestal zelf /etc/resolv.conf handmatig in te stellen. Dat betekent ook dat resolvd uitgeschakeld dient te worden. Het voordeel van unwind wel erbij laten draaien is de eenvoudige configuratie en dat bij problemen met unbound, deze het verkeer alsnog naar een andere (backup) DNS-server kan doorsturen. Kortom, een keuze tussen minder onderdelen of een eenvoudigere configuratie.
E-mail, veiligheid en anti-spam
Er zijn verschillende technieken die helpen om e-mail betrouwbaarder en veiliger te maken. Denk dan aan privacy zoals versleutelde verbindingen, maar ook aan bewijzen wie jij bent (of de server).
SPF
De eerste is SPF, Sender Policy Framework, dat bepaalt wie er namens jou e-mail mogen zenden. Hiermee bouw je een ‘allow list’ op, waarbij je aangeeft welke systemen betrouwbaar genoeg zijn om e-mail met jouw domein als afzender te mogen versturen. Deze gegevens staan opgeslagen in DNS.
DKIM
Dan is er DKIM (DomainKeys Identified Mail) dat in het verlengde van SPF laat zien dat berichten daadwerkelijk verstuurd zijn met de juiste systemen, door ze digitaal te ondertekenen. De software zal met behulp van een geheime sleutel, onderdeel van een sleutelpaar, de ondertekening doen. De ontvanger kan het bericht vervolgens controleren door een gekoppelde publieke sleutel te selecteren vanuit DNS. Als het sleutelpaar bij elkaar hoort, is er meer zekerheid dat dit door een legitiem persoon of systeem is verstuurd.
DMARC
SPF en DKIM zijn een goede start. Ontvangende partijen kunnen aan de hand van informatie uit deze twee bronnen al lichte conclusie trekken. Echter er zijn genoeg bedrijven met fouten in hun records of ze zijn “soft” ingesteld. Vaak komt dit door twijfel of alles wel goed is geconfigureerd en dat er geen systemen zijn vergeten. Wie wel met vertrouwen zijn of haar configuratie op heeft gezet, kan tevens DMARC activeren.
DMARC geeft aan wat er moet gebeuren als er iets niet klopt. Bijvoorbeeld als een willekeurig systeem volgens SPF niet een bekende verzender is, kunnen we een signaal afgeven aan de ontvangende partij dat zij deze e-mail niet zouden moeten aannemen.
Een andere optie bij DMARC is zogeheten alignment. Een e-mail kan namelijk een afwijkend adres hebben als verzender en datgene wat in de “From:” staat. Dat kan bijvoorbeeld gebeuren bij het gebruik van mailgroepen of bij het automatisch doorsturen van e-mail.
Bij het gebruik van DMARC zijn er best veel opties mogelijk en dat maakt het lastiger om meteen de juiste configuratie te delen. Dat heeft bijvoorbeeld ook te maken of subdomeinen wel of niet e-mail ontvangen of mogen versturen. Dan is er de keuze wat te doen met e-mails die niet volgens de ingestelde waarden worden verstuurd.
Een paar tips vooraf:
- Lees wat meer over DMARC na het inrichten van het systeem
- Laat je informeren over de status met instelling rua
- Begin met p=none voor een bestaand domein waarbij het niet helemaal duidelijk is of alles goed is ingesteld
MTA-STS
Naast eerdergenoemde technieken, is er ook nog MTA-STS, afkorting voor Mail Transfer Agent Strict Transport Security. Het lijkt op HTST om te forceren dat HTTPS gebruikt dient te worden in plaats van het onversleutelde HTTP, maar dan voor e-mail.
Om MTA-STS in te richten, dienen we een webserver te draaien op de server.
URL: https://mta-sts.example.org/.well-known/mta-sts.txt (vervang example.org voor je eigen domeinnaam)
Aanmaken van de directory doen we met mkdir met -p om onderliggende directories ook meteen aan te maken.
mkdir -p /var/www/htdocs/mta-sts.example.org/.well-known
Vervolgens het eigenaarschap aanpassen voor de directory, inclusief al het onderliggende.
chown -R www:www /var/www/htdocs/mta-sts.example.org
Maak nu het bestand mta-sts.txt aan.
vi /var/www/htdocs/mta-sts.example.org/.well-known/mta-sts.txt met de volgende inhoud:
version: STSv1
mode: enforce
mx: mail.example.org
mx: mail2.example.org
max_age: 604800
Wat betekenen al deze velden en waarden?
- version: versie van STS, voor nu is er alleen STSv1
- mode: enforce, om te forceren dat we altijd versleutelde verbindingen willen
- mx: per mailserver een losse regel (dit voorbeeld heeft er twee)
- max_age: tijd van voordat er gecontroleerd moet worden of er een bijgewerkte versie is (604800 is een week)
Voor nu maken we dit bestand alleen aan. Later dienen we een bijbehorende virtuele host te maken binnen onze webserver-configuratie. Hiervoor is het eerst nodig om onze domeinnaam goed te configureren. Dat wil zeggen dat we de DNS-instellingen dienen aan te passen, zodat alles naar ons systeem verwijst. Vanaf dat punt kunnen we de benodigde SSL-certificaten aanvragen.
DNS instellen
Met de huidige kennis op zak, kunnen we onze DNS goed gaan zetten. Zo kunnen we in keer alles regelen voor de latere stappen, zoals certificaten en SPF/DKIM/DMARC/MTA-STS.
A/AAAA-records
- Naam: mail
- Type: A
- Verwijst naar: IP-adres van server
- Achterliggende diensten/protocollen: HTTP/HTTPS/SMTP
Doe dit hetzelfde voor het IPv6-adres, maar kies dan AAAA.
- Naam: mta-sts
- Type: A
- Verwijst naar: IP-adres van de server
- Achterliggende diensten/protocollen: HTTPS
MX-records
Voor nu beginnen we met een eerste MX-record aan te maken. Later is het handig om een tweede te hebben, die als backup kan dienen.
- Naam: @
- Type: MX
- Waarde: 10
- Verwijst naar: mail.example.org
Een eventuele backup mailserver krijgt een hoger nummer. Namelijk het MX-record met de laagste waarde zal als eerste worden gebruikt. Een andere optie is om meerdere records dezelfde waarde te geven, als het niet uitmaakt via welke machine de mail binnen komt. Dat is vooral interessant voor bedrijven waar heel veel e-mail binnen komt en deze verdeeld wordt over de inkomende servers, om vervolgens in de juiste mailbox te belanden.
CAA-record
Met behulp van Let’s Encrypt gaan we een aantal certificaten aanmaken. We kunnen instellen dat alleen deze CA-authority certificaten voor ons mag uitgeven.
- Naam: @
- Type: CAA
- Verwijst naar: 0 issue “letsencrypt.org”
De verwijzing heeft meerdere kenmerken:
- Flag: De 0 verwijst een ’non-critical’, meestal de juiste optie
- Tag: issue verwijst naar normale certificaten (in plaats van bijvoorbeeld een wildcard)
- CA: welke CA het certificaat mag uitgeven
SPF-configuratie
Nu komt SPF aan de beurt, waarin we een keuze moeten maken wat het beste past bij ons.
- “v=spf1 -all”: Geen enkel systeem mag e-mail versturen
- “v=spf1 a:mail.example.org -all”: Alleen ‘mail’ mag onze e-mail versturen
- “v=spf1 a:mailrelay.example.org mx -all”: Ook de IP-adressen achter de MX-records mogen e-mail versturen
- “v=spf1 ip4:46.1.2.4 ip6:2a03:6000:abcd:efab::4 -all”: alleen het genoemde IPv4-adres en IPv6-adres mogen versturen
Zelf gaat mijn voorkeur naar de laatste. Zeer expliciet noemen van de systemen die namens onze domeinnaam e-mail mogen uitsturen, zonder dat er extra DNS-verzoeken voor nodig zijn.
DMARC
DMARC bepaalt het gekozen beleid en wat er specifiek moet gebeuren als er iets bij SPF of DKIM niet in orde is.
- Naam: _dmarc
- Type: TXT
- Verwijst naar: v=DMARC1;p=none;rua=mailto:jouwemailadres@example.org
Is het een nieuw domein of wil je meteen voor een zeer strenge DMARC-configuratie gaan, gebruik dan p=reject en zet ook meteen alignment op ‘strict’. Voorbeeld:
v=DMARC1;p=reject;sp=reject;adkim=s;aspf=s;rua=mailto:dmarc@example.org
Hoofddomein
Als je met meerdere domeinen gaat werken, wil je wellicht onderscheid maken tussen het hoofddomein en onderliggende domeinen. Het hoofddomein is ook dat we gebruiken in de mailconfiguratie of als je het IP-adres van de server omzet naar een naam (PTR-record of reverse DNS, komt onderstaand aan bod).
- Naam: @
- Type: TXT
- Verwijst naar: v=spf1 ip4:1.2.3.4 -all
Wil je dat andere domeinen ook via het systeem kunnen mailen? Dan zou je een record kunnen aanmaken met de naam _spf en een soortgelijke waarde:
- _spf ➞ v=spf1 ip4:1.2.3.4 -all
Binnen de andere domeinen gebruiken we include vervolgens om te verwijzen naar het hoofddomein:
- @ ➞ v=spf1 include:_spf.example.org -all
PTR-records (Reverse DNS)
De volgende stap is het aanpassen van PTR-records. Deze kun je instellen bij je hoster en noemen we reverse DNS. Waar normaal een hostnaam wordt omgezet naar een IP-adres, doen we hem nu de andere kant op.
Waarom moeten we de reverse DNS instellen? Het is een extra stukje bewijs dat we toegang en controle hebben over de DNS én IP-adres. In mijn geval dus bij OpenBSD Amsterdam, die hiervoor specifieke instructies heeft opgesteld. Jouw hoster zal dit vaak in het control panel verwerkt hebben zitten.
Controleren:
- host -t ptr jouw-IPv4-adres
- host -t ptr jouw-IPv6-adres
Webserver inrichten
Open /etc/httpd.conf en voeg onderstaande volgende toe. Al hoewel we geen websites gaan vertonen op deze server, willen we aan Let’s Encrypt wel kunnen aantonen dat wij de server daadwerkelijk in beheer hebben.
server "*" {
listen on * port 80
# ACME http-01 challenge
location "/.well-known/acme-challenge/*" {
# /var/www/acme
root "/acme"
request strip 2
directory no auto index
}
}
server "example.org" {
listen on * tls port 443
tls {
certificate "/etc/ssl/example.org.fullchain.pem"
key "/etc/ssl/private/example.org.key"
}
gzip-static
hsts
root "/htdocs/example.org"
}
server "mta-sts.example.org" {
listen on * tls port 443
tls {
certificate "/etc/ssl/mta-sts.example.org.fullchain.pem"
key "/etc/ssl/private/mta-sts.example.org.key"
}
hsts
root "/htdocs/mta-sts.example.org"
}
Deze configuratie geeft toegang tot de zogeheten challenges die het programma acme-client klaar zet bij de aanvraag van onze certificaten. Deze dienen dus beschikbaar te zijn vanaf poort 80 op een URL die Let’s Encrypt verwacht.
Later gaan we de configuratie verder uitbreiden, maar dat kan pas als we daadwerkelijk de certificaten hebben aangevraagd.
Start httpd en maak hem ook beschikbaar tijdens het opstarten.
rcctl start httpd && rcctl enable httpd
- Maak een algemene opvangpagina aan binnen /var/www/htdocs/index.html, met zelfgekozen inhoud.
- Binnen httpd.conf het aanmaken van de virtuele host mta-sts.example.org (HTTPS) voor het gebruik van MTA-STS
Certificaten voor HTTPS
OpenBSD gebruikt acme-client om bij Let’s Encrypt een SSL-certificaat te registeren. Hiermee kunnen we een versleutelde HTTP-verbinding (HTTPS) opzetten tussen de server en computers die met onze server communiceren.
Open /etc/acme-client.conf voor de aanvraag van certificaten:
authority letsencrypt {
api url "https://acme-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-privkey.pem"
}
domain "example.org" {
alternative names { "www.example.org" }
domain key "/etc/ssl/private/example.org.key"
domain full chain certificate "/etc/ssl/example.org.fullchain.pem"
sign with letsencrypt
}
domain "mail.example.org" {
domain key "/etc/ssl/private/mail.example.org.key"
domain full chain certificate "/etc/ssl/mail.example.org.fullchain.pem"
sign with letsencrypt
}
domain "mta-sts.example.org" {
domain key "/etc/ssl/private/mta-sts.example.org.key"
domain full chain certificate "/etc/ssl/mta-sts.example.org.fullchain.pem"
sign with letsencrypt
}
Om vervolgens het certificaat aan te vragen, voer per hostnaam een verzoek uit.
acme-client -v mail.example.org
Met crontab -e kunnen we een terugkerende taak aanmaken, bijvoorbeeld wekelijks. Daarmee kunnen automatisch het certificaat vernieuwen.
30 4 * * 1 /usr/local/scripts/renew-certificates
De inhoud van /usr/local/scripts/renew-certificates is als volgt:
#!/bin/sh
set -o nounset
NEEDS_HTTPD_RELOADED=0
for D in $(awk '/^domain/ {print $2}' /etc/acme-client.conf | tr -d '"'); do
#echo "Domain: ${D}"
/usr/sbin/acme-client "${D}"
if [ $? -eq 0 ]; then NEEDS_HTTPD_RELOADED=1; fi
done
# Only reload http daemon when a certificate was renewed or updated
if [ ${NEEDS_HTTPD_RELOADED} -eq 1 ]; then
/usr/sbin/rcctl reload httpd
fi
exit 0
# EOF
OpenSMTPD
Ondersteuning voor SQLite kunnen we installeren met pkg_add opensmtpd-table-sqlite
Aanmaken locatie voor opslag e-mail
Ik kies in mijn geval om de email op te slaan in de werkdirectory van vmail aangezien de betreffende partitie voldoende opslagruimte heeft. Die dient wel eerst aangemaakt te worden:
mkdir -p /home/vmail/mailboxes
Dan het aanmaken van het account zelf:
useradd -c "Mail for virtual users" -d /home/vmail -s /sbin/nologin -u 2000 -g =uid -L staff vmail
Eigenaarschap instellen:
chown -R vmail:vmail /home/vmail
Database-structuur aanmaken
Tijd om de database-structuur aan te maken. We openen de database met behulp van sqlite3 gevolgd door de database-naam.
sqlite3 /etc/mail/smtpd.sqlite
Maak de tabellen domains aan voor de domeinen. Tabel credentials bevat de accounts en tabel virtuals de virtuele e-mailadressen en aliassen.
CREATE TABLE domains (
id INTEGER PRIMARY KEY AUTOINCREMENT,
domain VARCHAR(255) NOT NULL
);
CREATE TABLE credentials (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
is_active INTEGER DEFAULT 1
);
CREATE TABLE virtuals (
id INTEGER PRIMARY KEY AUTOINCREMENT,
email VARCHAR(255) NOT NULL,
destination VARCHAR(255) NOT NULL,
comment VARCHAR(255),
hyperlink VARCHAR(255),
is_active INTEGER DEFAULT 1,
expires_after DATE DEFAULT '2099-12-31'
);
Terwijl we de database toch open hebben, kunnen we alvast wat data invoeren. Om te beginnen met de domeinnamen.
INSERT INTO domains (domain) VALUES ('example.org');
Vervolgens het aanmaken van het account
INSERT INTO credentials (email, password, is_active) VALUES ("account123@example.org", "$2b$09$dEflangestringmetwillekeurigekarakters", 1);
We koppelen nu het e-mailadres met extra aliassen, die ook binnen het aan zullen komen.
INSERT INTO virtuals (email, destination, comment, is_active) VALUES("account123@example.org", "vmail", "Primaire e-mailadres voor account 123", 1);
INSERT INTO virtuals (email, destination, comment, is_active) VALUES("mailalias1@example.org", "account123@example.org", "Eerste alias voor account 123", 1);
INSERT INTO virtuals (email, destination, comment, is_active) VALUES("mailalias2@example.org", "account123@example.org", "Tweede alias voor account 123", 1);
Open cat /etc/mail/sqlite.conf om daarin de database-locatie en de benodigde database-queries te plaatsen.
# Database
dbpath /etc/mail/smtpd.sqlite
# Queries
query_alias SELECT destination FROM virtuals WHERE email=? AND is_active=1 AND current_date < expires_after;
query_credentials SELECT email, password FROM credentials WHERE email=? AND is_active=1;
query_domain SELECT domain FROM domains WHERE domain=?;
Optioneel: SenderScore
SenderScore is extra mogelijkheid die we hebben om verbindingen te blokkeren of te vertragen. Dit gebeurt aan de hand van een score die IP-adressen hebben gekregen. Het installeren van deze module is eenvoudig.
pkg_add opensmtpd-filter-senderscore
Binnen de OpenSMTPD-configuratie dienen we daarna SenderScore te activeren.
OpenSMTPD configureren
Open /etc/mail/smtpd.conf en stel de configuratie in. Voorbeeldconfiguratie:
# OpenSMTPD configuration v2026-01
# By Michael Boelen - https://bsd-audit.com
### Tables
# Primary tables for mailboxes
table aliases_local file:/etc/mail/aliases
table credentials sqlite:/etc/mail/sqlite.conf
table domains sqlite:/etc/mail/sqlite.conf
table virtuals sqlite:/etc/mail/sqlite.conf
# Other tables
table bad_rdns_regexes file:/etc/mail/block-rdns-regexes.list
table bad_sender_from_regexes file:/etc/mail/block-sender-regexes.list
table bad_sender_domains file:/etc/mail/block-sender-domains.list
### Filters
# Filter to combat spam
filter rspamd proc-exec "filter-rspamd"
filter senderscore proc-exec "filter-senderscore -junkBelow 70 -slowFactor 5000 -scoreHeader"
filter check_fcrdns phase connect match !fcrdns junk
filter check_rdns phase connect match !rdns junk
filter check_rdns_for_dynamic_ranges phase connect match rdns regex <bad_rdns_regexes> junk
filter blocklist_sender_from phase mail-from match mail-from regex <bad_sender_from_regexes> reject "550 bad sender?"
### Special options
smtp sub-addr-delim '_' # use underscore (_) instead of plus sign (+) as a delimiter, as a + is not always accepted and an underscore is typically not seen as a way to create multiple aliases referring to the same e-mail address
### Certificates
pki mail.example.org cert "/etc/ssl/mail.example.org.fullchain.pem"
pki mail.example.org key "/etc/ssl/private/mail.example.org.key"
### Mail routing
# Listen on localhost
listen on lo0
# Listen on our external interface to receive mail from other systems
listen on egress port 25 tls pki mail.example.org protocols "secure" ciphers "secure" filter { blocklist_sender_from, check_fcrdns, check_rdns, check_rdns_for_dynamic_ranges, rspamd, senderscore }
# Listen on our external interface to receive mail from trusted users for relaying purposes
# (auth requires authentication and mask-src removes the originator 'from' field)
listen on egress port 587 tls-require pki mail.example.org protocols "secure" ciphers "secure" auth <credentials> mask-src filter { rspamd }
### Actions
action "local_mail" mbox alias <aliases_local>
action "outbound" relay helo mail.example.org
action "store_mail" maildir "/home/vmail/mailboxes/%{dest.domain}/%{dest.user}" virtual <virtuals>
### Matches
# Store mail for valid user aliases
match from any for domain <domains> action "store_mail"
# Local mail can be delivered to local aliases
match from local for local action "local_mail"
# Allow authenticated users or from the local system itself to send out e-mail
match from any auth for any action "outbound"
# The local system may send mail out if needed
match from local for any action "outbound"
# EOF
Controleer vervolgens de configuratie met een ‘configtest’ of er geen fouten zijn.
# smtpd -n
configuration OK
Als dat werkt, dan kan OpenSMTPD herstart worden.
rcctl restart smtpd
Spam-filtering
Naast wat basiszaken in OpenSMTPD om spammers tegen te houden, kunnen we voor spam-filtering Rspamd gebruiken. Hiervoor dienen we een OpenSMTPD-filter te installeren en Rspamd. Voor de opslag van data installeren we Redis.
pkg_add opensmtpd-filter-rspamd rspamd redis
rcctl enable rspamd
rcctl enable redis
Standaard zal het geheel waarschijnlijk al werken met de standaardconfiguratie. Alleen is dit dan minder effectief.
Wil je Rspamd beter begrijpen? Er komt een diepgaand artikel genaamd spam-filter met rspamd. Stay tuned!
DKIM
Voorheen was het gebruikelijk om een RSA-sleutelpaar te maken met een grootte van 1024 bits. Tegenwoordig wordt 2048 aangeraden, maar heeft wel een aandachtspunt. Niet iedere provider laat de lengte toe van deze grotere sleutel. Afhankelijk van de geboden interface, dient de sleutel dan verdeeld te worden over meerdere regels.
Een sleutelgrootte van 4096 bits is niet aan te raden vanwege compatibiliteit. Sommige oplossingen ondersteunen dit (nog) niet.
Een andere optie is het gebruik van ed25519, modern en veel korter. Echter, het is mogelijk dat nog niet iedere mailserver dit ondersteunt voor DKIM. Kortom, een lastig dilemma. De oplossing? Maak beide sleuteltypes aan en configureer dat beiden gebruikt worden.
Optie 1 - Rspamd
Wie toch al extra spamfiltering wil doen, kan het ondertekenen van berichten laten doen door Rspamd. Deze is in staat om meerdere selectors op te geven voor een domein.
Directory aanmaken
We schermen de directory af dat alleen de rspamd-gebruiker (_rspamd) bij de geheime sleutels kan.
install -d -o root -g \_rspamd -m 770 /etc/mail/dkim
Sleutels genereren
Laten we beginnen met de ed25519-sleutel. Aangezien met meerdere sleutels gaan werken, is het handig om de selector zeer zorgvuldig een naam te geven. Ik kies voor ‘dkim’, aangevuld met het jaartal, een volgnummer en uiteindelijk het type. Zo is het duidelijk waar het voor is, in welk jaar het is aangemaakt en is rotatie mogelijk met behulp van het volgnummer.
rspamadm dkim_keygen --domain example.org --selector dkim-2026-01-ed25519 --privkey /etc/mail/dkim/example.org-ed25519.key --type ed25519
Standaard zal de ‘dkim_keygen’ een DNS-weergave gebruiken. Deze informatie gaan we dadelijk verwerken.
Vervolgens maken we de RSA-sleutel aan en geven het aantal bits op.
rspamadm dkim_keygen --domain example.org --selector dkim-2026-01-rsa2048 --privkey /etc/mail/dkim/example.org-rsa2048.key --type rsa --bits 2048
DNS-records aanpassen
Nu is het tijd om twee DNS-records aan te maken. Hierbij maken we dus 1 selector aan voor ed25519 en 1 voor RSA.
Tips:
- De naam voor het DNS-record staat aan de linkerzijde
- Het type record is TXT
- De waarde is v=DKIM1;k=ed25519;p=ABC of v=DKIM1;k=rsa;p=XYZ
- Bij een sleutel met ed25519 past de tekst direct achter ‘p=’ (zonder aanhalingstekens), bij RSA (2048 bits) dienen de inhoud tussen aanhalingstekens als 1 lange reeks geplakt te worden, mits jouw provider dat toestaat.
Rechten controleren en configureren
Controleer dat ‘_rspamd’ de gegenereerde sleutels kan lezen.
Open /etc/rspamd/local.d/dkim_signing.conf om de sleutels in te voegen. Een voorbeeld voor een domein (example.com) met slechts een enkele sleutel en eentje met meerdere selectors, zoals hierboven aangemaakt.
domain {
example.com {
selector = "dkim-2026-01";
path = "/etc/mail/dkim/dkim-example.com.key";
}
example.org {
selectors [
{
path: "/etc/mail/dkim/example.org-ed25519.key";
selector: "dkim-2026-01-ed25519";
},
{
path: "/etc/mail/dkim/example.org-rsa2048.key"
selector: "dkim-2026-01-rsa2048";
}
]
}
}
In een uitvoeriger artikel over Rspamd komt het gebruik van de DKIM-sleutels verder aan bod.
Optie 2 - handmatig
Een andere optie is een alles met de hand aanmaken. We maken eerst de benodigde directories aan voor de opslag van onze DKIM-certificaten.
De volgende stap is het aanmaken van de certificaten waar we openssl voor gebruiken.
openssl genrsa -out /etc/mail/dkim/dkim-example.org.key 2048
openssl rsa -in /etc/mail/dkim/dkim-example.org.key -pubout -out /etc/mail/dkim-example.org.pub
Controleer de rechten en zorg ervoor dat de software die de sleutels gaat gebruiken er bij kan.
Nu dienen we de publieke sleutel van DKIM te publiceren via DNS. De publieke sleutel bestaat uit meerdere lijnen en dient samengevoegd te worden. Tevens dienen we de versie en het type van de sleutel toe te voegen.
printf "v=DKIM1;k=rsa;p=%s\n" $(grep -v '\-\-' /etc/mail/dkim/dkim-example.com.pub | tr -d '\n')
- Naam: dkim-2026-01._domainkey
- Type: TXT
- Waarde: v=DKIM1;k=rsa;p=willekeurige-string-van-karakters
Dovecot
Ontvangen e-mail willen we natuurlijk kunnen inzien. Om deze op te halen, is er het open source Dovecot beschikbaar.
De stappen om Dovecot te installeren, activeren en starten zijn als volgt:
pkg_add dovecot
rcctl enable dovecot
rcctl start dovecot
We willen gebruikers ook de mogelijkheid geven om aanvullende filters en regels toe te passen. Hiermee kan bijvoorbeeld e-mail dat vermoedelijk spam is, ook meteen in ‘Junk’ worden geplaatst. Daarvoor is Sieve en ManageSieve, onderdeel van van dovecot-pigeonhole. De logische stap is dus om die ook te installeren.
pkg_add dovecot-pigeonhole
Basisconfiguratie
Nu is het tijd om Dovecot te gaan configureren. Open /etc/login.conf en geef Dovecot ruimere waardes voor het aantal open bestanden. Zeker met het Maildir-formaat kunnen er de nodige bestanden gelijktijdig open zijn.
dovecot:\
:openfiles-cur=1024:\
:openfiles-max=2048:\
:tc=daemon:
Personaliseren van Dovecot
Dovecot kent vele opties, dus het is raadzaam om de documentatie te bekijken. Een aantal zaken zijn erg afhankelijk van het systeem, de gewenste authenticatie, ondersteuning voor Sieve-scripts en welke protocollen we wel of niet willen ondersteunen.
In het kort:
- Alleen IMAP voor ophalen van e-mail
- Gebruik PLAIN authenticatie, maar wel met een versleutelde verbinding
- Beschrijven hoe onze standaardmailbox eruit moet zien
- Waar kunnen we Dovecot- en Sieve-scripts vinden
Open /etc/dovecot/local.conf om eigen specifieke configuratie-instellingen te doen. Voorbeeld:
# Authenticatie-type en eerste geldige gebruiker/groep
auth_mechanisms = plain
first_valid_uid = 2000
first_valid_gid = 2000
ssl_cert = </etc/ssl/mail.example.org.fullchain.pem
ssl_key = </etc/ssl/private/mail.example.org.key
# Waar staan mailboxen opgeslagen
mail_location = maildir:/home/vmail/mailboxes/%d/%n
# Waar zijn plugins te vinden
mail_plugin_dir = /usr/local/lib/dovecot
# Sieve
managesieve_notify_capability = mailto
managesieve_sieve_capability = body copy environment fileinto envelope include mailbox stop variables vnd.dovecot.pipe
# Gebruik je NFS voor opslag van mail? Dan mmap() uitschakelen. Voor normale opslag op lokale harde schijf niet nodig
# mmap_disable = yes
# Beschrijven hoe een mailbox eruit ziet
namespace inbox {
inbox = yes
location =
mailbox Archive {
auto = subscribe
special_use = \Archive
}
mailbox Drafts {
auto = no
special_use = \Drafts
}
mailbox Junk {
auto = create # aanmaken, maar niet op abonneren
special_use = \Junk
}
mailbox Sent {
auto = subscribe
special_use = \Sent
}
mailbox Trash {
auto = no
special_use = \Trash
}
prefix =
}
# De plugins voor Sieve
plugin {
# Bericht verplaatst naar spam/junk? Dan leren als 'SPAM'.
imapsieve_mailbox1_before = file:/usr/local/lib/dovecot/sieve/learn-as-spam.sieve
imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_name = Junk
# Was bericht gemarkeerd als spam, maar verplaatst de ontvanger hem naar een normale map? Dan gaan we dit als 'HAM' leren.
imapsieve_mailbox2_before = file:/usr/local/lib/dovecot/sieve/learn-as-ham.sieve
imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_from = Junk
imapsieve_mailbox2_name = *
sieve = file:~/sieve;active=~/.dovecot.sieve
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
# Locatie waar onze scripts staan
sieve_pipe_bin_dir = /usr/local/lib/dovecot/sieve
# Activeer plugins om Sieve te kunnen gebruiken
sieve_plugins = sieve_imapsieve sieve_extprograms
# Extra script om mail gemarkeerd als 'SPAM' ook meteen te verplaatsen naar map 'Junk'
sieve_after = file:/usr/local/lib/dovecot/sieve/spam-to-folder.sieve
}
# Gebruikte protocollen (IMAP voor ophalen mail en Sieve voor scripts)
protocols = imap sieve
protocol imap {
mail_plugins = $mail_plugins imap_sieve
mail_max_userip_connections = 10
}
protocol sieve {
log_path = /var/log/dovecot-sieve-errors.log
info_log_path = /var/log/dovecot-sieve.log
}
service imap-login {
# We schakelen IMAP (poort 143) uit, zodat alleen IMAPS (993) wordt gebruikt
inet_listener imap {
port = 0
}
}
service managesieve-login {
inet_listener sieve {
port = 4190
}
}
Gebruik je iets niet (meteen)? Haal het dan weg, of zet er een hekje voor.
Dovecot koppelen met SQLite-database
Open /etc/dovecot/dovecot-sql.conf.ext om onze gegevens opgeslagen in de SQLite-database ook te gebruiken binnen Dovecot.
# We gebruiken SQLite
driver = sqlite
# Pad naar de database
connect = /etc/mail/smtpd.sqlite
# Expliciet benoemen hoe wachtwoorden zijn opgeslagen
default_pass_scheme = BLF-CRYPT
# Authenticatie van gebruiker
password_query = \
SELECT email AS user, password \
FROM credentials WHERE email = '%u' \
AND password NOT NULL AND is_active = 1 \
LIMIT 1;
# Controle of mailbox daadwerkelijk bestaat
user_query = \
SELECT '/home/vmail/%d/%n' AS home, 2000 AS uid, 2000 AS gid \
FROM credentials WHERE email = '%u' \
AND password NOT NULL AND is_active = 1 \
LIMIT 1;
Dovecot-configuratie controleren
Dovecot combineert de basisconfiguratie met jouw eigen instellingen. Daarom is het na het toepassen van alle benodigde configuratie-instellingen, zinvol om met doveconf | less goed een keer door de gehele configuratie heen te lopen.
SIEVE-configuratie
Maak /usr/local/lib/dovecot/learn-as-spam.sieve aan om berichten te kunnen leren die we verplaatsen naar onze spammap.
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment"];
if environment :is "imap.cause" "COPY" {
pipe :copy "rspamc" ["learn_spam"];
}
Voor het leren van normale e-mail, maak het bestand /usr/local/lib/dovecot/learn-as-ham.sieve aan. Als een bericht naar de prullenbak gaat, dan willen we er niks meer mee doen. Als we hem verplaatsen naar een andere map, dan geeft de gebruiker hiermee aan dat het legitieme e-mail is en willen we deze leren.
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.mailbox" "*" {
set "mailbox" "${1}";
}
if string "${mailbox}" ["Trash"] {
stop;
}
pipe :copy "rspamc" ["learn_ham"];
We kunnen spam automatisch ook nog laten verplaatsen. Dit geeft rust in de mailbox, zeker op momenten dat er weer de nodige spamruns zijn. Maak daarvoor het bestand /usr/local/lib/dovecot/move-spam-to-junk-folder.sieve aan.
require ["fileinto","mailbox"];
if header :contains "X-Spam" "Yes" {
fileinto :create "Junk";
stop;
}
Na het aanmaken van de scripts, is de volgende stap ze te compileren. Hiermee worden ze gecontroleerd en kunnen ook uitgevoerd worden door Dovecot:
sievec /usr/local/lib/dovecot/learn-as-spam.sieve
sievec /usr/local/lib/dovecot/learn-as-ham.sieve
sievec /usr/local/lib/dovecot/move-spam-to-junk-folder.sieve
Hiermee krijgen we twee nieuwe bestanden in dezelfde directory als de sieve-scripts met de extensie .svbin.
Om ervoor te zorgen dat de ‘pipe’ rspamc kan uitvoeren, dienen we deze te linken. Locatie van rspamc kunnen we vinden met whereis rspamc.
ln -s /usr/local/bin/rspamc /usr/local/lib/dovecot/sieve/rspamc
Verbinding met SQLite-database
Open /etc/dovecot/conf.d/auth-sql.conf.ext
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
override_fields = uid=vmail gid=vmail
}
Open /etc/dovecot/dovecot-sql.conf.ext
driver = sqlite
Verwijzing naar onze database om mee te verbinden:
connect = /etc/mail/smtp.sqlite
Hoe worden wachtwoorden opgeslagen?
default_pass_scheme = BLF-CRYPT
SSL-configuratie
Draai nu dovecot-mkcert.sh om een self-signed certificaat aan te maken. Die kunnen we daarna vervangen voor een eigen certificaat.
Ondersteuning voor sieve
Als het goed is bestaat /etc/dovecot/conf.d/20-sieve.conf al, waarin sieve is geactiveerd. De verwijzing naar poort 2000, met de naam managesieve_deprecated kan worden weggehaald. Zoals de naam al doet vermoeden, is het een oudere implementatie.
protocols = $protocols sieve
service managesieve-login {
inet_listener sieve {
port = 4190
}
}
plugin {
sieve = ~/.dovecot.sieve
sieve_dir = ~/sieve
}
Accounts
Aanmaken
Wachtwoord genereren: smtpctl encrypt
# smtpctl encrypt
paste-your-password-here
$2b$09$CVUigOvEqpik3GAOcUaZ4.tyYzU1bvOeIRexMlNZ38QLT12AZoxh6
# doveadm auth test account@example.org
Password:
passdb: account@example.org auth succeeded
extra fields:
user=account@example.org
Extra tips
Testen van mail
Testen kan met het commando mail gevolgd door verzender, ontvanger en onderwerp. Daarna de tekst invoeren en op een lege regel afsluiten met een punt.
# mail -s test -r afzender@domein.nl ontvanger@example.org
Dit is een testbericht
.
Handige commando’s
Dovecot
- doveadm auth test (test authenticatie)
- doveadm kick (disconnect gebruikers)
- doveadm mailbox list (toon welke mailboxen er zijn)
- doveadm log errors (toon foutmeldingen)
- doveadm reload (configuratie herladen)
- doveadm stats (toon statistieken)
- doveadm user (toon beschikbare gebruikers)
OpenSMTPD
- smtpctl encrypt (genereer een wachtwoord voor nieuw account)
Algemeen systeembeheer
- syspatch
- fw_update
- pkg_add -u
- sysupgrade
Handige diensten
- internet.nl
- MailShield.app (Nederlands, betaalde dienst, eerste domein gratis)
Overzicht DNS-records
Qua TXT-records:
_dmarc TXT 1 hour v=DMARC1;p=reject;sp=reject;adkim=s;aspf=s;rua=mailto:dmarc@example.org
_mta-sts TXT 1 hour v=STSv1; id=20260605
_smtp._tls TXT 1 hour v=TLSRPTv1; rua=mailto:tlsrpt@example.org;
_spf TXT 1 hour v=spf1 ip4:1.2.3.4 ip6:2a03:6000:aaaa:bbbb:::123 -all
Foutmeldingen
lookup: table-proc en lka socket closed (OpenSMTPD)
Jun 1 10:43:35 mail smtpd[60534]: lookup: table-proc: unexpected EOF during handshake
Jun 1 10:43:35 mail smtpd[67030]: smtpd: process lka socket closed
Oorzaak: SQL-query was onjuist, doordat er een verkeerde tabel werd gebruikt. Helaas is dit niet direct uit de foutmeldingen te halen.
Dovecot
Jun 1 21:18:28 mail dovecot: auth-worker(5269): Error: conn unix:auth-worker (pid=64967,uid=518): auth-worker<2>: sql(myuser@mydomain.eu): Password query failed: no such table: credentials
Verkeerde verwijzing naar database in dovecot-sql.conf.ext
Jun 1 21:21:56 mail dovecot: auth-worker(98895): Error: conn unix:auth-worker (pid=63146,uid=518): auth-worker<1>: sql(auth-michael@example.org): Password query failed: no such column: active
Verkeerd veld werd gebruikt, waardoor de SQL-query niet kan worden uitgevoerd. In dit geval het veld ‘active’ dat niet bestond.
dovecot: imap(account@example.org)<96356><vIZjqddUouktjpAw>: Error: sieve: failed to pipe message to program `rspamc': refer to server log for more information. [2026-06-22 15:31:43]
dovecot: imap(account@example.org)<96356><vIZjqddUouktjpAw>: Error: sieve: Execution of script /usr/local/lib/dovecot/sieve/learn-as-ham.sieve failed
rspamc was niet beschikbaar in het pad opgegeven binnen Dovecot.
In dit geval /etc/dovecot/local.conf heeft de volgende waarde:
sieve_pipe_bin_dir = /usr/local/lib/dovecot/sieve
Oplossing is een symlink maken in dit pad.
ln -s /usr/local/bin/rspamc /usr/local/lib/dovecot/sieve/rspamc
2026-06-27 23:56:06 #85922(normal) <004d42>; task; dkim_module_load_key_format: cannot load dkim key /etc/mail/dkim/private/dkim-example.org.key: cannot stat key file: '/etc/mail/dkim/private/dkim-example.org.key' Permission denied
Rechten te strak, controleer de bestandsrechten.
Bronnen
Het is natuurlijk zonde om werk te doen dat al is uitgezocht door anderen. Dus bij het opstellen van mijn configuratie heb ik me ook laten inspireren door de configuraties van andere bloggers en het rspamd-boek. Soms zijn configuratie-snippets zo over te nemen, maar vaak ook niet. Denk aan verouderde configuraties of verschillende naamgevingen. Een aantal bronnen die ik zowel tegen ben gekomen zijn:
- https://jmmr.dev/posts/dynamic-ip-ssh-allow-list-with-pf/
- https://jkossen.nl/obsd-server-setup/
- https://blog.thechases.com/posts/bsd/aggressive-pf-config-for-ssh-protection/
- https://dataswamp.org/
- https://www.openbsdhandbook.com/
- https://www.protectstar.com/download/blog/pf.conf_noDMZ.txt
- https://brycev.com/blog/openbsd-smtpd/
- https://corrupted.io/2014/06/09/OpenSMTPD-virtual-users-with-sqlite.html
Toelichting en begrippen
| Begrip | Uitleg |
|---|---|
| DNS | Vertaalt namen en IP-adressen, bevat informatie voor domeinnaam |
| Domeinnaam | Unieke naam die gebruikt kan worden om bijvoorbeeld een website beschikbaar te maken |
| Hostnaam | De naam van een computer of een naam in DNS |
| HTTPS | Versleutelde verbinding tussen een webserver en client |
| SQL | Commando’s om database te beheren, te ondervragen en te voorzien van data |
Speciale dank
De volgende personen hebben een grote bijdrage geleverd bij de totstandkoming van dit document
- Misha Peters
- Jeroen Janssen
Nog te doen
- Aanmaken van database-tabel credentials en invulling van data
- Aanmaken van database-tabel en virtuals
- Monitoren van domeinnamen
- Monitoren van DNS-records
- Controleren, monitoren en beheer van DMARC/MTA-STS
- Flush pf tables totdat er een automatische expiry mogelijk is
- Authenticated users alleen laten versturen met hun eigen from:
senders <users> [masquerade]
Look up the authenticated user in the users mapping table
to find the email addresses that user is allowed to
submit mail as. In addition, if the masquerade option is
provided, the From header is rewritten to match the
sender provided in the SMTP session.