diff --git a/content/blog/mail_server_alpine_postfix_dovecot_tutorial.md b/content/blog/mail_server_alpine_postfix_dovecot_tutorial/index.md
similarity index 75%
rename from content/blog/mail_server_alpine_postfix_dovecot_tutorial.md
rename to content/blog/mail_server_alpine_postfix_dovecot_tutorial/index.md
index 6e9394d..21240ea 100644
--- a/content/blog/mail_server_alpine_postfix_dovecot_tutorial.md
+++ b/content/blog/mail_server_alpine_postfix_dovecot_tutorial/index.md
@@ -782,6 +782,292 @@ With our setup, we are also able to use STARTTLS on port 143 (incoming) and 587
You should be able to send and receive emails as normal now.
+# Set up SPF, DKIM, and DMARC
+
+SPF, DKIM, and DMARC records are TXT DNS records that
+protect against people spoofing your domain. Having correctly configured SPF, DKIM, and DMARC records helps your mail
+avoid getting caught by spam filters.
+
+SPF records indicate which hosts or IP addresses are allowed to send email from your domain.
+
+DKIM digitally signs emails with a private key to verify that they came from your server. If someone else without your
+private key sends email from your domain, they wouldn't be able to produce a valid DKIM signature. DKIM public keys are
+published in TXT DNS records, so that any other mail server can verify a signature of an email from your domain.
+
+DMARC records state that your domain uses SPF and DKIM, and that emails sent from your domain should pass SPF and DKIM
+checks.
+
+## Sender Policy Framework
+
+Add a TXT record for your root domain with the contents `v=spf1 mx ~all`, like:
+
+```dns
+revsuine.xyz. 900 IN TXT "v=spf1 mx ~all"
+```
+
+In your DNS manager, you would enter:
+
+
+
+
+
+ Name |
+ @ |
+
+
+ Type |
+ TXT |
+
+
+ TTL |
+ Default (mine is 900) |
+
+
+ TXT data |
+ v=spf1 mx ~all |
+
+
+
+This is assuming you're sending emails from `domain.com` instead of, e.g. `sub.domain.com`. If your email addresses are
+like `user@sub.domain.com`, you would use `sub` as the name in the DNS record instead of `@`, which denotes the apex
+domain. The same applies for all the DNS records in this section.
+
+Breaking down the TXT data:
+
+
+
+
+
+ Part |
+ Explanation |
+
+
+ v=spf1 |
+ This is an SPF record, and the SPF record version is SPF1. |
+
+
+ mx |
+ All hosts listed in MX records are allowed to send emails from this domain. |
+
+
+ ~all |
+
+ Emails from your domain should only come from hosts specified by your SPF record. Can also be
+ +all , -all , ?all , but those are rarely used. -all means
+ that emails not from SPF-approved hosts should be rejected; however, this option can cause valid emails to
+ be rejected if the recipient has multiple SMTP servers, and an email is relayed from one of their SMTP
+ servers to another, for instance if one SMTP server goes down and they have a backup server.
+ |
+
+
+
+## DomainKeys Identified Mail
+
+### Configure OpenDKIM
+
+OpenDKIM is an open-source implementation of DKIM signing and authentication. You can install it with:
+
+ # apk add opendkim opendkim-utils
+
+You may also want `opendkim-doc` for documentation.
+
+Add the `postfix` user to the `opendkim` group:
+
+ # adduser postfix opendkim
+
+Edit your OpenDKIM config file at `/etc/opendkim/opendkim.conf`. Ensure the following is present (`Canonicalization` is
+likely already there, so just change and uncomment things, and add lines where necessary):
+
+```conf
+Canonicalization relaxed/simple
+Mode sv
+SubDomains no
+AutoRestart yes
+AutoRestartRate 10/1M
+Background yes
+DNSTimeout 5
+SignatureAlgorithm rsa-sha256
+```
+
+Add the following to the config file:
+
+```conf
+# OpenDKIM user
+# Remember to add user postfix to group opendkim
+UserID opendkim
+
+# Map domains in From addresses to keys used to sign messages
+KeyTable refile:/etc/opendkim/key.table
+SigningTable refile:/etc/opendkim/signing.table
+
+# Hosts to ignore when verifying signatures
+ExternalIgnoreList /etc/opendkim/trusted.hosts
+
+# A set of internal hosts whose mail should be signed
+InternalHosts /etc/opendkim/trusted.hosts
+```
+
+Create a directory for OpenDKIM's keys at `/etc/opendkim/keys/`, and ensure the directory is owned by `opendkim` and
+that no one else has read or write access to the keys directory:
+
+ # mkdir /etc/opendkim/keys
+ # chown -R opendkim:opendkim /etc/opendkim
+ # chmod go-rw /etc/opendkim/keys
+
+Create `/etc/opendkim/signing.table` and set its contents to the following:
+
+```
+*@domain.com default._domainkey.domain.com
+*@*.domain.com default._domainkey.domain.com
+```
+
+This tells OpenDKIM to use your domain's private key to sign any emails originating from `domain.com` and its
+subdomains. Replace `domain.com` with your domain.
+
+Now create `/etc/opendkim/key.table` and set its contents to:
+
+```
+default._domainkey.domain.com domain.com:default:/etc/opendkim/keys/domain.com/default.private
+```
+
+Replacing `domain.com` with your domain. This tells OpenDKIM where your private key is stored.
+
+Create `/etc/opendkim/trusted.hosts` and set its contents to
+
+```
+127.0.0.1
+localhost
+
+.domain.com
+```
+
+Similarly, replace `domain.com` with your domain.
+
+### Generate your keys
+
+Create a directory for your domain's keys at `/etc/opendkim/keys/domain.com`. Use `opendkim-genkey` to generate your
+keys:
+
+ # opendkim-genkey -b 2048 -d domain.com -D /etc/opendkim/keys/domain.com -s default -v
+
+Replace `domain.com` with your domain.
+
+Set the owner and permissions of the private key so that only `opendkim` has read and write access to it:
+
+ # chown opendkim:opendkim /etc/opendkim/keys/domain.com/default.private
+ # chmod 600 /etc/opendkim/keys/domain.com/default.private
+
+### Publish your public key in your DNS records
+
+Look at your public key:
+
+ # cat /etc/opendkim/keys/domain.com/default.txt
+
+You'll see something like this:
+
+```
+default._domainkey IN TXT ( "v=DKIM1; k=rsa; "
+ "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu7QJxihVsEGhsZBLMxGKCVecIhjINp/zMGH0ExHN5QelxRIKdAHpJ33cZUBEsL0H27/4E8BK9RZ4AOaDMHfIGJ9FybyyD+gHhvKFFHzyts0QpkwLV+3bApsMqSR4ZsSzt3pZvRhQrXaoUds+9CyQBuEGx16PcA2O04/vWlvWhwStJrZWWHDYl2PX3QHfFFSsJaTsiFMwnMECvg"
+ "a6TdBTcsbcHwfedkoeMv5RQFlKisqCEiJkUYbJaczDA88fcZm21eGW8HiCSwq3324ExfWSwPGVsXAn1Blq/oKklpjXQIwwrphglK//G6AF7M3AAfqBdCvUbkAjs28fJwGqiVxaCwIDAQAB" ) ; ----- DKIM key default for revsuine.xyz
+```
+
+This is what your DNS record should look like. Copy **everything between the brackets** and add it to your DNS record:
+
+
+
+
+
+ Name |
+ default._domainkey |
+
+
+ Type |
+ TXT |
+
+
+ TTL |
+ Default value (mine is 900) |
+
+
+ TXT data |
+
+ What you copied from between the brackets, with all double quotes and extra whitespace (beyond a single
+ space character) removed
+ |
+
+
+
+So with the above public key, my DNS record is
+
+```dns
+default._domainkey.revsuine.xyz. 900 IN TXT (
+ "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQ"
+ "EFAAOCAQ8AMIIBCgKCAQEAu7QJxihVsEGhsZBLMx"
+ "GKCVecIhjINp/zMGH0ExHN5QelxRIKdAHpJ33cZU"
+ "BEsL0H27/4E8BK9RZ4AOaDMHfIGJ9FybyyD+gHhv"
+ "KFFHzyts0QpkwLV+3bApsMqSR4ZsSzt3pZvRhQrX"
+ "aoUds+9CyQBuEGx16PcA2O04/vWlvWhwStJrZWWH"
+ "DYl2PX3QHfFFSsJaTsiFMwnMECvg a6TdBTcsbcH"
+ "wfedkoeMv5RQFlKisqCEiJkUYbJaczDA88fcZm21"
+ "eGW8HiCSwq3324ExfWSwPGVsXAn1Blq/oKklpjXQ"
+ "IwwrphglK//G6AF7M3AAfqBdCvUbkAjs28fJwGqi"
+ "VxaCwIDAQAB"
+ )
+```
+
+and what I entered into the data field of my DNS manager when adding the record was
+
+```
+v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu7QJxihVsEGhsZBLMxGKCVecIhjINp/zMGH0ExHN5QelxRIKdAHpJ33cZUBEsL0H27/4E8BK9RZ4AOaDMHfIGJ9FybyyD+gHhvKFFHzyts0QpkwLV+3bApsMqSR4ZsSzt3pZvRhQrXaoUds+9CyQBuEGx16PcA2O04/vWlvWhwStJrZWWHDYl2PX3QHfFFSsJaTsiFMwnMECvg a6TdBTcsbcHwfedkoeMv5RQFlKisqCEiJkUYbJaczDA88fcZm21eGW8HiCSwq3324ExfWSwPGVsXAn1Blq/oKklpjXQIwwrphglK//G6AF7M3AAfqBdCvUbkAjs28fJwGqiVxaCwIDAQAB
+```
+
+You can now test your DKIM key with:
+
+ # opendkim-testkey -d domain.com -s default -vvv
+
+Don't worry about
+
+```
+opendkim-testkey: key not secure
+```
+
+This just means that DNSSEC isn't enabled for your domain name.
+
+### Use OpenDKIM with Postfix
+
+You can use a Unix socket for this, but I couldn't get the Unix socket to work, so I'll show you how to connect Postfix
+to OpenDKIM using a TCP/IP socket on port 8891 instead.
+
+Edit your OpenDKIM config `/etc/opendkim/opendkim.conf`, and ensure that the following line is present:
+
+```conf
+Socket inet:8891@localhost
+```
+
+Also make sure there are no other uncommented `Socket` lines.
+
+Now configure Postfix at `/etc/postfix/main.cf`, and add the following lines:
+
+```conf
+milter_default_action = accept
+milter_protocol = 6
+smtpd_milters = inet:127.0.0.1:8891
+non_smtpd_milters = $smtpd_milters
+```
+
+This uses the Milter extension, which is something that can be used to process mail; in this case, to add headers to
+emails relating to DKIM.
+
+
+
+### Test SPF, DKIM, and DMARC
+
+You can use [mail-tester.com](https://www.mail-tester.com/) and send an email from your domain to check that SPF, DKIM,
+and DMARC are all working for your server.
+
+![Screenshot of mail-tester.com authentication results passing all checks](mail-tester_auth_results.png)
+
[^server_trust]: This is only true to the extent that your server is not compromised. You could say there's an order of
diff --git a/content/blog/mail_server_alpine_postfix_dovecot_tutorial/mail-tester_auth_results.png b/content/blog/mail_server_alpine_postfix_dovecot_tutorial/mail-tester_auth_results.png
new file mode 100644
index 0000000..fc95125
Binary files /dev/null and b/content/blog/mail_server_alpine_postfix_dovecot_tutorial/mail-tester_auth_results.png differ