From 5b5c9f0a43f9d3e148a14a53f5caa61e6efb2a30 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Sun, 2 Aug 2020 18:30:56 -0400 Subject: [PATCH] Write installation guide and clean up README.md. --- README.md | 44 +++++--- deployment/mailpopbox.service | 2 +- docs/install.md | 190 ++++++++++++++++++++++++++++++++++ 3 files changed, 219 insertions(+), 17 deletions(-) create mode 100644 docs/install.md diff --git a/README.md b/README.md index 4b21e7a..d44f04a 100644 --- 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 +*\*, 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 diff --git a/deployment/mailpopbox.service b/deployment/mailpopbox.service index 7e371bd..aa09e5b 100644 --- a/deployment/mailpopbox.service +++ b/deployment/mailpopbox.service @@ -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 index 0000000..9b7ea5a --- /dev/null +++ b/docs/install.md @@ -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: + + ``` + + ServerName mx.yourdomain.com + + ErrorLog logs/yourdomain_error_log + CustomLog logs/yourdomain_access_log combined + + DocumentRoot /home/mailpopbox/www + + + + Require all granted + + ``` + +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. -- 2.22.5