{"id":13838590,"url":"https://github.com/linux-audit/audit-userspace","last_synced_at":"2026-02-02T03:01:15.708Z","repository":{"id":4239149,"uuid":"52464964","full_name":"linux-audit/audit-userspace","owner":"linux-audit","description":"Linux audit userspace repository","archived":false,"fork":false,"pushed_at":"2024-10-21T02:25:37.000Z","size":5724,"stargazers_count":594,"open_issues_count":14,"forks_count":206,"subscribers_count":29,"default_branch":"master","last_synced_at":"2024-10-21T05:41:56.109Z","etag":null,"topics":["linux","logging","security"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linux-audit.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":"audit.spec","citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-02-24T18:31:30.000Z","updated_at":"2024-10-21T02:25:42.000Z","dependencies_parsed_at":"2023-07-07T03:46:21.073Z","dependency_job_id":"caf2e347-b86e-4cb8-a265-21cea7f0b9db","html_url":"https://github.com/linux-audit/audit-userspace","commit_stats":{"total_commits":2379,"total_committers":57,"mean_commits":41.73684210526316,"dds":"0.41109709962168983","last_synced_commit":"7d35e1411cb4cb4b1382c63d47eeafe434885e8d"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linux-audit%2Faudit-userspace","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linux-audit%2Faudit-userspace/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linux-audit%2Faudit-userspace/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linux-audit%2Faudit-userspace/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linux-audit","download_url":"https://codeload.github.com/linux-audit/audit-userspace/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225663555,"owners_count":17504435,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linux","logging","security"],"created_at":"2024-08-04T16:00:22.610Z","updated_at":"2025-10-21T05:07:22.887Z","avatar_url":"https://github.com/linux-audit.png","language":"C","readme":"# Linux Audit\n\nThe Linux Audit System is designed to make Linux compliant with the requirements from Common Criteria, PCI-DSS, and other security standards by intercepting system calls and serializing audit log entries from privileged user space applications. The framework allows the configured events to be recorded to disk and distributed to plugins in realtime. Each audit event contains the date and time of event, type of event, subject identity, object acted upon, and result (success/fail) of the action if applicable.\n\n## RUNTIME DEPENDENCIES\n\n* coreutils\n* initscripts-service (Recommended - soft requirement)\n* kernel \u003e= 5.15\n* systemd\n\nNOTE: While this repository provides support for systemd to start the audit\ndaemon, other init systems can be used as well. For example, [Alpine\nLinux](https://git.alpinelinux.org/aports/tree/main/audit/auditd.initd) provides\nan init script for OpenRC.\n\n## BUILD-TIME DEPENDENCIES (for tar file)\n* gcc (or clang)\n* make\n* kernel-headers \u003e= 5.15\n* systemd\n\n## ADDITIONAL BUILD-TIME DEPENDENCIES (if using github sources)\n* autoconf\n* automake\n* libtool\n\n## OPTIONAL DEPENDENCIES\n* libcap-ng-devel  (dropping capabilities)\n* krb5-devel       (remote logging)\n* python3-devel    (python bindings)\n* swig             (python bindings)\n* openldap-devel   (zos-remote logging)\n* golang           (golang bindings)\n\n## SUPPORTED ARCHITECTURES\n* AARCH64\n* ARM (some versions)\n* MIPS\n* PPC \u0026 PPCLE\n* s390 \u0026 s390x\n* x86_64 \u0026 i386\n\nNOTE: **There is a moratorium on adding support for any new platforms.** Syscalls and other lookup tables get updated frequently. Without an active community maintaining the code, it is not sustainable to add more. If you would like to see more platforms supported, please consider working on bugs and code cleanups and then maybe we can add more. Any submitted pull requests adding a new platform with be marked with a 'wont_fix' label. It will be left available in case anyone wants to use it. But it is unsupported.\n\n## MAIL LIST\nThe audit community has a [mail list](https://lists.linux-audit.osci.io/archives/list/linux-audit@lists.linux-audit.osci.io/). It is the best place to ask questions because the mail archive is searchable and therefore discoverable.\n\n## CONFIGURING AND COMPILING\nTo build from the repo after cloning and installing dependencies:\n\n```\ncd audit\nautoreconf -f --install\n./configure --with-python3=yes --enable-gssapi-krb5=yes --with-arm \\\n    --with-aarch64 --with-libcap-ng=yes --without-golang --with-io_uring\nmake\nmake install\n```\n\nIf you are packaging this, you probably want to do \"make dist\" instead and use the resulting tar file with your package building framework. A spec file is included in the git repo as an example of packaging it using rpm. This spec file is not known to be the official spec file used by any distribution. It's just an example.\n\n## CROSS COMPILING\nCross compiling is not officially supported. There have been people that have submitted patches to make it work. But it is not documented how to make it work. It is likely that you have to somehow override CC, CXX, RANLIB, AR, LD, and NM when running configure to pickup the cross compiler, linker, archive, etc. If you have patches that fix any problems, they will be merged. If you have suggestions for how to improve cross compiling documentation, file an issue stating how to improve instructions.\n\n## OVERVIEW\nThe following image illustrates the architecture and relationship of the components in this project:\n\n![audit-components](https://github.com/linux-audit/audit-userspace/blob/assets/audit-components.png)\n\nIn the above diagram, auditd is in the middle. It interfaces with the kernel to receive events. It writes them to the audit logs. It also distributes events in realtime to audisp plugins. To load rules on 3.x audit system, you use the augenrules program. As of audit-4.0, you would use the audit-rules.service with systemctl. They in turn uses auditctl to load rules into the kernel. Auditctl is used to create, load, and delete rules; configure the kernel's backlog and other parameters; and to gather status about the audit system.\n\nThe kernel does the heavy lifting to generates the events. In the case of a trusted application such as shadow-utils, the kernel receives the event, adds origin information, timestamps, and queues the event for delivery to the audit daemon.\n\n## DAEMON CONSIDERATIONS\n### Disk Full\nAlmost all Security Standards are concerned about what happens when logging space fills up. Because of this, the audit daemon keeps careful track of free space and emits warnings at admin defined levels called \"space left\" and \"admin space left\". The former is considered a low disk space warning which should give the admin time to do something. The latter is more serious because you are just about out.\n\nTo get an accurate reading, the audit daemon should log to a disk partition that is reserved only for the audit daemon. This way someone using the logger command can't suddenly fill up the audit space and trigger an admin defined action. It is recommended to set aside a partition, /var/log/audit, for exclusive use by the audit daemon. The size of which depends on your audit retention policy.\n\n### Systemd Security Settings\nThe audit daemon is started by systemd. Some people run the \"systemd-analyze security\" command. It tells you all sorts of things to do to protect your system from auditd. However, doing the things it suggests places auditd in namespaces. When that happens, the audit rules may not trigger correctly and auditd may not be able to access trusted databases. The auditd.service file is the result of trial and error based on well intentioned patches gone wrong. You can lock auditd down more, but it likely will not work as intended.\n\n### Starting and Stopping the Daemon\nThe systemctl application was designed to interact with systemd to control system services. It is designed to use dbus to talk to systemd which then works to carry out the command if the user is authorized to do so. This can create a problem on shutdown.\n\nMany people have to run in environments that require compliance to regulatory standards. One of these requirements is to record anyone's interaction with the audit trail. See [FAU_GEN1.1](https://www.niap-ccevs.org/static_html/protection-profile/469/OS%204.3%20PP/index.html#fau) clause \"a\" and \"c\" bullet point 2. This means direct file access, changes to audit configuration, or starting/stopping the daemon. We can place watches on the files to meet the requirements. However, who stopped the daemon is trickier.\n\nPrior to systemd, people used sysvinit and then upstart. Both of those used a service command to wrap the need to send signals to the daemon to direct it to do something. SIGHUP meant reload the configuration. SIGTERM meant halt the daemon. To meet Common Criteria requirements, the Linux kernel notices any signal heading to the audit daemon and records the login uid of whoever sent it. When the audit daemon receives this signal, it queries the kernel so that it can create an event with this information.\n\nAs noted above, systemctl uses dbus to ask systemd to send the signal. Dbus loses the login uid information of who sent the signal. So, when auditd queries the kernel, the login uid is -1 which means unknown. Therefore any use of systemctl to interact with the audit daemon is non-compliant with many security standards. To solve this, the default auditd service file includes the setting:\n\n```\nRefuseManualStop=yes\n```\n\nThis causes systemctl to refuse stopping the audit system. This requires us use the old service command to send signals in the user's login context so that the audit trail is not broken. To work correctly, the service command must support legacy actions. The audit daemon ships these which must be installed to\n\n```\n/usr/libexec/initscripts/legacy-actions/\n```\n\nThese scripts are wrappers to \"auditctl --signal\" which locates the audit daemon and then sends the right signal to it. A lot of distributions want to get rid of this legacy mode of action, but it cannot be done away with. The original plan was to move dbus into the kernel where it could see both ends of a socket and transfer credentials if both parties agreed. This was shotdown back around 2010 and now we're stuck. (This also means the Linux desktop cannot meet common criteria or any serious security standards since it loses who originated any action.)\n\nThe main point is that if you use systemctl and only systemctl to manage auditd, you not in compliance with security standards that require monitoring the configuration of the audit trail.\n\n## RULES\nThe audit package comes with pre-written rules. For audit-3.x, they should be located in /usr/share/audit/sample-rules. For audit-4.x, they should be located in /usr/share/audit-rules. These rules should be close enough most of the time. To use them, copy select rules to /etc/auditd/rules.d. If you look at the rules, you will notice that the filenames begin with a number. This number has the following suggested meaning:\n\n```\n10 - Kernel and auditctl configuration\n20 - Rules that could match general rules - but we want a different match (override)\n30 - Main rules\n40 - Optional rules\n50 - Server Specific rules\n70 - System local rules\n90 - Finalize (immutable)\n```\n\nThe rules are meant to be used by the augenrules program. The augenrules program expects rules to be located in /etc/audit/rules.d. The rules will get processed in a specific order based on their natural sort order. The kernel's rule engine uses a first match wins strategy. So, the order of the rules matters.\n\nThe sample rules are not meant to be used all at the same time. They are pieces of a policy that should be thought out and individual files copied to /etc/audit/rules.d/ For example, if you wanted to set a system up in the STIG configuration, copy rules 10-base-config, 30-stig, 31-privileged, and 99-finalize. You can add more if you like. But these 4 files are a baseline policy.\n\nIf you want to learn more about writing custom rules, look for the audit.rules and auditctl man pages.\n\n## EVENTS\nThe audit events come in two flavors: simple and compound. A simple event is sent from a trusted application such as sshd. It has only one record in the event. A compound event has multiple records in the same event. These multiple records are considered to be in the same event because they have the same timestamp and serial number.\n\nAudit events all start with the following preamble:\n\n```\ntype=\u003csomething\u003e msg=audit(1679598373.352:1256072):\n```\n\nThe first item is the record type. This tells you what kind of information and the meaning of the record is. Next there is a msg=audit field which has parenthesis. Inside it is the time since the epoch in seconds, a millisecond time, and a serial number. The millisecond is used to separate events within the same second. The serial number is used to separate events within the same millisecond.\n\nAfter the time stamp comes fields that are in key=value format. What these field are varies by record type. But the overall event should have the following:\n\n- Login ID (auid): the user ID that the user originally logged in with regardless of changing the real or effective user ID afterwards.\n- Session ID (ses): an identifier unique to the specific login in case the same user has multiple logins.\n- User ID (uid): the real user ID of the process at the time the audit event was generated.\n- Process ID (pid): the process ID of the subject that caused the event.\n- Results (res): Whether the subject's action was a success or failure.\n\nThere can be optional information, depending on the kind of the event, which may include, but is not limited to:\n\n- The system call that a process made that caused the event\n- The group ID of the subject\n- Hostname or terminal the subject used for performing the action\n- File being accessed\n- Process being executed with arguments\n- Network address\n- Keystrokes\n- Netfilter packet decisions\n\n## SEARCHING AND REPORTING FROM LOGS\nThe intended way to view audit events is by using the ausearch program. Audit events are not serialized in the kernel and could be interlaced and out of order. To straighten this out, ausearch/aureport/auparse all put the records on a holding list until the event is complete. It then emits them in sequential order so they are presented in numeric order.\n\nSome fields are searchable. Typically you will search for a specific kind of event, a specific process, a specific file, or a specific user. The ausearch man page details all the different options. Here are some example searches:\n\n```\nSearching for bad logins:\nausearch -m USER_LOGIN --success no -i\n\nSearching for events on shadow file today:\nausearch --start today -f shadow -i\n\nSearching for failed file opens for user acct 1000:\nausearch -m PATH --success no --syscall open --loginuid 1000 -i\n```\n\nSometimes you want summary information. In this case you would want to use the aureport program. It can summarize all of the searchable kinds of fields. It can also pick out all of a kind of data without summary so that you can later use ausearch to see the full event. Below are some examples of using aureport:\n\n```\nMonthly summary report:\naureport --start this-month --summary\n\nFiles accessed today summary:\naureport --start today --file --summary\n\nSyscall events summarized by key:\naureport --start today --key --summary\n\nAll account modifications this month:\naureport --start this-month --mods -i\n\nReport all log files and their time range:\naureport -t\n```\n\nSometimes aureport provides too much information. You might want a summary of files accessed by a specific user. In this case, you can combine ausearch and aureport to get the information you need. The main trick to remember is that the output of ausearch has to be in the \"raw\" format. For example:\n\n```\nSummary of files accessed by uid 1000\nausearch --start today --auid 1000 --raw | aureport --file --summary\n\nSummary of files accessed by vi\nausearch --start this-week -x vi --raw | aureport --file --summary\n\nSummary of programs with files access associated with the unsuccessful-access key\nausearch --start this-month --key unsuccessful-access --raw | aureport -x --summary -i\n\nHosts user logged in from\nausearch --start this-week -m user_login --raw | aureport --host --summary\n```\n\nThe ausearch program also has a couple more tricks worth knowing about. It has an option, --format, which can take \"csv\" or \"text\" as options. In the case of csv, it will emit a condensed audit event normalized to be suitable as a Comma Separated Value file. In this format, you can take the audit logs and do data science queries using Excel/Sheets, python/pandas, or the R programming language.\n\nThe other option, text, can be used to turn the audit events into simple sentences that describe what the event means. There are times when it doesn't have a mapping because the event is new. In those cases, the event may not make sense until the software is updated.\n\n## PERFORMANCE AND MONITORING\nThe audit system can output two sets of data to let you know how it's doing. The first method is to use:\n\n```\nauditctl -s\n```\n\nThis outputs some basic information such as the kernel backlog size, the current backlog, and how many events have been lost. The backlog size is the size of the queue in records that the kernel can hold waiting for auditd to collect them. This should be around 8k or larger for a system that really does auditing. If you use the audit system to casually collect SELinux AVC's, then you can go lower to something like 256.\n\nThe current backlog tells you how many events are awaiting delivery to auditd at that instant. This number should normally be low - less than 10. If this is getting bigger and approaching the backlog limit in size, then you have a problem to look into. Either you are generating too many events (rules need adjusting) or an auditd plugin is taking too long to dequeue records. The auditd daemon is very fast at writing records to disk and can handle thousands per second.\n\nAnother way to check performance is to use\n\n```\nauditctl --signal state\ncat /run/audit/auditd.state\n\naudit version = 4.0.5\ncurrent time = 06/02/25 20:21:31\nprocess priority = -4\nwriting to logs = yes\ncurrent log size = 2423 KiB\nmax log size = 8192 KiB\nlogs detected last rotate/shift = 0\nspace left on partition = yes\nLogging partition free space 45565 MiB\nspace_left setting 75 MiB\nadmin_space_left setting 50 MiB\nlogging suspended = no\nfile system space action performed = no\nadmin space action performed = no\ndisk error detected = no\nNumber of active plugins = 1\ncurrent plugin queue depth = 0\nmax plugin queue depth used = 5\nplugin queue size = 2000\nplugin queue overflow detected = no\nplugin queueing suspended = no\nlistening for network connections = no\nglibc arena (total memory) is: 388 KiB, was: 388 KiB\nglibc uordblks (in use memory) is: 92 KiB, was: 90 KiB\nglibc fordblks (total free space) is: 295 KiB, was: 297 KiB\n```\n\nThis command causes auditd to dump its internal metrics to /run/audit/auditd.state. This can tell you if auditd is healthy. Also, you can make auditd periodically update the state file by adjusting the report_interval setting in auditd.conf (note - only available in audit-4.0.5 and later). See the man page for details. Setting this allows for the continuous updating for metrics collection.\n\n## AUPARSE\nThe auparse library is available to allow one to create custom reporting applications. The library is patterned after a dbase or foxpro database library and has the following categories of functions:\n\n- General functions that affect operation of the library\n- Functions that traverse events\n- Accessors to event data\n- Functions that traverse records in the same event\n- Accessors to record data\n- Functions that traverse fields in the same record\n- Accessors to field data\n\nYou can write programs in one of two ways: iterate across events, records, and fields; or use the feed API to which a callback function is presented with a single, complete event that can be iterated across the records and fields. The former is best for working with files, while the latter is more appropriate for realtime data for a plugin.\n\n## AUPLUGIN\nThe auplugin library helps developers write auditd plugins. It multi-threads\na plugin with a queue in between the threads. One thread pulls event records\nfrom auditd, then enqueues them. The other thread sees the events and calls\nback a function of your choosing. This keeps auditd running at top speed\nsince plugins keep their socket drained. The library offers functions to\nmanage an event queue and dispatch audit records to a callback for\nprocessing.  Its functionality falls into several categories:\n\n- Initialization and shutdown helpers\n- Event loop processing or feeding events through libauparse\n- Queue statistics and management helpers\n- Buffered line readers for descriptor based input\n\nPlugins generally follow one of two patterns.  They can use\n`auplugin_event_loop()` with a record callback when raw records are\nsufficient.  Alternatively `auplugin_event_feed()` queues the records\nfor libauparse and presents fully formed events to the callback.  The\nlatter is typically used when plugin logic needs structured event data.\n\n## Audit Standards\nYou can find the standards to which the audit system conforms to in the ![Audit Documentation Project](https://github.com/linux-audit/audit-documentation).\n\n","funding_links":[],"categories":["osquery and linux audit"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinux-audit%2Faudit-userspace","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinux-audit%2Faudit-userspace","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinux-audit%2Faudit-userspace/lists"}