Docker-mailserver: Default mail aliases - what mechanism makes the most sense?

Created on 7 Dec 2020  路  26Comments  路  Source: tomav/docker-mailserver

  • [x] I would like to contribute to the project (code, documentation, advocacy, integration, ...)
    I want to make a PR that adds the following default aliases (or similar) at the time of container image creation or deployment
    postmaster -> root
    amavis -> root
    clamav -> root

Description

After looking under the hood of this container for a bit, it seems there are multiple, sometimes competing ways to handle aliases:

1: An (empty) /etc/aliases file gets created inside the Dockerfile
2: The start-mailserver.sh script (that gets run out of supervisord?) overwrites /etc/aliases with one that points root -> postmaster
3: The check-for-changes.sh (that gets run out of supervisord?) also overwrites /etc/aliases. There is a comment here that identfies that as a bug, presumably since it competes with (2).
4: /tmp/docker-mailserver/postfix-aliases.cf (external to the container, making it not a great option to set container defaults).
5: Similar to mechanism (4), /tmp/docker-mailserver/postfix-virtual.cf

I find these multiple options both confusing and somewhat dangerous for unsuspecting users of the package. For example if you do "postfix standard things" to set up aliases then the scripts run out of supervisord will simply blow them away (silently, at that).

Need to brainstorm with somebody on what is a good way to streamline this and hopefully define one "internal" way to create default aliases, while keeping the external post-setup way. I think it makes sense to put the defaults in /etc/aliases and leave the /tmp/docker-mailserver supervisord stuff alone, so that external configs are not hampered/complicated by the process. I guess that implies changing the start-mailserver.sh and then fixing the seemingly documented bug in the check-for-changes.sh script.

Thoughts?

needs triage question

All 26 comments

Well, personally I add the accounts to the config/postfix-virtual.cf file using setup.sh. In addition I don't use root (who ever logs in with the root account in the docker image?), rather I forward the accounts to one of my own mail accounts.

If we fix this with documentation that is the route I would propose. We could also add a warning from the start script if these aliases have not been defined.

If we are going to add the aliases regardless then /etc/aliases (with some discipline down the line) is probably the way to go.

I'm suggesting that there needs to be a default alias for all the accounts because the system sends mail to amavis, and I also believe dovecot. I believe those should get delivered, someplace, no matter what the user has or has not done. Currently the system tries to deliver them locally but can't due to permissions on /var/mail (see issue #1701 for example), and so some amount of informational email about what the system is doing goes into the bit bucket. Hence my suggestion to deliver them locally, to root (which I believe skirts the permissions issue). At the very least they should all get delivered to postmaster and a note added to the docs instructing people to immediately make a virtual alias that causes the postmaster mail to get delivered to an inbox that is monitored.

Another strategy might be to create empty /var/mail/amavis and /var/mail/dovecot files with the right permissions. But that makes extra steps to later get that info out of local delivery and into a monitored inbox. As I write this I'm leaning towards the [email protected] idea becuase despite the fact that I do in fact routinely log into containers as root, I recognize that not everybody does. And I think in every case people should have postmaster delivered to a monitored inbox. The image as-is already delivers mail destined for root to that address, so maybe that is keeping closest to the original spirit of how the container should get used.

This was closed, but state is somewhat unclear to me. I actually like to the idea of adding the default aliases with /etc/aliases. So what's the status here?

I also see that there is a lot going on with aliases, and they are all over the place. This should somehow be fixed or documented better.

It's really hard/confusing. Or I'm really dumb. Take your pick.

I decided to put them (root, amavis, clamav) in /etc/aliases, pointing at [email protected]. So I put that on the relevant lines in target/check-for-changes.sh and target/start-mailserver.sh, built the container, ran it. /etc/aliases is empty. I'm confused right now. Do all the functions in start-mailserver.sh not get run when the container starts?

EDIT: the failure to populate /etc/aliases had somethign to do with the default environment variables. I plugged in my custom ones and it works. So, there is something I don't understand about when the setup_postfix_aliases function gets triggered.

Not all functions located in start-mailserver.sh are run by default. Some of them only run when certain variables ore true/false. This makes it hard to debug and hard to get an overview, I agree, but that's just how it is.

I can image default environment variables affecting aliases too well - which _should_ only be the case when it's really necessary. The function setup_postfix_aliases does, as far as I can see, three things with /etc/aliases:

echo "root: ${POSTMASTER_ADDRESS}" > /etc/aliases

which overrides /etc/aliases,

cat /tmp/docker-mailserver/postfix-aliases.cf >> /etc/aliases

will just append something and in the end postalias /etc/aliases (which loads aliases?). I really don't know whether the last command alters the alias file.

The only other place where /etc/aliases appears in startmailserver is near line 865:

[[ ${ENABLE_LDAP} -eq 1 ]] && postconf -e "smtpd_sender_login_maps=ldap:/etc/postfix/ldap-users.cf ldap:/etc/postfix/ldap-aliases.cf ldap:/etc/postfix/ldap-groups.cf" || postconf -e "smtpd_sender_login_maps=texthash:/etc/postfix/virtual, hash:/etc/aliases, pcre:/etc/postfix/regexp, pcre:/etc/postfix/maps/sender_login_maps.pcre"

How does your PR #1709 play with this issue?:)

The way things are now, each time those functions get run out of check-for-changes.sh and start-mailserver.sh, the entire /etc/aliases file inside the image gets blown away and rebuilt. AFAIK the postalias command builds that into a Berkeley DB or similar (I think it is stored at /etc/aliases.db - we should check), which is the object the daemon actually interacts with. I think.

What I suspect has occurred is that when I tried to start the server with the default variables, it failed to bring the mail server completely up but the container kept running. That's my working hypothesis, unless we find some condition that isn't met which would cause the function to not run - it seems you looked but didn't find one. And nothing I've done here has fundamentally changed the way aliases are built or used. In the end I decided the only thing that I should "fix" was the thing which caused me to create this issue. And I believe #1709 does.

And in any case I wanted to get the PR in because I felt I was going in circles at this point, on my own. :-)

That said, if somebody who knows the 30,000ft view of how the boostrapping works and where those scripts (functions inside them, really) get called, I'd like to learn. :)

Alright:)

What I suspect has occurred is that when I tried to start the server with the default variables, it failed to bring the mail server completely up but the container kept running.

FWIW this is confirmed. I can see it happening in supervisord.log. When using the default docker-compose.yml and environment vars to build the container, mailserver starts, then dies. Container keeps going, mailserver does not respawn. So I guess something in the startup script causes it to abort before it even gets to the lines that form /etc/aliases.

Can you try the latest 3 commits on master and see whether this was possibly introduced with a recent change? What do the logs say? Something must be logged somewhere? And when you use your own cars, it does work?

Can you try the latest 3 commits on master and see whether this was possibly introduced with a recent change? What do the logs say? Something must be logged somewhere? And when you use your own cars, it does work?

I can barely make github work. Let me try, LOL.

Just a simple checkout:)

Are you absolutely certain about this? I cannot imagine this behaviour has not been seen by anyone else...

I'd really like to see logs about this:D

Oh, trivial shit. Sorry.

mail | Initializing setup
mail | Checking configuration
mail | Configuring mail server
mail | grep: /tmp/docker-mailserver/postfix-accounts.cf: No such file or directory
mail | Fatal Error: Unless using LDAP, you need at least 1 email account to start Dovecot.
mail | Fatal Error: Please fix your configuration. Exiting...
mail | 2020-12-09 20:51:22,017 INFO exited: mailserver (exit status 1; not expected)

As far as I know, this is _intended_ when you start for the first time. You will need to add an account with setup.sh (i.e. ./setup.sh email add MAIL PW). Can you try this?

Rebuilding, will try again with default docker-compose.yml. But it's going to work. I had to do it the first time (which did confuse me; I had not used 'docker-compose --verbose' until just now). Since then I had my accounts and virtual aliases stored on /config. So I'd forgotten it was needed inside my testing environment (a fresh VM).

Rebuilding, will try again with default docker-compose.yml. But it's going to work. I had to do it the first time (which did confuse me; I had not used 'docker-compose --verbose' until just now). Since then I had my accounts and virtual aliases stored on /config. So I'd forgotten it was needed inside my testing environment (a fresh VM).

You had me worried for a second there. I thought something had just gone downhill because of the latest commits / PRs. But it's nice everything seems to be fine.

Yes, the mail server starts with the default docker-compose.yml (well, minorly tweaked with host/domain/container names and also changing the tag from latest to testing) and environment vars.

However, I'm more confused than ever about aliases. Look at how they come out:

```root@mail:/# cat /etc/aliases

See man 5 aliases for format

postmaster: root
clamav: root
```
Where did that come from? Is it the default one that did not get overwritten due to my change to "touch" instead of "echo >" ?

Where did that come from? Is it the default one that did not get overwritten due to my change to "touch" instead of "echo >" ?

Yes that is exactly where it came from. And the mail service is up now, with default vars and docker-compose.yml, but /etc/aliases is still empty. I guess I need to start from init and find out what calls all these scripts in /usr/local/bin.

Edit: This is all a red herring, ignore please:

OK - start-mailserver.sh gets called out of supervisord. The setup_postfix_alias function only gets "registered" if this condition is met. I don't entirely understand the syntax in that bash script, but it must be where that function gets triggered - and only if that condition is met.

That seems entirely arbitrary, to me. But it explains the behavior I'm seeing because my preferred container variables have POSTFIX_INET_PROTOCOLS=ipv4 and the default setup has it at "all".

How does this function

https://github.com/tomav/docker-mailserver/blob/2629b575900759920a31ad6a5c0603cbc7b25af7/target/start-mailserver.sh#L1283-L1287

set up aliases? Sorry, but I don't quite see how. Isn't the _setup_postfix_aliases function set up here

https://github.com/tomav/docker-mailserver/blob/2629b575900759920a31ad6a5c0603cbc7b25af7/target/start-mailserver.sh#L140

and then executed here

https://github.com/tomav/docker-mailserver/blob/2629b575900759920a31ad6a5c0603cbc7b25af7/target/start-mailserver.sh#L990-L991

?


The explanation for what's happening in line 126 you mentioned

https://github.com/tomav/docker-mailserver/blob/2629b575900759920a31ad6a5c0603cbc7b25af7/target/start-mailserver.sh#L126

is the following: If ${POSTFIX_INET_PROTOCOLS} != "all" is true, i.e. if you are using "ipv4", then the script will register the "_setup_inet_protocols" function and execute it later, here

https://github.com/tomav/docker-mailserver/blob/2629b575900759920a31ad6a5c0603cbc7b25af7/target/start-mailserver.sh#L374-L381

My tired eyes saw that as an 'if' that wrapped all the lines below it. So I'm back to not understanding why aliases don't get setup with defaults.

I'm very sorry to hear that. But doesn't the PR #1709 you provided set up the aliases correctly (for root, amavis and clam) or did I misunderstand something now?

I think I have to learn supervisord before I can understand what is (not) happening. This is also linked to the syntax of e.g. the start-mailserver.sh script, much of which is opaque to me. It just looks like a bunch of function definitions. When/where do they actually get run?

This script uses advanced and idiomatic Bash - I know, because I've re-written many parts :D

In the beginning functions are registered, for example here

https://github.com/tomav/docker-mailserver/blob/2629b575900759920a31ad6a5c0603cbc7b25af7/target/start-mailserver.sh#L126

if a certain condition is true, and then they will later be executed for example here

https://github.com/tomav/docker-mailserver/blob/2629b575900759920a31ad6a5c0603cbc7b25af7/target/start-mailserver.sh#L368-L381

...

Takes some time to get used to.


This is done to register almost all functions, daemon startups etc. Some work is done in the end as well.

I've confirmed that if you use "safe" values for the HOSTNAME and DOMAIN environment vars (e.g. mail.local or so) in docker-compose.yml, and add at least one email account so that dovecot is happy, the alias creation works as expected. I didn't probe deeper. I think it doesn't matter terribly much if the container isn't working quite right when no effort is put into configuring it from the defaults. I was originally working under the assumption that the defaults would be fine for building/testing images but it seems not, at least in my hands. It's fine.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jholster picture jholster  路  4Comments

landergate picture landergate  路  4Comments

42wim picture 42wim  路  4Comments

strarsis picture strarsis  路  5Comments

dragonito picture dragonito  路  5Comments