Browse Source

Add some documentation

Simon Detheridge 4 months ago
parent
commit
09907aa42b
1 changed files with 264 additions and 0 deletions
  1. 264 0
      README.md

+ 264 - 0
README.md

@@ -0,0 +1,264 @@
+# Simple Self-Hosted Mail
+
+A quick way to host your own mail.
+
+## Overview
+
+This is a `docker-compose`-based environment for setting up a personal
+mailserver as quickly and simply as possible. Included are a collection of
+components, bundled together via a compose file, which provide a simple but
+fully-functional mail stack.
+
+It supports:
+
+- Multiple users
+- Multiple domains
+- Webmail
+- Antispam
+- DKIM/SPF/DMARC to ensure good outgoing delivery rates
+- SSL
+- Server-side mail filtering
+
+The framework is built from the following components:
+
+- [Haraka](https://haraka.github.io/) message transfer agent (SMTP)
+- [Dovecot](https://www.dovecot.org) mail delivery agent (IMAP) and filtering
+  (Sieve)
+- [Rainloop](https://www.rainloop.net/) moden web-mail interface
+- [Rspamd](https://www.rspamd.com/) spam filtering system
+- [MariaDB](https://mariadb.org) database for simple user management
+- [ClamAV](https://www.clamav.net/) anti-virus
+- [Nginx](https://nginx.org) reverse proxy for Rainloop
+- [Redis](https://redis.io) backend for Rspamd
+
+The default configuration is fairly minimal but will be enough to get started
+straight out of the box, but can be tweaked by modifying the config files in the
+repository.
+
+## Getting Started
+
+### Prerequisites
+
+You will need:
+
+- A domain, and a way to edit the DNS. [Cloudflare](https://cloudflare.com)
+  works well.
+- A Linux server, with Docker installed.
+- IMAP[S], SMTP[S] and HTTP[S] ports free
+- SSL certificates from [Let's Encrypt](https://letsencrypt.org) via
+  [Certbot](https://certbot.eff.org)
+
+#### SSL
+
+The configuration expects you to have SSL certificates, and will look for them
+in [Certbot](https://certbot.eff.org)'s default directory. (`/etc/letsencrypt/`)
+
+An example of using `certbot` to obtain a certificate using your Cloudflare
+account:
+
+```bash
+docker run -ti --rm -v /etc/letsencrypt:/etc/letsencrypt \
+  certbot/dns-cloudflare \
+    certonly --dns-cloudflare \
+    --dns-cloudflare-credentials /etc/letsencrypt/renewal/cloudflare.ini \
+    -d mail.MYDOMAIN.XYZ
+```
+
+This assumes that you have written your cloudflare credentials to
+`/etc/letsencrypt/renewal/cloudflare.ini` - more information is available on
+this and other ways of getting free SSL certificates in the documtation for
+[Certbot](https://certbot.eff.org)
+
+### Installation
+
+#### Clone the repository
+
+```bash
+git clone https://git.sd.ai/simon/simple-selfhosted-mail
+```
+
+All following comands are relative to the root directory of the repository.
+
+#### DKIM keys
+
+You'll want to generate a DKIM key for your domain, as follows:
+
+```bash
+cd dkim
+./dkim_gen_key.sh MYDOMAIN.XYZ
+
+cat MYDOMAIN.XYZ/dns
+```
+
+The file `MYDOMAIN.XYZ/dns` contains the DNS records you need to add to your
+domain for SPF, DKIM and DMARC.
+
+#### DNS
+
+In your DNS, you will need to add:
+
+- An `A` record for your server's public IP. e.g. `mail.MYDOMAIN.XYZ`
+- An `MX` record for your domain, pointing at your `A` record.
+- The DNS records from the file above. Specifically:
+  - The `monthYYYY._domainkey` `TXT` record for DKIM
+  - The `TXT` and `SPF` records in the root of your domain for SPF
+  - The `_dmarc` `TXT` record containing your DMARC record
+
+_Important_: The reverse DNS for your IP should match the `A` record you want to
+use. Without this, you will look spammy to other mail servers and may experience
+delivery problems.
+
+The entries generated in the `dns` file should work without modification, and
+should be added as-is unless you know what you are doing.
+
+#### Environment variables
+
+You need three environment variables set before you bring up the mail stack:
+
+- `MAIL_HOSTNAME` should be the hostname of your mail server, and should match
+  your reverse DNS
+- `SSL_DOMAIN` is the name of the directory in `/etc/letsencrypt/live` that
+  contains your SSL certificate.
+  - Normally this will match `MAIL_HOSTNAME` if your certificate just has one
+    host, but if you have multiple hosts in the same cert then it may be
+    something different.
+- `MYSQL_PASSWORD` is the password used to initialise and connect to the MariaDB
+  database. (The username will be `dovecot`)
+  - Once you have brought the stack up for the first time, you'll want to keep
+    this the same. To change it, you will need to connect to the database
+    directly and modify it as the root user.
+  - This can be anything you like, but it's best to randomly generate it.
+
+The easiest way to set these up is to add them to your `~/.bashrc`. e.g.:
+
+```bash
+export MAIL_HOSTNAME=mail.MYDOMAIN.XYZ
+export SSL_DOMAIN=mail.MYDOMAIN.XYZ
+export MYSQL_PASSWORD=some_secure_password
+```
+
+Don't forget to reload your `.bashrc` when done:
+
+```bash
+. ~/.bashrc
+```
+
+#### Building the stack
+
+The `docker-compose build` command will download all of the necessary base
+images and configure them. Run this inside your repository.
+
+You can then bring everything up with `docker-compose up -d`
+
+#### Creating your first user
+
+There are user-management scripts in the `bin` subdirectory, which call
+`docker-compose` so should be run from the repository root. These commands are
+fairly self-explanatory:
+
+- `list_users`
+- `add_user`
+- `set_user_password`
+- `delete_user`
+
+To create the first user you'll want to run:
+
+```bash
+bin/add_user me@MYDOMAIN.XYZ
+```
+
+You will be prompted for a password.
+
+#### Configuring Rainloop
+
+Rainloop webmail should be listening on your mail server now. You will need to
+set up your domain via the admin interface before you can log in:
+
+- Visit: `https://mail.YOURDOMAIN.XYZ/?admin`
+  - username: `admin`
+  - password: `12345`
+- Go to `security` and change the admin password!
+- Go to `domains` and add your domain:
+  - Click `Add Domain`
+  - Enter `YOURDOMAIN.XYZ` under `Name`
+  - In the `IMAP` section:
+    - Enter `dovecot` for `Server`
+    - Select `STARTTLS` for `Secure`
+    - Enter `10143` for `Port`
+  - In the `SMTP` section:
+    - Enter `haraka` for `Server`
+    - Select `STARTTLS` for `Secure`
+    - Enter `2525` for `Port`
+    - Check `Use authentication`
+  - Click `Test` - it should say everything is OK
+  - Click `Sieve configuration`
+    - Check `Allow sieve scripts` and `Allow custom user script`
+    - Enter `dovecot` for `Server`
+    - Leave `4190` for `Port`
+    - For `Secure` set `STARTTLS`
+  - Click `Test` again - it should test the sieve configuration and verify that
+    it is OK
+  - Click `Add`
+
+**TODO:** Add some screenshots!
+
+**NOTE:** The internal ports specified above are different to the ports
+externally published, which are the standard IMAP and SMTP ports. The internal
+ports are on numbers >1024 so that the processes can be run as a non-root user.
+
+This will have configured Rainloop to handle your domain, so that it knows how
+to send and receive mail from the rest of the stack.
+
+#### Logging in
+
+Visit `https://mail.MYDOMAIN.XYZ/` and log in as the user you created earlier.
+
+You may want to use the DKIM tester at (http://www.appmaildev.com/en/dkim) to
+verify that your setup is correctly signing messages.
+
+### Updating
+
+To update and rebuild the stack, run:
+
+```bash
+git pull
+docker-compose build --pull
+```
+
+## Important information and potential gotchas
+
+There are a couple of things that it helps to be aware of:
+
+### Where the data is stored
+
+Your mail and settings are stored in Docker volumes defined in
+`docker-compose.yml`. Please be careful when running commands such as
+`docker-compose down` (don't run it with the `-v` parameter) or `docker prune`
+as these may delete volumes, which will wipe out your mail!
+
+### Errors about volumes being already mounted
+
+If you rebuild any of the containers in the stack and then re-run
+`docker-compose up`, you may see errors about volumes already being mounted.
+When you rebuild, you must run `docker-compose down` before bringing it back up
+again.
+
+### 'Permission denied' errors for SSL certificates
+
+It may be that the programs running inside your containers can't read your SSL
+certificates, due to the fact that they run as their own user (e.g. users
+`dovecot` and `haraka`.) The SSL certificates are bind-mounted into the running
+containers and inherit the permissions that they have on disk.
+
+You may need to change the permissions on the files to support this. If you are
+confident that only you have access to the server, running
+`chmod a+r /etc/letsencrypt/archive/mail.YOURDOMAIN.XYZ/*` will work, but be
+aware of the security implications of doing this.
+
+### Multiple domains
+
+Multiple domains are supported. Simply add another user with `bin/add_user` and
+
+## Contributing
+
+Feel free to make a PR or open issues. Feedback is good.