diff options
author | Prefetch | 2020-04-27 04:08:47 +0200 |
---|---|---|
committer | Prefetch | 2020-04-27 04:08:47 +0200 |
commit | c30193921ef3fa3e74d79030f50b456eb63a84f3 (patch) | |
tree | e93ef50161ba0369ac3e31026247b025eb35b87f /content/blog/2020 | |
parent | d7695acb4a70f5fb7cc9cce0b65c71fd3e0380aa (diff) |
Migrate to prefetch.eu etc.
Diffstat (limited to 'content/blog/2020')
-rw-r--r-- | content/blog/2020/email-server.md | 706 |
1 files changed, 706 insertions, 0 deletions
diff --git a/content/blog/2020/email-server.md b/content/blog/2020/email-server.md new file mode 100644 index 0000000..f089863 --- /dev/null +++ b/content/blog/2020/email-server.md @@ -0,0 +1,706 @@ ++++ +title = "Setting up an email server in 2020 with OpenSMTPD and Dovecot" ++++ + +# + +So, you want to set up your own email server? In that case, welcome. + +There are many reasons to run a custom email server, +ranging from privacy concerns about providers like Google, +to just wanting to do it for fun and/or learning. +Since you're here, I assume you've already found a reason. + +Beware: this is a messy topic, and the available documentation +is even messier, so it could take a while before you get it to work properly. +I've compiled this guide according to my experiences +in an attempt to make this dark art more accessible, +but your mileage may vary considerably. I hope you find it useful. + +This guide is aimed at people who are comfortable with +the Linux/*BSD command line. + +Last updated 2020-04-26. + + + +## Preparation + +Setting up email is relatively complex compared to e.g. a static website, +because you need to configure not one, but *two* server programs, +*and* you need to shoehorn modern security features into email's Stone-Age design. +I'll start by explaining the general structure of a mail server setup. + + +### How email works + +The programs involved in the exchange of emails are called [agents](https://en.wikipedia.org/wiki/Email_agent_(infrastructure)). +Officially, there are 5 different types of agent: MUA, MSA, MTA, MDA and MRA. +But fortunately, it's reasonable to treat the MRA and MSA +as being part of the MUA and MTA, respectively. + +The *Mail User Agent* (MUA) is simply the client on your device at home +that you use to send and receive emails, and this guide assumes +you already have a favourite program for this, e.g. [Thunderbird](https://www.thunderbird.net/en-US/). +Nowadays it's fashionable to use a web interface for emails, +but that's also beyond the scope of this guide. + +The *Mail Delivery Agent* (MDA) is a program that watches over +the server's copy of your mailbox: it manages your inbox, +remembers which messages you have or haven't read, +keeps a copy of your drafts, etc. +When you open your mailbox, your MUA will connect to +your server's MDA using the [IMAP](https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol) protocol +(or [POP3](https://en.wikipedia.org/wiki/Post_Office_Protocol), but that one's [obsolete](https://pop2imap.com/)). + +The *Mail Transfer Agent* (MTA) is responsible for +making messages arrive at the right destination. +When you send an email, your MUA will pass it on to your server's MTA, +which will in turn pass it on to the recipient's mail server. +Likewise, when someone sends *you* an email from another server, +the MTA will receive it and hand it over to the MDA so you can read it later. +In both cases the MTA speaks the [SMTP](https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol) protocol. + +In this guide our MDA will be [Dovecot](https://dovecot.org/), +which is a very popular choice for that role. +As for the MTA, there exist several options, +the most popular being [Postfix](http://www.postfix.org/) and [Exim](https://exim.org/). +However, this guide uses the newer, lesser-known [OpenSMTPD](https://opensmtpd.org/), +which in my experience is *much* easier to set up: +Postfix and Exim have complex configurations and +are geared towards large-scale email providers, +whereas OpenSMTPD is more beginner-friendly. + + + +### Security + +The base email system is horribly insecure on its own, +so we still need to duct-tape on some security features. +In this context, "security" has two meanings: +spam protecion and privacy protection (encryption). + +Spam protection also means two things here: +defending yourself against spammers, and +preventing that *your* emails get flagged as spam. +The former is optional, but the latter is not: +big providers such as Google and Microsoft +use infamously strict spam filters, +and if they decide that your server is a spammer, +there's almost nothing you can do about it. +Spam protection techniques will be discussed +in more detail over the course of this guide. + +Privacy protection is important in the 21st century: +you don't want a random router in the Internet to read all your emails, +which may contain sensitive information such as +private conversations and account password reset links. +You should therefore try to make sure that emails are +transported over an encrypted channel. +To do this, you have two options for encryption: +*mandatory* and *opportunistic* encryption. + +Mandatory encryption is only practical for client-server +communication (not server-server), and is provided by IMAPS and SMTPS, +which wrap the IMAP and SMTP protocols in [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security), +in the same way that [HTTPS](https://en.wikipedia.org/wiki/HTTPS) does for [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol). + +For server-server communication, the only option is +opportunistic encryption in the form of [STARTTLS](https://en.wikipedia.org/wiki/STARTTLS), +where communication is only encrypted if both parties agree +after a short unencrypted discussion. +That last part is vulnerable to [MitM](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) attacks, +where anyone along the path of the email servers' discussion +can alter the exchange to block the use of encryption, +which sometimes actually [happens](https://www.eff.org/deeplinks/2014/11/starttls-downgrade-attacks) in practice. + +The only way to make sure that STARTTLS is used in that case +is to refuse any exchange unless the servers agree to use encryption. +Unfortunately, that's a risky approach that I can't recommend, +because not all servers support encryption (unbelievable, right?). +For example, I've received airline booking confirmations, +full of personal details, and made with billion-dollar companies, +sent across the Internet without any protection. + +This guide includes intructions to enable encryption, +but assumes that you already have a TLS certificate for that. +If not, find a guide to get one from [Let's Encrypt](https://letsencrypt.org/) (it's free!), +and remember that you'll need to renew it every few months. +Using a self-signed certificate *may* work, but I don't recommend it. + +In the rest of this guide I'll assume that +you have a public full-chain TLS certificate at `/etc/ssl/certs/example.com.pem`, +and a private encryption key at `/etc/ssl/private/example.com.pem`. + + + +### Server + +Obviously, you'll need a server to run the MTA and MDA on. +You can host your own at home, but the more reliable option is +to rent one in a data center ([VPS](https://en.wikipedia.org/wiki/Virtual_private_server.)). +This guide was written with a Linux server in mind, +but in theory it should also work on the BSDs +([OpenBSD](https://www.openbsd.org/), [FreeBSD](https://www.freebsd.org/), +[NetBSD](https://www.netbsd.org/), etc.) with minimal adaptation. + +The server must be online 24/7, you must have root SSH access, +it must have a static IP address, and TCP network port 25 must be open. +Especially check that last one: you may need to explicitly ask +your home ISP or the server provider to enable port 25, +because they often close it to prevent spam. +You can usually do this from their web interface. + +You also must have a domain name, which I'll call `example.com`. +This will be necessary for basically everything: +DNS records, TLS certificate, MTA network configuration, etc. +If you don't have one yet, you can choose between many registrars +to rent one from. Personally I use and can recommend [Gandi](https://www.gandi.net/). + +Note that it's a **bad** idea to use a domain like `foo.bar.com`, +where you control the `foo` part but *not* the `bar` part: +in that case, a spammer in control of `qux.bar.com` +could negatively affect *your* reputation +in the eyes of other email providers. + +Lastly, when setting up an email server, you also have the choice +between using to *system* users or *virtual* users. +With system users, if an email arrives for `john@example.com`, +then the MTA and MDA will expect that there exists +a `john` Unix user on the server to deliver it to. +With virtual users, you have much more flexibility, so that's what we'll use. +All email will be managed under a single Unix user/group called `vmail`. +Create it as follows: +```sh +# GNU CoreUtils: +$ groupadd vmail +$ useradd -g vmail vmail +# BusyBox: +$ addgroup vmail +$ adduser -D -G vmail vmail +# *BSD: +$ no clue, but it should be similar +``` + + +## DNS records + +Now we must set up all the necessary DNS records, which +is usually possible from the domain registrar's web interface. +It may take a while for your changes to propagate over the Internet, +so I recommend doing this section now and the rest tomorrow. + +Firstly, you should already have an A and/or AAAA record +to associate your domain `example.com` with the server's IP address. +For email it is **essential** that you also have [reverse DNS](https://en.wikipedia.org/wiki/Reverse_DNS_lookup) +set up correctly. If you're renting your server remotely, +you can often do this from the provider's configuration tool, +otherwise, you should create a PTR-type DNS record, +although that's beyond the scope of this guide. + +Once you're done, I recommend testing your DNS records +using the [MX Lookup](https://mxtoolbox.com/MXLookup.aspx) online tool. + + + +### MX + +To inform the rest of the Internet that your server is an email server, +create an MX (Mail eXchanger) DNS record for your domain. +Note the dot at the end of the domain name: +``` +example.com. MX 42 example.com. +``` +When a message is sent to an email address ending in `@example.com`, +the sender will query DNS for any MX records for `example.com`. +There it will find a domain name (in this case `example.com` again), +for which it will look up the IP address using an A/AAAA record. +The domain name in the record must **not** have an associated CNAME record; +it must be directly translatable to an IP address. + +You may have multiple MX records, containing different domain names, +each with a preference number (`42` in the example above). +The sender will try MX records with *lower* numbers first, +and if that server is unavailable, it will try a higher number. +If you have multiple mail servers (which is a good idea), +you can thus declare those as follows: +``` +example.com. MX 13 mx1.example.com. +example.com. MX 42 mx2.example.com. +``` +Here, a server sending an email to your domain `example.com` +will try to send it to the IP address of `mx1.example.com` first, +and if that fails, it will move on to `mx2.example.com`. +If both `mx1` and `mx2` have the same number, then the sender +will randomly choose one, which is useful for load balancing, +although that's probably overkill for a private server. + + + +### SPF + +The [Sender Policy Framework](https://en.wikipedia.org/wiki/Sender_Policy_Framework) (SPF), +is a feature which helps prevent spammers from impersonating +your server in an attempt to get around blacklists. +This security feature is **required** nowadays: +if you don't use it, you'll probably get flagged as spam. + +SPF works by specifying which IP addresses are authorized +to send emails from your domain name. +You must publish this information in a +TXT-type DNS record (**not** SPF-type, which also exists!) with the following contents: +``` +example.com. TXT "v=spf1 mx -all" +``` +Everything after the version `v=spf1` is a list of *verification mechanisms* +for a spam filter to try out in the given order. +The `-all` at the end says to reject your email +if all of the previous mechanisms fail. +See the [SPF spec](https://tools.ietf.org/html/rfc7208) for details. + +I recommend only using the `mx` mechanism, which tells the verifier +to look at the A/AAAA addresses of the domains in your MX records. +This allows you to add, remove, or change your servers +without needing to update this record. + + + +### DKIM + +Then we have [DomainKeys Identified Mail](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) (DKIM), +which is a more comprehensive form of anti-impersonation, +and, like SPF, is practically **mandatory** in the modern era. + +It adds a cryptographic signature to all emails from your server, +which the receiver's spam filter will verify using the email's contents, +and a public key that you need to publish in a DNS record. +Again, you should implement *both* SPF and DKIM, despite their overlap. + +To set up DKIM, create an RSA keypair, using the `openssl` utility: +```sh +$ openssl genrsa -out /path/to/dkim/private.key 2048 +$ openssl rsa -in /path/to/dkim/private.key -out /path/to/dkim/public.key +``` +The minimum size is 1024 bits, but I recommend 2048 bits. +Bigger is better, but because DNS is involved you can't stretch it +to 4096 bits without causing discomfort to [some](https://serverfault.com/questions/747185/dkim-can-i-use-a-rsa-key-larger-than-2048bit-i-e-4096) servers. +And I think it goes without saying that you should keep the private key private. + +Importantly, the DKIM DNS record **cannot** be +attached directly to your domain `example.com`; +instead, it should belong to a subdomain of the form +`<selector>._domainkey.example.com`, +where `<selector>` is an alphanumeric string you can choose (e.g. today's date), +just remember your choice for later when configuring the DKIM signer. +And if you change your key, keep the old record around +for a while so old emails can still be verified. + +Your DKIM policy must be published in a TXT record +as follows, where `<pubkey>` is the public RSA key `MI...AB` +stored in `/path/to/dkim/public.key`, with the newlines removed: +``` +<selector>._domainkey.example.com. TXT "v=DKIM1; t=s; h=sha256; p=<pubkey>" +``` +Here, `v=DKIM1` is the version and must be the first tag. +The flag `t=s` enables strict mode, as recommended by the [DKIM spec](https://tools.ietf.org/html/rfc6376), +meaning that emails sent from subdomains immediately fail verification. +The optional tag `h=sha256` blocks the use of the old SHA1 algorithm. + + + +### DMARC + +Lastly, we have [Domain-based Message Authentication, Reporting and Conformance](https://en.wikipedia.org/wiki/DMARC) (DMARC), +which is *technically* optional, but *highly* recommended, +because it will make you look more legitimate in the eyes of Google and Microsoft. +It can modify the behaviour of SPF and DKIM, +and also provides advice about what a receiver should do +if one of your emails fails verification. + +To enable it, create yet another TXT record, which, +similarly to DKIM, **must** belong to the subdomain `_dmarc.example.com`, +and give it the following contents, +where `<admin>` is an email address of your choosing, +which may or may not belong to your domain: +``` +_dmarc.example.com. TXT "v=DMARC1; p=reject; sp=reject; pct=100; aspf=s; adkim=s; fo=1; ruf=mailto:<admin>" +``` +The version tag `v=DMARC1` must come first, +followed by `p=` and `sp=`, which control what to do to unverified messages +coming from the main domain and subdomains, respectively. +Unsurprisingly, `reject` means that delivery should be refused, +`none` asks to let it through anyway, and `quarantine` tells +the filter to take a closer look or to put it in a spam folder. +The percentage `pct=100` says how many of your emails to apply the policy to. +Next, `aspf=s` and `adkim=s` enable strict mode for both SPF and DKIM, +which blocks subdomains from passing the test. +Finally, `fo=1` asks the filter to create a forensic report +if any type of verification fails, and `ruf=` gives an address to send it to. +If in doubt, see the [DMARC spec](https://tools.ietf.org/html/rfc7489). + + + +## MDA: Dovecot + +[Dovecot](https://www.dovecot.org/) is a very popular IMAP server, +focused on being lightweight, simple, and secure, +and has extensive and up-to-date documentation. +It's very flexible and scalable, and keeps up well +with the lastest security best-practices. + +If you installed Dovecot via a package manager, +you'll probably have lots of configuration files +in the `/etc/dovecot` directory. +I want you to delete all of them. Yes, `rm -rf` that crap. +Dovecot is simple to configure, and doesn't care where +you put its settings, so having all that chaos in `/etc/dovecot` +just makes things unnecessarily confusing. + + + +### Network + +Create a new configuration file `/etc/dovecot/dovecot.conf`, +and start by filling in the details of your TLS certificate, +making clear that unencrypted connections are unacceptable: +```sh +ssl = required +ssl_cert = </etc/ssl/certs/example.com.pem +ssl_key = </etc/ssl/private/example.com.key + +ssl_min_protocol = TLSv1.2 +ssl_prefer_server_ciphers = yes + +disable_plaintext_auth = yes +``` +The final `disable_plaintext_auth` option tells Dovecot +to reject any passwords that were sent unencrypted. +This means it must be [hashed](https://en.wikipedia.org/wiki/Cryptographic_hash_function) +or sent over an encrypted connection, or both. + +Next, tell Dovecot which protocols to use +and where to expect them as follows: +```sh +protocols = lmtp imap + +service lmtp { + unix_listener lmtp { + user = vmail + group = vmail + } +} + +service imap-login { + inet_listener imap { + port = 143 + } + inet_listener imaps { + port = 993 + } +} +``` +LMTP is the Local Mail Transport Protocol, which is basically SMTP +but for exchanges within a single server or over a trusted network. +When an email is received, Dovecot will start a child process +under the `vmail` user/group to deliver the message to its recipient. + +Since we set `ssl = required` earlier, clients will only get their mail +if the STARTTLS handshake was successful during the IMAP exchange, +or if they connect via IMAPS to force the use of encryption. +You can therefore optionally remove one of the two +`inet_listener`s according to your preferences. + + + +### Users + +Next, we need to inform Dovecot which email addresses it should handle, +and what to do with their messages. Create a file `/etc/dovecot/users` for this, +which describes a user on each line in a similar format as `/etc/passwd`: +``` +user:password:uid:gid::homedir +``` +In this guide, we're using the `vmail` user for all accounts, +so leave the `uid`, `gid`, and `homedir` fields blank. +We'll be storing all emails in `vmail`'s home directory. +The `user` field should be the email address excluding the `@example.com` +(in fact, you *can* include it, but this guides assumes a small-scale +server managing only one domain, so we exclude it). +Create the password hash to put in the `password` field as follows: +```sh +# If your server is fast and has lots of RAM: +$ doveadm pw -s ARGON2ID-CRYPT +# If you're using a potato: +$ doveadm pw -s SHA512-CRYPT +``` +After you've entered your password, simply copy-paste the entire +hash string outputted by the program into the `password` field. + +Now, Dovecot needs a file describing user accounts on two separate occasions: +* To check whether a client logging into the IMAP server + is valid and has given the right password. + This is handled by the `passdb` block(s) in the configuration. +* To know which email addresses the server is responsible for. + This is given by the `userdb` block(s) in the configuration. + +These functions aren't necessarily fulfilled by the same `users` file: +you can map multiple email addresses to one acccount, +or multiple accounts to one email address. +For simplicity, though, we'll use the `users` file for both: +```sh +passdb { + driver = passwd-file + args = scheme=ARGON2ID-CRYPT username_format=%n /etc/dovecot/users + #args = scheme=SHA512-CRYPT username_format=%n /etc/dovecot/users +} + +userdb { + driver = passwd-file + args = username_format=%n /etc/dovecot/users + override_fields = uid=vmail gid=vmail home=/home/vmail/%n +} +``` +The `driver` option sets the kind of table Dovecot should expect. +We tell it to use a file in the `passwd`-like format described above, +but other possibilities include e.g. an SQL database. +The options available in `args` depend on the chosen `driver`. + +In the `passdb` block, the hashing algorithm is given by `scheme`, +while `username_format=%n` says that the `users` file +only contains `name` out of `name@example.com`. + +In the `userdb` block, we force the use of `vmail:vmail` +for all accounts, and tell Dovecot to put their data in `/home/vmail/%n`, +where `%n` means the address up until the `@`, so +e.g. mail to `name@example.com` is stored in `/home/vmail/name`. + +Now that Dovecot knows where to store messages, +we just need to specify in what format to store them: +```sh +mail_location = maildir:~/Maildir +``` +The two standard mailbox formats to choose from are `maildir` and `mbox`. +I highly recommend `maildir`; it's more modern than the ancient `mbox` format. +That `~/Maildir` says which subfolder to use. +Ensure that `/home/vmail` is owned by `vmail:vmail`, +so that Dovecot has write access. + + + +## MTA: OpenSMTPD + +[OpenSMTPD](https://opensmtpd.org/) is an MTA by the [OpenBSD](https://www.openbsd.org/) project, +who are known for their focus on security and minimalism. +Compared to other MTAs it's a joy to set up, thanks to +its intuitive configuration syntax and to-the-point manual. +This guide is for OpenSMTPD version 6.4 or newer: +older versions used a substantially different syntax. + +If you have any problems with OpenSMTPD, +take a look at the maintainer's [blog](https://poolp.org/), +which contains a lot of useful information, +and was a big help when writing this guide. + + + +### Users + +To begin, delete the contents of the `/etc/smtpd/aliases` file, +if it exists, which maps recipient addresses to system users. +In our case, we're using `vmail` for everyone, +and we'll let Dovecot manage the details by simply writing: +``` +@example.com vmail +``` +Then create a new file `/etc/smtpd/passwds` +and fill it in according to the following format: +``` +name@example.com <hash> +``` +Generate the password hash with this command for each user. +Be sure to use the same password for every account as in Dovecot: +```sh +$ smtpctl encrypt '<password>' +``` +Then, like with Dovecot, just delete the contents of +the main config file `/etc/smtpd/smtpd.conf`, +and start by putting in the following: +```sh +table aliases "/etc/smtpd/aliases" +table passwds "/etc/smtpd/passwds" +``` + + +### Network + +Write your domain name on a single line in `/etc/smtpd/mailname`. +This is the name that OpenSMTPD will use to introduce itself +to other servers, and it's important that this matches +the reverse DNS domain name of the server's IP: +```sh +example.com +# Or mx1.example.com or whatever +``` +Then continue in `/etc/smtpd/smtpd.conf` by importing your TLS certificate: +```sh +pki "prefet.ch" cert "/etc/ssl/certs/example.com.pem" +pki "prefet.ch" key "/etc/ssl/private/example.com.key" +``` +And tell OpenSMTPD which keys to use for the [Sender Rewriting Scheme](https://en.wikipedia.org/wiki/Sender_Rewriting_Scheme), +which prevents forwarded emails from breaking SPF and looking like spam: +```sh +srs key "<secret1>" +srs key backup "<secret2>" # optional, read below +``` +It's recommended to change the key every year or so, +but in that case you need to ensure that emails from the last month +can still be verified using the old one, so if you change it, +simply move it to the backup slot for a month. + +It's very important that the secrets can't be guessed, +otherwise *anyone* can send mail through your server, +so I recommend generating these keys randomly as follows: +```sh +$ head -c 30 /dev/urandom | base64 +``` +Next, define the spam filters as follows. +For the last line to work, you'll need to [download](https://github.com/poolpOrg/filter-rspamd) +and build the `filter-rspamd` adapter binary for yourself, +created by OpenSMTPD's official maintainer. +We'll set up the Rspamd service in the next section, +which will be responsible for spam filtering and DKIM signing: +```sh +filter "rdns" phase connect match !rdns disconnect "550 DNS error" +filter "fcrdns" phase connect match !fcrdns disconnect "550 DNS error" +filter "rspamd" proc-exec "/etc/smtpd/filter-rspamd" +``` +I cannot overstate the importance of the first two lines: +these will block hundreds of spam attempts, and have, +at least for me, never blocked anything legitimate so far. + +The only thing left to do here is to tell OpenSMTPD which ports to listen on +and what to do with the incoming traffic. +This comes in two parts: first, we listen on port 25 for incoming +messages for your domain coming from other email servers: +```sh +# Inbound +listen on eth0 port 25 tls pki "example.com" filter { "rdns", "fcrdns", "rspamd" } +action "RECV" lmtp "/var/run/dovecot/lmtp" rcpt-to virtual <aliases> +match from any for domain "example.com" action "RECV" +``` +Line 1 says to listen on `port 25` of interface `eth0`, +providing *optional* `tls` using the certificate for `example.com`, +and passing everything through the three filters definer earlier. +Making TLS mandatory is a **bad** idea here, because not all servers can use TLS. + +Line 2 defines an action called `RECV`, +which relays an email to Dovecot's LMTP socket, +with the `rcpt-to` and `virtual` making sure +that Dovecot will actually accept the message. + +Line 3 then simply says that any incoming mail +for your domain should have the action `RECV` applied to it, +unless the spam filters rejected it. + +Secondly, we listen on port 465 (SMTPS) +and/or port 587 (STARTTLS) for messages getting sent +from your email client to the rest of the world, +so we require user authentication: +```sh +# Outbound +listen on eth0 port 465 smtps pki "example.com" auth <passwds> filter "rspamd" +listen on eth0 port 587 tls-require pki "example.com" auth <passwds> filter "rspamd" +action "SEND" relay srs +match from any auth for any action "SEND" +``` +The only difference between lines 1 and 2 is the port and the protocol. +Both demand a mandatory TLS connection, and that users authenticate +themselves according to the password file created earlier. +The `filter` at the end is for DKIM signing of outgoing mail. + +Lines 3 and 4 are only triggered after successful `auth`entication, +and, unsurprisingly, `relay` the email to its destination. +The `srs` at the end enables using the SRS settings from earlier. + +OpenSMTPD is the only program in this setup that needs to handle +untrusted connections, when other MTAs send you messages. +Since, like most server software, it may have [vulnerabilities](https://opensmtpd.org/security.html), +it is **very** important that you keep it as up-to-date as possible. + + + +## Spam filter: Rspamd + +[Rspamd](https://www.rspamd.com/) is a modern spam filtering solution, +with many features that you could spend hours tweaking. +In this guide, however, we'll keep it short, +because we're only really interested in its ability add +our server's DKIM signature to outgoing messages. + +Besides, according to my limited experience, +for small-scale servers spam filtering isn't essential, +as long as you tell OpenSMTPD to check reverse DNS as described above. +However, there are some much more experienced people who disagree with me. + +Basically, for our purposes, don't touch any of Rspamd's default +configuration except for creating/editing the file +`/etc/rspamd/local.d/dkim_signing.conf` with the following contents, +where `<selector>` is the DKIM selector you chose in the DNS record: +```sh +allow_username_mismatch = true; + +domain { + example.com { + path = "/path/to/dkim/private.key"; + selector = "<selector>"; + } +} +``` +Make sure that the DKIM `private.key` file is +readable (and *only* readable) by `rspamd:rspamd`. + +And... that's it! Of course, don't forget to start all the necessary daemons. + + + +## Testing + +Everything is set up now, so it's time to test. Fingers crossed! + +As mentioned earlier, you can check the correctness +of your DNS using the [MX Lookup](https://mxtoolbox.com/MXLookup.aspx) tool. +You can use the same website to test OpenSMTPD +with the [SMTP Diagnostics](https://mxtoolbox.com/diagnostic.aspx) tool. + +All decent email clients include an option to set the server for an email account. +This guide excludes instructions for that, +because it will vary a lot from client to client. +If asked for your login type, choose plain/normal/unencrypted passwords. +Don't worry, the client-server connection is TLS-encrypted, +so nobody will be able to steal it. + +Next, to test sending and receiving messages, +use the aptly-named [Is my email working?](https://ismyemailworking.com/) website. +If everything is good so far, congratulations! + +Now comes the big scary final test: +sending an email to one of the "big guys", Google or Microsoft. +Their spam filters are very strict, so if you get through, great! +Because these companies probably use AI-powered account-aware filters, +you should *not* put anything identifiable in the test email. +For example, if your name is "John Smith", +do *not* put "John" nor "Smith" in the message, +and do *not* send it from an addres like `john.smith@example.com`. + +If something failed, then you have some investigating to do. +Either one of the daemons is misconfigured, or there's a problem +with your domain name and/or DNS records. +Do some research, and you'll get there, don't give up. + +But if everything works, congratulations! +You're now the proud administrator of a private email server. +Have fun with it, and don't forget to update your +TLS certificate and DKIM and SRS keys. + +PS: and please don't spam; you'll ruin it for everyone else. + |