removing auditd / disabling logging

removing auditd / disabling logging

  • Written by
    Walter Doekes
  • Published on

After installing auditd for testing purposes and removing it again, my kernel logs got flooded with messages. How do I disable them?

If you happened to have installed auditd, it is likely that the kernel audit subsystem was enabled. Even when there are no rules left (auditctl -l) you can still get more messages in your kernel logs than before.

For instance, after uninstalling auditd, I still get the following ones:

$ sudo journalctl -o cat --dmesg --grep audit -n2

audit: type=1106 audit(1688134323.226:190): pid=2476506 uid=1000 auid=1000 ses=3 subj=unconfined
  msg='op=PAM:session_close grantors=pam_limits,.. acct="root"
  exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/15 res=success'

audit: type=1104 audit(1688134323.226:191): pid=2476506 uid=1000 auid=1000 ses=3 subj=unconfined
  msg='op=PAM:setcred grantors=pam_permit acct="root"
  exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/15 res=success'

The audit rules might be gone, but userland can still log messages, and they are now forwarded through the kernel ring buffer. The pam subsystem does this, for instance:

int _pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags, struct handler *h)
/* ... */
  case PAM_CLOSE_SESSION:
    message = "session_close";
/* ... */
  if (_pam_audit_writelog(pamh, audit_fd, type, message,
      grantors ? grantors : "?", retval) < 0)
/* ... */

Not expecting those logs after removing auditd?

Here's a quick way to disable audit logging again: compile the following C snippet, and run it to disable.

$ gcc -Wall -o audit_enable_disable audit_enable_disable.c
$ sudo ./audit_enable_disable 0

audit_enable_disable.c

/* GPL2.1+ */
#include <asm/types.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/audit.h>
#include <linux/netlink.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

#define MAX_AUDIT_MESSAGE_LENGTH 8970 // PATH_MAX*2+CTX_SIZ*2+11+256+1

struct audit_message {
    struct nlmsghdr nlh;
    char data[MAX_AUDIT_MESSAGE_LENGTH];
};
struct audit_reply {
    int type;
    int len;
    struct nlmsghdr *nlh;
    struct audit_message msg;
    struct nlmsgerr *error;
};

int audit_open(void) {
    int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
    if (fd < 0) {
        perror("socket");
        return -1;
    }
    if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
        perror("fcntl");
        close(fd);
        return -1;
    }
    return fd;
}

int audit_recv_error(int fd) {
    struct audit_message resp = {0};
    struct sockaddr_nl nladdr;
    int ret;

    socklen_t nladdrlen = sizeof(nladdr);
    do {
        ret = recvfrom(
             fd, &resp, sizeof(resp), 0,
             (struct sockaddr*)&nladdr, &nladdrlen);
    } while (ret < 0 && errno == EINTR);

    if (ret < 0 || nladdrlen != sizeof(nladdr) || nladdr.nl_pid) {
        perror("recvfrom");
        return -1;
    }

    if (resp.nlh.nlmsg_type != NLMSG_ERROR) {
        fprintf(
            stderr, "audit_recv_error: got unexpected %d\n",
            resp.nlh.nlmsg_type);
        return -1;
    }

    return ((struct nlmsgerr*)NLMSG_DATA(&resp.nlh))->error == 0 ? 0 : -1;
}

int audit_send(int fd, int type, const void *data, unsigned int size) {
    struct audit_message req = {0};
    struct sockaddr_nl addr = {.nl_family = AF_NETLINK};
    int ret;

    req.nlh.nlmsg_len = NLMSG_SPACE(size);
    req.nlh.nlmsg_type = type;
    req.nlh.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
    req.nlh.nlmsg_seq = 1;
    if (size && data) {
        memcpy(NLMSG_DATA(&req.nlh), data, size);
    }

    do {
        ret = sendto(
            fd, &req, req.nlh.nlmsg_len, 0,
            (struct sockaddr*)&addr, sizeof(addr));
    } while (ret < 0 && errno == EINTR);

    if (ret < 0 || ret != (int)req.nlh.nlmsg_len) {
        perror("sendto");
        return -1;
    }
    return audit_recv_error(fd);  /* because NLM_F_ACK */
}

int audit_set_enabled(int fd, uint32_t enabled) {
    struct audit_status s = {
        .mask = AUDIT_STATUS_ENABLED, .enabled = enabled};
    int ret = audit_send(fd, AUDIT_SET, &s, sizeof(s));
    if (ret < 0) {
        fprintf(stderr, "audit_set_enabled: failed, are you root?\n");
        return -1;
    }
    return ret;
}

int main(int argc, const char *argv[]) {
    int ret = 0;
    int fd = audit_open();

    if (fd < 0) {
        ret = -1;
    } else if (argc == 2) {
        uint32_t enable = atoi(argv[1]);
        /* allow 2 here to permanently enable until reboot */
        if (enable != 1) {
            enable = 0;
        }
        if (audit_set_enabled(fd, enable) < 0) {
            ret = 2;
        }
    } else {
        printf("Usage: %s 0|1\n", argv[0]);
        ret = 1;
    }
    if (fd >= 0) {
        close(fd);
    }
    return ret;
}

Or, if you still have auditctl, just do: auditctl -e 0


Back to overview Newer post: viewing unencrypted traffic / ltrace / bpftrace Older post: netplan / docker0 / bind on 172.17.0.1