wiki: add SELinux AVC chart, enriched alerts, new server setup, and pending articles; update indexes
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
137
02-selfhosting/monitoring/netdata-selinux-avc-chart.md
Normal file
137
02-selfhosting/monitoring/netdata-selinux-avc-chart.md
Normal file
@@ -0,0 +1,137 @@
|
||||
---
|
||||
title: "Netdata SELinux AVC Denial Monitoring"
|
||||
domain: selfhosting
|
||||
category: monitoring
|
||||
tags: [netdata, selinux, fedora, monitoring, ausearch, charts.d]
|
||||
status: published
|
||||
created: 2026-03-27
|
||||
updated: 2026-03-27
|
||||
---
|
||||
|
||||
# Netdata SELinux AVC Denial Monitoring
|
||||
|
||||
A custom `charts.d` plugin that tracks SELinux AVC denials over time via Netdata. Deployed on all Fedora boxes in the fleet where SELinux is Enforcing.
|
||||
|
||||
## What It Does
|
||||
|
||||
The plugin runs `ausearch -m avc` every 60 seconds and reports the count of AVC denial events from the last 10 minutes. This gives a real-time chart in Netdata Cloud showing SELinux denial spikes — useful for catching misconfigurations after service changes or package updates.
|
||||
|
||||
## Where It's Deployed
|
||||
|
||||
| Host | OS | SELinux | Chart Installed |
|
||||
|------|----|---------|-----------------|
|
||||
| majorhome | Fedora 43 | Enforcing | Yes |
|
||||
| majorlab | Fedora 43 | Enforcing | Yes |
|
||||
| majormail | Fedora 43 | Enforcing | Yes |
|
||||
| majordiscord | Fedora 43 | Enforcing | Yes |
|
||||
|
||||
Ubuntu hosts (dca, teelia, tttpod, majortoot, majorlinux) do not run SELinux and do not have this chart.
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Create the Chart Plugin
|
||||
|
||||
Create `/etc/netdata/charts.d/selinux.chart.sh`:
|
||||
|
||||
```bash
|
||||
cat > /etc/netdata/charts.d/selinux.chart.sh << 'EOF'
|
||||
# SELinux AVC denial counter for Netdata charts.d
|
||||
selinux_update_every=60
|
||||
selinux_priority=90000
|
||||
|
||||
selinux_check() {
|
||||
which ausearch >/dev/null 2>&1 || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
selinux_create() {
|
||||
cat <<CHART
|
||||
CHART selinux.avc_denials '' 'SELinux AVC Denials (last 10 min)' 'denials' selinux '' line 90000 $selinux_update_every ''
|
||||
DIMENSION denials '' absolute 1 1
|
||||
CHART
|
||||
return 0
|
||||
}
|
||||
|
||||
selinux_update() {
|
||||
local count
|
||||
count=$(sudo /usr/bin/ausearch -m avc -if /var/log/audit/audit.log -ts recent 2>/dev/null | grep -c "type=AVC")
|
||||
echo "BEGIN selinux.avc_denials $1"
|
||||
echo "SET denials = ${count}"
|
||||
echo "END"
|
||||
return 0
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
### 2. Grant Netdata Sudo Access to ausearch
|
||||
|
||||
`ausearch` requires root to read the audit log. Add a sudoers entry for the `netdata` user:
|
||||
|
||||
```bash
|
||||
echo 'netdata ALL=(root) NOPASSWD: /usr/bin/ausearch -m avc -if /var/log/audit/audit.log -ts recent' > /etc/sudoers.d/netdata-selinux
|
||||
chmod 440 /etc/sudoers.d/netdata-selinux
|
||||
visudo -c
|
||||
```
|
||||
|
||||
The `visudo -c` validates syntax. If it reports errors, fix the file before proceeding — a broken sudoers file can lock out sudo entirely.
|
||||
|
||||
### 3. Restart Netdata
|
||||
|
||||
```bash
|
||||
systemctl restart netdata
|
||||
```
|
||||
|
||||
### 4. Verify
|
||||
|
||||
Check that the chart is collecting data:
|
||||
|
||||
```bash
|
||||
curl -s 'http://localhost:19999/api/v1/chart?chart=selinux.avc_denials' | python3 -c "
|
||||
import sys, json
|
||||
d = json.load(sys.stdin)
|
||||
print(f'Chart: {d[\"id\"]}')
|
||||
print(f'Update every: {d[\"update_every\"]}s')
|
||||
print(f'Type: {d[\"chart_type\"]}')
|
||||
"
|
||||
```
|
||||
|
||||
If the chart doesn't appear, check that `charts.d` is enabled in `/etc/netdata/netdata.conf` and that the plugin file is readable by the `netdata` user.
|
||||
|
||||
## Known Side Effect: pam_systemd Log Noise
|
||||
|
||||
Because the `netdata` user calls `sudo ausearch` every 60 seconds, `pam_systemd` logs a warning each time:
|
||||
|
||||
```
|
||||
pam_systemd(sudo:session): Failed to check if /run/user/0/bus exists, ignoring: Permission denied
|
||||
```
|
||||
|
||||
This is cosmetic. The `sudo` command succeeds — `pam_systemd` just can't find a D-Bus user session for the `netdata` service account, which is expected. The message volume scales with the collection interval (1,440/day at 60-second intervals).
|
||||
|
||||
**To suppress it**, the `system-auth` PAM config on Fedora already marks `pam_systemd.so` as `-session optional` (the `-` prefix means "don't fail if the module errors"). The messages are informational log noise, not actual failures. No PAM changes are needed.
|
||||
|
||||
If the log volume is a concern for log analysis or monitoring, filter it at the journald level:
|
||||
|
||||
```ini
|
||||
# /etc/rsyslog.d/suppress-pam-systemd.conf
|
||||
:msg, contains, "pam_systemd(sudo:session): Failed to check" stop
|
||||
```
|
||||
|
||||
Or in Netdata's log alert config, exclude the pattern from any log-based alerts.
|
||||
|
||||
## Fleet Audit
|
||||
|
||||
To verify the chart is deployed and functioning on all Fedora hosts:
|
||||
|
||||
```bash
|
||||
for host in majorhome majorlab majormail majordiscord; do
|
||||
echo -n "=== $host: "
|
||||
ssh root@$host "curl -s 'http://localhost:19999/api/v1/chart?chart=selinux.avc_denials' 2>/dev/null | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d[\"id\"], \"every\", str(d[\"update_every\"])+\"s\")' 2>/dev/null || echo 'NOT FOUND'"
|
||||
done
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [Deploying Netdata to a New Server](netdata-new-server-setup.md)
|
||||
- [Tuning Netdata Web Log Alerts](tuning-netdata-web-log-alerts.md)
|
||||
- [Tuning Netdata Docker Health Alarms](netdata-docker-health-alarm-tuning.md)
|
||||
- [SELinux: Fixing Dovecot Mail Spool Context](/05-troubleshooting/selinux-dovecot-vmail-context.md)
|
||||
Reference in New Issue
Block a user