Hallo Axel,
wir verteilen unsere main.cf auf Server und Workstations per
Konfigurationsmanagement.
Tolle Sache! Warum nutzt Du dann Dein Konfigurationmanagement nicht um Dein Problem zu lösen? Warum nutzt Du Dein Konfigurationsmanagement lieber um den armen Postfix zu verbiegen? Ich meine das bei Dir eingesetzte System zur Konfiguration Eurer Server wird doch ganz sicher eine Funktion _replace_in_file haben, zur Not auch ein _system_call, in dem Du dann ein sed -i 's/PATTERN/replace' machen kannst. Nicht nur ein stumpfes "Hole mir irgendwelche Dateien und klebe diese aneinander", so wie Du das in Deiner Mail beschreibst.

Du verteilst einfach Dein Template mit Variablen anstelle echter Konfiguration, holst Dir Deine Konfiguration aus den Variablen Deines Konfigurationsmanagements und ersetzt dann nach dem Import des Templates die Variablen im Template durch Deine Konfiguration: Genau so wie man das eben üblicherweise macht, wenn man ein Konfigurationsmanagement nutzt. Ich kenne ja Dein Konfigurationsmanagement nicht, deshalb nur Pseudocode dazu:

targethost=silberspitz.ethz.ch

# import template
___get_variable CONTEXT postfix VARNAME configfile DEFAULT "/etc/postfix/main.cf " HOST $targethost
___import_file $cfgfile HOST $targethost

# get variable
___get_variable CONTEXT postfix VARNAME mydestination DEFAULT "localhost" HOST $targethost ___get_variable CONTEXT postfix VARNAME relayhost DEFAULT "smtp.phys.ethz.ch" HOST $targethost ___get_variable CONTEXT postfix VARNAME inet_interfaces DEFAULT "loopback-only" HOST $targethost

# replace variable in template
___replace_in_file filename ${configfile} pattern '^mydestination =.*$' with "mydestination = ${mydestination}" HOST $targethost ___replace_in_file filename ${configfile} pattern '^relayhost =.*$' with "relayhost = ${relayhost}" HOST $targethost ___replace_in_file filename ${configfile} pattern '^mydestination =.*$' with "inet_interfaces = ${mydestination}" HOST $targethost

Der Kontext in Deinem Konfigurationsmanagement zum Host silberspitz.ethz.ch müsste dann in etwa so aussehen:
# context postfix
mydestination='
        silberspitz.ethz.ch
        silberspitz
        localhost
        bb.phys.ethz.ch
        hobbit.phys.ethz.ch
        xymon.phys.ethz.ch'
relayhost=''
inet_interfaces='all'

Das ist doch viel viel einfacher als nachträglich an der Postfix-Config rum zu fummeln um hilfreiche Neuerungen abzustellen, und das nur weil das Konfigurationsmanagement momentan nicht die Konfiguration liefert die Postfix braucht um glücklich zu sein.

Gruß Lutz

Am 28.01.15 um 11:54 schrieb Axel Beckert:
Hallo,

wir verteilen unsere main.cf auf Server und Workstations per
Konfigurationsmanagement.

Es gibt eine Default-main.cf, die meistens ausreicht. Braucht es
Abweichungen, so werden diese durch ein beim Deployment angehängtes
per-host-Konfigurationsschnipsel gelöst. In diesem sind
ggf. Einstellungen  drin, die in der Default-Datei bereits mit anderen
Wertten drin sind, um diese zu überschreiben.

Mit Debian 7 Wheezy und Postfix 2.9.6 funktioniert dies wunderbar,
aber seit Debian 8 Jessie und Postfix 2.11.3 jammert Postfix in
verschiedensten Situationen über diese "Überschreib"-Methoden:

# postconf > /dev/null
postconf: warning: /etc/postfix/main.cf, line 29: overriding earlier entry: 
mydestination=
postconf: warning: /etc/postfix/main.cf, line 30: overriding earlier entry: 
relayhost=smtp.phys.ethz.ch
postconf: warning: /etc/postfix/main.cf, line 31: overriding earlier entry: 
inet_interfaces=loopback-only
#

Die dazugehörige main.cf sieht wie folgt aus:

---8<---
# Note: file generated by dphys-config   DO NOT EDIT IN /etc/postfix/main.cf

# Default settings (hostname has been inserted by the configuration
# deployment tool)
myhostname = silberspitz.ethz.ch
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU Linux)
biff = no
append_dot_mydomain = no
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
relayhost = smtp.phys.ethz.ch
mynetworks = 127.0.0.0/8, [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = loopback-only
sender_canonical_maps = pcre:/etc/postfix/sender_canonical
mydestination =

# Per-host settings
mydestination =
         silberspitz.ethz.ch
         silberspitz
         localhost
         bb.phys.ethz.ch
         hobbit.phys.ethz.ch
         xymon.phys.ethz.ch
relayhost =
inet_interfaces = all
--->8---

(Grundidee bei diesem Beispiel: Alle Standard-Server sollen Mails via
Mailserver verschicken, nicht aber der Monitoring-Server von dem
o.g. Beispiel stammt. Der soll auch noch Mails an das SMS-Gateway
verschicken können, wenn der Mailserver down ist.)

Um o.g. Warnungen zu unterdrücken habe ich dann noch ein

   helpful_warnings = no

ganz vorne in der main.cf hinzugefügt.

Gemäss man page unterdrückt dies "warnings about problematic
configuration settings, and helpful suggestions." -- Klang für mich
nach genau der richtigen Einstellung, hat aber leider keinen
Unterschied gemacht.

Deswegen meine Frage: Wie bekomme ich Postfix dazu, diese Warnungen
nicht mehr auszugeben? Sie verursachen diverse Mails von Cron-Jobs,
weil Output (auf STDERR) kommt, z.B. von popularity-contest:

---8<---
Subject: Cron <root@silberspitz> test -x /usr/sbin/anacron || ( cd / && 
run-parts --report /etc/cron.daily )

/etc/cron.daily/popularity-contest:
sendmail: warning: /etc/postfix/main.cf, line 28: overriding earlier entry: 
mydestination=
sendmail: warning: /etc/postfix/main.cf, line 29: overriding earlier entry: 
relayhost=smtp.phys.ethz.ch
sendmail: warning: /etc/postfix/main.cf, line 30: overriding earlier entry: 
inet_interfaces=loopback-only
postdrop: warning: /etc/postfix/main.cf, line 28: overriding earlier entry: 
mydestination=
postdrop: warning: /etc/postfix/main.cf, line 29: overriding earlier entry: 
relayhost=smtp.phys.ethz.ch
postdrop: warning: /etc/postfix/main.cf, line 30: overriding earlier entry: 
inet_interfaces=loopback-only
--->8---

Und nein, ich will nicht pauschal allen Output nach STDERR
unterdrücken, da könnte ja durchaus mal ein relevanter Fehler drin
sein. :-) (Mal ganz davon abgesehen, dass ich das nicht in jedem
Skript machen will, welches irgendwann mal "sendmail" aufruft.)

Im Changelog habe ich diesen Eintrag gefunden:

20130404

         Human factors: warning when a main.cf parameter has multiple
         entries with different values.  File: util/dict.c.

Aber das ist doch gar kein Bug, das ist ein Feature! ;-)

Code-Stelle dazu ist recht sicher dies hier:

     459         if ((old = dict->lookup(dict, member)) != 0
     460             && strcmp(old, val) != 0)
     461             msg_warn("%s, line %d: overriding earlier entry: %s=%s",
     462                      VSTREAM_PATH(fp), lineno, member, old);

Bei Weiterverfolgen, ob das Log-Level irgendwo ausgewertet wird und
beeinflusst werden kann, bin ich bis zur Funktion msg_text am Ende von
util/msg_output.c gekommen, aber da haben mich meine C-Kenntnisse dann
irgendwann verlassen...

                Mit freundlichem Gruss, Axel Beckert

Antwort per Email an