journal: give the ability to enable/disable systemd-journald-audit.so… - #25687
Conversation
|
I also considered introducing a new option such as I'm not sure why PID1 keeps a reference after it passes the fd to the service though. |
|
The messages processing or mere listening audit socket can cause some performance headaches. I may suggest a convenience comment into |
Indeed it's a good suggestion. I'll add a comment if there's a chance for this PR to be accepted. |
|
hmm, i guess this would be ok to do. But could you please make three additions:
|
|
@poettering thanks for the feedback. Before addressing the points you raised, I'd like to know why PID1 keeps the socket fds opened from its side once they have been handed over to the services. I'm asking because the best solution IMO would be to introduce a new config option but it's currently not ideal because even if journald closes the audit socket, PID1 keeps a reference on it, which prevents the kernel from freeing the resources allocated for the audit socket. |
|
@fbuihuu Maybe PID1 needs extra functionality to detect if the fd, used for the audit socket, gets closed so it frees it again. 🤔 I guess no-one of the coders even thought about the possibility of that socket getting closed because the default was/is to always have a service read from that socket... But then there comes another hick-up: What should happen when the service gets activated again manually afterwards by the operator or otherwise ? |
to make restarts work? i.e. that we hand the same sockets down without losing a single message. |
You could just issue the equivalent bus call of "systemctl stop systemd-journald-audit.socket" from journald so that PID1 closes the sockets. That's kinda what a socket unit is after all: the encapsulation of a listening socket, and via "start" you allocate/bind it, and via "stop" you close it. But please, let's not do that. Let's not add multiple layers of config here, that do the same thing. There's nothing wrong with just telling people "hey, if you want audit gone, use |
Hmm isn't the service supposed to send the socket fds it wants to keep opened back to PID1 in that case (via |
That's for stuff the daemon itself allocates. For example, if a daemon accepts connections on a listener socket. The listener socket would be allocated by PID 1, but the connection sockets would be accept()ed by the daemon itself. If those are long-running connections it might make sense to hand them over to PID 1 so that they can be continued to be processed after a restart. Moreover, if the listener fd itself would first be handed to the service, and then handed back to PID 1 from there this would not just be more work, but also racy: if the service dies before it can send the listener fd back up, then it is lost. Socket activation is really supposed to be about reliability though: the daemon always can recover the service if it dies, by passing the original listener fd back in, so that the daemon can continue where it left of. |
|
If the daemon fails to send connection sockets it setup itself to PID1 or any fds that are part of its state, it's likely that it won't be able to recover properly if it dies unexpectedly, no ? Anyway, I'll update the PR. |
dunno, failures often are transient, i.e. resource issues triggered on overloaded systems. since these issues are recoverable we should make recovery obvious. generally the assumption is that we can assert the service manager is reasonably good quality code. it's harder to assert the same for all possible services. hence it's good not leaving too much chance for the service code to fuck up, and make it robust by not even giving the services the chance to fuck up. |
7eebabe to
270f674
Compare
|
@poettering new version submitted, PTAL. |
270f674 to
6b1ddc1
Compare
|
@poettering is that better ? thanks |
|
Unfortunately this changes the default: before systemd-journald-audit.socket was enabled by default, now it is disabled by default. Please also add a setting in presets to make it enabled by default. |
…cket Before this patch the only way to prevent journald from reading the audit messages was to mask systemd-journald-audit.socket. However this had main drawback that downstream couldn't ship the socket disabled by default (beside the fact that masking units is not supposed to be the usual way to disable them). Fixes systemd#15777
6b1ddc1 to
b8b0095
Compare
Good catch, fixed. Thanks. |
|
Just curious: what's the benefit of disabling |
|
|
||
| [Install] | ||
| WantedBy=sockets.target | ||
| WantedBy=systemd-journald.service |
There was a problem hiding this comment.
Why WantedBy=systemd-journald.service? Shouldn't sockets.target be sufficient and more closely mirror the previous state where there only was a static link in socket.target.wants
There was a problem hiding this comment.
journald is an early-boot service that should work as intended on its own. sockets.target is a pulled in as part of basic.target, i.e. when you boot at least into "single user mode". That's substantially more than just logging.
So in order to support systems that want to boot exactly one other service + journal i think it makes sense to hook it into systemd-journald.service directly. (not saying this is a reallly relevant scenario, but hey, probably still worth supporting).
There was a problem hiding this comment.
IIRC, it's also useful when starting/stopping journald manually at runtime. So if one decides to enable the collection of audit messages after the system booted, he would simply need to issue systemctl enable systemd-journald-audit.socket; systemctl restart systemd-journald
The former disables audit message collection of journald, the latter controls audit message generation of the kernel. The distinction matters once other audit implementations should be used in conjunction |
Also, not having the audit socket (idling in PID1) reduces performance impact (on systems where audit isn't intended). |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
So we now have these combinations afaics. What happens in those different states? And in what situations should I use
|
|
Unfortunately this change exposed a significant bug in systemd transaction logic. I'll file a separate bug with the details. |
The socket unit opens the audit socket. if you don't open it no audit for you, none at all. It's a complete kill switch of any audit logic inside of journald. Audit=yes|no is a wrapper around a specific command that can be issued on the audit socket. if you don't have the audit socket in the first place, we cannot issue that command, hence Audit= is without effect. Audit=yes tells the kernel via the audit socket to generate audit events. Audit=no tells the kernel to not do so. Audit unset skips the step entirely. You can also issue the command that Audit= wraps via "auditctl -e…" from outside. This allows journald to listen for audit events on the socket all the time, but until that external invocation is done no audit events will actually be seen. Basically the socket unit enablement controls whether a) systemd will consume any audit messages that are generated on the system, and b) it controls whether Audit= will have any effect whatsoever. You might wonder what the point of enabling the socket, but then not using Audit=yes would be. In that mode journald will be a "silent listener", so it won't get any messages until some other tool enables the stuff explicity, such as the original audit tools. |
@keszybz, could you share the details ? |
This was broken due to systemd/systemd#25687 but we never noticed.
This was broken due to systemd/systemd#25687 but we never noticed. (cherry picked from commit 13b1062)
…cket
Before this patch the only way to prevent journald from reading the audit messages was to mask systemd-journald-audit.socket. However this had main drawback that downstream couldn't ship the socket disabled by default (beside the fact that masking units is not supposed to be the usual way to disable them).
Fixes #15777