# 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
--- /dev/null
+# 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.