summaryrefslogtreecommitdiffstats
path: root/_posts/2018-08-05-Local-mail-server.md
blob: 65d42fd6c230c9a6449de472bcc9bed13062be1d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
---
layout: post
title: Setting up a local dev mail server
tags: [mail, instructional]
---

As part of my work on [lists.sr.ht](https://meta.sr.ht), it was necessary for
me to configure a self-contained mail system on localhost that I could test
with. I hope that others will go through a similar process in the future when
they set up [the code](https://git.sr.ht/~sircmpwn/lists.sr.ht) for hacking on
locally or when working on other email related software, so here's a guide on
how you can set it up.

There are lots of things you can set up on a mail server, like virtual mail
accounts backed by a relational database, IMAP access, spam filtering, and so
on. We're not going to do any of that in this article - we're just interested in
something we can test our email code with. To start, install your distribution
of `postfix` and pop open that `/etc/postfix/main.cf` file.

Let's quickly touch on the less interesting config keys to change. If you want
the details about how these work, consult the postfix manual.

- *myhostname* should be your local hostname
- *mydomain* should also be your local hostname
- *mydestination* should be `$myhostname, localhost.$mydomain, localhost`
- *mynetworks* should be `127.0.0.0/8`
- *home_mailbox* should be `Maildir/`

Also ensure your hostname is set up right in `/etc/hosts`, something like this:

```
127.0.0.1 homura.localdomain homura
```

Okay, those are the easy ones. That just makes it so that your mail server
oversees mail delivery for the `127.0.0.0/8` network (localhost) and delivers
mail to local Unix user mailboxes. It will store incoming email in each user's
home directory at `~/Maildir`, and will deliver email to other Unix users. Let's
set up an email client for reading these emails with. Here's my development
[mutt](http://mutt.org) config:

```
set edit_headers=yes
set realname="Drew DeVault"
set from="sircmpwn@homura"
set editor=vim
set spoolfile="~/Maildir/"
set folder="~/Maildir/"
set timeout=5
color index blue default ~P
```

Make any necessary edits. If you use mutt to read your normal mail, I suggest
also setting up an alias which runs `mutt -C path/to/dev/config`. Now, you
should be able to send an email to yourself or other Unix accounts with
mutt[^1]. Hooray!

[^1]: Mutt crash course: run `mutt`, press `m` to compose a new email, enter the recipient (`$USER@$HOSTNAME` to send to yourself) and the subject, then compose your email, exit the editor, and press `y` to send. A few moments later the email should arrive.

To accept email over SMTP, mozy on over to `/etc/postfix/master.cf` and
uncomment the submission service. You're looking for something like this:

```
127.0.0.1:submission inet n       -       n       -       -       smtpd
#  -o syslog_name=postfix/submission
#  -o smtpd_tls_security_level=encrypt
#  -o smtpd_sasl_auth_enable=yes
#  -o smtpd_tls_auth_only=yes
#  -o smtpd_reject_unlisted_recipient=no
#  -o smtpd_client_restrictions=$mua_client_restrictions
#  -o smtpd_helo_restrictions=$mua_helo_restrictions
#  -o smtpd_sender_restrictions=$mua_sender_restrictions
#  -o smtpd_recipient_restrictions=
  -o smtpd_relay_restrictions=permit
#  -o milter_macro_daemon_name=ORIGINATING
```

This will permit delivery via localhost on the submission port (587) to anyone
whose hostname is in `$mydestination`. A good old `postfix reload` later and you
should be able to send yourself an email with SMTP:

```
$ telnet 127.0.0.1 587
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
220 homura ESMTP Postfix
EHLO example.org
250-homura
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8
MAIL FROM:<sircmpwn@homura>
250 2.1.0 Ok
RCPT TO:<sircmpwn@homura> 
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
From: Drew DeVault <sircmpwn@homura>
To: Drew DeVault <sircmpwn@homura>
Subject: Hello world

Hey there 
.
250 2.0.0 Ok: queued as 8267416366B
QUIT
221 2.0.0 Bye
Connection closed by foreign host.
```

Pull up mutt again to read this. Any software which will be sending out mail and
speaks SMTP (for example, sr.ht) can be configured now. Last step is to set up
LTMP delivery to lists.sr.ht or any other software you want to process incoming
emails. I want most mail to deliver normally - I only want LTMP configured for
my lists.sr.ht test domain. I'll set up some transport maps for this purpose. In
`main.cf`:

```
local_transport = local:$myhostname
transport_maps = hash:/etc/postfix/transport
```

Then I'll edit `/etc/postfix/transport` and add these lines:

```
lists.homura.localdomain lmtp:unix:/tmp/lists.sr.ht-lmtp.sock
homura.localdomain local:homura
```

This will deliver mail normally to `$user@homura` (my hostname), but will
forward mail sent to `$user@lists.homura` to the Unix socket where the
[lists.sr.ht LMTP
server](https://git.sr.ht/~sircmpwn/lists.sr.ht/tree/lists-srht-lmtp) lives.

Add the subdomain to `/etc/hosts`:

```
127.0.0.1 lists.homura.localdomain lists.homura
```

Run `postmap /etc/postfix/transport` and `postfix reload` and you're good to go.
If you have the lists.sr.ht daemon working, send some emails to
`~someone/example-list@lists.$hostname` and you should see them get picked up.