mkhost 0.12: your own mail server, done right
Email is the closest thing we have to a universal identity layer for the internet. It is how you sign up, sign in, reset, verify, and prove you are you. In email we trust — it is the ultimate distributed social network, older than the web and woven right into the fabric of the internet, and unlike every walled garden that came after it, nobody owns it. mkhost is about claiming your slice of that: your personal mail server, on your box, under your control.
And today it gets a lot better. mkhost 0.12 is out, and it is the strongest release yet.
mkhost turns a fresh Debian box into a real, production-grade mail server: Postfix, Dovecot, OpenDKIM, Let's Encrypt and the DNS records to tie them together, all from a single configuration file. You describe the mail server you want in mkhost/cfg.py, run mkhost.py reconfigure, and the machine becomes exactly that. Declarative, idempotent, and dependency-free — standard library only, plus the trusty UNIX tools it was always going to call. Ultimate flexibility, zero magic.
Reconfigure with total confidence
The headline of 0.12 is trust. When you run mkhost, you now know precisely what it will do — before it does it.
mkhost.py reconfigure --dry-run shows you the full plan and changes nothing at all: not a file, not a service, not a byte. When you are ready, the real run applies that plan and every generated file lands atomically — written aside, then swapped into place in one motion, with the previous version tucked away as a .bak. Ownership and permissions are re-asserted on every run, output is byte-for-byte deterministic, and anything you hand-added to a config file is preserved, not clobbered. Run it once, run it a hundred times: you converge on the same clean state every time. That is what idempotent should feel like.
Spam stops at the door
0.12 puts a proper bouncer on port 25. mkhost now turns away mail from hosts and domains that Spamhaus flags — the IP blocklist (ZEN) checks the sender's address, and the domain blocklist (DBL) checks the sender domain, the HELO name and the reverse DNS. Known-bad senders get a 554 and never make it into your mailbox.
Crucially, it does this the right way. mkhost rejects only on genuine listings (zen.spamhaus.org=127.0.0.[2..11]), so legitimate mail always flows — the blocklist protects you without ever getting in your way. And because a blocklist is only as good as the resolver behind it, mkhost probes yours on every run and tells you, in plain language, if it needs your attention. Set it up, and let the noise bounce off.
Your configuration, validated before it ships
mkhost reads your intent and checks it makes sense before touching production. It maps your mail-forwarding graph and refuses to deploy a loop before it can bite. It confirms that the addresses you publish — DMARC reports, the certificate contact, the aliases in /etc/aliases — actually land somewhere real. Mistakes get caught at plan time, on your terms, instead of at 3 a.m. as a bounce storm.
Secure and DKIM-signed by default
Every message your server sends goes out DKIM-signed, so the rest of the internet trusts it too. The private signing keys — the crown jewels — are locked down to the OpenDKIM user alone (0600, in a directory the world cannot even peek into). Mailbox passwords are generated strong by default, and you can dial the length up, never down past a sane floor. Sensible security, out of the box, with nothing to remember.
A command line that respects you
Run mkhost.py with no arguments and it does the safe thing: it prints help and waits. The machine only changes when you say so, with an explicit reconfigure. Want to look before you leap? mkhost.py show-config lays out the fully resolved configuration; every option lives in one flat --help, no hunting. It is a tool that assumes you are in charge — because you are.
Even the DNS story is smoother: mkhost checks which records you have already published and shows you only what is left to do, counted up front ("List of 14 DNS changes to apply"). Copy, paste, done.
Flexible enough for the real world
Running Mailman virtual hosts alongside your mail? The EXTRA_VIRTUAL_DOMAINS hook has you covered, and in 0.12 each domain can carry both its certificate contact and its own DMARC report address:
| mkhost/cfg.py | |
|---|---|
1 2 3 4 | |
Reports land where a human (or a machine) will actually read them. Little touches like this are the whole point: mkhost bends to your setup, not the other way round.
Built to last
Under the hood, mkhost 0.12 is a proper, well-tended project: an importable entry point, a pytest suite guarding the parsing and file-handling logic, a pyproject.toml, and a GitLab CI pipeline that lints and tests on Debian stable for every change. Solid foundations for the mail server your digital life runs on.
Take the wheel
Point mkhost at a fresh Debian box, describe the server you want, and run it. In a few minutes you have a self-hosted, spam-filtering, DKIM-signing, TLS-secured mail server that answers to you and nobody else. Reclaim your corner of the fabric of the internet — and enjoy the ride.
Grab it, read the README, and go. mkhost is free software under the Apache 2.0 licence.

