-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Config Templates for LDAP support #3524
base: master
Are you sure you want to change the base?
feat: Config Templates for LDAP support #3524
Conversation
105b393
to
198b452
Compare
I was quite confused about this test failure, but after fixing some lint issues another lint issue was raised about the line endings of the new template files... they're using
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice changes, I have a few notes that I'd like to be resolved first :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM ππΌ
Serial tests time out; I just stopped them. |
# Opt-out of generated config if `query_filter` was not configured: | ||
if ! grep -q '^query_filter =' "${LDAP_CONFIG_FILE}"; then | ||
_log 'warn' "'${LDAP_CONFIG_FILE}' is missing the 'query_filter' setting - disabling" | ||
|
||
sed -i "s/$(_escape_for_sed "${LDAP_CONFIG_FILE}")//" /etc/postfix/main.cf | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't handle smtpd_sender_login_maps
in spoofing.sh
.
Technically we could add our own variable to main.cf
for this like we've done with milters and restrictions, so that we could disable that.
Not sure if removing the file from the main.cf
setting like this is the correct call either, but the alternative would be restoring the conditionals for retaining the original file based lookups that may not exist with ACCOUNT_PROVISIONER=LDAP
, so perhaps this opt-out approach is the way to go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotta be honst, your call here :D I am not sure as I lack a bit of context (due to a lack of time).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The LDAP support isn't as complicated as originally thought:
- LDAP service has the data and receives a search query with 1 or more keys (attributes) with some value or pattern to match.
- The query is like a conditional statement in that sense and supports
&
(aka&&
) or|
(aka (||
). That's good enough for DMS at least. - Postfix has the
ldap:/
lookup table type. Same config for each separate file that we assign inmain.cf
, they mostly only differ by thequery_filter
(search query).
Technical details aside, they function and work the same as our text file counterparts, the query just makes the content a bit more dynamic instead of the left-side column lookup in text:/
tables.
lack a bit of context (due to a lack of time)
No worries, I understand π
I'll be running out of time soon enough myself, just trying to avoid the LDAP support rotting away :)
@@ -6,9 +6,9 @@ function _setup_spoof_protection() { | |||
|
|||
if [[ ${ACCOUNT_PROVISIONER} == 'LDAP' ]]; then | |||
if [[ -z ${LDAP_QUERY_FILTER_SENDERS} ]]; then | |||
postconf 'smtpd_sender_login_maps = ldap:/etc/postfix/ldap-users.cf ldap:/etc/postfix/ldap-aliases.cf ldap:/etc/postfix/ldap-groups.cf' | |||
postconf 'smtpd_sender_login_maps = ldap:/etc/postfix/ldap/users.cf ldap:/etc/postfix/ldap/aliases.cf ldap:/etc/postfix/ldap/groups.cf' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also not sure about this in general. I think it was the original approach before senders.cf
was contributed, and was provided as a compatibility fallback. I can check.
The result_attribute
for these configs isn't necessarily going to be correct for this feature like it should be for senders.cf
.
A future PR can address that though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ππΌ
fyi: I just did a quick look.. A detailed review will follow. I think, a pure bash alternative for zenv is: #!/bin/bash
[ $# -lt 2 ] && echo "Usage: $0 <env file> <binary> [args]" && exit 1
# Mark variables which are modified or created for export.
set -a
# source env file
source "$1"
# run binary with arguments
shift
exec "$@" |
Thanks! β€οΈ I wanted to give you time to have a chance to glance over it. I'm also juggling a bit elsewhere, but one other blocker for this PR will be a docs rewrite that I have as WIP and will push separately. Once the docs PR is ready this is good to merge (a small change for
No, I had something like this prior to You'd potentially have a problem with spaces/quotes to account for I think? (at least with how I'm creating the temporary VAR_NAME=some value that isn't quote-wrapped Additionally, since we're calling an executable ( These was mentioned in my PR description under the
So Just to clarify the generated
|
Sorry for the late update. Just want to let you know, that I can't review before October π Maybe next weekend. |
No worries. Did you want to hold off merging until then? I've been busy elsewhere and still need to get the associated docs update PR ready, so no rush if you'd like to review this before it's merged. I can also walk you through the PR diff if it helps. |
I will have a bit of time from Friday to Sunday and I can review this PR. |
I think there is actually no issue in releasing v14. The base image update warrants that anyway :) So merging this should be fine at all times. |
This looks quite interesting ! |
From a inline config via HereDoc to using a `.tmpl` file that has of all supported keys for SASLAuthd LDAP config. This additionally supports layering the ENV `.tmpl` generated config over a user-provided config. With a utility method that will ensure earlier duplicate keys are removed. The two new utilities are documented well enough to grok. `Dockerfile` and `packages.sh` updated to bring in new dependencies and provide the `.tmpl` file. `log_level` is not documented as a LDAP config key. Original PR did not explain why this key and value chosen were added.
This avoids the ENV overriding user-provided settings due to the ENV having hard-coded fallback defaults when not explicitly set.
Similar to the prior commit, this ensures default ENV fallback doesn't accidentally override explicit user-provided config settings.
Same process as described by earlier commits for SASLAuthd. To avoid introducing potential breakage, the ENV fallback convenience for `DOVECOT_PASS_FILTER` is retained.
- `postfix.base` defaults are now potentially breaking: - The `query_filter` default is common between `ldap-users.cf` and `ldap-senders.cf`, but the `mailEnabled` attribute locks it in to requiring the `postfix-book` OpenLDAP schema. Like the `result_attribute` setting, this is only set as a convenient default but not as broadly useful like the `bind` + `version` settings. - `version = 3` is required as unlike SASLAuthd and Dovecot, the default for Postfix is `2`. - `bind = yes` because we only support configuring for this in DMS? - `ldap-senders.cf` originally differed with it's `result_attribute` setting, but that default chosen looks to be more of a workaround introduced and should be more explicit? - The Postfix `.base` template does not include the four common attributes (_that Dovecot and SASLAuthd base configs do_), as the `LDAP_` prefix is presently the same (no`POSTFIX_` prefix), thus would override user config regardless.. - `sender_login_maps.ldap` doesn't exist and isn't relevant to LDAP queries (seems to be accidentally included here). `ldap-senders.cf` provides this functionality. - `ldap-senders.cf` was not supporting copying over a user-provided config, it does now. - Internal location for these Postfix generated configs is now `/etc/postfix/ldap/`.
Remove the prefix in favor of moving these files into a subdirectory: `/etc/postfix/ldap/`. Original LDAP config files provided via `Dockerfile` are now removed as the new `.tmpl` generation makes them redundant.
Generic approach to configuring Postfix with the LDAP tables in `main.cf`. Instead of opt-in when file exists (always did), opt-out when the `query_filter` is missing. This fixes a bug reported when deployment does not require LDAP queries for a lookup type, like groups. Avoids introducing misconfiguration by default.
Previously only `query_filter` had this support via an inconsistent `_${QUERY_KIND}` ENV suffix. This has been shifted to the left under the new `POSTFIX_` prefix, so that it can easily leverage the ENV prefix with config templates, layering after the generic `POSTFIX_` template. Naming is now consistent with `${QUERY_KIND}` (upper-cased). This also enables using the common `LDAP_` prefix in the Postfix `.base` template. As a part of the previous commit toggling based on presence of `query_filter`, this is now dropped from the Postfix `.base` template.
- `packages.sh` + `utils.sh` lint fix. - `.tmpl` + `.base` files column aligned. - `mail_with_ldap.bats` updated to ignore white-space between key/value entries being checked.
These files were created on Windows, linter caught the discrepancy. Now they're `LF`.
Inverse the assert to process the config file entry lookup to reduce the white-space between key and value to a consistent ` = ` which can then be compared directly to the `KEY_VALUE` input (_instead of the KV isolation dance used previously_).
Co-authored-by: Georg Lauterbach <[email protected]>
7810508
to
c811e6c
Compare
Just a rebase with some conflicts resolved. |
Shall I already review this? |
Last I recall reviews were already done and I had a bit more to address. Main blocker has been on me providing a rewrite of the LDAP docs page to update to changes here. Probably not wise to merge this until that's handled π I don't want this going stale so I'll try to address it by mid-jan. There's not much else on DMS that should need my time prioritized after the OAuth PR AFAIK. |
This is marked for v14.0.0. Will it be addresses for v14.0.0, or should we immediately postpone to v14.1.0? |
It's a breaking change, must be a major release. Push out the base image update, this can wait as I chip away at the docs rewrite as time allows. |
Description
Implements the proposed change "LDAP config override support (config files + ENV)".
This is a rather large diff to review, but the feature is basically two new helper methods with supporting template files:
.tmpl
has supported config keys with a${KEY_NAME}
as the variable to be replaced by the helper function..base
template with static default values or ENV (sharing a common prefixLDAP_
), that has subsequent configs (templates and optional user-provided config) with their own overrides or new settings layered over the base (viacat
).Still WIP:
Highlights:
_replace_by_env_in_file()
helper redundant.ldap-users.cf
andldap-groups.cf
Postfix LDAP tables configured, but DMS had virtual aliases and domains also configured, which was messing with their deployment. They presently workaround with an emptyquery_filter
to opt-out. There was checks to enable based on the config existing in/etc/postfix
, but at some point configs were moved into this location internally by default making those toggles ineffective._replace_by_env_in_file()
helper via a layered config with folding/merge approach. Users can provide their configs without having to copy/paste in each file the common connection settings, and still use ENV overrides without requiring the setting to be in their custom configs that we copy over internally./tmp/docker-mailserver/ldap/
location has been added to source the new custom LDAP config support for Dovecot and Saslauthd, providing parity to the Postfix support.query_filter
fix, these are now unset.POSTFIX_
prefix, and individual configs now use the query config type (eg:ldap-users.cf
=>POSTFIX_USERS
), instead of the prior support which only handledLDAP_QUERY_FILTER
by appending a suffix that was not consistent with the query config type in the filename (eg:ldap-users.cf
=>LDAP_QUERY_FILTER_USER
).ldap-*.cf
files is now/etc/postfix/ldap/*.cf
. The custom config from users config volume has been left as-is for now to minimize breaking changes.New dependencies:
zenv
(350KB):zenv
was a handy small dotenv program to properly load the.env
file format as ENV.envsubst
) usingCommand::envs()
. This was needed as simply sourcing thegrep
+sed
filtered ENV would need extra work to be valid forsource
(eg: proper quote wrap handling of values, which may already have quotes), I didn't really want to think about any other potential gotchas πenvbed
, this program properly splits at the first=
usingsplitn()
. Quote wrapped values or the lack of any is also handled correctly.envsubst
(package 150KB, program only 35KB):envsubst
:teller
:envsubst
, it struggled with variables for defaults. Since the use-case of this PR isn't related to secrets management,teller
isn't likely to address the drawbacks I experienced with my experiments.envbed
:.env
input (although I haven't tried it, it looks like it'd flop when value has=
) or filter to an ENV prefix (but not remove it, which is needed for a common Postfix template at least).dotenv-linter
:fix
feature that's meant to format.env
properly, but a bit weighty for that..env
parser into a separate crate though (dotenv-lookup
), if ever writing a program that needs that functionality in rust.configomat-rs
that could be polished up and adapted for this template instead of replacement approach. I cannot justify the time or future maintenance responsibility right now for writing and releasing my own tool πteller
can do that but doesn't handle prefix filtering a group of ENV well and too big for only that purpose.env -i
withzenv
(andgrep
+sed
) will have to do? π€·ββοΈType of change
Checklist:
docs/
)