maddy

Fork https://github.com/foxcpp/maddy

git clone git://git.lin.moe/go/maddy.git

  1# Installation & initial configuration
  2
  3This is the practical guide on how to set up a mail server using maddy for
  4personal use. It omits most of the technical details for brevity and just gives
  5you the minimal list of things you need to be aware of and what to do to make
  6stuff work.
  7
  8For purposes of clarity, these values are used in this tutorial as examples,
  9wherever you see them, you need to replace them with your actual values:
 10
 11- Domain: example.org
 12- MX domain (hostname): mx1.example.org
 13- IPv4 address: 10.2.3.4
 14- IPv6 address: 2001:beef::1
 15
 16## Getting a server
 17
 18Where to get a server to run maddy on is out of the scope of this article. Any
 19VPS (virtual private server) will work fine for small configurations. However,
 20there are a few things to keep in mind:
 21
 22- Make sure your provider does not block SMTP traffic (25 TCP port). Most VPS
 23  providers don't do it, but some "cloud" providers (such as Google Cloud) do
 24  it, so you can't host your mail there.
 25
 26- It is recommended to run your own DNS resolver with DNSSEC verification
 27  enabled.
 28
 29## Installing maddy
 30
 31Your options are:
 32
 33* Pre-built tarball (Linux, amd64)
 34
 35    Available on [GitHub](https://github.com/foxcpp/maddy/releases) or
 36    [maddy.email/builds](https://maddy.email/builds/).
 37
 38	The tarball includes maddy executable you can
 39	copy into /usr/local/bin as well as systemd unit file you can
 40	use on systemd-based distributions for automatic startup and service
 41	supervision. You should also create "maddy" user and group.
 42	See below for more detailed instructions.
 43
 44* Docker image (Linux, amd64)
 45
 46    ```
 47    docker pull foxcpp/maddy:0.6
 48    ```
 49
 50    See [here](../../docker) for Docker-specific instructions.
 51
 52* Building from source
 53
 54    See [here](../building-from-source) for instructions.
 55
 56* Arch Linux packages
 57
 58	For Arch Linux users, `maddy` and `maddy-git` PKGBUILDs are available
 59	in AUR. Additionally, binary packages are available in 3rd-party
 60	repository at [https://maddy.email/archlinux/](https://maddy.email/archlinux/)
 61
 62## System configuration (systemd-based distribution)
 63
 64If you built maddy from source and used `./build.sh install` then
 65systemd unit files should be already installed. If you used
 66a pre-built tarball - copy `systemd/*.service` to `/etc/systemd/system`
 67manually.
 68
 69You need to reload service manager configuration to make service available:
 70
 71```
 72systemctl daemon-reload
 73```
 74
 75Additionally, you should create maddy user and group. Unlike most other
 76Linux mail servers, maddy never runs as root.
 77
 78```
 79useradd -mrU -s /sbin/nologin -d /var/lib/maddy -c "maddy mail server" maddy
 80```
 81
 82## Host name + domain
 83
 84Open /etc/maddy/maddy.conf with vim^W your favorite editor and change
 85the following lines to match your server name and domain you want to handle
 86mail for.
 87If you setup a very small mail server you can use example.org in both fields.
 88However, to easier a future migration of service, it's recommended to use a
 89separate DNS entry for that purpose. It's usually mx1.example.org, mx2, etc.
 90You can of course use another subdomain, for instance: smtp1.example.org.
 91An email failover server will become possible if you forward mx2.example.org
 92to another server (as long as you configure it to handle your domain).
 93
 94```
 95$(hostname) = mx1.example.org
 96$(primary_domain) = example.org
 97```
 98
 99If you want to handle multiple domains, you still need to designate
100one as "primary". Add all other domains to the `local_domains` line:
101
102```
103$(local_domains) = $(primary_domain) example.com other.example.com
104```
105
106## TLS certificates
107
108One thing that can't be automagically configured is TLS certs. If you already
109have them somewhere - use them, open /etc/maddy/maddy.conf and put the right
110paths in. You need to make sure maddy can read them while running as
111unprivileged user (maddy never runs as root, even during start-up), one way to
112do so is to use ACLs (replace with your actual paths):
113```
114$ sudo setfacl -R -m u:maddy:rX /etc/ssl/mx1.example.org.crt /etc/ssl/mx1.example.org.key
115```
116
117maddy reloads TLS certificates from disk once in a minute so it will notice
118renewal. It is possible to force reload via `systemctl reload maddy` (or just
119`killall -USR2 maddy`).
120
121### Let's Encrypt and certbot
122
123If you use certbot to manage your certificates, you can simply symlink
124/etc/maddy/certs into /etc/letsencrypt/live. maddy will pick the right
125certificate depending on the domain you specified during installation.
126
127You still need to make keys readable for maddy, though:
128```
129$ sudo setfacl -R -m u:maddy:rX /etc/letsencrypt/{live,archive}
130```
131
132### ACME.sh
133
134If you use acme.sh to manage your certificates, you could simply run:
135
136```
137mkdir -p /etc/maddy/certs/mx1.example.org
138acme.sh --force --install-cert -d mx1.example.org \
139  --key-file       /etc/maddy/certs/mx1.example.org/privkey.pem  \
140  --fullchain-file /etc/maddy/certs/mx1.example.org/fullchain.pem
141```
142
143## First run
144
145```
146systemctl start maddy
147```
148
149The daemon should be running now, except that it is useless because we haven't
150configured DNS records.
151
152## DNS records
153
154How it is configured depends on your DNS provider (or server, if you run your
155own). Here is how your DNS zone should look like:
156```
157; Basic domain->IP records, you probably already have them.
158example.org.   A     10.2.3.4
159example.org.   AAAA  2001:beef::1
160
161; It says that "server mx1.example.org is handling messages for example.org".
162example.org.   MX    10 mx1.example.org.
163; Of course, mx1 should have A/AAAA entry as well:
164mx1.example.org.   A     10.2.3.4
165mx1.example.org.   AAAA  2001:beef::1
166
167; Use SPF to say that the servers in "MX" above are allowed to send email
168; for this domain, and nobody else.
169example.org.     TXT   "v=spf1 mx ~all"
170; It is recommended to server SPF record for both domain and MX hostname
171mx1.example.org. TXT   "v=spf1 a ~all"
172
173; Opt-in into DMARC with permissive policy and request reports about broken
174; messages.
175_dmarc.example.org.   TXT    "v=DMARC1; p=quarantine; ruf=mailto:postmaster@example.org"
176
177; Mark domain as MTA-STS compatible (see the next section)
178; and request reports about failures to be sent to postmaster@example.org
179_mta-sts.example.org.   TXT    "v=STSv1; id=1"
180_smtp._tls.example.org. TXT    "v=TLSRPTv1;rua=mailto:postmaster@example.org"
181```
182
183And the last one, DKIM key, is a bit tricky. maddy generated a key for you on
184the first start-up. You can find it in
185/var/lib/maddy/dkim_keys/example.org_default.dns. You need to put it in a TXT
186record for `default._domainkey.example.org.` domain, like that:
187```
188default._domainkey.example.org.    TXT   "v=DKIM1; k=ed25519; p=nAcUUozPlhc4VPhp7hZl+owES7j7OlEv0laaDEDBAqg="
189```
190
191## MTA-STS and DANE
192
193By default SMTP is not protected against active attacks. MTA-STS policy tells
194compatible senders to always use properly authenticated TLS when talking to
195your server, offering a simple-to-deploy way to protect your server against
196MitM attacks on port 25.
197
198Basically, you to create a file with following contents and make it available
199at https://mta-sts.example.org/.well-known/mta-sts.txt:
200```
201version: STSv1
202mode: enforce
203max_age: 604800
204mx: mx1.example.org
205```
206
207**Note**: mx1.example.org in the file is your MX hostname, In a simple configuration,
208it will be the same as your hostname example.org.
209In a more complex setups, you would have multiple MX servers - add them all once
210per line, like that:
211
212```
213mx: mx1.example.org
214mx: mx2.example.org
215```
216
217It is also recommended to set a TLSA (DANE) record.
218Use https://www.huque.com/bin/gen_tlsa to generate one.
219Set port to 25, Transport Protocol to "tcp" and Domain Name to **the MX hostname**.
220Example of a valid record:
221```
222_25._tcp.mx1.example.org. TLSA 3 1 1 7f59d873a70e224b184c95a4eb54caa9621e47d48b4a25d312d83d96e3498238
223```
224
225## User accounts and maddy command
226
227A mail server is useless without mailboxes, right? Unlike software like postfix
228and dovecot, maddy uses "virtual users" by default, meaning it does not care or
229know about system users.
230
231IMAP mailboxes ("accounts") and authentication credentials are kept separate.
232
233To register user credentials, use `maddy creds create` command.
234Like that:
235```
236$ maddy creds create postmaster@example.org
237```
238
239Note the username is a e-mail address. This is required as username is used to
240authorize IMAP and SMTP access (unless you configure custom mappings, not
241described here).
242
243After registering the user credentials, you also need to create a local
244storage account:
245```
246$ maddy imap-acct create postmaster@example.org
247```
248
249Note: to run `maddy` CLI commands, your user should be in the `maddy`
250group. Alternatively, just use `sudo -u maddy`.
251
252That is it. Now you have your first e-mail address. when authenticating using
253your e-mail client, do not forget the username is "postmaster@example.org", not
254just "postmaster".
255
256You may find running `maddy creds --help` and `maddy imap-acct --help`
257useful to learn about other commands. Note that IMAP accounts and credentials
258are managed separately yet usernames should match by default for things to
259work.