-
Notifications
You must be signed in to change notification settings - Fork 58
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
Blocks not appearing in the audit logs when using deny_audit #84
Comments
Rule 6 says it will not allow xz to access any files. This probably means its own shared objects at link time. And that is probably why it blocks. To block execution of xz, you probably want deny_audit perm=execute all : path=/usr/local/bin/xz. Also, I think you would want this below the shared object rules but before the elf executables. It is not expected that a rule with deny_audit would not log something. I just tested this on my system using the rule as given and I see an event. However, its rule 15 which is a general no execution rule. |
I'm still having a devil of a time getting something to show up in the audit log. I went and updated the rule per your suggestion and now it appears to properly deny execution by bash, but the deny event still isn't appearing in the audit.log. If I run fapolicyd like this:
Here is the list of rules:
Here's the test: Root terminal:
User terminal:
So we can see rule #8 is denying execution of /usr/local/bin/xz and its a deny_audit rule, but the audit.log remains untouched for the duration of the test. Any suggestions on where I should look next? |
Another data point. If I change the rule from deny_audit, to deny_log, I get an entry in /var/log/messages, but still no entry in /var/log/audit/audit.log.
|
Thanks Steve, I'll pull down the latest and give it another whirl later today and update this thread with my results. |
No dice! The latest code deadlocks my system when started via
The ssh hangs until I
Even the VM console itself is locked. My only recourse is to |
It was missing a set of parenthesis in policy.h. Last commit should fix that. |
I can confirm that the system no longer deadlocks with this change. I'm still not able to get anything in the audit log. User terminal:
Root terminal:
Running in debug mode, we see that rule 14 is what's blocking the execution of /usr/local/bin/xz and we see that the rule is a deny_audit rule. When running via systemd, the execution gets blocked, but still nothing shows up in the audit log. I'm trying to collect some fapolicyd audit logs so I can take libauparse for a spin, but I need sample data! |
Wild guess, does "ldd /usr/sbin/fapolicyd" show that libaudit.so.1.0.0 is linked to it? |
|
In policy.c, in the make_policy_decision function, I added Running
Running
/var/log/audit/audit.log:
This is on a fresh installation of CentOS 8.2 with all the latest updates applied.
From there, here is how the prerequisites and the build are run to setup the test:
as user:
|
It appears that what is going into the kernel is correct. If audit is enabled and there is an audit pid, shown by auditctl -s, then it should be going into the audit logs. |
I just installed RHEL 8.3 beta and fapolicyd from the official repository. I copied xz from
Next we run
I
Still nothing appears in the Here's some data that may help:
It appears that the audit behavior is the same on CentOS 8.2 and RHEL 8.3 beta. |
What do you get when you do: |
Still nothing. root terminal:
user terminal:
root terminal:
|
I tried Fedora 32 now in addition to RHEL 8.2, RHEL 8.3 beta, CentOS 8.1 and CentOS 8.2 and have the same results across all 5 of these operating systems. It's consistent on these fresh installs using the official repos and the code currently in master for CentOS (so at least version 1.0). Can this not be reproduced? root terminal:
user terminal:
root terminal:
Relevant info:
|
I've reproduced this on the 8.2 kernel. |
One more data point. I built from master and installed the built RPM on this Fedora 32 instance and the results are the same... access to |
cp /usr/share/audit/sample-rules/43-module-load.rules /etc/audit/rules.d/ |
Even with that rules file in place and restarting the services, I'm not finding anything in the audit log on Fedora 32. root terminal:
user terminal:
root terminal:
|
I had success on RHEL 8.3 beta. root terminal:
|
This is the first time I'm seeing an audit log. This is full of great information. Is there a way to trace this denial back to the matching fapolicyd rule? |
Unfortunately not. I was forbidden to make the change that would allow it. The decision was something like they do not want to make kernel changes that benefit a single application. This is exactly the reason why the syslog option was added. |
I can understand the "benefit a single application" argument and I don't disagree. However, when creating a framework, it's not unusual to have a field for "context". In C/C++ we see this with callbacks taking a void pointer that it just passes through. For audit logging, can a reasonable argument be made for something like a "context field" that different applications can use for their own purposes (a CLOB) to pass information similar to a void pointer in callbacks? For FANOTIFY denial context would be the rule ID, for other applications it can be something else. A context field could benefit all applications that use the audit subsystem, so the "benefit a single application" argument no longer applies. Sometimes engineering requires a dollop of marketing, but I digress. If it's not currently possible to use the audit log to create an "audit2allow" workalike, and parsing syslog is a dicy proposition considering that the logging format is user-defined, which could make processing the data we need problematic or impossible. |
Alternatively, are there any other fields in the audit record that can be coopted for the rule ID? Another option might to use journald. |
The problem is that we have no control over any fields from user space. The code is here: |
It is important to know the rule ID responsible for a file access being denied and this traceability, is objectively, an audit function. The tradeoff in this proposal is that the rule limit (and distinct responses) will be capped at 64K, which sounds completely reasonable. I think we should advocate hard for this. Please try again and let me know if there is anything I can do to help! |
Thinking a bit more on the rule ID and the judgement unioned into the 32 bit response... using the upper 3 bytes (24 bits) for the rule ID and the lower byte (8 bits) might be a superior split yielding limits of 2^24 (~16.7 million) rule IDs and 2^8 (256) distinct types of judgements. |
I don't think we can be that greedy taking all the bits. I was thinking of 3 for context type and 8 for context. I'm mulling over whether its worth 5 more bits to identify the exact item that was objected to. That would leave 13 bits for future use. |
3 for context type for 8 distinct types |
3 bits allows 8 different context_types. Of which none and rules would be initially defined. Then under context_type=rules, 8 bits would allow 256 rules to be identified. A policy with more rules is utterly messed up. Then 5 more bits allow up to 32 objects in the rules category to be pointed to. We currently have 3 bits allocated for a response. So, 3+3+8+5=19 used. 32 - 19 = 13 unused bits. |
I don't know what this means? Can you restate that or give me an example? I'm also not convinced that there won't be reasonable use cases where the number of rules can number into the hundreds. The richness provided in the current rules language means that a lot of ground can be covered in a handful of rules. I'm thinking of examples where the rules are very targeted and specific aimed at specific applications and services, for specific groups and specific users. Entities that are skeptical of ftype determinations will also tend to have a larger number of rules in their policies. Simple automated tooling will lack the logic required to coalesce a set of narrowly focused rules into a single, more complex rule. Being able to trace an audit event back to the responsible rule ID is a big win. |
A kernel patch has been accpepted upstream. The new audit record will look like this when translated: type=FANOTIFY msg=audit(02/06/2023 17:42:13.837:298) : resp=deny fan_type=rule_info fan_info=13 subj_trust=unknown obj_trust=no This says that access is denied, the additional info is a rule number, rule 13 triggered, subject trust is unknown, and object is not trusted. That should allow closing the loop via audit records. With that, I think we can close this issue. Also, the accepted patch allows 32 bits to express the rule number. |
Closing. |
@stevegrubb please list a link to the patch so we can track its implementation. |
It is in the 6.3 kernel. The user space piece has to be compiled with the new data structures in patch 2 in the build root. Support is disabled if not found at compile time. |
Add support for analyzing from kernel audit logs --- Adds an "audit" analyze event source that reads fanotify events from libaudit to be displayed in the analyzer. The records are read into the common Event structure that allows them to flow through the same API as the events from syslog and debug logs. The entrypoint to this functionality is found in the Analyze menu and behaves similar to syslog where there is not a prompt to provide a path to the log file. The backend uses the libaudit API to locate and parse the system audit log. This currently only has runtime support in the Kernel on Fedora Rawhide (fc39), so while the backend is always built the frontend is disabled on all other platforms. It is anticipated that rhel 8 and 9 will both contain the required audit support at some point in the future. The build is currently wired into both of them with the feature flag disabled, hiding the functionality in the UI. The audit support is implemented using bindgen to create native bindings to libaudit and auparse. To enable this our build requirements have grown to include clang and the audit dev libs to support building the bindings with bindgen. These bindings are generated at compile time and are excluded from version control. ### Also adds - Adds Python LogType enum in place of some magic strings - Plumbs Cargo feature support into the python build - Improves the make header-check to support piping the output ### Requires - Kernel >= 6.3 - Audit >= 3.1 - fapolicyd >= 1.2 It may be possible to move the feature flag to a runtime check, allowing upgraded systems to use the audit feature, but this is not within the scope of this PR. Given that that there is no support outside of fc39, there is some time to refine audit related capability before it has wide applicability. ### Reference - linux-audit/audit-kernel@032bffd - linux-audit/audit-userspace@d1aec22 - https://lore.kernel.org/linux-fsdevel/20230207120921.7pgh6uxs7ze7hkjo@quack3/ - linux-application-whitelisting/fapolicyd#84 - linux-application-whitelisting/fapolicyd@ee9c99a Closes #294
I just built and installed fapolicyd via an RPM ($ sudo yum install -y /home/scholarsmate/rpmbuild/RPMS/x86_64/fapolicyd-1.0.1-1.x86_64.rpm). Everything is stock, except I created a rule to deny (with audit) /usr/local/bin/xz. The details of the test are below.
I was expecting something to show up in /var/log/audit/audit.log, but nothing was written to it after the execution of /usr/local/bin/xz was blocked. Is this the expected behavior?
Thanks.
The text was updated successfully, but these errors were encountered: