Re: Dumping effective postfix configuration

2023-01-06 Thread Wietse Venema
Viktor Dukhovni:
> > The Postfix master creates as many sockets as needed for an inet
> > service, and sets the socket option SO_REUSEADDR on each socket,
> > and bind()s them to the desired addresses.
> > 
> > With that, it may be possible for the Postfix master to create new
> > sockets, set SO_REUSEADDR on each socket, and bind() them to the
> > new addresses; if successful, close() the old sockets, otherwise
> > close() the new sockets.
> 
> Yes, typically doable, by determining which bindings are unchanged,
> which new, and which old.
> 
> > Am I missing something? This will have to work on all supported
> > systems, though. Not just Linux, not just *BSD.
> 
> The tricky case is changing a wildcard binding to a set of non-wildcard
> bindings.  When a wildcard binding is active, it is AFAIK not generally
> possible to bind non-wildcard listeners for the same port, and
> presumably the converse.
> 
> Changes in explicit lists of IPs should be viable as you noted.

The configurations of interest are:

inet_interfaces = all (wildcard binding)
inet_interfaces = enumeration (non-wildcard binding)

Changes of type wildcard->wildcard are noops.

Changes of type enumeration->enumeration are partial noops if one
only touches the sockets whose addresses have changed.

That leaves wildcard->enumeration and enumeration->wildcard.  Both
*should* be safe on BSD-ish (and Solaris, HP-UX) systems, given how
SO_REUSEADDR was originally implemented. See the "BSD SO_REUSEADDR"
discussion with a nice table in:
https://stackoverflow.com/questions/14388706/how-do-so-reuseaddr-and-so-reuseport-differ
This also comes with a nice test program.

With Linux the changes of type wildcard->enum and enum->wildcard
require code that is kernel version dependent.  If we consider only
kernels >= 3.9 then we can keep it simple with SO_REUSEPORT.

All of this needs to be evaluated not only on an idle server where
'listen' sockets are open only in the master, but also with child
process that hold a reference to a master's listen socket as well
as connected sockets. And then it needs to deal with sockets that
are in the TIME_WAIT state.

Wietse


Re: Dumping effective postfix configuration

2023-01-06 Thread Wietse Venema
Demi Marie Obenour:

Checking application/pgp-signature: FAILURE
-- Start of PGP signed section.
> On 1/6/23 07:15, Wietse Venema wrote:
> > Peter Wienemann:
> >> Hi,
> >>
> >> is there a way to dump the effective postfix configuration rather than 
> >> the one specified in main.cf/master.cf? It seems that changes to 
> >> main.cf/master.cf have an immediate impact on the output of postconf 
> >> regardless of whether a reload/restart of the service was performed.
> > 
> > How would that work? Different Postfix processes start at different
> > times, and some processes (qmgr, master) run forever.
> 
> What about using inotify/kqueue to determine when a config file has
> changed and reload accordingly?

It is not necessarily desirable that a daemon refreshes as soon as
one file has changed, especially when multiple files need to be
updated. I think that it is not burdensome to "postfix reload".

kqueue and inotify were introduced to BSD and Linux years after
Postfix was already released. They have no equivalent on other
systems, and MacOS kqueue has a problematic history with Postfix.

Wietse


Re: Dumping effective postfix configuration

2023-01-06 Thread Viktor Dukhovni
On Fri, Jan 06, 2023 at 03:28:23PM -0500, Wietse Venema wrote:

> > The documentation of inet_interfaces says otherwise, my recollection is
> > that master(8) does not attempt to rebind inet sockets on "reload":
> 
> I see. Yes, that could be dififcult. Or maybe not. 
> 
> The Postfix master creates as many sockets as needed for an inet
> service, and sets the socket option SO_REUSEADDR on each socket,
> and bind()s them to the desired addresses.
> 
> With that, it may be possible for the Postfix master to create new
> sockets, set SO_REUSEADDR on each socket, and bind() them to the
> new addresses; if successful, close() the old sockets, otherwise
> close() the new sockets.

Yes, typically doable, by determining which bindings are unchanged,
which new, and which old.

> Am I missing something? This will have to work on all supported
> systems, though. Not just Linux, not just *BSD.

The tricky case is changing a wildcard binding to a set of non-wildcard
bindings.  When a wildcard binding is active, it is AFAIK not generally
possible to bind non-wildcard listeners for the same port, and
presumably the converse.

Changes in explicit lists of IPs should be viable as you noted.

-- 
Viktor.


Re: Dumping effective postfix configuration

2023-01-06 Thread Emmanuel Fusté

Le 06/01/2023 à 21:03, Demi Marie Obenour a écrit :

On 1/6/23 07:15, Wietse Venema wrote:

Peter Wienemann:

Hi,

is there a way to dump the effective postfix configuration rather than
the one specified in main.cf/master.cf? It seems that changes to
main.cf/master.cf have an immediate impact on the output of postconf
regardless of whether a reload/restart of the service was performed.

How would that work? Different Postfix processes start at different
times, and some processes (qmgr, master) run forever.

What about using inotify/kqueue to determine when a config file has
changed and reload accordingly?

Too dangerous and useless.
I want to issue reload for long running processes only when I want.
Periodically recycled process will take automatically the new conf when 
they restarts, inotify/kqueue is not needed for that. That is something 
you must know as a postfix user to not inadvertently crash your running 
config with half edited but saved config files.

Same expectations and warning for maps (according to their type).
For the conf files, one interesting change would be to do the opposite : 
Process only run with copies of validated conf files and new copies (+ 
process reload) are done only when explicit reload command is issued to 
avoid new conf taken by surprise on process recycling.


Emmanuel.



Re: Dumping effective postfix configuration

2023-01-06 Thread Wietse Venema
Viktor Dukhovni:
> On Fri, Jan 06, 2023 at 01:45:48PM -0500, Wietse Venema wrote:
> 
> > > Most changes in main.cf require a reload to become effective but there 
> > > are some exceptions requiring a restart, e. g. a change of 
> > > inet_interfaces. 
> > 
> > That is incorrect. If inet_interfaces is changed, then a "postfix
> > reload" (not restart) is required because the master daemon is a
> > long-running process.
> 
> The documentation of inet_interfaces says otherwise, my recollection is
> that master(8) does not attempt to rebind inet sockets on "reload":

I see. Yes, that could be dififcult. Or maybe not. 

The Postfix master creates as many sockets as needed for an inet
service, and sets the socket option SO_REUSEADDR on each socket,
and bind()s them to the desired addresses.

With that, it may be possible for the Postfix master to create new
sockets, set SO_REUSEADDR on each socket, and bind() them to the
new addresses; if successful, close() the old sockets, otherwise
close() the new sockets.

Am I missing something? This will have to work on all supported
systems, though. Not just Linux, not just *BSD.

Wietse


Re: Dumping effective postfix configuration

2023-01-06 Thread Demi Marie Obenour
On 1/6/23 07:15, Wietse Venema wrote:
> Peter Wienemann:
>> Hi,
>>
>> is there a way to dump the effective postfix configuration rather than 
>> the one specified in main.cf/master.cf? It seems that changes to 
>> main.cf/master.cf have an immediate impact on the output of postconf 
>> regardless of whether a reload/restart of the service was performed.
> 
> How would that work? Different Postfix processes start at different
> times, and some processes (qmgr, master) run forever.

What about using inotify/kqueue to determine when a config file has
changed and reload accordingly?
-- 
Sincerely,
Demi Marie Obenour (she/her/hers)


OpenPGP_0xB288B55FFF9C22C1.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: Dumping effective postfix configuration

2023-01-06 Thread Peter Wienemann

On 06.01.23 20:02, Viktor Dukhovni wrote:

On Fri, Jan 06, 2023 at 01:45:48PM -0500, Wietse Venema wrote:


Most changes in main.cf require a reload to become effective but there
are some exceptions requiring a restart, e. g. a change of
inet_interfaces.


That is incorrect. If inet_interfaces is changed, then a "postfix
reload" (not restart) is required because the master daemon is a
long-running process.


The documentation of inet_interfaces says otherwise, my recollection is
that master(8) does not attempt to rebind inet sockets on "reload":

 src/master/master_ent.c: /*
 src/master/master_ent.c:  * XXX We cannot change the inet_interfaces 
setting for a running master
 src/master/master_ent.c:  * process. Listening sockets are inherited by 
child processes so that
 src/master/master_ent.c:  * closing and reopening those sockets in the 
master does not work.
 src/master/master_ent.c:  *
 src/master/master_ent.c:  * Another problem is that library routines still 
cache results that are
 src/master/master_ent.c:  * based on the old inet_interfaces setting. It 
is too much trouble to
 src/master/master_ent.c:  * recompute everything.
 src/master/master_ent.c:  *
 src/master/master_ent.c:  * In order to keep our data structures 
consistent we ignore changes in
 src/master/master_ent.c:  * inet_interfaces settings, and issue a warning 
instead.
 src/master/master_ent.c:  */

If one really wants to change the IP address and/or number of listen
endpoints, a restart is required.


This also matches the warnings in the logs. After a reload following a 
change of inet_interfaces the logs contain the following warning:


---
postfix/master[58283]: reload -- version 3.5.17, configuration /etc/postfix
postfix/master[58283]: warning: service smtp: ignoring inet_interfaces 
change
postfix/master[58283]: warning: to change inet_interfaces, stop and 
start Postfix

---

Peter


Re: Dumping effective postfix configuration

2023-01-06 Thread Viktor Dukhovni
On Fri, Jan 06, 2023 at 01:45:48PM -0500, Wietse Venema wrote:

> > Most changes in main.cf require a reload to become effective but there 
> > are some exceptions requiring a restart, e. g. a change of 
> > inet_interfaces. 
> 
> That is incorrect. If inet_interfaces is changed, then a "postfix
> reload" (not restart) is required because the master daemon is a
> long-running process.

The documentation of inet_interfaces says otherwise, my recollection is
that master(8) does not attempt to rebind inet sockets on "reload":

src/master/master_ent.c: /*
src/master/master_ent.c:  * XXX We cannot change the inet_interfaces 
setting for a running master
src/master/master_ent.c:  * process. Listening sockets are inherited by 
child processes so that
src/master/master_ent.c:  * closing and reopening those sockets in the 
master does not work.
src/master/master_ent.c:  *
src/master/master_ent.c:  * Another problem is that library routines still 
cache results that are
src/master/master_ent.c:  * based on the old inet_interfaces setting. It is 
too much trouble to
src/master/master_ent.c:  * recompute everything.
src/master/master_ent.c:  *
src/master/master_ent.c:  * In order to keep our data structures consistent 
we ignore changes in
src/master/master_ent.c:  * inet_interfaces settings, and issue a warning 
instead.
src/master/master_ent.c:  */

If one really wants to change the IP address and/or number of listen
endpoints, a restart is required.

-- 
Viktor.


Re: Dumping effective postfix configuration

2023-01-06 Thread Wietse Venema
Peter Wienemann:
> Most changes in main.cf require a reload to become effective but there 
> are some exceptions requiring a restart, e. g. a change of 
> inet_interfaces. 

That is incorrect. If inet_interfaces is changed, then a "postfix
reload" (not restart) is required because the master daemon is a
long-running process.

Similar considerations apply when changes are made that affect the
queue mamager process (for example, changes that affect concurrency
management).

Other Postfix processes have a finite life time, and will eventually
pick up configuration changes. If you can't wait, then use "postfix
reload".

Wietse


Re: Dumping effective postfix configuration

2023-01-06 Thread Viktor Dukhovni
On Fri, Jan 06, 2023 at 06:42:18PM +0100, Peter Wienemann wrote:

> Most changes in main.cf require a reload to become effective

No. In most cases they merely require the passage of time, and typical
changes are not that time-sensitive.

> I am trying to put main.cf under configuration 
> management and have to trigger an action each time main.cf changes such 
> that the changes become effective.

If you make changes to main.cf that are time-sensitive, push a separate
file whose update will cause a reload.  If your changes require a
restart, push a separate file whose update triggers a restart.  Most of
the time leave both sentinel files alone.

> At the moment I always perform a restart after a change of main.cf
> (just to be on the safe side).

This is not necessary in most cases, and should be avoided if possible.

> But on a busy mail server this is not ideal. I am looking for a way to
> do better. One idea that came to my mind is:

Reloads are also not ideal.

> 1. Initially try a reload and check whether the effective configuration 
> is different from the target configuration as specified in main.cf.
> 
> 2. If both match, we are done. If there is a discrepancy, launch a restart.

You're over-engineering the problem.  Let the operator who authors the
change decide whether a restart or reload is required, or whether just
normal Postfix process recycling is sufficient for your needs.

On a busy server, you can reduce max_idle and or max_use to recycle
processes more often:

max_idle = 3s
max_use = 20

Most smtpd(8) processes and delivery agents would last not much longer
than a minute before they exit and are replaced.  The additional cost
of process creation will be modest.

-- 
Viktor.


Re: Dumping effective postfix configuration

2023-01-06 Thread Peter Wienemann

On 06.01.23 17:33, Wietse Venema wrote:

Peter Wienemann:

On 06.01.23 13:15, Wietse Venema wrote:

is there a way to dump the effective postfix configuration rather than
the one specified in main.cf/master.cf? It seems that changes to
main.cf/master.cf have an immediate impact on the output of postconf
regardless of whether a reload/restart of the service was performed.


How would that work? Different Postfix processes start at different
times, and some processes (qmgr, master) run forever.


I could think of something like this:

Instead of sending a HUP signal like it is done to trigger a reload, one
sends a different signal (e. g. USR1) to the master. The further
processing of the signal is similar to the HUP case except that
configuration dumps are triggered rather than configuration reloads.


How could that be useful? On a busy server, there will be be 100+
smtpd (SMTP server) processes, 100+ cleanup processes, 100+ smtp
(SMTP client) processes and so on. Those processes were started an
different times and they will produce different dumps if you change
Postfix configuration without "postfix reload".

If you want an accurate picture of what configuration is in effect.
then I think that is not too much trouble to run "postfix reload"
after a configuration change. Then "postconf" output reflects the
effective configuration.

Instead of dumping configurations, there are other ways. For example,
each daemon could log configuration file stamps when the process
is started (or communicate that info in some other manner). Given
a history of (time stamp, config file content) you could use the
logged time stamps to find out what configuration is (or was) in
effect for each daemon process.


I am trying to solve the following problem:

Most changes in main.cf require a reload to become effective but there 
are some exceptions requiring a restart, e. g. a change of 
inet_interfaces. I am trying to put main.cf under configuration 
management and have to trigger an action each time main.cf changes such 
that the changes become effective. At the moment I always perform a 
restart after a change of main.cf (just to be on the safe side). But on 
a busy mail server this is not ideal. I am looking for a way to do 
better. One idea that came to my mind is:


1. Initially try a reload and check whether the effective configuration 
is different from the target configuration as specified in main.cf.


2. If both match, we are done. If there is a discrepancy, launch a restart.

That is how I ended up with my initial question. Maybe there are 
better/simpler ways to accomplish the desired result. Suggestions are 
welcome.


Peter


Re: Dumping effective postfix configuration

2023-01-06 Thread Viktor Dukhovni
On Fri, Jan 06, 2023 at 11:33:28AM -0500, Wietse Venema wrote:

> > Instead of sending a HUP signal like it is done to trigger a reload, one 
> > sends a different signal (e. g. USR1) to the master. The further 
> > processing of the signal is similar to the HUP case except that 
> > configuration dumps are triggered rather than configuration reloads.
> 
> How could that be useful? On a busy server, there will be be 100+
> smtpd (SMTP server) processes, 100+ cleanup processes, 100+ smtp
> (SMTP client) processes and so on. Those processes were started an
> different times and they will produce different dumps if you change
> Postfix configuration without "postfix reload".

+1.  It makes little sense to ask a distributed (over multiple
dynamically spawned processes) system about its "current" state.

The age in seconds of master and its descendants can be obtained via,
for example:

$ ps -c -o etimes= -o pid= -o command= -p $(pgrep -g $(ps -o pgid= $(pgrep 
-x master))) | sort -nr
2466115 87674 master
 384351 70993 qmgr
 384315 71008 tlsmgr
   2402 39744 pickup
368 39967 anvil
368 39965 smtpd
 52 40089 proxymap
 52 40088 smtpd
 14 40098 smtpd
 12 40099 trivial-rewrite

Even fancier, splice in the age the main.cf and master.cf files:

$ (
ps -c -o etimes= -o pid= -o command= -p $(pgrep -g $(ps -o pgid= $(pgrep -x 
master)))
perl -le '
use File::stat;
for (@ARGV) {printf "%d - %s\n", time - stat($_)->mtime, $_}
' /usr/local/etc/postfix/ma*.cf
  ) | awk '{printf "%10s %10s %s\n", $1, $2, $3}' | sort -nr
  28755246  - /usr/local/etc/postfix/master.cf
   2467086  87674 master
385324  - /usr/local/etc/postfix/main.cf
385322  70993 qmgr
385286  71008 tlsmgr
  3373  39744 pickup
 1  40259 anvil
 1  40258 proxymap
 1  40257 smtpd
 0  40260 trivial-rewrite

The master(8) process is younger than master.cf and the rest are younger
than main.cf, so all is well, assuming that no critical changes
affecting master(8) were made in main.cf (inet_interfaces, ...).

-- 
Viktor.


Re: Dumping effective postfix configuration

2023-01-06 Thread Wietse Venema
Peter Wienemann:
> On 06.01.23 13:15, Wietse Venema wrote:
> >> is there a way to dump the effective postfix configuration rather than
> >> the one specified in main.cf/master.cf? It seems that changes to
> >> main.cf/master.cf have an immediate impact on the output of postconf
> >> regardless of whether a reload/restart of the service was performed.
> > 
> > How would that work? Different Postfix processes start at different
> > times, and some processes (qmgr, master) run forever.
> 
> I could think of something like this:
> 
> Instead of sending a HUP signal like it is done to trigger a reload, one 
> sends a different signal (e. g. USR1) to the master. The further 
> processing of the signal is similar to the HUP case except that 
> configuration dumps are triggered rather than configuration reloads.

How could that be useful? On a busy server, there will be be 100+
smtpd (SMTP server) processes, 100+ cleanup processes, 100+ smtp
(SMTP client) processes and so on. Those processes were started an
different times and they will produce different dumps if you change
Postfix configuration without "postfix reload".

If you want an accurate picture of what configuration is in effect.
then I think that is not too much trouble to run "postfix reload"
after a configuration change. Then "postconf" output reflects the
effective configuration.

Instead of dumping configurations, there are other ways. For example,
each daemon could log configuration file stamps when the process
is started (or communicate that info in some other manner). Given
a history of (time stamp, config file content) you could use the
logged time stamps to find out what configuration is (or was) in
effect for each daemon process.

Wietse


Re: Dumping effective postfix configuration

2023-01-06 Thread Peter Wienemann

On 06.01.23 13:15, Wietse Venema wrote:

is there a way to dump the effective postfix configuration rather than
the one specified in main.cf/master.cf? It seems that changes to
main.cf/master.cf have an immediate impact on the output of postconf
regardless of whether a reload/restart of the service was performed.


How would that work? Different Postfix processes start at different
times, and some processes (qmgr, master) run forever.


I could think of something like this:

Instead of sending a HUP signal like it is done to trigger a reload, one 
sends a different signal (e. g. USR1) to the master. The further 
processing of the signal is similar to the HUP case except that 
configuration dumps are triggered rather than configuration reloads.


What I have in mind would be a similar user experience to what one gets 
when running "ceph config show [...]" [0] in the Ceph case or 
"condor_config_val [daemon]" [1] in case of HTCondor.


Peter

[0] https://docs.ceph.com/en/latest/rados/configuration/ceph-conf/#commands

[1] 
https://htcondor.readthedocs.io/en/latest/man-pages/condor_config_val.html


Re: Dumping effective postfix configuration

2023-01-06 Thread Wietse Venema
Peter Wienemann:
> Hi,
> 
> is there a way to dump the effective postfix configuration rather than 
> the one specified in main.cf/master.cf? It seems that changes to 
> main.cf/master.cf have an immediate impact on the output of postconf 
> regardless of whether a reload/restart of the service was performed.

How would that work? Different Postfix processes start at different
times, and some processes (qmgr, master) run forever.

Wietse


Dumping effective postfix configuration

2023-01-06 Thread Peter Wienemann

Hi,

is there a way to dump the effective postfix configuration rather than 
the one specified in main.cf/master.cf? It seems that changes to 
main.cf/master.cf have an immediate impact on the output of postconf 
regardless of whether a reload/restart of the service was performed.


Peter