summaryrefslogtreecommitdiffstats
path: root/README
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2024-08-02 16:39:50 -0400
committerMalfurious <m@lfurio.us>2024-08-02 16:39:50 -0400
commit714d9219a448e847803d9256bf2b6a9516690bf7 (patch)
tree4a8cf51747b739557413a4c2ae515efe15c2bc00 /README
parent15b788b4d41bc36dc357898ca5b20ca5ed7b55db (diff)
downloadmailnode-714d9219a448e847803d9256bf2b6a9516690bf7.tar.gz
mailnode-714d9219a448e847803d9256bf2b6a9516690bf7.zip
Add README
Signed-off-by: Malfurious <m@lfurio.us>
Diffstat (limited to 'README')
-rw-r--r--README333
1 files changed, 333 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..54c7c56
--- /dev/null
+++ b/README
@@ -0,0 +1,333 @@
+ _____________________________
+ / ____ / / /
+ / .' __ \ /__./ /
+ / / .' \ | ________ /
+ / | | (_/ | ________ /_____ _____ ____ __ _____ _____ ____ _____
+ / \ `.__.'\ ________ /| | _ | | | | | | | \| __|
+ / `.___ .' _____ / | | | | |- -| |__| | | | | | | | __|
+/____________________________/ |_|_|_|__|__|____|_____|_|___|_____|____/|_____|
+
+Mailnode is a dockerized email service that supports virtual inboxes, virtual
+mail domains, address aliases, a mailing list service, and is compatible with
+the DNS-based message authentication schemes SPF, DKIM, and DMARC.
+
+Mailnode runs solely on well-established free software components. Mailnode's
+daemons and required default port numbers are listed below. Due to the
+prevalence of email spam, it is important to ensure that email ports are not
+blocked or filtered by your hosting provider / ISP.
+
+ Service Description TCP ports
+ -------------------------------------------------------------
+ postfix Mail transfer agent 25, 465
+ dovecot Mail delivery agent 993
+ mlmmj Mailing list manager -
+ opendkim Message auth mail filter -
+ nginx-proxy (*) Reverse proxy / TLS helper 80, 443
+
+* Nginx-proxy (with acme-companion) is an extra dependency which is required to
+obtain and manage TLS certificates for the mail server. The proxy service is
+used so that mailnode doesn't require exclusive control over the web ports.
+docker-compose.yml contains the integrations with nginx-proxy.
+
+
+
+Prerequisites
+=============
+ 1) Forward DNS host record(s) for mail server: Create an A record and/or
+ AAAA record pointed at the mail server IP address.
+
+ 2) Reverse DNS record(s): Create PTR records for the server's IPv4 and, if
+ necessary, IPv6 addresses. You may need to ask your hosting provider to
+ do this for you.
+
+ 3) Unblock your ports: If any of the above TCP ports are blocked (either
+ inbound or outbound) by your upstream provider, submit a support ticket
+ to have them opened. Otherwise, seek another service provider.
+ Mailnode makes no official recommendation regarding ISP or hosting
+ providers.
+
+ 4) Run nginx-proxy: Clone docker compose files from the "proxy-docker" git
+ repository and launch the reverse-proxy with ACME companion service.
+ `docker compose --file ./docker-compose-acme.yml up --detach`
+
+
+
+Configuration
+=============
+ docker-compose.yml
+ ------------------
+ There are a couple variables in this file that must be filled in with
+ information about your server. Eg: the server hostname and a list of valid
+ "local" mail domains. Look for comments that say "# CONFIGURE ME!"
+
+ Virtual domains must be comma separated. An example value for this field
+ might be: "foo.com,baz.bar.net" in order to accept mail for addresses like
+ "user@foo.com" and "user@baz.bar.net" respectively.
+
+
+ userconfig/passwd
+ -----------------
+ This is the master user/inbox database for the Mailnode instance. It is in
+ the format of a standard system passwd file - fields are separated by colons,
+ and comments and blank lines are not allowed. The format for each line of
+ this file is:
+
+ USERNAME:PASSWORDHASH:UID:GID::::
+
+ Username must be the user's full email address. This is because Mailnode
+ supports multiple receiving domains.
+
+ A Password hash can be generated using the `makepasswd.sh` script. Hashes
+ are given a unique salt. Therefore, even if two users will use the same
+ password, it is wise to assign them independent hashes. This way, someone
+ reading the passwd file will be unable to determine which passwords match,
+ if any.
+
+ UID and GID refer to the underlying unix account which actually owns the
+ stored mail files. These must be the constant value `2000`. The final few
+ fields are not used at the moment.
+
+ The default file contains a dummy user record to show an example, this line
+ should be removed when adding real users.
+
+
+ userconfig/aliases
+ ------------------
+ This file defines email address alias lists. Each line contains the name of
+ an alias, followed by one or more addresses that the alias will forward to.
+ Forwarding addresses can be of different domains than the alias address.
+ They can even reside at domains not managed by the Mailnode instance.
+
+ Unlike the passwd file, blank lines and comment lines (`#`) are allowed.
+
+ This example forwards both "webmaster" and "postmaster" addresses to a
+ generic "admin" address, and delivers all mail to admin to two real human
+ beings:
+
+ webmaster@site.com admin@site.com
+ postmaster@site.com admin@site.com
+ admin@site.com alice@site.com bob@site.com
+
+
+
+Installation
+============
+After making modifications to the config files, use docker compose to start
+Mailnode or update an existing instance. When building and starting Mailnode
+for the first time, it is recommended to direct output to a log file so you can
+easily grab the DKIM key that is generated for your server. This public key
+will be needed for a DNS record later.
+
+ docker compose up --detach --build | tee log.txt
+
+The DKIM key generated by the build process is persisted by a named volume.
+This allows the image to be rebuilt without requiring the need to rotate keys.
+
+
+
+Final DNS Records
+=================
+After setting up Mailnode, some additional DNS entries are required in order to
+properly federate with other mail servers. Add them to your domain's zone file.
+(domain.com => your domain name, mail.domain.com => mail server hostname)
+
+ domain.com MX 10 mail.domain.com
+ domain.com TXT "v=spf1 mx -all"
+ default._domainkey.domain.com TXT "v=DKIM1; h=sha256; k=rsa; p=MIGfMA0GCSqGSIb3D....."
+ _dmarc.domain.com TXT "v=DMARC1; p=none; rua=mailto:postmaster@domain.com"
+
+
+ MX (Mail exchange)
+ ------------------
+ This is a standard DNS record that instructs external senders which server(s)
+ to direct your incoming mail to. The given record directs all mail to
+ `mail.domain.com:25`. 10 is a priority value, which is meaningful if
+ multiple MX entries are present.
+
+ The remaining records pertain to message sender authentication and apply to
+ your outgoing mail.
+
+
+ SPF (Sender policy framework)
+ -----------------------------
+ An SPF record states which internet hosts are permitted to send mail on
+ behalf of your domain. The given record permits all your domain's mail
+ exchangers (aka: any host referred to by an MX record) and hard-fails all
+ others. For more information on SPF records, see:
+ http://www.open-spf.org/SPF_Record_Syntax/
+
+
+ DKIM (DomainKeys identified mail)
+ ---------------------------------
+ DKIM uses asymmetric cryptography to sign outgoing mail, proving that each
+ message originates from one of your domain's approved mail servers. DKIM
+ signatures include a key selector field - this enables you to publish many
+ public keys in your domain. Mailnode uses only a single key pair, with the
+ selector name "default". Key selectors are part of the DNS entry name, as
+ seen above. The body of the TXT record contains all the crypto parameters
+ for the public key.
+
+ To find your DKIM record value, refer to the output of the docker image
+ build log. After opendkim generated an initial key pair, the data for the
+ public key DNS record is echoed to the console.
+
+
+ DMARC (Domain-based message authentication, reporting, and conformance)
+ -----------------------------------------------------------------------
+ DMARC instructs a message receiver what to do if a message from your domain
+ fails either of the SPF or DKIM checks. Note that implementing DMARC may be
+ optional for your site.
+
+ The given record specifies a policy of "none", which effectively allows the
+ delivery of unauthenticated messages. Alternatives are "quarantine" (spam
+ folder) and "reject" (return error code during SMTP). The "rua" tag
+ specifies an email address to deliver aggregate DMARC reports to. If your
+ "postmaster" mailbox is not setup, change this value or remove the tag.
+
+ For more information on DMARC records, see:
+ https://mxtoolbox.com/dmarc/details/what-is-a-dmarc-record
+
+
+
+Login to Mailboxes
+==================
+Connect to Mailnode with any normal email client using the information below.
+
+ Incoming mail
+ -------------
+ Server: <your mail server hostname>
+ Protocol: IMAPS (Implicit SSL/TLS encryption, not STARTTLS) port 993
+ Username: <user's email address>
+ Password: <user's plaintext password>
+
+
+ Outgoing mail
+ -------------
+ Server: <your mail server hostname>
+ Protocol: SMTPS (Implicit SSL/TLS encryption, not STARTTLS) port 465
+ Username: <user's email address>
+ Password: <user's plaintext password>
+
+Note that new accounts initially only have an INBOX folder where new messages
+are delivered. Message archival, saving sent messages, or message drafts must
+be handled by clients.
+
+The "From:" header used in outgoing messages is managed by clients - users
+configure their "real names" locally instead of on the server. However the
+return path ("envelope sender", etc) must match the user's email address,
+otherwise the message will be rejected.
+
+
+
+Mailing Lists
+=============
+Mailnode hosts configurable mailing lists using the Mlmmj mailing list manager.
+Basic usage is explained here, although it is a good idea to familiarize
+yourself with the underlying system: https://mlmmj.org/
+
+Mlmmj uses a directory for each mailing list to record its configuration and
+metadata. This includes things like the message archive, list of subscribers,
+message queues, and configuration parameters. In particular, there are two
+subdirectories of interest: (1) "control", which contains list configuration
+options and (2) "text", which contains message templates to use when delivering
+automated responses to users.
+
+Under Mailnode, each list's main metadata directory is managed for you. You
+Only need to manually configure "control" and "text" content in directories
+under `userconfig/`.
+
+ userconfig/lists/<NAME>/*
+ -------------------------
+ Create subdirectories under `userconfig/lists/` for each of your desired
+ mailing lists. The directory name is used to identify the list, and the
+ directory contents are the files which would reside in the list's "control"
+ (configuration options) directory.
+
+ The `makelist.sh` script can be used to automatically create a mailing list
+ using some recommended sane default settings. Keep in mind that the list's
+ post address will really be the only user-facing identifier for the list.
+ The owner email address will be used as the initial list owner and moderator.
+ Emails sent to `listname+owner@domain.com` will be delivered to this person.
+
+ For a fuller description of the available configuration settings, see the
+ Mlmmj documentation: https://mlmmj.org/TUNABLES.html
+
+ Be careful when removing a list directory! Whenever Mailnode is restarted
+ (rebuilt) after removing lists, the list's real metadata directory will be
+ purged from the system. This includes all subscribers and the full message
+ archive as well!
+
+
+ userconfig/listtext/*
+ ---------------------
+ This directory contains the "text" auto mail templates that are shared by
+ all configured mailing lists. You shouldn't need to change anything, but if
+ you wish to customize any messages, this is the place to do it.
+
+After creating lists, rebuild and restart Mailnode. The mailing lists are
+interacted with by sending an email to one of several "request" email addresses.
+Assuming a mailing list whose post address is "mylist@domain.com", the following
+basic actions are possible:
+
+ mylist@domain.com Deliver message to all list subscribers
+ mylist+owner@domain.com Deliver message to the list owner(s)
+ mylist+help@domain.com Retrieve a summary of list information
+ mylist+subscribe@domain.com Subscribe to receive all list messages (*)
+ mylist+subscribe-digest@domain.com Subscribe to receive list digests (*)
+ mylist+unsubscribe@domain.com Unsubscribe from all list messages (*)
+
+For all "request" addresses ("mylist+xxx@domain.com"), the message subject and
+body are ignored.
+
+* Subscribe and unsubscribe requests require reply to a confirmation message to
+prevent abuse.
+
+
+
+Mailing List Archives
+=====================
+Some web frontends exist for Mlmmj to allow searching and browsing message
+archives. However, I personally don't like any of the user interfaces available.
+
+At the moment, Mailnode does not expose any message archive interface.
+Implementing one is left as a TODO for a future release.
+
+
+
+Testing and Troubleshooting
+===========================
+For help validating your mail setup, check out these tools that will test your
+DNS records, message signatures, and deliverability.
+
+ https://intodns.com/ Validate domain DNS records
+ https://appmaildev.com/en/dkim Test SPF, DKIM, and DMARC via email
+ https://mxtoolbox.com/blacklists.aspx Check blacklists for server IP
+ https://mxtoolbox.com/SuperTool.aspx MXToolBox super tool
+
+Your mail server's IP address may appear on various block lists if it was
+recently used to send email spam. Residential and many VPS IP blocks are also
+sometimes listed. If you appear on a blocklist, you will likely have a very
+hard time getting your mail accepted by major email providers such as Microsoft,
+Google, and Yahoo, etc. Blacklist maintainers will usually provide a process
+for getting your IP delisted. Initiate these procedures at your own discretion.
+
+In addition to the above tools, you can send mail to one of the auto-responders
+below. A reply should be returned shortly containing your original message along
+with all of the header changes that were made in transit. This will allow you
+to test DKIM functionality along with two-way message deliverability.
+
+ sa-test@sendmail.net
+ check-auth@verifier.port25.com
+ autorespond+dkim@dk.elandsys.com
+ dktest@exhalus.net
+ dkim-test@altn.com
+ dktest@blackops.org
+
+Look for the message headers "DKIM-Signature:" and "Authentication-Results:" to
+have been added. Authentication results injected by the remote system should
+indicate a PASS. Otherwise, there is a misconfiguration, or something along the
+way altered the email to invalidate the signature.
+
+The auto-responder's reply mail will also be DKIM-signed. If you inspect the
+reply's actual headers you should see authentication results injected by your
+own server. This should also give a PASS.