Should some snapd interfaces be modified?

Hello mates,

Please, can you help me identify if some snapd interfaces should be extended and/or is there a proper interface we are not using?

node-exporter is a server application that exports host metrics in Prometheus format.

We are trying to come up with a proper snapcraft.yaml definition in order to be able to export host’s metrics in a strict confinement.

After installing the snap and enabling all its exporters:

sudo snap set node-exporter collectors="buddyinfo cgroups cpu_vulnerabilities drm drbd ethtool interrupts ksmd lnstat logind meminfo_numa mountstats network_route perf processes qdisc slabinfo softirqs sysctl systemd tcpstat wifi xfrm zoneinfo"

I see a lot of errors in syslog.

My gut feeling is that some of the files node-exporter cannot access should be enabled in some the snapd interfaces.

  • /sys/fs/btrfs/
  • /proc/softirqs
  • /proc/spl/kstat/zfs/
  • /proc/buddyinfo
  • /proc/slabinfo
  • /proc/sys/kernel/random/poolsize
  • /sys/kernel/mm/ksm/full_scans
  • /proc/sys/kernel/threads-max

I tried with a custom plug, but the errors are still there:

@@ -11,6 +11,22 @@ confinement: strict
 base: core24
 adopt-info: node-exporter
 
+plugs:
+  proc-sys-kernel-random:
+    interface: system-files
+    read:
+      - /lib/systemd/systemd-logind
+      - /proc/buddyinfo
+      - /proc/slabinfo
+      - /proc/softirqs
+      - /proc/spl/kstat/zfs
+      - /proc/sys/kernel/random/poolsize
+      - /proc/sys/kernel/random/write_wakeup_threshold
+      - /proc/sys/kernel/threads-max
+      - /proc/sys/kernel/threads-max
+      - /sys/fs/btrfs
+      - /sys/kernel/mm/ksm/full_scans
+
 parts:
   wrapper:
     plugin: dump
@@ -49,3 +65,4 @@ apps:
     - mount-observe
     - network-observe
     - system-observe
+    - proc-sys-kernel-random

Besides, there are some apparmor DENIED messages.

The log lines from syslog are:

2025-08-16T13:35:12.626012-03:00 guille kernel: audit: type=1400 audit(1755362112.624:427589): apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=1745355 comm="node_exporter" capability=12  capname="net_admin"
2025-08-16T13:35:12.629993-03:00 guille kernel: audit: type=1400 audit(1755362112.628:427590): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/sys/fs/btrfs/" pid=1745355 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-16T13:35:12.631983-03:00 guille kernel: audit: type=1400 audit(1755362112.630:427591): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/softirqs" pid=1745355 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-16T13:35:12.631986-03:00 guille kernel: audit: type=1400 audit(1755362112.630:427592): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/spl/kstat/zfs/" pid=1745355 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-16T13:35:12.632045-03:00 guille node-exporter.node-exporter[1745355]: time=2025-08-16T16:35:12.631Z level=ERROR source=collector.go:168 msg="collector failed" name=softirqs duration_seconds=1.3615e-05 err="couldn't get softirqs: open /proc/softirqs: permission denied"
2025-08-16T13:35:12.633312-03:00 guille node-exporter.node-exporter[1745355]: time=2025-08-16T16:35:12.633Z level=ERROR source=collector.go:168 msg="collector failed" name=buddyinfo duration_seconds=1.1271e-05 err="couldn't get buddyinfo: open /proc/buddyinfo: permission denied"
2025-08-16T13:35:12.633982-03:00 guille kernel: audit: type=1400 audit(1755362112.632:427593): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/buddyinfo" pid=1745355 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-16T13:35:12.634574-03:00 guille node-exporter.node-exporter[1745355]: time=2025-08-16T16:35:12.634Z level=ERROR source=collector.go:168 msg="collector failed" name=slabinfo duration_seconds=1.1491e-05 err="couldn't get slabinfo: open /proc/slabinfo: permission denied"
2025-08-16T13:35:12.634983-03:00 guille kernel: audit: type=1400 audit(1755362112.633:427594): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/slabinfo" pid=1745355 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-16T13:35:12.652310-03:00 guille node-exporter.node-exporter[1745355]: time=2025-08-16T16:35:12.652Z level=ERROR source=collector.go:168 msg="collector failed" name=entropy duration_seconds=3.9745e-05 err="failed to get kernel random stats: open /proc/sys/kernel/random/poolsize: permission denied"
2025-08-16T13:35:12.652934-03:00 guille node-exporter.node-exporter[1745355]: time=2025-08-16T16:35:12.652Z level=ERROR source=collector.go:168 msg="collector failed" name=ksmd duration_seconds=2.5778e-05 err="open /sys/kernel/mm/ksm/full_scans: permission denied"
2025-08-16T13:35:12.653006-03:00 guille kernel: audit: type=1400 audit(1755362112.651:427595): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/poolsize" pid=1745355 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-16T13:35:12.653016-03:00 guille kernel: audit: type=1400 audit(1755362112.651:427596): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/sys/kernel/mm/ksm/full_scans" pid=1745355 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-16T13:35:12.659989-03:00 guille kernel: audit: type=1400 audit(1755362112.658:427597): apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=1745355 comm="node_exporter" capability=2  capname="dac_read_search"
2025-08-16T13:35:12.659997-03:00 guille kernel: audit: type=1400 audit(1755362112.658:427598): apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=1745355 comm="node_exporter" capability=1  capname="dac_override"
2025-08-16T13:35:12.734453-03:00 guille node-exporter.node-exporter[1745355]: time=2025-08-16T16:35:12.734Z level=ERROR source=collector.go:168 msg="collector failed" name=processes duration_seconds=0.110195732 err="unable to retrieve limit number of threads: open /proc/sys/kernel/threads-max: permission denied"
2025-08-16T13:35:12.734553-03:00 guille node-exporter.node-exporter[1745355]: time=2025-08-16T16:35:12.734Z level=ERROR source=collector.go:168 msg="collector failed" name=logind duration_seconds=0.099305684 err="unable to get seats: An AppArmor policy prevents this sender from sending this message to this recipient; type=\"method_call\", sender=\":1.64728\" (uid=0 pid=1745355 comm=\"/snap/node-exporter/1941/bin/node_exporter --colle\" label=\"snap.node-exporter.node-exporter (enforce)\") interface=\"org.freedesktop.login1.Manager\" member=\"ListSeats\" error name=\"(unset)\" requested_reply=\"0\" destination=\"org.freedesktop.login1\" (uid=0 pid=8852 comm=\"/usr/lib/systemd/systemd-logind\" label=\"unconfined\")"

Hey! Let me answer file-by-file:

This causes a denial such as this one:

[93779.675425] audit: type=1400 audit(1755520881.137:261): apparmor=“DENIED” operation=“open” class=“file” profile=“snap.test-snapd-sh.sh” name=“/proc/buddyinfo” pid=7468 comm=“cat” requested_mask=“r” denied_mask=“r” fsuid=1000 ouid=0

No interface grants this file currently. My suggestion is to propose it as an addition to system-observe interface. I could not find a manual page that documents the file but a quick search returned this RedHat document which leads me to believe it is appropriate to add there.

This is always going to look at the systemd-logind of the base snap of your snap. If that is what you want then we can look but I suspect you’d rather know about the one used on the host. What is the reason for accessing logind like that? Is it to look for a specific version (e.g. scan it for known issues etc?)

This causes denial such as this one:

[94251.092035] audit: type=1400 audit(1755521352.554:265): apparmor=“DENIED” operation=“capable” class=“cap” profile=“snap.test-snapd-sh.sh” pid=7789 comm=“cat” capability=2 capname=“dac_read_search” [94251.092049] audit: type=1400 audit(1755521352.554:266): apparmor=“DENIED” operation=“capable” class=“cap” profile=“snap.test-snapd-sh.sh” pid=7789 comm=“cat” capability=1 capname=“dac_override” [94251.092475] audit: type=1400 audit(1755521352.554:267): apparmor=“DENIED” operation=“open” class=“file” profile=“snap.test-snapd-sh.sh” name=“/proc/slabinfo” pid=7789 comm=“cat” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0

This is similar to buddyinfo but has an added restriction of needing root or capability to access.

Again, similar story. My suggestion is to add it to system-observe.

None of my systems use ZFS so I have no idea about this. I’d defer this one to other reviewers.

Pool size is likely system-observe again. Write wakeup threshold is … probably the same unless you need to write to it, in such case it’d go to a new interface of some sort (a foo-control interface or a per-snap foo-support interface).

Similar story as write_wakeup_threshold since it is writable.

I didn’t have this file on my test system so I’m not sure. It probably belongs somewhere with the ZFS file in an -observe interface.

I was unable to find any manual page that documents it but some more search online this feels like something that would either end up in qemu-support like interface or perhaps a dedicated ksm interface (to be discussed).

EDIT: In general let’s break this down and start proposing pull requests. Please tag me in the pull request (reviewer) and I will help.

Hey @zyga !

Thank you very much for your guidance!

I have opened a PR for the system-observe interface: add more files to enable node-exporter to work by Abuelodelanada · Pull Request #15844 · canonical/snapd · GitHub

About the other interfaces:

I need this file in order for the node-exporter’s exporter logind to work, which Exposes session counts from logind.

Wait, but what do you need exactly? Do you need to run logind itself (very unlikely)? Do you need a specific D-Bus API call?

According to node-exporter’s doc, that collector “Exposes session counts from logind.”

By reading this collector’s code I can see that there are some dbus API calls:

Right, but do you need to invoke those APIs or do you need to invoke the binary so that it gets to do those calls internally?

I think we can allow some of the D-Bus calls (but they have to be more precise - exact methods / objects) but the binary is probably not relevant.

Our knowledge of the logind collector for node-exporter is minimal, since we only maintain the snap.

My gut feeling is that node-exporter does not invoke the binary since it uses the godbus lib

What would you do to avoid error logs like this one in syslog? Is something we can do from the snap creation point of view?

2025-08-16T13:35:12.734553-03:00 guille node-exporter.node-exporter[1745355]: time=2025-08-16T16:35:12.734Z level=ERROR source=collector.go:168 msg="collector failed" name=logind duration_seconds=0.099305684 err="unable to get seats: An AppArmor policy prevents this sender from sending this message to this recipient; type=\"method_call\", sender=\":1.64728\" (uid=0 pid=1745355 comm=\"/snap/node-exporter/1941/bin/node_exporter --colle\" label=\"snap.node-exporter.node-exporter (enforce)\") interface=\"org.freedesktop.login1.Manager\" member=\"ListSeats\" error name=\"(unset)\" requested_reply=\"0\" destination=\"org.freedesktop.login1\" (uid=0 pid=8852 comm=\"/usr/lib/systemd/systemd-logind\" label=\"unconfined\")"

This looks like a D-Bus message and thus no access to logind executable is needed. Can you collect more with?

sudo dmesg | grep ALLOWED

This is not perfect but should give us some idea as to what messages are required. Make sure to this with the snap in devmode, so that we see the whole communication pattern.

Hey @zyga, look:

[4376740.636009] audit: type=1400 audit(1755689895.273:455115): apparmor="ALLOWED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=2431686 comm="node_exporter" capability=38  capname="perfmon"
[4376746.716885] audit: type=1400 audit(1755689901.354:455741): apparmor="ALLOWED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/poolsize" pid=2431686 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
[4376746.716890] audit: type=1400 audit(1755689901.354:455742): apparmor="ALLOWED" operation="file_perm" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/poolsize" pid=2431686 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
[4376746.716893] audit: type=1400 audit(1755689901.354:455743): apparmor="ALLOWED" operation="file_perm" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/poolsize" pid=2431686 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
[4376746.716895] audit: type=1400 audit(1755689901.354:455744): apparmor="ALLOWED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/urandom_min_reseed_secs" pid=2431686 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
[4376746.716902] audit: type=1400 audit(1755689901.354:455745): apparmor="ALLOWED" operation="file_perm" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/urandom_min_reseed_secs" pid=2431686 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
[4376746.716905] audit: type=1400 audit(1755689901.354:455746): apparmor="ALLOWED" operation="file_perm" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/urandom_min_reseed_secs" pid=2431686 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
[4376746.716913] audit: type=1400 audit(1755689901.354:455747): apparmor="ALLOWED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/write_wakeup_threshold" pid=2431686 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
[4376746.716920] audit: type=1400 audit(1755689901.354:455748): apparmor="ALLOWED" operation="file_perm" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/write_wakeup_threshold" pid=2431686 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
[4376746.716923] audit: type=1400 audit(1755689901.354:455749): apparmor="ALLOWED" operation="file_perm" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/write_wakeup_threshold" pid=2431686 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
[4376746.717285] audit: type=1400 audit(1755689901.354:455750): apparmor="ALLOWED" operation="capable" class="cap" info="optional: no audit" error=-1 profile="snap.node-exporter.node-exporter" pid=2431686 comm="node_exporter" capability=12  capname="net_admin"

EDIT: These log were generated with the published snap in edge

He @zyga

Could you see these log lines?

Hi @zyga

I created two VM running Ubuntu 24.04, named snapd-orig and snapd-pr

In snapd-pr I downloaded the snapd package built in the CI in the PR I opened and upgrade it.

In both machines, I also installed and configured node-exporter snap.

$ sudo snap set node-exporter collectors="buddyinfo cgroups cpu_vulnerabilities drm drbd ethtool interrupts ksmd lnstat logind meminfo_numa mountstats network_route perf processes qdisc slabinfo softirqs sysctl systemd tcpstat wifi xfrm zoneinfo"

This way I have:

ubuntu@snapd-pr:~$ snap list | egrep "snapd|node-exporter"
node-exporter    v1.9.1                  1959  latest/edge    jose-masson  -
snapd            1337.2.71+g118.32d8555  x1    latest/stable  -            snapd
ubuntu@snapd-orig:~$ snap list | egrep "snapd|node-exporter"
node-exporter    v1.9.1    1959   latest/edge    jose-masson  -
snapd            2.71      25202  latest/stable  canonical**  snapd

With this, I could verify that the amount of log lines in syslog decreased! :tada:

Show logs
ubuntu@snapd-pr:~$ sudo tail -F /var/log/syslog | grep "node-exporter"

2025-08-28T21:13:03.409013+00:00 snapd-pr kernel: audit: type=1400 audit(1756415583.407:210): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/urandom_min_reseed_secs" pid=4336 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-28T21:13:03.409142+00:00 snapd-pr node-exporter.node-exporter[4336]: time=2025-08-28T21:13:03.408Z level=ERROR source=collector.go:168 msg="collector failed" name=entropy duration_seconds=8.3459e-05 err="failed to get kernel random stats: open /proc/sys/kernel/random/urandom_min_reseed_secs: permission denied"
2025-08-28T21:13:03.420014+00:00 snapd-pr kernel: audit: type=1400 audit(1756415583.418:211): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/sys/kernel/mm/ksm/full_scans" pid=4336 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-28T21:13:03.420030+00:00 snapd-pr kernel: audit: type=1400 audit(1756415583.418:212): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/sys/fs/btrfs/" pid=4336 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-28T21:13:03.427437+00:00 snapd-pr node-exporter.node-exporter[4336]: time=2025-08-28T21:13:03.419Z level=ERROR source=collector.go:168 msg="collector failed" name=ksmd duration_seconds=8.2487e-05 err="open /sys/kernel/mm/ksm/full_scans: permission denied"
2025-08-28T21:13:03.432003+00:00 snapd-pr kernel: audit: type=1400 audit(1756415583.430:213): apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=4336 comm="node_exporter" capability=12  capname="net_admin"
2025-08-28T21:13:03.438012+00:00 snapd-pr kernel: audit: type=1400 audit(1756415583.436:214): apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=4336 comm="node_exporter" capability=2  capname="dac_read_search"
2025-08-28T21:13:03.438025+00:00 snapd-pr kernel: audit: type=1400 audit(1756415583.436:215): apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=4336 comm="node_exporter" capability=1  capname="dac_override"
2025-08-28T21:13:03.439229+00:00 snapd-pr kernel: audit: type=1400 audit(1756415583.437:216): apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=4336 comm="node_exporter" capability=12  capname="net_admin"
2025-08-28T21:13:03.443856+00:00 snapd-pr node-exporter.node-exporter[4336]: time=2025-08-28T21:13:03.443Z level=ERROR source=collector.go:168 msg="collector failed" name=logind duration_seconds=0.036154468 err="unable to get seats: An AppArmor policy prevents this sender from sending this message to this recipient; type=\"method_call\", sender=\":1.30\" (uid=0 pid=4336 comm=\"/snap/node-exporter/1959/bin/node_exporter --colle\" label=\"snap.node-exporter.node-exporter (enforce)\") interface=\"org.freedesktop.login1.Manager\" member=\"ListSeats\" error name=\"(unset)\" requested_reply=\"0\" destination=\"org.freedesktop.login1\" (uid=0 pid=883 comm=\"/usr/lib/systemd/systemd-logind\" label=\"unconfined\")"
2025-08-28T21:13:03.444012+00:00 snapd-pr kernel: audit: type=1107 audit(1756415583.441:217): pid=868 uid=101 auid=4294967295 ses=4294967295 subj=unconfined msg='apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/org/freedesktop/login1" interface="org.freedesktop.login1.Manager" member="ListSeats" mask="send" name="org.freedesktop.login1" pid=4336 label="snap.node-exporter.node-exporter" peer_pid=883 peer_label="unconfined"
ubuntu@snapd-orig:~$ sudo tail -F /var/log/syslog | grep "node-exporter"

2025-08-28T21:13:07.413163+00:00 snapd-orig node-exporter.node-exporter[3770]: time=2025-08-28T21:13:07.412Z level=ERROR source=collector.go:168 msg="collector failed" name=ksmd duration_seconds=3.0798e-05 err="open /sys/kernel/mm/ksm/full_scans: permission denied"
2025-08-28T21:13:07.413328+00:00 snapd-orig node-exporter.node-exporter[3770]: time=2025-08-28T21:13:07.413Z level=ERROR source=collector.go:168 msg="collector failed" name=softirqs duration_seconds=1.9667e-05 err="couldn't get softirqs: open /proc/softirqs: permission denied"
2025-08-28T21:13:07.413588+00:00 snapd-orig kernel: audit: type=1400 audit(1756415587.412:204): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/sys/kernel/mm/ksm/full_scans" pid=3770 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-28T21:13:07.413588+00:00 snapd-orig kernel: audit: type=1400 audit(1756415587.412:205): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/softirqs" pid=3770 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-28T21:13:07.417223+00:00 snapd-orig node-exporter.node-exporter[3770]: time=2025-08-28T21:13:07.417Z level=ERROR source=collector.go:168 msg="collector failed" name=buddyinfo duration_seconds=2.5849e-05 err="couldn't get buddyinfo: open /proc/buddyinfo: permission denied"
2025-08-28T21:13:07.417617+00:00 snapd-orig kernel: audit: type=1400 audit(1756415587.416:206): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/buddyinfo" pid=3770 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-28T21:13:07.428153+00:00 snapd-orig node-exporter.node-exporter[3770]: time=2025-08-28T21:13:07.428Z level=ERROR source=collector.go:168 msg="collector failed" name=processes duration_seconds=0.00759529 err="unable to retrieve limit number of threads: open /proc/sys/kernel/threads-max: permission denied"
2025-08-28T21:13:07.430944+00:00 snapd-orig kernel: audit: type=1400 audit(1756415587.427:207): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/threads-max" pid=3770 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-28T21:13:07.430875+00:00 snapd-orig node-exporter.node-exporter[3770]: time=2025-08-28T21:13:07.430Z level=ERROR source=collector.go:168 msg="collector failed" name=entropy duration_seconds=4.795e-05 err="failed to get kernel random stats: open /proc/sys/kernel/random/poolsize: permission denied"
2025-08-28T21:13:07.431546+00:00 snapd-orig kernel: audit: type=1400 audit(1756415587.430:208): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/poolsize" pid=3770 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-28T21:13:07.434544+00:00 snapd-orig kernel: audit: type=1400 audit(1756415587.433:209): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/slabinfo" pid=3770 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-28T21:13:07.434768+00:00 snapd-orig node-exporter.node-exporter[3770]: time=2025-08-28T21:13:07.434Z level=ERROR source=collector.go:168 msg="collector failed" name=slabinfo duration_seconds=4.5185e-05 err="couldn't get slabinfo: open /proc/slabinfo: permission denied"
2025-08-28T21:13:07.435546+00:00 snapd-orig kernel: audit: type=1400 audit(1756415587.434:210): apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/sys/fs/btrfs/" pid=3770 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
2025-08-28T21:13:07.435681+00:00 snapd-orig kernel: audit: type=1400 audit(1756415587.434:211): apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=3770 comm="node_exporter" capability=12  capname="net_admin"
2025-08-28T21:13:07.438983+00:00 snapd-orig kernel: audit: type=1400 audit(1756415587.437:212): apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=3770 comm="node_exporter" capability=2  capname="dac_read_search"
2025-08-28T21:13:07.438999+00:00 snapd-orig kernel: audit: type=1400 audit(1756415587.437:213): apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=3770 comm="node_exporter" capability=1  capname="dac_override"
2025-08-28T21:13:07.444613+00:00 snapd-orig node-exporter.node-exporter[3770]: time=2025-08-28T21:13:07.444Z level=ERROR source=collector.go:168 msg="collector failed" name=logind duration_seconds=0.030463919 err="unable to get seats: An AppArmor policy prevents this sender from sending this message to this recipient; type=\"method_call\", sender=\":1.28\" (uid=0 pid=3770 comm=\"/snap/node-exporter/1959/bin/node_exporter --colle\" label=\"snap.node-exporter.node-exporter (enforce)\") interface=\"org.freedesktop.login1.Manager\" member=\"ListSeats\" error name=\"(unset)\" requested_reply=\"0\" destination=\"org.freedesktop.login1\" (uid=0 pid=884 comm=\"/usr/lib/systemd/systemd-logind\" label=\"unconfined\")"

Of the 11 log lines produced with the PR snapd shown above

  • 8 are apparmor="DENIED":
apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/proc/sys/kernel/random/urandom_min_reseed_secs" pid=4336 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/sys/kernel/mm/ksm/full_scans" pid=4336 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
apparmor="DENIED" operation="open" class="file" profile="snap.node-exporter.node-exporter" name="/sys/fs/btrfs/" pid=4336 comm="node_exporter" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=4336 comm="node_exporter" capability=12  capname="net_admin"
apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=4336 comm="node_exporter" capability=2  capname="dac_read_search"
apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=4336 comm="node_exporter" capability=1  capname="dac_override"
apparmor="DENIED" operation="capable" class="cap" profile="snap.node-exporter.node-exporter" pid=4336 comm="node_exporter" capability=12  capname="net_admin"
pid=868 uid=101 auid=4294967295 ses=4294967295 subj=unconfined msg='apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/org/freedesktop/login1" interface="org.freedesktop.login1.Manager" member="ListSeats" mask="send" name="org.freedesktop.login1" pid=4336 label="snap.node-exporter.node-exporter" peer_pid=883 peer_label="unconfined"
  • 2 that are permission denied (probably related to apparmor too)
level=ERROR source=collector.go:168 msg="collector failed" name=entropy duration_seconds=8.3459e-05 err="failed to get kernel random stats: open /proc/sys/kernel/random/urandom_min_reseed_secs: permission denied"
level=ERROR source=collector.go:168 msg="collector failed" name=ksmd duration_seconds=8.2487e-05 err="open /sys/kernel/mm/ksm/full_scans: permission denied"
  • and 1 more that are also from apparmor but with completely different message:
level=ERROR source=collector.go:168 msg="collector failed" name=logind duration_seconds=0.036154468 err="unable to get seats: An AppArmor policy prevents this sender from sending this message to this recipient; type=\"method_call\", sender=\":1.30\" (uid=0 pid=4336 comm=\"/snap/node-exporter/1959/bin/node_exporter --colle\" label=\"snap.node-exporter.node-exporter (enforce)\") interface=\"org.freedesktop.login1.Manager\" member=\"ListSeats\" error name=\"(unset)\" requested_reply=\"0\" destination=\"org.freedesktop.login1\" (uid=0 pid=883 comm=\"/usr/lib/systemd/systemd-logind\" label=\"unconfined\")"

What other interfaces can be modified in order to have a node-exporter package strictly confined?

1 Like

Hi @jslarraz !

I had a chat with @zyga about my last message in this thread.

He mentioned that probably the remaining things should go to system-observe, except for loginct… for the last one a new interface is fine as well, session-observe or seat-observe…

Please, may I have your thoughts here?

I’m happy to open new PRs or adding bits to the current one.

Besides the original PR I have opened this one and also this one

  • Maybe /proc/sys/kernel/random/urandom_min_reseed_secs could go to the template as we already have other random related files there snapd/interfaces/apparmor/template.go at master · canonical/snapd · GitHub. Does urandom_min_reseed_secs look sensitive in anyway to you? See https://docs.kernel.org/admin-guide/sysctl/kernel.html#random

  • Regarding /sys/kernel/mm/ksm/full_scans, I wonder if it should go be included in the kvm interface (See https://docs.kernel.org/admin-guide/mm/ksm.html). Are you aware of any other application using it nowadays?

  • system-observe could be a good place for /sys/fs/btrfs/

  • you may want to plug log-observe interface for dac_read_search and dac_override capabilities. I’m not sure if plugging network-control might be an overkil for net_admin capability, but semantically it makes possibly the most sens.

  • If I’m not mistaken, interface="org.freedesktop.login1.Manager" member="ListSeats" mask="send" name="org.freedesktop.login1" should be provided by the login-session-observe interface