summaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)AuthorFilesLines
2024-08-03Add UNLICENSEHEADv0.1.0masterMalfurious1-0/+24
Signed-off-by: Malfurious <m@lfurio.us>
2024-08-02Add READMEMalfurious1-0/+333
Signed-off-by: Malfurious <m@lfurio.us>
2024-08-02Add 'mail' subdomain to hostname placeholdersMalfurious1-3/+3
Add this subdomain as a hint to the user, to distinguish the specific server hostname from the virtual domain list, which should usually only contain second-level domain names. Signed-off-by: Malfurious <m@lfurio.us>
2024-07-13Add mailing list generation scriptMalfurious1-0/+40
Create a user mailing list under userconfig with a sane set of initial configuration variables. Available configuration can be found at https://mlmmj.org/TUNABLES.html Signed-off-by: Malfurious <m@lfurio.us>
2024-07-13Add password hash generation scriptMalfurious1-0/+3
Signed-off-by: Malfurious <m@lfurio.us>
2024-07-13opendkim: Check additional headers to determine senderMalfurious1-0/+1
Despite the default semantics for `InternalHosts` option in opendkim.conf, OpenDKIM seems to generally only consider the labeled sender of a message when deciding whether to sign a message or validate. This means that previously, when a message was sent to a mailing list from a domain outside of the mailnode host, the copies of this message that the list sent out did not get a signature applied to them. Since we will usually be injecting headers for mailing list information, we can search these first to determine the message envelope sender. X-Mailing-List will be the list's full address. Sender is added just in case. Advice is taken from the "Mailing Lists" section of http://www.opendkim.org/opendkim-README Signed-off-by: Malfurious <m@lfurio.us>
2024-07-09Merge branch 'dkim'Malfurious4-2/+86
Install and configure OpenDKIM according to the instructions found in the OpenDKIM readme: http://www.opendkim.org/opendkim-README * dkim: opendkim: Start milter service opendkim: Disable syslog opendkim: Configure postfix milter socket opendkim: Generate keys / TXT record opendkim: Configure signing parameters opendkim: Add default config file opendkim: Setup package and data volume
2024-07-09opendkim: Start milter serviceMalfurious1-0/+9
Signed-off-by: Malfurious <m@lfurio.us>
2024-07-09opendkim: Disable syslogMalfurious1-2/+2
Signed-off-by: Malfurious <m@lfurio.us>
2024-07-09opendkim: Configure postfix milter socketMalfurious2-5/+5
Signed-off-by: Malfurious <m@lfurio.us>
2024-07-09opendkim: Generate keys / TXT recordMalfurious1-0/+12
Keys are generated using the config from the previous commit and stored in the dkim data volume. The key length is set to 1024 bits for compatibility with nameservers. See this quote from the opendkim readme: BIND servers have a 256 byte limit on serving TXT records, so a 1024 bit RSA key is recommended if using BIND as your primary DNS server. Signed-off-by: Malfurious <m@lfurio.us>
2024-07-09opendkim: Configure signing parametersMalfurious2-4/+4
We use a hard-coded key selector of "default" and store keyfiles in the dkim volume. `Domain` indicates the mail sources for which mail should be signed rather than verified. Because we are using ENV_VIRTUAL_DOMAINS in this context, we now require the variable to be comma separated (no whitespace), as that is what this file requires. All previous usages of ENV_VIRTUAL_DOMAINS are compatible with comma separation. Signed-off-by: Malfurious <m@lfurio.us>
2024-07-09opendkim: Add default config fileMalfurious2-1/+53
Signed-off-by: Malfurious <m@lfurio.us>
2024-07-09opendkim: Setup package and data volumeMalfurious2-0/+11
The postfix user is added to the opendkim group so that the MTA can eventually interact with the filter over its socket file. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-30Don't useradd --system accountsMalfurious1-3/+3
Removing this option causes the UIDs and GIDs to match, which is desirable since GIDs have not yet been predictable. The other differences with --system don't matter for our purposes. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-30Mount certificates readonlyMalfurious1-2/+2
We don't need to modify any files within this volume, so mark it as read only, especially since the volume belongs to nginx-proxy. We require write access to the other volumes. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-15Merge branch 'mailing-lists'Malfurious24-9/+680
* mailing-lists: mlmmj: Add maintenance service mlmmj: Don't mention FAQ address mlmmj: Use simpler message prologue mlmmj: Add user configuration directories mlmmj: Integration with postfix mlmmj: Setup mailing list package
2024-06-15mlmmj: Add maintenance serviceMalfurious1-0/+9
Define a container to run mlmmj-maintd service. It runs daemonized so it will schedule its own tasks (its forground mode is one-shot execution). Signed-off-by: Malfurious <m@lfurio.us>
2024-06-15mlmmj: Don't mention FAQ addressMalfurious1-3/+0
It is not currently supported for each list to customize its own FAQ. Therefore it is pointless to advertise this information in the help messages. The default response is of course still returned if xxx+faq@domain is ever contacted, but this makes the feature more hidden. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-15mlmmj: Use simpler message prologueMalfurious1-2/+1
Signed-off-by: Malfurious <m@lfurio.us>
2024-06-15mlmmj: Add user configuration directoriesMalfurious18-0/+607
Configuration variables for individual mailing lists should go in subdirectories under `userconfig/lists/`. The directory name is the list name and files/directories beginning with a '.' are ignored. The contents within these list directories should be the list's "tunable" settings which usually reside in the lists's "control" directory. See https://mlmmj.org/TUNABLES.html for more information. Files under `userconfig/listtext/` are the auto-response messages sent out by the lists. The files we store here are shared by all lists, and much of their contents are parameterized. This commit adds the default versions of these files. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-15mlmmj: Integration with postfixMalfurious5-9/+58
Incoming mail for an mlmmj list is caught by a virtual mapping and directed via virtual transport to the mlmmj system for processing. Outgoing mail is implicitly allowed since it originates from the localhost. The postfix entrypoint script now dynamically generates these mailing list mappings on startup from data in the mlmmj spool directory, so user configuration is minimal. In addition, the script will now sync the user's mailing list parameters into the spool directory, thus automatically creating new lists and deleting old ones. The list creation logic is implemented in a new script `make_list.sh`. This is made necessary as the mlmmj built in tooling for this must be run interactively, so we duplicate the logic. This is separate from `entrypoint.sh` mainly because we need to drop privileges to the mlmmj user while creating files. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-15mlmmj: Setup mailing list packageMalfurious2-0/+10
Signed-off-by: Malfurious <m@lfurio.us>
2024-06-14postfix: Deny submission sender/login mismatchMalfurious3-3/+10
Prevent outgoing spoofed emails by requiring the MAIL FROM header to match the SASL login name. Specifically, the SASL user must "own" the address. `smtpd_sender_login_maps` defines a lookup table to determine ownership. We create a placeholder table that states each user simply owns their own email address (aka: the value of their username). Signed-off-by: Malfurious <m@lfurio.us>
2024-06-10postfix: Prevent leaking MUA IP addressesMalfurious3-0/+6
Protect user privacy by stripping IP addresses from headers received from authenticated mail submission. Headers for mail received from other servers are unaffected. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-10postfix: Don't chroot subprogramsMalfurious1-25/+25
Sending mail to an external server previously fails due to name resolution error. ("Host or domain name not found. Name service error for name=xxxxxxxxxx type=A: Host not found, try again") The reason this was happening is because the relay process runs in a chroot jail and can not access the docker container's resolve.conf file. Given the system is containerized, which is like a chroot on steroids, I'm comfortable disabling chrooting for mail processes to work around this. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-09Write logs to stdoutMalfurious2-0/+2
This allows output to be read with `docker compose logs`. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-09Create docker image and servicesMalfurious2-0/+99
As hinted by the previous commit, the mailnode system is built in a single docker image for simplicity. Defining multiple Dockerfiles would lead to many redundant tasks and be harder to maintain. So a common image for all services is built. However, the compose file spawns a unique container for each service, and communication occurs via the filesystem, through volumes. Note also that some fields in docker-compose.yml are required to be set by the end-user. The mail system is oriented around virtual users, so that nobody needs their own unix system account. However, best security practice is to create a dedicated user to own the mails - this user shouldn't be used for any other purpose. For this, the Dockerfile creates the user "vmailbox". The reason for declaring port exposure for TCP/80 is to enable automated TLS encryption with nginx-proxy-acme. This port is not actually opened by the compose file. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-09postfix: Add service entrypoint scriptMalfurious1-0/+12
This is used to generate database files used by postfix daemons. In theory, this could also be performed at build-time by the Dockerfile. However, I intend to create only a single image that each service separately spawns from, since there will be several commonalities between them. Moving these postfix-specific tasks to an entrypoint script keeps the common Dockerfile more managable. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-09postfix: Enable secure submission of outgoing emailMalfurious2-39/+23
The encrypted "submissions" port (465) is opened in postfix and is configured for delivery of outgoing mail of authenticated users only. The authentication is provided by dovecot via unix socket and account data is sourced from the userconfig directory. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-09Basic service configurationMalfurious2-111/+58
Setup postfix and dovecot to work with virtual domains/mailboxes and user accounts defined in the userconfig directory. Services are also configured to use TLS certificates that will later be provided by the nginx-proxy acme service. Basic formatting and informative comments are added to config files. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-09Add user config files for accounts and email addressesMalfurious2-0/+1
passwd is formatted like a standard unix password file, and is currently used to record a username, password, uid, and gid for each mail user. The row present in the file is a dummy record. Because the mailnode system will support multiple virtual domains and users, usernames should be full email addresses. At the moment, it is also important for all uid/gids to be set to the static value 2000, since that is the real unix account that will own the data files. aliases will hold virtual alias addresses. Each is one-per-line, with one alias address mapping to one or more forwarding addresses. Forward addresses can be of different domains, or even domains foreign to this mailnode install. Signed-off-by: Malfurious <m@lfurio.us>
2024-06-06Add default dovecot config fileMalfurious1-0/+101
Signed-off-by: Malfurious <m@lfurio.us>
2024-06-06Add default postfix config filesMalfurious2-0/+183
Signed-off-by: Malfurious <m@lfurio.us>