setting up an email server with opensmtpd+dovecot+postgresql

today, i'm going to talk on how to set up an email server with the components explained above

cirno holding a letter

your requirements will be: – access to alter rDNS of ur IP (tl;dr: set it to ur domain) – a domain that you can manage via DNS – a debian/openbsd server – a public IP address – a server that can serve port 25 (important: CONSULT to your ISP/VPS provider's ToS)

what we gonna do (in order so you won't cry): – set up dns – configure spf – configure dkim – step 1: make le key – step 2: make le DNS record – configure dmarc – get the server software working – prepare le postgresql database – prepare le mailbox – configure le opensmtpd – configure le rspamd – tool for inbox (dovecot)


set up the DNS first.

this part, we will configure these two things: – [required] SPF: basically a policy that tells a mail server, what mailer IP is allowed to send as your domain – [required] DKIM: ur key for signing ur mail on your domain behalf so anyone can't spoof their mail with your domain – [optional] DMARC: final verifier after SPF and DKIM


spf: the easiest thing to setup

assuming you have the following public IP address (that's also used as an ip used to relay ur mail to other email server): – ipv4: 203.0.113.5 – ipv6: 2001:db8::5

and then assuming your domain is waltuh.cyou,

you set a TXT record in ur domain's DNS. It should look like this:

v=spf1 mx ip4:203.0.113.5 ip6:2001:db8::5 -all

or if you only have ipv4:

v=spf1 mx ip4:203.0.113.5 -all

that's it. now let's continue


dkim: “this is my signature. i am real.”

step 1: make le key

get into ur server's shell, and go make a directory at /etc/mail/dkim.

go here, assuming ur current dir is now /etc/mail/dkim, do this:

openssl genpkey -algorithm ed25519 -outform PEM -out waltuh.cyou-ed25519.key

this will make a key under path /etc/mail/dkim/waltuh.cyou-ed25519.key. you can adjust it accordingly to ur use.

then, make the string of le dns TXT DKIM record:

printf "v=DKIM1;k=ed25519;p=%s" "$(openssl pkey -outform DER -pubout -in waltuh.cyou-ed25519.key | tail -c +13 | openssl base64)"

it should look like this:

v=DKIM1;k=ed25519;p=tM22KunOkYfEtLzvaUQQcwjUGw8c6hg/v24gIa46oSY=

step 2: make le DNS record

before we continue, you need to know this: so, in dkim, there's something called selector. you can, basically use it as a versioning of ur dkim. this will be important on both dns, and ur smtp server, especially when you're rerolling ur dkim key.

so, for dns, You must make a DNS record at <selector>._domainkey.waltuh.cyou (assuming ur domain is waltuh.cyou)

now, assuming our selector is mail2026, that would be mail2026._domainkey.waltuh.cyou.

so, make a TXT record here, put the previously generated DKIM pubkey that looked like this before:

v=DKIM1;k=ed25519;p=tM22KunOkYfEtLzvaUQQcwjUGw8c6hg/v24gIa46oSY=

now save it.

please rember the selector.


dmarc: “if spf fail, or dkim fail, what should i do?”

it's basically that.

It does stuff when SPF and DKIM are not valid,

this is optional, but i suggest you to use it.

You just put this DNS record into your domain, Specifically, _dmarc subdomain containing a TXT record that writes:

v=DMARC1; p=reject; rua=mailto:dmarc@waltuh.cyou

and then just apply it, Say, on _dmarc.waltuh.cyou

That's basically it.


the loud machine and it's endministrator

get the server software working

oh?

you finished the warmup?

OMEDETOU

now, i will just be quick here. Assuming you have debian or openbsd host, You need to install these:

or,

apt install opensmtpd{,-filter-{dkimsign,rspamd},table-postgres} dovecot-{core,imapd,lmtpd,pop3d,sieve,pgsql} postgresql{,-contrib}

prepare le postgresql database

go start the postgresql database server (haven't init ur db? go init it first), then make le db for opensmtpd:

sudo -Hu postgres psql

then

CREATE USER opensmtpd WITH PASSWORD 'thestrong9stpassw0rd!';
CREATE DATABASE opensmtpdb OWNER opensmtpd;
\c opensmtpdb
CREATE TABLE virtuals (
    id SERIAL,
    email VARCHAR(255) NOT NULL DEFAULT '',
    destination VARCHAR(255) NOT NULL DEFAULT ''
);
CREATE TABLE credentials (
    id SERIAL,
    email VARCHAR(255) NOT NULL DEFAULT '',
    password VARCHAR(255) NOT NULL DEFAULT ''
);
CREATE TABLE users (
    id SERIAL,
    username VARCHAR(255) NOT NULL DEFAULT '',
    email VARCHAR(255) NOT NULL DEFAULT ''
)

yea. copy and paste w o k s

then, quit le psql by CTRL+C, open ur editor, can be nano in ur server, write this to initsetup.sql:

insert into virtuals (email, destination) values ('root', 'yonle@waltuh.cyou');
insert into virtuals (email, destination) values ('postmaster@waltuh.cyou', 'root');
insert into virtuals (email, destination) values ('webmaster@waltuh.cyou', 'root');
insert into virtuals (email, destination) values ('abuse@waltuh.cyou', 'root');
insert into virtuals (email, destination) values ('dmarc@waltuh.cyou', 'root');
insert into virtuals (email, destination) values ('yonle@waltuh.cyou', 'vmail');

insert into users (username, email) values ('yonle@waltuh.cyou', 'yonle@waltuh.cyou');
insert into users (username, email) values ('noreply@waltuh.cyou', 'noreply@waltuh.cyou');

insert into credentials (email, password) values ('yonle@waltuh.cyou', '$2b$...');
insert into credentials (email, password) values ('noreply@waltuh.cyou', '$2b$...');

the virtuals is an alias of your email address. To put it simply, If one sends an email to abuse@waltuh.cyou, It will gets delivered to yonle@waltuh.cyou. Cool right?

when the virtual address got vmail in the end, it then gets delivered to your inbox, marking the end of the alias venture. for example, if yonle@waltuh.cyou alias is vmail, that means the mail will be delivered to an mailbox specifically for yonle@waltuh.cyou.

adjust it according to your use, then

sudo -Hu postgres psql -d opensmtpd -f initsetup.sql

you wonder about password hashing? it must be in bcrypt. google how to generate a blowfish hash, coz there's so many out here.

but i don't wanna

OKAY, OKAY, YOU FUCK. GO INSTALL A GO COMPILER, MAKE A FOLDER, OPEN A EDITOR, WRITE THIS CODE:

package main

import (
        "fmt"
        "golang.org/x/crypto/bcrypt"
        "os"
)

func main() {
        if len(os.Args) != 2 {
                panic("give me password.")
        }

        hash, _ := bcrypt.GenerateFromPassword([]byte(os.Args[1]), 12)
        fmt.Println(string(hash))
}

then, compile it

go mod init a
go mod tidy
go build -o gen

and do your thing

./gen 'yourstr0ng9stp4ssw0rd!'

it will emit, like this:

$2a$12$wrhwp/F/vakmnznJvDyrfOlNzKVZYtOY05CMBcvVQi8LOmEJimLI6

prepare le mailbox

tl;dr:

useradd -m -r -u 5000 -g mail -d /var/vmail -s /sbin/nologin vmail

# Make sure the mail directory exists
sudo mkdir -p /var/vmail
sudo chown -R vmail:mail /var/vmail
sudo chmod -R 700 /var/vmail

configure le opensmtpd

in debian, the config is located at /etc/smtpd.conf.

in openbsd, it's at /etc/mail/smtpd.conf.

but the tl;dr: go use my config here.

and then, go to /etc/mail

make the following files: – hosts: a file listing the IPs that you will use for relaying email to outside – mailname: ur mail name – postgresql.conf: configuration for opensmtpd to connect to ur postgresql

you can check for the examples here.

before we start our opensmtpd, first,

configure le rspamd.

just, go use my config here in ur /etc/rspamd/local.d/settings.conf.

then start ur rspamd, systemctl enable --now rspamd


before we be all good and all,

chown _dkimsign:_dkimsign /etc/mail/dkim/waltuh.cyou-ed25519.key

also, ensure that ur ssl keys are owned by root. if not, opensmtpd won't start.

finally, start ur opensmtpd. systemctl enable --now opensmtpd

if everything goes smooth, congratulations,

You just started ur first mail server!


tool for inbox (dovecot)

this is your final part, before you finally able to go to rest.

it's just 2 deadass simple config. go check my config here.

you will then just need to alter psql connection in local.conf before you start dovecot server by running systemctl enable --now dovecot


finally,

go try connect ur email server and try send email.

be note though, sending email to gmail or yahoo or outlook might make ur mail to be ended up in spam folder at first & this is normal. you just need to make ur ip & domain rep to be good and you're all good to go. The button [Report as not spam] is a thing for the purpose.

alright. hope this helps you.

bye.