selfhosting-blogposts/mail2/index.md

301 lines
13 KiB
Markdown

---
search:
exclude: true
---
# emailwiz Setup
![](0.png)
In this tutorial we're going to setup a self hosted mail server using lukesmith's [emailwiz.sh](https://github.com/LukeSmithxyz/emailwiz/blob/master/emailwiz.sh) script:
## **Initial Setup**
First step is, get a VPS on [vultr.com](https://vultr.com/), and ssh to it after you've setup an A record to it, for me it's **mail.void.yt**
[ 10.66.66.2/32 ] [ /dev/pts/37 ] [~]
→ ssh root@mail.void.yt
Welcome to Ubuntu 21.10 (GNU/Linux 5.13.0-20-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sun Oct 31 01:36:43 PM UTC 2021
System load: 0.04 Processes: 143
Usage of /: 10.3% of 54.41GB Users logged in: 0
Memory usage: 11% IPv4 address for enp1s0: 45.32.9.224
Swap usage: 0%
0 updates can be applied immediately.
Last login: Sun Oct 31 13:34:04 2021 from 78.141.239.68
root@mail:~# apt update -y ; apt upgrade -y ; apt install vim tmux curl certbot python3-certbot-nginx nginx -y
root@mail:~# curl -LO lukesmith.xyz/emailwiz.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 178 100 178 0 0 221 0 --:--:-- --:--:-- --:--:-- 221
100 154 100 154 0 0 104 0 0:00:01 0:00:01 --:--:-- 104
100 12137 100 12137 0 0 7122 0 0:00:01 0:00:01 --:--:-- 455k
root@mail:~# chmod +x emailwiz.sh
root@mail:~# systemctl disable --now ufw
Now before we continue, let's update the DNS and Reverse DNS:
![](1.png) ![](2.png)
if you're confused about the MX record, here it is (do not forget the trailing dot at the end):
![](3.png)
Once that's done, make sure the DNS record points to your VPS:
root@mail:~# curl ifconfig.me ; echo; echo; nslookup mail.void.yt
45.76.133.0
Server: 108.61.10.10
Address: 108.61.10.10#53
Non-authoritative answer:
Name: mail.void.yt
Address: 45.76.133.0
Name: mail.void.yt
Address: 2001:19f0:7001:4de1:5400:3ff:fea6:e93f
Name: mail.void.yt
Address: 2001:19f0:7002:e3c:5400:3ff:fea7:8e7
Name: mail.void.yt
Address: 2001:19f0:7401:85a0:5400:3ff:fea7:20d2
Name: mail.void.yt
Address: 2001:19f0:7402:2c6:5400:3ff:fea7:22a3
Then we're going to setup a basic nginx website along with a free TLS certificate using certbot:
root@mail:~# vim /etc/nginx/sites-available/default
root@mail:~# cat /etc/nginx/sites-available/mail.void.yt.conf
server {
listen 80;
listen [::]:80 ;
root /var/www/mail;
index index.html;
server_name mail.void.yt;
location / {
try_files $uri $uri/ =404;
}
}
root@mail:~# mv /etc/nginx/sites-available/default /etc/nginx/sites-available/mail.void.yt.conf
root@mail:~# rm -rf /etc/nginx/sites-enabled/default
root@mail:~# ln -s /etc/nginx/sites-available/mail.void.yt.conf /etc/nginx/sites-enabled/mail.void.yt.conf
root@mail:~# systemctl restart nginx
root@mail:~# systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-10-31 19:19:48 UTC; 1s ago
Docs: man:nginx(8)
Process: 2211 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Process: 2212 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Main PID: 2213 (nginx)
Tasks: 2 (limit: 2340)
Memory: 2.5M
CPU: 23ms
CGroup: /system.slice/nginx.service
├─2213 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
└─2215 nginx: worker process
Oct 31 19:19:48 mail systemd[1]: Starting A high performance web server and a reverse proxy server...
Oct 31 19:19:48 mail systemd[1]: nginx.service: Failed to parse PID from file /run/nginx.pid: Invalid argument
Oct 31 19:19:48 mail systemd[1]: Started A high performance web server and a reverse proxy server.
root@mail:~# cat /etc/nginx/sites-available/mail.void.yt.conf
root@mail:~# mkdir /var/www/mail/
root@mail:~# echo 'Welcome to mail.void.yt !' > /var/www/mail/index.md
root@mail:~# curl mail.void.yt
Welcome to mail.void.yt !
` ![](16.png)
And when we check the website, it says that it is secured via Letsencrypt!
![](17.png)
Now let's run luke's emailwiz.sh script:
root@mail:~# sh emailwiz.sh
Installing programs...
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
cpp cpp-11 dns-root-data dovecot-core fontconfig-config fonts-dejavu-core gcc gcc-11 libasan6 libatomic1 libauthen-sasl-perl libc-dev-bin libc-devtools libc6-dev libcc1-0 libclone-perl libcommon-sense-perl libcrypt-dev
libcrypt-openssl-bignum-perl libcrypt-openssl-random-perl libcrypt-openssl-rsa-perl libdeflate0 libdigest-bubblebabble-perl libdigest-hmac-perl libencode-locale-perl libexttextcat-2.0-0 libexttextcat-data libfontconfig1
libgcc-11-dev libgd3 libgomp1 libhtml-parser-perl libhtml-tagset-perl libhttp-date-perl libhttp-message-perl libidn11 libio-html-perl libio-socket-inet6-perl libio-socket-ssl-perl libisl23 libitm1 libjbig0 libjpeg-turbo8
libjpeg8 libjson-perl libjson-xs-perl liblsan0 liblua5.1-0 liblua5.3-0 liblwp-mediatypes-perl libmail-authenticationresults-perl libmail-dkim-perl libmail-spf-perl libmailtools-perl libmemcached11 libmilter1.0.1 libmpc3
libnet-dns-perl libnet-dns-sec-perl libnet-ip-perl libnet-libidn-perl libnet-smtp-ssl-perl libnet-ssleay-perl libnetaddr-ip-perl libnsl-dev libopendbx1 libopendbx1-sqlite3 libopendkim11 libperl4-corelibs-perl libquadmath0
librbl1 libsocket6-perl libsodium23 libsys-hostname-long-perl libtiff5 libtimedate-perl libtirpc-dev libtsan0 libtypes-serialiser-perl libubsan1 libunbound8 liburi-perl libvbr2 libwebp6 libxpm4 linux-libc-dev make
manpages-dev opendkim-tools perl-openssl-defaults re2c rpcsvc-proto sa-compile ssl-cert
Suggested packages:
cpp-doc gcc-11-locales dovecot-gssapi dovecot-ldap dovecot-lmtpd dovecot-lucene dovecot-managesieved dovecot-mysql dovecot-pgsql dovecot-pop3d dovecot-solr dovecot-sqlite dovecot-submissiond ntp gcc-multilib autoconf
automake libtool flex bison gdb gcc-doc gcc-11-multilib gcc-11-doc libgssapi-perl glibc-doc libgd-tools libdata-dump-perl libwww-perl make-doc procmail postfix-mysql postfix-pgsql postfix-ldap postfix-pcre postfix-lmdb
postfix-sqlite resolvconf postfix-cdb mail-reader postfix-doc razor libdbi-perl pyzor libencode-detect-perl libgeoip2-perl libnet-patricia-perl libbsd-resource-perl
The following NEW packages will be installed:
cpp cpp-11 dns-root-data dovecot-core dovecot-imapd dovecot-sieve fontconfig-config fonts-dejavu-core gcc gcc-11 libasan6 libatomic1 libauthen-sasl-perl libc-dev-bin libc-devtools libc6-dev libcc1-0 libclone-perl
libcommon-sense-perl libcrypt-dev libcrypt-openssl-bignum-perl libcrypt-openssl-random-perl libcrypt-openssl-rsa-perl libdeflate0 libdigest-bubblebabble-perl libdigest-hmac-perl libencode-locale-perl libexttextcat-2.0-0
libexttextcat-data libfontconfig1 libgcc-11-dev libgd3 libgomp1 libhtml-parser-perl libhtml-tagset-perl libhttp-date-perl libhttp-message-perl libidn11 libio-html-perl libio-socket-inet6-perl libio-socket-ssl-perl libisl23
libitm1 libjbig0 libjpeg-turbo8 libjpeg8 libjson-perl libjson-xs-perl liblsan0 liblua5.1-0 liblua5.3-0 liblwp-mediatypes-perl libmail-authenticationresults-perl libmail-dkim-perl libmail-spf-perl libmailtools-perl
libmemcached11 libmilter1.0.1 libmpc3 libnet-dns-perl libnet-dns-sec-perl libnet-ip-perl libnet-libidn-perl libnet-smtp-ssl-perl libnet-ssleay-perl libnetaddr-ip-perl libnsl-dev libopendbx1 libopendbx1-sqlite3 libopendkim11
libperl4-corelibs-perl libquadmath0 librbl1 libsocket6-perl libsodium23 libsys-hostname-long-perl libtiff5 libtimedate-perl libtirpc-dev libtsan0 libtypes-serialiser-perl libubsan1 libunbound8 liburi-perl libvbr2 libwebp6
libxpm4 linux-libc-dev make manpages-dev opendkim opendkim-tools perl-openssl-defaults postfix re2c rpcsvc-proto sa-compile spamassassin spamc ssl-cert
0 upgraded, 100 newly installed, 0 to remove and 0 not upgraded.
Need to get 138 MB of archives.
After this operation, 421 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
When you get prompted by postfix configuration, do the following:
![](4.png) ![](15.png)
(Yes, you must put the TLD, not the mail.TLD)
![](6.png)
Now that's done, let's update our dns records as described above:
![](7.png) ![](8.png) ![](14.png)
Now the way this server works is that if you have a user that is in the mailgroup, he can log into the mail server. Let's add our first user:
root@mail:~# useradd -G mail -m nothing
useradd: warning: the home directory /home/nothing already exists.
useradd: Not copying any file from skel directory into it.
root@mail:~# passwd nothing
New password:
Retype new password:
passwd: password updated successfully
Now let's check if the server has the ports we need opened:
root@mail:~# apt install nmap -y
root@mail:~# nmap 127.0.0.1
Starting Nmap 7.80 ( https://nmap.org ) at 2021-10-31 19:33 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0000030s latency).
Not shown: 991 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
80/tcp open http
143/tcp open imap
443/tcp open https
465/tcp open smtps
587/tcp open submission
783/tcp open spamassassin
993/tcp open imaps
the ports we need are opened on the serverside, let's check them from the clientside:
[ 10.66.66.2/32 ] [ /dev/pts/0 ] [~]
→ nmap mail.void.yt
Starting Nmap 7.92 ( https://nmap.org ) at 2021-10-31 20:34 UTC
Nmap scan report for mail.void.yt (45.76.133.0)
Host is up (0.033s latency).
Other addresses for mail.void.yt (not scanned): 2001:19f0:7402:2c6:5400:3ff:fea7:22a3 2001:19f0:7001:4de1:5400:3ff:fea6:e93f 2001:19f0:7401:85a0:5400:3ff:fea7:20d2 2001:19f0:7002:e3c:5400:3ff:fea7:8e7
Not shown: 989 closed tcp ports (conn-refused)
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
80/tcp open http
139/tcp filtered netbios-ssn
143/tcp open imap
443/tcp open https
445/tcp filtered microsoft-ds
465/tcp open smtps
587/tcp open submission
993/tcp open imaps
1688/tcp filtered nsjtp-data
Looks good aswell! Now let's test if our server works, let's connect to it using thunderbird:
[ 10.66.66.2/32 ] [ /dev/pts/38 ] [~]
→ sudo pacman -S thunderbird
[ 10.66.66.2/32 ] [ /dev/pts/38 ] [~]
→ thunderbird
![](20.png) ![](21.png) ![](22.png)
Looks like the connection was successful, now let's try to send the mail to a gmail address, which is probably the most picky email service provider:
![](23.png)
So by default when gmail recieves a new domain name, it flags it as spam, wait a few weeks and it will no longer consider it as spam, in the mean time let's signal it as non-spam:
![](24.png)
Now let's reply to our mail to test if we can recieve mails from gmail:
![](25.png)
If you don't recieve mail from gmail, do a DKIM test from [appmaildev](https://appmaildev.com/en/dkim)
![](26.png)
You might need to wait 12 hours or so for your DNS records to propagate, most notably for the DKIM record.
![](27.png)
Looks good! and when we try to send a mail from gmail to our server we recieve it:
![](28.png)
And that's it! We managed to setup a public mail server!
If you want a web interface for your mail server, check out my tutorial on how to install rainloop [here](../rainloop/index.md).
If thunderbird gives you the invalid SSL certificate error, do not click add exception, but rather edit dovecot's ssl config:
root@mail:~# vim /etc/dovecot/conf.d/10-ssl.conf
root@mail:~# cat /etc/dovecot/conf.d/10-ssl.conf | grep ssl_
#ssl_cert = <****/etc/dovecot/private/dovecot.pem
#ssl_key = <****/etc/dovecot/private/dovecot.key
ssl_cert = <****/etc/letsencrypt/live/mail.void.yt/fullchain.pem
ssl_key = <****/etc/letsencrypt/live/mail.void.yt/privkey.pem