Went through the same journey in November and now handle both inbound and outbound e-mail on my Hetzner box (should get a secondary SMTP going at some point for redundancy though). I have delivery to both Google and Microsoft (known to be among the worst of the actors) confirmed working for about a month.

My simpler (?) setup based on the same logical flow as Nico's:

1. Check assigned IP from provider (Hetzner in my case) for issues on black lists (MxToolbox worked great for me).

2. Set up reverse DNS with your provider.

3. Install OpenBSD: confirm default, confirm default, ..., enter hostname, enter username, enter password, confirm default, confirm default, ..., select mirror, confirm default, confirm default, ...

4. Use ssh-copy-id(1) to authorise key logins for the user you set up during the installation.

5. Set up DNS records for both the hostname and SPF (confirm propagation/settings with say MxToolbox, it will be helpful at pretty much every step, so I will stop repeating it now)

6. Enable httpd(8) with `rcctl enable httpd && rcctl start httpd` and set up acme-client(1) with the examples from: https://man.openbsd.org/acme-client

7. Enable and configure spamd(8) (note that I disable greylisting) and uncomment a few lines in `/etc/pf.conf` and reload your PF rules:

> echo spamd_flags=-b >> /etc/rc.conf.local
> rcctl start spamd
> vi /etc/pf.conf
> pfctl -f /etc/pf.conf

8. Configure and enable (`rcctl enable smtpd`) OpenSMTPD, which is about as easy as it gets (I am being more explicit about the hostname than I need to, but it is necessary as the box has multiple hostnames and the MX one is not the primary):

pki $HOSTNAME cert "/etc/ssl/$HOSTNAME.fullchain.pem"
pki $HOSTNAME key "/etc/ssl/private/$HOSTNAME.key"

table aliases file:/etc/mail/aliases
table domains file:/etc/mail/domains
table secrets file:/etc/mail/secrets
table virtuals file:/etc/mail/virtuals

filter "rdns" phase connect match !rdns \
disconnect "550 Reverse DNS lookup failed"
filter "fcrdns" phase connect match !fcrdns \
disconnect "550 Forward-confirmed reverse DNS failed"

listen on all tls hostname $HOSTNAME pki $HOSTNAME \
filter { "rdns" "fcrdns" }
listen on all smtps port smtps hostname $HOSTNAME \
pki $HOSTNAME auth <secrets> mask-src

action "local" mbox alias <aliases>
action "relay" relay tls helo $HOSTNAME
action "virtual" mbox virtual <virtuals>

9. Fill in `/etc/mail/domains` and `/etc/mail/virtuals` with the domains and virtual inboxes you want to handle.

10. `rcctl start smtpd`

That is it. DKIM is annoying, as it requires a package from ports and all we just did above was with the OpenBSD base system, but it turns out delivery works just fine without it for a small family server (even for Google and M$). I think there is an argument for DKIM (although it adds next to nothing over SPF) to be in base OpenSMTPD as I believe all the complicated code is already in base, but I am not intimately familiar with the OpenSMTPD code base and trust that it will happen if the e-mail climate becomes even more oppressive.

I am cheating somewhat here as I am not doing local delivery/retrieval but relaying to an external SMTP server as I have yet to find a more minimal solution for POP3 than Dovecot that I feel comfortable hosting (pop3d gets close (https://github.com/snimmagadda/pop3d/), but I would need a code audit and I have lacked the time).

This is all from memory (apart from the nearly default `/etc/mail/smtpd.conf`) and I of course take no responsibility for anyone copying and pasting blindly without thinking (this is OpenBSD after all: Use your head).

A final word, if you ever have trouble, use MxToolbox or similar and they will lead you in the right direction if you have misunderstood the documentation or in other ways messed up the configuration.