I’ve been using my own personal email server for the last week.
These are my notes, inspired by Luke’s Smith emailwiz script.
Requirements
To setup your own email server you need to:
- Investigate first to know what your getting into. See my research references 1 2 3 4 5
- A domain name
- A server to host your mail
Server setup
I’ll be using Vultr to setup my email server.
You can get 100$ credit by using Luke Smith’s reference link. You can find it in his video description.
I chose a Debian 10 Cloud Compute machine in New York whith a 10 GB SSD, 1 CPU, 512MB of Memory and 500GB Bandwidth, for $3.50/month. Don’t forget to enable IPv6.
Make sure the 25, 933 and 587 ports are open. In the case of Vultr you must open a ticket and ask for it, because port 25 is closed.
In Vultr you can also setup a firewall. Make sure to open the 25, 933 and 587 ports and the 22 port for ssh.
Domain name
My domain name provider is Namecheap.
I’m using a ‘mail’ sub-domain. This way my setup is using ‘mail’ as the Host in the DNS records, instead of ‘@’.
The difference is that I’ll be accessing my email server using ‘mail.mydomain.com’ instead of just ‘mydomain.com’. The reason is the fact that I’m already using ‘mydomain.com’ with another server.
Setup two A records with your server IPv4 address and two AAA records with your server IPv6 address.
Type | Host | Value |
---|---|---|
A Record | 10.11.12.13 | |
A Record | www.mail | 10.11.12.13 |
AAAA Record | 1234:aaaa:0:12ab:1111a:bcd:ffff:4444 | |
AAAA Record | www.mail | 1234:aaaa:0:12ab:1111a:bcd:ffff:4444 |
Also, add a MX record for your mail. Even if you are using ‘mydomain.com’ to point to the server, use ‘mail.mydomain.com’ in the MX record.
Type | Host | Value | Priority |
---|---|---|---|
MX Record | @ | mail.mydomain.com. | 10 |
Accessing your server
You can access your server with ssh.
ssh root@mail.mydomain.com
Copy your ssh key to the server so you don’t need to write your password every time.
ssh-copy-id root@mail.mydomain.com
Now disable password access with ssh. This way only from your computer, with your private key your can access the server.
vim /etc/ssh/sshd_config
Make sure ‘UsePAM’ and ‘PasswordAuthentication’ are set to ’no’
UsePAM no
PasswordAuthentication no
Restart ‘sshd’:
systemctl reload sshd
Server setup and install needed software
Upgrade Debian:
apt update && apt upgrade
Some ‘.bashrc’ configuration:
vim .bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.
# Note: PS1 and umask are already set in /etc/profile. You should not
# need this unless you want different defaults for root.
PS1='${debian_chroot:+($debian_chroot)}\h:\w\$ '
umask 022
# You may uncomment the following lines if you want `ls' to be colorized:
# export LS_OPTIONS='--color=auto'
# eval "`dircolors`"
alias ls='ls $LS_OPTIONS'
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'
#
# Some more alias to avoid making mistakes:
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
set -o vi
TERM=xterm
Install ’nginx’ and ‘python-certbot-nginx’:
apt install nginx python-certbot-nginx
nginx setup
Configure your ‘mail.mydomain.com’ sub-domain:
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/mail
vim /etc/nginx/sites-available/mail
server {
listen 80 ;
listen [::]:80 ;
root /var/www/mail;
index index.html index.htm index.nginx-debian.html;
server_name mail.mydomain.com www.mail.mydomain.com;
location / {
try_files $uri $uri/ =404;
}
Enabling:
ln -s /etc/nginx/sites-available/mail /etc/nginx/sites-enabled/
systemctl reload nginx
Create a certificate with certbot
Easy as:
certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): me@mydomain.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: mail.mydomain.com
2: www.mail.mydomain.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):
Obtaining a new certificate
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/mail
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/mail
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://mail.mydomain.com
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=mail.mydomain.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Setup the mail server
Here’s where Luke Smith’s script enters.
curl -LO lukesmith.xyz/emailwiz.sh
sh emailwiz.sh
In the end the script outputs 3 TXT record lines. You should now configure these records in your domain.
Type | Host | Value |
---|---|---|
TXT Record | @ | v=spf1 mx a:mail.mydomain.com -all |
TXT Record | _dmarc | v=DMARC1; p=reject; rua=mailto:dmarc@mydomain.com; fo=1 |
TXT Record | mail._domainkey | v=DKIM1; k=rsa; p=XXXXXXX…… |
2021-06 Update: for the SPF record, I had to change it to the following to work.
Type | Host | Value |
---|---|---|
TXT Record | @ | v=spf1 a mx ~all |
Create user mailboxes
Just create a user in the system:
useradd -G mail -m me
passwd me
This will create a me@mydomain.com email.
You can also create alias:
vim /etc/aliases
dmarc: me
mail: me
newaliases
This will delivery mails to dmarc@mydomain.com and mail@mydomain.com to your me@mydomain.com email.
Mail Clients
I’m using Thunderbird and K9 in Android.
Setup for a me@mydomain.com email:
Incoming | Outgoing | |
---|---|---|
Protocol | IMAP | SMTP |
Server | mail.mydomain.com | mail.mydomain.com |
Port | 993 | 587 |
SSL | SSL/TLS | STARTTLS |
Authentication | Normal password | Normal password |
Username | me | me |
Testing your new server
Check these sites to test if anything is wrong:
Also send an email to a gmail account to see your you’re going directly to Spam. It can happen, it’s just something you (and the people you will be sending emails) will have to live with.
Setting up backups
Check my BorgBackup posts for more info, but basically:
apt install borgbackup
ssh-keygen -o -a 100 -t ed25519
cat /root/.ssh/id_ed25519.pub
Add your key in BorgBase (Account > SSH Keys), create a new Repository and associate your SSH Key.
borg init --encryption=repokey-blake2 xxxx@xxxx.repo.borgbase.com:repo
echo "New backup"
borg create --list --progress --info --log-json --json --filter=AM -C lz4 --exclude '/root/.ssh/' xxxx@xxxx.repo.borgbase.com:repo::RepoName-{now:%Y-%m-%dT%H:%M:%S} /etc /var /root /opt /usr /boot /home/
echo "Prune"
borg prune -v --list --stats --keep-within=10d --keep-weekly=4 --keep-monthly=6 --keep-yearly=2 xxxx@xxxx.repo.borgbase.com:repo
-
https://sealedabstract.com/code/nsa-proof-your-e-mail-in-2-hours/ ↩︎
-
https://www.paritybit.ca/blog/a-month-and-a-half-of-self-hosted-email ↩︎
-
https://arstechnica.com/information-technology/2014/02/how-to-run-your-own-e-mail-server-with-your-own-domain-part-1/2/ ↩︎
-
https://blog.paranoidpenguin.net/2020/02/self-hosting-email-in-2020-joe-nobody-vs-world/ ↩︎