Hi! This is my ansible playbook for self-hosting your own email, web hosting, XMPP chat,
Matrix Homeserver, Tiny Tiny RSS, Git repos, and and DNS records using OpenBSD.
I use it to host everything on c0ffee.net, but you can easily adapt
it for your own domain by setting a few variables in vars.yml
.
NEW: Read the changelog before running this playbook after updates! There are often breaking changes!!
- Configure a secondary DNS provider and set them as your nameservers at your registrar. Set up reverse DNS for your server.
./scripts/bootstrap_openbsd.sh
cp vars-sample.yml vars.yml && vi vars.yml
ansible-playbook site.yml
./scripts/ds_records.sh YOURDOMAIN
and set DS records at your registrar for DNSSEC.- Create your user account with
dankctl useradd
.
- You have a public-facing server (probably a VPS) running OpenBSD, with an IPv4 and IPv6 address. I recommend Vultr.
- You have your own domain name, and a registrar that supports DNSSEC. I recommend Namecheap.
- You have a secondary DNS provider that supports DNSSEC. I recommend DNS Made Easy. (Why do I need this?)
- You're crazy enough to run your own mail server :-)
-
A small and secure OpenBSD platform to host email, DNS, XMPP chat, Matrix, TTRSS, Git, and some web sites.
- Scale: you and your family members, and maybe a few technically oriented friends.
- Really not suited for the general public, no automated password reset, no web GUIs...
-
Use as much of the OpenBSD base system as possible:
- acme-client(1) for LetsEncrypt certificates
- smtpd(8) for mail handling
- spamd(8) for spam filtering
- nsd(8) for authoritative DNS server
- httpd(8) for web server
- ldapd(8) authentication for UNIX accounts and all services (except Matrix...I'm working on it!)
-
Of course, some packages from the ports tree will be necessary:
- nginx for TLS reverse proxy
- prosody for XMPP chat
- postgresql for Prosody data storage
- ldns-utils for DNSSEC zone signing
- dovecot for IMAP access
- dkimproxy for DKIM signing of outgoing mail
-
And some third-party projects not currently in packages:
- synapse for running your own Matrix homeserver
- Tiny Tiny RSS as a personal RSS aggregator
- Gitea for your Git repositiories.
-
Encryption Everywhere:
- Automated DNSSEC with
nsd
and cron tasks usingldns-signzone
for daily zone re-signing and slaveNOTIFYs
- TLS for all public-facing services using LetsEncrypt certificates with automated renewal and daemon reload hooks
- Automatic publishing of SSHFP records for authoritative SSH fingerprints
- Automatic publishing of TLSA records for DANE email encryption
- Automatic publishing of DKIM records for outgoing email verification
- Automated DNSSEC with
-
Keep it Simple
- Unopinionated baseline for what most people want from a personal domain
- Keep dependencies to a minimum and stick to UNIX conventions
- Automate the tedious stuff, so you can focus on hacking!
- Boot up your OpenBSD server.
- Create a user account for provisioning the system. Make sure to add the account to the
wheel
group. Don't use your preferred username for this account - save that for your LDAP username. - Run
scripts/bootstrap_openbsd.sh
as root to add a package repo URL and set up doas for your user (required for Ansible). - Configure your secondary DNS provider to accept
NOTIFYs
and perform zone transfers from your server's IP address. cp vars-sample.yml vars.yml
and edit the configuration to your liking.- Run the playbook!
ansible-playbook site.yml
- Ensure you have reverse DNS in place for your server's IP address. This is a critical step to avoid your outgoing mail being flagged as spam. At Vultr, this is configured under "Settings > IPv4". You should set one for your primary IPv6 address as well.
- The last step is to configure DS records for DNSSEC at your domain registrar. Run
scripts/ds_records.sh YOURDOMAIN
to generate the records. At Namecheap, this is configured under "Advanced DNS > DNSSEC" in the web portal. - Create your "real" user account in LDAP via
dankctl useradd your_username -c "Your Name" -G ssh,sudo -r admin -k "your ssh key"
- Yell at me via email, xmpp, or matrix when you inevitably find bugs in my code.
-
Login info: the credentials for SMTP (STARTTLS, port 587) and IMAP (SSL, port 993) are simply your username (without the @domain.com portion) and login password. XMPP uses the
[email protected]
syntax for logins, but the password is the same. Mail is stored under~/Maildir
in each user's home directory for easy access using local clients likemutt
. -
Email Filtering: any sieve script located at
~/.dovecot.sieve
will automatically apply filters to your incoming mail. You can compile the sieve script and check for syntax errors usingsievec ~/.dovecot.sieve
. For example, to filter all your cron emails into a folder calledLogs
:
require ["regex", "fileinto", "imap4flags", "mailbox", "envelope", "variables"];
if allof ( address :is "from" "[email protected]",
anyof ( header :contains "subject" "cron",
header :contains "subject" "output" )) {
fileinto :create "Logs";
stop;
}
-
XMPP Chat: the XMPP server, Prosody, is really slick. As configured here, it supports HTTP file upload for image sharing, delivery to multiple devices via carbons, push notifications, group chats, message history, and basically everything you'd expect from a modern chat solution. XMPP isn't all that bad! The best clients are ChatSecure for iOS, Conversations for Android, and Gajim for *nix and Windows. No decent clients for OS X, sadly. All those clients support end-to-end crypto via OMEMO. Easily federate with others on separate XMPP servers for truly decentralized, open communication!
-
Account Maintenance: to add, remove, and modify accounts and groups, use the
dankctl
command. It's help output should be quite self-explanatory. -
IPv6:
spamd
does not currently support IPv6, so don't go adding a AAAA record formail
in the zonefile! -
Monitoring spamd: just run
spamdb
to see a list of senders currently greylisted/whitelisted. -
Virtual Hosts: a default vhost will be created for
www.domain.com
, with a bare domain redirect. Shove HTML files into/var/www/htdocs/www.domain.com
to start sharing your worthless opinions with the internet! To add more vhosts, just put a configuration file in/etc/sites
and include it in/etc/httpd.d/sites.conf
. -
Greylisting pitfalls:
spamd
works by greylisting. Unfortunately, big mailers like GMail often don't retry delivery from the same address, resulting in a greylist black hole described here. To alleviate this, I included a daily cron job that whitelists the IP addresses found in the SPF records for some of the big mailers like GMail and Yahoo. If you notice any other problematic domains, override the to thebigmailers
list defined in roles/spamd/deaults/main.yml to have their IP ranges whitelisted. (And be sure to send me a pull request!) -
Password Resets: Passwords can be reset using
dankctl resetpass
. Currently, only an administrator can do this, since giving users write access to their LDAP user entry could allow them to write a non-hashed password into theiruserPassword
field. It's on my todo list to make some kind of web interface for this. -
SSH: SSH keys are stored in LDAP and can be added/removed using
dankctl usermod
. If a user has a shell on the box, he can run this command with his own credentials. Users must be in thessh
group to connect. -
Backups: another thing I'm leaving up to you, since your requirements will almost certainly be unique. Shouldn't be too difficult:
- Maildirs: tar them up, maybe encrypt them, and scp them offsite periodically.
- User accounts: back up
/etc/{passwd,master.passwd,group}
- Backup MX records: I don't bother with a backup MX. They are a massive target for spammers, and legit mail servers will keep retrying delivery for multiple days if your primary MX goes down.
- Prosody: periodically tar up the HTTP upload dir and do a
pg_dump
to save user info and message archives. - Keys: tar up your DNSSEC keys (
/var/nsd/keys
) and DKIM keys (/etc/mail/dkim
) - LDAP: you can either tar up
/var/db/ldap
or save the output ofldap search
as the root DN. - Assuming you copy all these items back to their original locations, the playbook won't generate new keys if they already exist.
-
How to Run Your Own Mail Server: my original email guide. Written for FreeBSD, but still lots of great info about mail hosting. HN Discussion
-
DNS Hosting Guide: Hidden Master with DNSSEC: my original guide for running your own DNS. Again, written for FreeBSD, but gives a lot of details about why you'd want a hidden master setup.