Home fit for a mailbox
This is a follow up (part 8) to Sent from my terminal.
Typically, you would build a mailbox to make it easier to communicate to and from your home. Here, I've build this website as a home for my mailbox.
The Minimum viable email service I have been working on now has a new home and a new name to go with it: the basic echo.ls email service (BEES). Since I went through the effort of re-deploying everything, I figured I may as well document the process. Although the instruction set below is specific to my server, it can be easily generalized for any aspiring email-preneurs.
How to deploy an email server
- Obtain a server that can serve on ports :25, :110, and :587 (many VPS providers block these ports to prevent spam and domain reputation harm)
- Replace hardcoded values (particularly
echo.lsininclude/config.h) - Clone the repo to your server at
/opt/bees/ - Build:
make clean all - (Optional) Test:
make test Add local users
Write a new line to
local_users.txtfor each user in the format of[username]:[password].Generate self trusted cert
openssl req -x509 -newkey rsa:2048 \ -keyout tls_key.pem \ -out tls_cert.pem \ -days 365 \ -nodes \ -subj "/CN=mail.echo.ls"
Generate DKIM key
openssl genrsa -out dkim_private.pem 2048 openssl pkey -in dkim_private.pem -pubout -out dkim_public.pem
Generate SPF, DKIM, and DMARC records
sh ./scripts/print_mail_dns_records.sh
- Set SPF, DKIM, and DMARC records for your domain's DNS (from previous step)
Set A and MX record for your domain's DNS
mail.echo.ls. 60 IN A 96.126.120.46
and
echo.ls. 600 IN MX 10 mail.echo.ls.
Make sure to use your server's public IP address for the A record.
- Set a PTR (rDNS) record with your hosting provider
Setup systemd service to run the server
Put this file in
/etc/systemd/system/bees.service:[Unit] Description=BEES service # wait for networking Wants=network-online.target After=network-online.target [Service] Type=simple # working directory and executable path WorkingDirectory=/opt/bees ExecStart=/opt/bees/build/bees # restarts Restart=on-failure RestartSec=5 [Install] # start on boot WantedBy=multi-user.target
- Reload systemctl:
systemctl daemon-reload - Restart BEES:
systemctl restart bees - (Optional) Check service status:
systemctl status bees - (Optional) Check logs:
journalctl -u bees -f (Optional) Setup mpop as a POP3 client
Write config to
~/.mpoprc:defaults tls on tls_trust_file [local path to tls_cert.pem, required for TLS with self-signed cert] auth user account [username] host mail.echo.ls port 110 user [username] password [password] delivery maildir ~/Maildir keep on account default : [username]
(Optional) Setup msmtp as a SMTP client
Write config to
~/.msmtprc:account [username] host mail.echo.ls port 587 from [username]@echo.ls auth on user [username] password [password] tls on tls_starttls on tls_trust_file [local path to tls_cert.perm] account default : [username]
(Optional) Setup client cron job to autofetch mail
Open cron job editor (
crontab -e) then add the following to runmpoponce ever five minutes:*/5 * * * * /usr/bin/mpop >/dev/null 2>&1
(Optional) Send an email
echo "Subject: Test\n\nHello world" | msmtp alice@echo.ls
Last updated May 16, 2026