summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Luevano Alvarado <david@luevano.xyz>2021-03-18 21:26:40 -0700
committerDavid Luevano Alvarado <david@luevano.xyz>2021-03-18 21:26:40 -0700
commit7ef3f1e57d6f2985d53276e0574b925328df2fb0 (patch)
treef6e83bc5445c4019b99025c16a0c0bb45345b735
parent3c10d209d706c286817e7150595113d9cda444bd (diff)
Start mail server blog post
-rw-r--r--blog/src/a/mail_server_with_postfix.md129
-rw-r--r--blog/src/a/website_with_nginx.md32
2 files changed, 145 insertions, 16 deletions
diff --git a/blog/src/a/mail_server_with_postfix.md b/blog/src/a/mail_server_with_postfix.md
new file mode 100644
index 0000000..c985793
--- /dev/null
+++ b/blog/src/a/mail_server_with_postfix.md
@@ -0,0 +1,129 @@
+# Create a Mail server with Postfix, Dovecot, Spamassassin and OpenDKIM
+
+The entry is going to be long because it's a *tedious* process. This is also based on [Luke Smith's script](https://github.com/LukeSmithxyz/emailwiz), but adapted to Arch Linux (his script works on debian-based distributions). This entry is mostly so I can record all the notes required while I'm in the process of installing/configuring the mail server on a new VPS of mine; also I'm going to be writing a script that does everything in one go, that will be hosted in [here](https://git.luevano.xyz/server_scripts.git).
+
+This configuration works for local users (users that appear in `/etc/passwd`), and does not use any type of SQL.
+
+## Prerequisites
+
+Basically the same as with the [website with Nginx and Certbot](https://blog.luevano.xyz/a/website_with_nginx.html):
+
+* A domain name. Got mine on [Epik](https://www.epik.com/?affid=da5ne9ru4) (affiliate link, btw).
+ * Later we'll be adding some **MX** and **TXT** records.
+ * I also recommend to add a **CNAME** ("mail" and "www.mail") for SSL certificates.
+* A VPS or somewhere else to host. I'm using [Vultr](https://www.vultr.com/?ref=8732849) (also an affiliate link).
+ * Also `ssh` configured.
+ * Ports 25, 587 (SMTP), 465 (SMTPS), 143 (IMAP) and 993 (IMAPS) open on the firewall (I use `ufw`).
+
+## Postfix
+
+Install the `postfix` package:
+
+```sh
+pacman -S postfix
+```
+
+We have two main files to configure (inside `/etc/postfix`): `master.cf` ([master(5)](https://man.archlinux.org/man/master.5)) and `main.cf` ([postconf(5)](https://man.archlinux.org/man/postconf.5)). We're going to edit `main.cf` first either by using the command `postconf -e 'setting'` or by editing the file itself (I prefer to edit the file).
+
+Note that the default file itself has a lot of comments with description on what each thing does (or you can look up the manual, linked above), I used what Luke's script did plus some other settings that worked for me.
+
+Now, first locate where your website cert is, mine is at the default location `/etc/letsencrypt/live/`, so my `certdir` is `/etc/letsencrypt/live/luevano.xyz`. Given this information, change `{yourcertdir}` on the corresponding lines. The configuration described below has to be appended in the `main.cf` configuration file.
+
+Certificates and ciphers to use for authentication and security:
+
+```conf
+smtpd_tls_key_file={yourcertdir}/privkey.pem
+smtpd_tls_cert_file={yourcertdir}/fullchain.pem
+smtpd_use_tls = yes
+smtpd_tls_auth_only = yes
+smtp_tls_security_level = may
+smtp_tls_loglevel = 1
+smtp_tls_CAfile={yourcertdir}/cert.pem
+smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+tls_preempt_cipherlist = yes
+smtpd_tls_exclude_ciphers = aNULL, LOW, EXP, MEDIUM, ADH, AECDH, MD5,
+ DSS, ECDSA, CAMELLIA128, 3DES, CAMELLIA256,
+ RSA+AES, eNULL
+smtpd_relay_restrictions = permit_sasl_authenticated, permit_mynetworks, defer_unauth_destination
+```
+
+Also, for the *connection* with `dovecot`, append the next few lines (telling postfix that `dovecot` will use user/password for authentication):
+
+```conf
+smtpd_sasl_auth_enable = yes
+smtpd_sasl_type = dovecot
+smtpd_sasl_path = private/auth
+smtpd_sasl_security_options = noanonymous, noplaintext
+smtpd_sasl_tls_security_options = noanonymous
+```
+
+Specify the mailbox home (this is going to be a directory inside your user's home):
+
+```conf
+home_mailbox = Mail/Inbox/
+```
+
+Pre-configuration to work seamlessly with `dovecot` and `opendkim`:
+
+```conf
+myhostname = {yourdomainname}
+mydomain = localdomain
+mydestination = $myhostname, localhost.$mydomain, localhost
+inet_interfaces = $myhostname, localhost
+
+milter_default_action = accept
+milter_protocol = 6
+smtpd_milters = inet:127.0.0.1:8891
+non_smtpd_milters = inet:127.0.0.1:8891
+mailbox_command = /usr/lib/dovecot/deliver
+```
+
+Where `{yourdomainname}` is `luevano.xyz` in my case, or if you have `localhost` configured to your domain, then use `localhost` for `myhostname` (`myhostname = localhost`).
+
+Lastly, if you don't want the sender's IP and user agent (application used to send the mail), add the following line:
+
+```conf
+smtp_header_checks = regexp:/etc/postfix/smtp_header_checks
+```
+
+And create the `/etc/postfix/smtp_header_checks` file with the following content:
+
+```conf
+/^Received: .*/ IGNORE
+/^User-Agent: .*/ IGNORE
+```
+
+That's it for `main.cf`, now we have to configure `master.cf`. This one is a bit more tricky.
+
+First look up lines (they're uncommented) `smtp inet n - n - - smtpd`, `smtp unix - - n - - smtp` and `-o syslog_name=postfix/$service_name` and either delete or uncomment them... or just run `sed -i "/^\s*-o/d;/^\s*submission/d;/\s*smtp/d" /etc/postfix/master.cf` as stated in Luke's script.
+
+Lastly, append the following lines to complete postfix setup and pre-configure for `spamassassin`.
+
+```conf
+smtp unix - - n - - smtp
+smtp inet n - y - - smtpd
+ -o content_filter=spamassassin
+submission inet n - y - - smtpd
+ -o syslog_name=postfix/submission
+ -o smtpd_tls_security_level=encrypt
+ -o smtpd_sasl_auth_enable=yes
+ -o smtpd_tls_auth_only=yes
+smtps inet n - y - - smtpd
+ -o syslog_name=postfix/smtps
+ -o smtpd_tls_wrappermode=yes
+ -o smtpd_sasl_auth_enable=yes
+spamassassin unix - n n - - pipe
+ user=spamd argv=/usr/bin/vendor_perl/spamc -f -e /usr/sbin/sendmail -oi -f \${sender} \${recipient}
+```
+
+Now, I ran into some problems with postfix, one being [smtps: Servname not supported for ai_socktype](https://www.faqforge.com/linux/fix-for-opensuse-error-postfixmaster-fatal-0-0-0-0smtps-servname-not-supported-for-ai_socktype/), to fix it, as *Till* posted in that site, edit `/etc/services` and add:
+
+```conf
+smtps 465/tcp
+smtps 465/udp
+```
+
+## Dovecot
diff --git a/blog/src/a/website_with_nginx.md b/blog/src/a/website_with_nginx.md
index 4e55fed..43264de 100644
--- a/blog/src/a/website_with_nginx.md
+++ b/blog/src/a/website_with_nginx.md
@@ -2,7 +2,7 @@
These are general notes on how to setup a Nginx web server plus Certbot for SSL certificates, initially learned from [Luke's video](https://www.youtube.com/watch?v=OWAqilIVNgE) and after some use and research I added more stuff to the mix. And, actually at the time of writing this entry, I'm configuring the web server again on a new VPS instance, so this is going to be fresh.
-As a side note, (((i use arch btw))) so everything here es aimed at an Arch Linux distro, and I'm doing everything on a VPS.
+As a side note, (((i use arch btw))) so everything here es aimed at an Arch Linux distro, and I'm doing everything on a VPS. Also note that most if not all commands here are executed with root privileges.
## Prerequisites
@@ -12,7 +12,7 @@ You will need two things:
* With the corresponding **A** and **AAA** records pointing to the VPS' IPs ("A" record points to the ipv4 address and "AAA" to the ipv6, basically). I have three records for each type: empty one, "www" and "\*" for a wildcard, that way "domain.name", "www.domain.name", "anythingelse.domain.name" point to the same VPS (meaning that you can have several VPS for different sub-domains).
* A VPS or somewhere else to host it. I'm using [Vultr](https://www.vultr.com/?ref=8732849) (also an affiliate link).
* With `ssh` already configured both on the local machine and on the remote machine.
- * Firewall already configured to allow ports 80 (http) and 443 (https). I use `ufw` so it's just a matter of doing `ufw allow 80,443/tcp` as root and you're golden.
+ * Firewall already configured to allow ports 80 (HTTP) and 443 (HTTPS). I use `ufw` so it's just a matter of doing `ufw allow 80,443/tcp` as root and you're golden.
* `cron` installed if you follow along (you could use `systemd` timers, or some other method you prefer to automate running commands every X time).
## Nginx
@@ -20,9 +20,9 @@ You will need two things:
You have two options: `nginx` and `nginx-mainline`. I prefer `nginx-mainline` because it's the "up to date" package even though `nginx` is labeled to be the "stable" version. Install the package and enable/start the service:
```sh
-# pacman -S nginx-mainline
-# systemctl enable nginx.service
-# systemctl start nginx.service
+pacman -S nginx-mainline
+systemctl enable nginx.service
+systemctl start nginx.service
```
And that's it, at this point you can already look at the default initial page of nginx if you enter the ip of your server in a web browser. You should see something like this:
@@ -32,7 +32,7 @@ And that's it, at this point you can already look at the default initial page of
As stated in the welcome page, configuration is needed, head to the directory of nginx:
```sh
-# cd /etc/nginx
+cd /etc/nginx
```
Here you have several files, the important one is `nginx.conf`, which as its name implies, contains general configuration of the web server. If you peek into the file, you will see that it contains around 120 lines, most of which are commented out and contains the welcome page server block. While you can configure a website in this file, it's common practice to do it on a separate file (so you can scale really easily if needed for mor websites or sub-domains).
@@ -62,9 +62,9 @@ http {
Next, inside the directory `/etc/nginx/` create the `sites-available` and `sites-enabled`, and go into the `sites-available` one:
```sh
-# mkdir sites-available
-# mkdir sites-enabled
-# cd sites-available
+mkdir sites-available
+mkdir sites-enabled
+cd sites-available
```
Here, create a new `.conf` file for your website and add the following lines (this is just the sample content more or less):
@@ -96,7 +96,7 @@ Note several things:
Then, make a symbolic from this config file to the `sites-enabled` directory:
```sh
-# ln -s /etc/nginx/sites-available/your_config_file.conf /etc/nginx/sites-enabled
+ln -s /etc/nginx/sites-available/your_config_file.conf /etc/nginx/sites-enabled
```
This is so the `nginx.conf` file can look up the newly created server config. With this method of having each server configuration file separate you can easily "deactivate" any website by just deleting the symbolic link in `sites-enabled` and you're good, or just add new configuration files and keep everything nice and tidy.
@@ -104,8 +104,8 @@ This is so the `nginx.conf` file can look up the newly created server config. Wi
All you have to do now is restart (or enable and start if you haven't already) the nginx service (and optionally test the configuration):
```sh
-# nginx -t
-# systemctl restart nginx
+nginx -t
+systemctl restart nginx
```
If everything goes correctly, you can now go to your website by typing "domain.name" on a web browser. But you will see a "404 Not Found" page like the following (maybe with different nginx version):
@@ -133,21 +133,21 @@ For more: [Arch Linux Wiki: nginx](https://wiki.archlinux.org/index.php/nginx).
The only "bad" (bloated) thing about certbot, is that it uses `python`, but for me it doesn't matter too much. You may want to look up another alternative if you prefer. Install the packages `certbot` and `certbot-nginx`:
```sh
-# pacman -S certbot certbot-nginx
+pacman -S certbot certbot-nginx
```
After that, all you have to do now is run `certbot` and follow the instructions given by the tool:
```sh
-# certbot --nginx
+certbot --nginx
```
It will ask you for some information, for you to accept some agreements and the names to activate https for. Also, you will want to "say yes" to the redirection from http to https. And that's it, you can now go to your website and see that you have https active.
-Now, the certificate given by certbot expires every 3 months or something like that, so you want to renew this certificate every once in a while. Using `cron`, you can do this by running:
+Now, the certificate given by `certbot` expires every 3 months or something like that, so you want to renew this certificate every once in a while. Using `cron`, you can do this by running:
```sh
-# crontab -e
+crontab -e
```
And a file will be opened where you need to add a new rule for certbot, just append the line: `1 1 1 * * certbot renew` (renew on the first day of every month) and you're good. Alternatively use `systemd` timers as stated in the [Arch Linux Wiki](https://wiki.archlinux.org/index.php/Certbot#Automatic_renewal).