Write installation guide and clean up README.md.
authorRobert Sesek <rsesek@bluestatic.org>
Sun, 2 Aug 2020 22:30:56 +0000 (18:30 -0400)
committerRobert Sesek <rsesek@bluestatic.org>
Sun, 2 Aug 2020 22:30:56 +0000 (18:30 -0400)
README.md
deployment/mailpopbox.service
docs/install.md [new file with mode: 0644]

index 4b21e7af8f393eabd648694d393553df5342581a..d44f04aba1428a1678dda43747a5b532c1c005fa 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,27 +1,39 @@
 # mailpopbox
 
-Mailpopbox is a combination delivery SMTP server and POP mailbox. The purpose is to act as a
-catch-all delivery server for an MX domain. All messages that it receives are deposited into a
-single mailbox, which can then be accessed using the POP3 protocol.
+Mailpopbox is a single-user mail server, providing SMTP and POP facilities. It acts as a catch-all,
+wildcard email server for an entire domain name. Any message addressed to an account at the
+configured domain will be deposited into a single mailbox, which can then be accessed using the POP3
+protocol.
 
-## TLS Support
+The usage scenario is to configure your primary email provider (e.g.,
+[Gmail](https://support.google.com/mail/answer/7104828)) or client to POP messages off the
+server. Any time you need to provide an email address, you can give out
+*\<arbitrary-string@domain.com\>*, allowing you to use site/service/person-specific email addresses.
+Mail is collected into a single maildrop that can be POP'd out into your normal mailbox.
 
-TLS is recommended in production environments. To facilitate live-reloading of certificates, you can
-send a running instance SIGHUP.
+## Installation
+
+Installation requires a server capable of binding on port 25 for SMTP and 995 for POP3. A TLS
+certificate is also required to have a secure connection for authenticating to the server. See the
+[installation guide](docs/install.md) for a full set of steps.
+
+## Building
+
+To build mailpopbox for a Linux server, you need [Go](https://golang.org) and git:
+
+    $ git clone https://src.bluestatic.org/mailpopbox.git
+    $ cd mailpopbox
+    $ GOOS=linux GOARCH=amd64 go build
+
+The `GOOS` and `GOARCH` environment variables are only needed when cross-compiling (e.g. on a Mac).
 
 ## Send-As SMTP
 
+Mailpopbox also provides a way to reply to messages from an arbitrary email address at the domain.
 Since mailpopbox is designed as a catch-all mail server, it would be impractical to administer SMTP
-accounts to enable replying from any address handled by the server. The SMTP server instead
-provides a way to send messages from arbitrary addresses by authenticating as the mailbox@DOMAIN
-user. Any valid SMTP MAIL FROM is supported after authentication, but mail clients will typically
-use the mailbox@DOMAIN user or the From header. The SMTP server's feature is that if the message's
-Subject header has a special "[sendas:ANYTHING]" string, the server will alter the From message
-header to be from ANYTHING@DOMAIN.
-
-Practically, this means configuring an outbound mail client to send mail as mailbox@DOMAIN and
-authenticate to the SMTP server as such. And in order to change the sending address as perceived by
-the recipient, edit the subject with [sendas:ADDRESS].
+accounts to enable replying from any address handled by the server. Instead, the SMTP authenticates
+a single *mailbox* user, and if the message's Subject header has a special `[sendas:ADDRESS]`
+string, the server will alter the From message header to be from ADDRESS@DOMAIN.
 
 ## RFCs
 
index 7e371bd852e50582a63e0268c60ee2a47dd6fa24..aa09e5bb0decb59f646aafa4bc4858cf9bee1e8a 100644 (file)
@@ -6,7 +6,7 @@ Requires=network.target
 Type=simple
 ExecStartPre=/sbin/iptables -t nat -A PREROUTING -p tcp --dport 25 -j REDIRECT --to-ports 9025
 ExecStartPre=/sbin/iptables -t nat -A PREROUTING -p tcp --dport 995 -j REDIRECT --to-ports 9995
-ExecStart=/home/mailpopbox/mailpopbox /home/mailpopbox/mailpopbox.config
+ExecStart=/home/mailpopbox/mailpopbox /home/mailpopbox/config.json
 ExecStopPost=/sbin/iptables -t nat -D PREROUTING -p tcp --dport 995 -j REDIRECT --to-ports 9995
 ExecStopPost=/sbin/iptables -t nat -D PREROUTING -p tcp --dport 25 -j REDIRECT --to-ports 9025
 PermissionsStartOnly=true
diff --git a/docs/install.md b/docs/install.md
new file mode 100644 (file)
index 0000000..9b7ea5a
--- /dev/null
@@ -0,0 +1,190 @@
+# Mailpopbox Installation Guide
+
+This guide covers how to install mailpopbox, set up auto-renewing TLS certificates, and setting up
+Gmail to POP messages off the server.
+
+## Server
+
+Installation requires root access on a server capable of running long-lived processes. I recommend
+[Digital Ocean droplets](https://www.digitalocean.com/products/droplets/), which cost $5/month. This
+guide does not cover how to properly secure a Linux server, such as SSH configuration; please use
+other guides to do that if this is a new instance.
+
+## Install Mailpopbox
+
+These commands assume you are running as root; if not, precede the commands with `sudo`.
+
+1. Download the latest mailpopbox release and copy the binary to `/usr/local/bin`
+
+2. Set ownership and permissions:
+    - `chown root:wheel /usr/local/bin/mailpopbox`
+    - `chmod 755 /usr/local/bin/mailpopbox`
+
+3. Create a new user that the server will run under: `useradd mailpopbox --shell /sbin/nologin`
+
+4. Create some directories with the correct permissions:
+    - `cd /home/mailpopbox`
+    - `mkdir -p maildrop/yourdomain.com cert www/.well-known/acme-challenge`
+    - `chown -R mailpopbox:mailpopbox maildrop cert www`
+
+5. Create a file at `/home/mailpopbox/config.json`:
+
+    ```
+    {
+        "SMTPPort": 9025,
+        "POP3Port": 9995,
+        "Hostname": "mx.yourdomain.com",
+        "Servers": [
+            {
+                "Domain": "yourdomain.com",
+                "MailboxPassword": "yourpassword",
+                "TLSKeyPath": "/home/mailpopbox/cert/certificates/mx.yourdomain.com.key",
+                "TLSCertPath": "/home/mailpopbox/cert/certificates/mx.yourdomain.com.crt",
+                "MaildropPath": "/home/mailpopbox/maildrop/yourdomain.com"
+            }
+        ]
+    }
+    ```
+
+    - The SMTP and POP3 ports are not the values that will be exposed to the Internet, as those are
+        reserved ports that require root access to bind. Instead, mailpopbox binds these
+        unprivileged ports and *iptables* will be used to route Internet traffic to the server. This
+        is handled by the included systemd unit.
+    - The `Hostname` is the MX server hostname. Multiple catch-all domains can be configured, but
+        they will all share this MX hostname in e.g. the SMTP HELO.
+    - The `Domain` is the domain name for which `*@yourdomain.com` will be set up.
+    - The `MailboxPassword` is the password for the `mailbox@yourdomain.com` account, used to
+        authenticate POP3 and outbound SMTP connections. Choose a strong password!
+    - The `TLSKeyPath` and `TLSCertPath` are used to find the TLS certificate, which will be
+        configured below.
+    - The `MaildropPath` is where delivered messages are stored until they are POP'd off the
+        server.
+
+## Setup Automatic TLS Certificates
+
+This guide will assume that your instance of mailpopbox is running on a system that also has a
+web server running. The web server will be used to host [ACME
+certificate](https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment) challenges.
+I recommend the [lego](https://github.com/go-acme/lego) tool for certificate management. If you
+already have a mechanism to get certificates, you can use that and just adjust the paths in
+`config.json`.
+
+1. Install [lego](https://github.com/go-acme/lego) on the server.
+
+2. Configure your web server to serve the content under the mailpopbox home directory. With an
+apache2 configuration, this can be done by editing `/etc/httpd/conf.d/mx.yourdomain.com` with this
+content:
+
+    ```
+    <VirtualHost *:80>
+        ServerName mx.yourdomain.com
+
+        ErrorLog logs/yourdomain_error_log
+        CustomLog logs/yourdomain_access_log combined
+
+        DocumentRoot /home/mailpopbox/www
+    </VirtualHost>
+
+    <Directory /home/mailpopbox/www>
+        Require all granted
+    </Directory>
+    ```
+
+3. Reload the web server `systemctl reload httpd.service`
+
+4. Customize this command and register for the initial account and certificate:
+
+        sudo -u mailpopbox /usr/local/bin/lego --email email@domain.com --domains mx.yourdomain.com --http --http.webroot /home/mailpopbox/www --path /home/mailpopbox/cert run
+
+  This will register *email@domain.com* with [LetsEncrypt](https://letsencrypt.org) to get a
+  certificate for *mx.yourdomain.com* by putting an authentication challenge file in the
+  `/home/mailpopbox/www` directory, with the resulting certificate files in `/home/mailpopbox/cert`.
+
+
+5. Let mailpopbox restart itself via systemd by editing the sudoers file with `visudo`, and add this
+line:
+
+        mailpopbox ALL=(root) NOPASSWD: /usr/bin/systemctl restart mailpopbox.service
+
+6. Set up a cron job to automatically renew the certificate using `sudo crontab -u mailpopbx -e`
+and specifying this command (which is nearly the same as the `run` above, except it uses `renew` and
+a hook). Customize this command:
+
+        0 22 * * * /usr/local/bin/lego --email email@domain.com --domains mx.yourdomain.com --http --http.webroot /home/mailpopbox/www --path /home/mailpopbox/cert renew --renew-hook "sudo /usr/bin/systemctl restart mailpopbox.service"
+
+## Configure DNS
+
+1. Add a DNS A record to `yourdomain.com`, to set up `mx.yourdomain.com` to point to the public IP
+address of the server running mailpopbox.
+
+2. Set or change the DNS MX record of `yourdomain.com` to point to `mx.yourdomain.com`.
+
+Changes to DNS can take up between 1 and 24 hours to propagate.
+
+## Starting Mailpopbox
+
+1. Copy the `mailpopbox.service` systemd unit file from the release archive to
+`/usr/local/lib/systemd/system`
+
+> Note that the systemd unit file uses `/sbin/iptables` to forward traffic from ports 25 and 995 to
+> the ports specified in the `config.json` file. It also specifies the path to the `config.json`
+> file.
+
+2. Enable the systemd unit with `systemctl enable mailpopbox.service`
+
+3. Start mailpopbox with `systemctl start mailpopbox.service`
+
+4. Verify that the server has started with `journalctl -u mailpopbox`
+
+5. Test the connection to the server from your local machine: `openssl s_client -connect
+mx.yourdomain.com:995`. You should see your certificate printed by `openssl` and then a line that
+says `+OK POP3 (mailpopbox) server mx.yourdomain.com`.
+
+## Configuring Your Email Client
+
+Now that mailpopbox is running and DNS is configured, it is time to set your mail client up to
+connect to it. We will set up both a POP3 account to download delivered mail, and a SMTP account to
+enable replying. This guide is for Gmail, but the configuration parameters are the same regardless
+of client.
+
+1. Go to **Gmail Settings** > **Accounts and Import**
+
+2. Under **Check mail from other accounts:**, click **Add a mail account**
+
+3. Specify `mailbox@yourdomain.com` as the email address and click **Next**
+
+4. Choose **Import emails from my other account (POP3)** and click **Next**
+
+5. Specify the following configuration and add the account:
+    - **Username:** `mailbox@yourdomain.com`
+    - **Password:** The password you specified in `config.json`
+    - **POP Server:** `mx.yourdomain.com`
+    - **Port:** `995`
+    - Check **Always use a secure connection (SSL) when retrieving mail**
+    - Optionally, apply a label to all the messages sent to this domain
+
+Gmail will now fetch messages delivered to the server. You can send a test message to
+`install-test@yourdomain.com` and it should be delivered within a few minutes. Note that Gmail
+fetches mail from the POP account periodically via polling, so message delivery can seem slower than
+normal.
+
+1. Go to **Gmail Settings** > **Accounts and Import**
+
+2. Under **Send mail as:**, click **Add another email address**
+
+3. Specify the following and click **Next**:
+    - **Name:** Whatever you prefer
+    - **Email:** `mailbox@yourdomain.com`
+    - Check **Treat as an alias**
+
+4. Specify the following and add the account:
+    - **SMTP Server:** `mx.yourdomain.com`
+    - **Port:** `25`
+    - **Username:** `mailbox@yourdomain.com`
+    - **Password:** The password you specified in `config.json`
+    - Check **Secured connection using TLS**
+
+Gmail will now let you send email as *mailbox@yourdomain.com*. But if you are replying to a message
+sent to *random@yourdomain.com*, you do not want the recipient to see the "mailbox" username in your
+reply. If you append `[sendas:random]` to the Subject line of the message, the SMTP server will
+change the From address to `random@yourdomain.com` and remove the special tag from the Subject line.