Blob Blame History Raw
From 66b01d9b55ee6b1d791383467827a6444673a51c Mon Sep 17 00:00:00 2001
From: Watson Sato <wsato@redhat.com>
Date: Wed, 29 Apr 2020 18:36:39 +0200
Subject: [PATCH 1/6] Add fields arg to ansbile audit syscall macros

The field arg allows one to specify syscall fields for the audit rule.
These fields can be auid, exit, argument, or any field used by audit.
Reference:
https://github.com/linux-audit/audit-documentation/wiki/SPEC-Writing-Good-Events#field-names
---
 shared/macros-ansible.jinja | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/shared/macros-ansible.jinja b/shared/macros-ansible.jinja
index 03e4306051..7674c290fa 100644
--- a/shared/macros-ansible.jinja
+++ b/shared/macros-ansible.jinja
@@ -352,9 +352,11 @@ The macro requires following parameters:
 - arch: an architecture to be used in the Audit rule (b32, b64)
 - syscalls: list of syscalls supplied as a list ["syscall1", "syscall2"] etc.
 - key: a key to use as rule identifier.
+- fields (optional): list of syscall fields to add (e.g.: auid=unset, exit=-EPERM, a0&0100);
+  Add them in the order you expect them to be in the audit rule.
 Note that if there  already exists a rule wit the same key in the /etc/audit/rules.d directory, the rule will be placed in the same file.
 #}}
-{{% macro ansible_audit_augenrules_add_syscall_rule(arch="", syscalls=[], key="") -%}}
+{{% macro ansible_audit_augenrules_add_syscall_rule(arch="", syscalls=[], key="", fields=[]) -%}}
 - name: Declare list of syscals
   set_fact:
     syscalls: {{{ syscalls }}}
@@ -362,10 +364,17 @@ Note that if there  already exists a rule wit the same key in the /etc/audit/rul
 - name: Declare number of syscalls
   set_fact: audit_syscalls_number_of_syscalls="{{ syscalls|length|int }}"
 
+{{# This dictionary is a Jinja2 trick to allow loops to change variables defined out of its scope #}}
+{{% set fields_data = { 'regex' : "", 'list': "" } %}}
+{{% for field in fields %}}
+    {{% set not_used = fields_data.update({'regex': fields_data.regex + '(?:-F\s+' + field + ')'}) %}}
+    {{% set not_used = fields_data.update({'list': fields_data.list+ ' -F ' + field }) %}}
+{{% endfor %}}
+
 - name: Check existence of syscalls for architecture {{{ arch }}} in /etc/audit/rules.d/
   find:
     paths: "/etc/audit/rules.d"
-    contains: '^[\s]*-a[\s]+always,exit[\s]+(?:.*-F[\s]+arch={{{ arch }}}[\s]+)(?:.*(-S[\s]+{{ item }}[\s]+|([\s]+|[,]){{ item }}([\s]+|[,]))).*(-k[\s]+|-F[\s]+key=)[\S]+[\s]*$'
+    contains: '^[\s]*-a[\s]+always,exit[\s]+(?:.*-F[\s]+arch={{{ arch }}}[\s]+)(?:.*(-S[\s]+{{ item }}[\s]+|([\s]+|[,]){{ item }}([\s]+|[,]))).*{{{ fields_data.regex }}}(-k[\s]+|-F[\s]+key=)[\S]+[\s]*$'
     patterns: "*.rules"
   register: audit_syscalls_found_{{{ arch }}}_rules_d
   loop: "{{ syscalls }}"
@@ -401,7 +410,7 @@ Note that if there  already exists a rule wit the same key in the /etc/audit/rul
       loop: "{{ audit_syscalls_found_{{{ arch }}}_rules_d.results }}"
       when: item.matched is defined and item.matched == 0
     - name: "Construct rule: add key"
-      set_fact: tmpline="{{ tmpline + '-k {{{ key }}}' }}"
+      set_fact: tmpline="{{ tmpline + '{{{ fields_data.list }}} -k {{{ key }}}' }}"
     - name: "Insert the line in {{ all_files[0] }}"
       lineinfile:
         path: "{{ all_files[0] }}"
@@ -417,8 +426,10 @@ The macro requires following parameters:
 - arch: an architecture to be used in the Audit rule (b32, b64)
 - syscalls: list of syscalls supplied as a list ["syscall1", "syscall2"] etc.
 - key: a key to use as rule identifier.
+- fields (optional): list of syscall fields to add (e.g.: auid=unset, exit=-EPERM, a0&0100);
+  Add them in the order you expect them to be in the audit rule.
 #}}
-{{% macro ansible_audit_auditctl_add_syscall_rule(arch="", syscalls=[], key="") -%}}
+{{% macro ansible_audit_auditctl_add_syscall_rule(arch="", syscalls=[], key="", fields=[]) -%}}
 - name: Declare list of syscals
   set_fact:
     syscalls: {{{ syscalls }}}
@@ -426,10 +437,17 @@ The macro requires following parameters:
 - name: Declare number of syscalls
   set_fact: audit_syscalls_number_of_syscalls="{{ syscalls|length|int }}"
 
+{{# This dictionary is a Jinja2 trick to allow loops to change variables defined out of its scope #}}
+{{% set fields_data = { 'regex' : "", 'list': "" } %}}
+{{% for field in fields %}}
+    {{% set not_used = fields_data.update({'regex': fields_data.regex + '(?:-F\s+' + field + ')'}) %}}
+    {{% set not_used = fields_data.update({'list': fields_data.list + ' -F ' + field }) %}}
+{{% endfor %}}
+
 - name: Check existence of syscalls for architecture {{{ arch }}} in /etc/audit/audit.rules
   find:
     paths: "/etc/audit"
-    contains: '^[\s]*-a[\s]+always,exit[\s]+(?:.*-F[\s]+arch={{{ arch }}}[\s]+)(?:.*(-S[\s]+{{ item }}[\s]+|([\s]+|[,]){{ item }}([\s]+|[,]))).*(-k[\s]+|-F[\s]+key=)[\S]+[\s]*$'
+    contains: '^[\s]*-a[\s]+always,exit[\s]+(?:.*-F[\s]+arch={{{ arch }}}[\s]+)(?:.*(-S[\s]+{{ item }}[\s]+|([\s]+|[,]){{ item }}([\s]+|[,]))).*{{{ fields_data.regex }}}(-k[\s]+|-F[\s]+key=)[\S]+[\s]*$'
     patterns: "audit.rules"
   register: audit_syscalls_found_{{{ arch }}}_audit_rules
   loop: "{{ syscalls }}"
@@ -445,8 +463,8 @@ The macro requires following parameters:
       set_fact: tmpline="{{tmpline + '-S ' + item.item + ' ' }}"
       loop: "{{ audit_syscalls_found_{{{ arch }}}_audit_rules.results }}"
       when: item.matched is defined and item.matched == 0
-    - name: "Construct rule: add key"
-      set_fact: tmpline="{{ tmpline + '-k {{{ key }}}' }}"
+    - name: "Construct rule: add fields and key"
+      set_fact: tmpline="{{ tmpline + '{{{ fields_data.list }}} -k {{{ key }}}' }}"
     - name: Insert the line in /etc/audit/audit.rules
       lineinfile:
         path: "/etc/audit/audit.rules"

From 5de069a558c4456d0610764d8fc9da23f0ba294e Mon Sep 17 00:00:00 2001
From: Watson Sato <wsato@redhat.com>
Date: Wed, 29 Apr 2020 18:43:08 +0200
Subject: [PATCH 2/6] Fix spacing between syscalls and fields

By having the white space at the beginning of the token, it is easy to
concatenate them without worries.
---
 shared/macros-ansible.jinja | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/shared/macros-ansible.jinja b/shared/macros-ansible.jinja
index 7674c290fa..2aaf0c366b 100644
--- a/shared/macros-ansible.jinja
+++ b/shared/macros-ansible.jinja
@@ -404,12 +404,12 @@ Note that if there  already exists a rule wit the same key in the /etc/audit/rul
 - name: "Insert the syscall rule in {{ all_files[0] }}"
   block:
     - name: "Construct rule: add rule list, action and arch"
-      set_fact: tmpline="-a always,exit -F arch={{{ arch }}} "
+      set_fact: tmpline="-a always,exit -F arch={{{ arch }}}"
     - name: "Construct rule: add syscalls"
-      set_fact: tmpline="{{tmpline + '-S ' + item.item + ' ' }}"
+      set_fact: tmpline="{{tmpline + ' -S ' + item.item }}"
       loop: "{{ audit_syscalls_found_{{{ arch }}}_rules_d.results }}"
       when: item.matched is defined and item.matched == 0
-    - name: "Construct rule: add key"
+    - name: "Construct rule: add fields and key"
       set_fact: tmpline="{{ tmpline + '{{{ fields_data.list }}} -k {{{ key }}}' }}"
     - name: "Insert the line in {{ all_files[0] }}"
       lineinfile:
@@ -458,9 +458,9 @@ The macro requires following parameters:
 - name: Insert the syscall rule in /etc/audit/audit.rules
   block:
     - name: "Construct rule: add rule list, action and arch"
-      set_fact: tmpline="-a always,exit -F arch={{{ arch }}} "
+      set_fact: tmpline="-a always,exit -F arch={{{ arch }}}"
     - name: "Construct rule: add syscalls"
-      set_fact: tmpline="{{tmpline + '-S ' + item.item + ' ' }}"
+      set_fact: tmpline="{{tmpline + ' -S ' + item.item }}"
       loop: "{{ audit_syscalls_found_{{{ arch }}}_audit_rules.results }}"
       when: item.matched is defined and item.matched == 0
     - name: "Construct rule: add fields and key"

From 80a3b0cca2b3af62e1a7cff578a45e844bd12fb4 Mon Sep 17 00:00:00 2001
From: Watson Sato <wsato@redhat.com>
Date: Thu, 30 Apr 2020 09:10:41 +0200
Subject: [PATCH 3/6] Add tests for audit_rules_time_clock_settime

---
 .../tests/correct_syscall.pass.sh                          | 7 +++++++
 .../tests/incorrect_arg_field.fail.sh                      | 7 +++++++
 .../tests/incorrect_syscall.fail.sh                        | 7 +++++++
 3 files changed, 21 insertions(+)
 create mode 100644 linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/correct_syscall.pass.sh
 create mode 100644 linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/incorrect_arg_field.fail.sh
 create mode 100644 linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/incorrect_syscall.fail.sh

diff --git a/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/correct_syscall.pass.sh b/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/correct_syscall.pass.sh
new file mode 100644
index 0000000000..b71cc454bc
--- /dev/null
+++ b/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/correct_syscall.pass.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# profiles = xccdf_org.ssgproject.content_profile_cis
+
+rm -rf /etc/audit/rules.d/*.rules
+echo "-a always,exit -F arch=b32 -S clock_settime -F a0=0x0 -k time-change" >> /etc/audit/rules.d/time.rules
+echo "-a always,exit -F arch=b64 -S clock_settime -F a0=0x0 -k time-change" >> /etc/audit/rules.d/time.rules
diff --git a/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/incorrect_arg_field.fail.sh b/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/incorrect_arg_field.fail.sh
new file mode 100644
index 0000000000..add0722747
--- /dev/null
+++ b/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/incorrect_arg_field.fail.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# profiles = xccdf_org.ssgproject.content_profile_cis
+
+rm -rf /etc/audit/rules.d/*.rules
+echo "-a always,exit -F arch=b32 -S clock_settime -F a0=0x1 -k time-change" >> /etc/audit/rules.d/time.rules
+echo "-a always,exit -F arch=b64 -S clock_settime -F a0=0x1 -k time-change" >> /etc/audit/rules.d/time.rules
diff --git a/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/incorrect_syscall.fail.sh b/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/incorrect_syscall.fail.sh
new file mode 100644
index 0000000000..9ab5cc3bc4
--- /dev/null
+++ b/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/tests/incorrect_syscall.fail.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+# profiles = xccdf_org.ssgproject.content_profile_cis
+
+rm -rf /etc/audit/rules.d/*.rules
+echo "-a always,exit -F arch=b32 -S stime -F a0=0x0 -k time-change" >> /etc/audit/rules.d/time.rules
+echo "-a always,exit -F arch=b64 -S stime -F a0=0x0 -k time-change" >> /etc/audit/rules.d/time.rules

From a5b36f8400f821e35fc5a7e77b36a9fee0124702 Mon Sep 17 00:00:00 2001
From: Watson Sato <wsato@redhat.com>
Date: Thu, 30 Apr 2020 09:34:35 +0200
Subject: [PATCH 4/6] Add Ansible for audit syscall clock_settime

Also demonstrates how to use the fields parameter in ansible audit
syscall macro.
---
 .../ansible/shared.yml                        | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/ansible/shared.yml

diff --git a/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/ansible/shared.yml b/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/ansible/shared.yml
new file mode 100644
index 0000000000..e77850fa25
--- /dev/null
+++ b/linux_os/guide/system/auditing/auditd_configure_rules/audit_time_rules/audit_rules_time_clock_settime/ansible/shared.yml
@@ -0,0 +1,22 @@
+# platform = multi_platform_all
+# reboot = false
+# strategy = restrict
+# complexity = low
+# disruption = low
+
+# What architecture are we on?
+#
+- name: Set architecture for audit tasks
+  set_fact:
+    audit_arch: "b{{ ansible_architecture | regex_replace('.*(\\d\\d$)','\\1') }}"
+
+- name: Perform remediation of Audit rules for clock_settime for x86 platform
+  block:
+    {{{ ansible_audit_augenrules_add_syscall_rule(arch="b32", syscalls=["clock_settime"], key="time-change", fields=["a0=0x0"])|indent(4) }}}
+    {{{ ansible_audit_auditctl_add_syscall_rule(arch="b32", syscalls=["clock_settime"], key="time-change", fields=["a0=0x0"])|indent(4) }}}
+
+- name: Perform remediation of Audit rules for clock_settime for x86_64 platform
+  block:
+    {{{ ansible_audit_augenrules_add_syscall_rule(arch="b64", syscalls=["clock_settime"], key="time-change", fields=["a0=0x0"])|indent(4) }}}
+    {{{ ansible_audit_auditctl_add_syscall_rule(arch="b64", syscalls=["clock_settime"], key="time-change", fields=["a0=0x0"])|indent(4) }}}
+  when: audit_arch == "b64"

From fe179d4d870878d29b603e7ab5a8bc79cb8eb05c Mon Sep 17 00:00:00 2001
From: Watson Sato <wsato@redhat.com>
Date: Thu, 30 Apr 2020 11:54:03 +0200
Subject: [PATCH 5/6] Fix regex spacing between fields and the key

There needs to be a space between them.
Change syntax to be consistent with rest of regex.
---
 shared/macros-ansible.jinja | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/shared/macros-ansible.jinja b/shared/macros-ansible.jinja
index 2aaf0c366b..eeafe5f6d5 100644
--- a/shared/macros-ansible.jinja
+++ b/shared/macros-ansible.jinja
@@ -367,7 +367,7 @@ Note that if there  already exists a rule wit the same key in the /etc/audit/rul
 {{# This dictionary is a Jinja2 trick to allow loops to change variables defined out of its scope #}}
 {{% set fields_data = { 'regex' : "", 'list': "" } %}}
 {{% for field in fields %}}
-    {{% set not_used = fields_data.update({'regex': fields_data.regex + '(?:-F\s+' + field + ')'}) %}}
+    {{% set not_used = fields_data.update({'regex': fields_data.regex + '(?:-F[\s]+' + field + '[\s]+)'}) %}}
     {{% set not_used = fields_data.update({'list': fields_data.list+ ' -F ' + field }) %}}
 {{% endfor %}}
 
@@ -440,7 +440,7 @@ The macro requires following parameters:
 {{# This dictionary is a Jinja2 trick to allow loops to change variables defined out of its scope #}}
 {{% set fields_data = { 'regex' : "", 'list': "" } %}}
 {{% for field in fields %}}
-    {{% set not_used = fields_data.update({'regex': fields_data.regex + '(?:-F\s+' + field + ')'}) %}}
+    {{% set not_used = fields_data.update({'regex': fields_data.regex + '(?:-F[\s]+' + field + '[\s]+)'}) %}}
     {{% set not_used = fields_data.update({'list': fields_data.list + ' -F ' + field }) %}}
 {{% endfor %}}
 

From 5e13b1a6698d4403cf4108664fd2c33be5ee9109 Mon Sep 17 00:00:00 2001
From: Watson Sato <wsato@redhat.com>
Date: Thu, 30 Apr 2020 14:41:59 +0200
Subject: [PATCH 6/6] Improve macro documenation and clarify var name

---
 shared/macros-ansible.jinja | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/shared/macros-ansible.jinja b/shared/macros-ansible.jinja
index eeafe5f6d5..7b64341fb7 100644
--- a/shared/macros-ansible.jinja
+++ b/shared/macros-ansible.jinja
@@ -364,11 +364,14 @@ Note that if there  already exists a rule wit the same key in the /etc/audit/rul
 - name: Declare number of syscalls
   set_fact: audit_syscalls_number_of_syscalls="{{ syscalls|length|int }}"
 
-{{# This dictionary is a Jinja2 trick to allow loops to change variables defined out of its scope #}}
-{{% set fields_data = { 'regex' : "", 'list': "" } %}}
+{{#
+This dictionary is a Jinja2 trick to allow loops to change variables defined out of its scope.
+See official documentation: https://jinja.palletsprojects.com/en/2.11.x/templates/#assignments
+#}}
+{{% set fields_data = { 'regex' : "", 'plain_text': "" } %}}
 {{% for field in fields %}}
     {{% set not_used = fields_data.update({'regex': fields_data.regex + '(?:-F[\s]+' + field + '[\s]+)'}) %}}
-    {{% set not_used = fields_data.update({'list': fields_data.list+ ' -F ' + field }) %}}
+    {{% set not_used = fields_data.update({'plain_text': fields_data.plain_text + ' -F ' + field }) %}}
 {{% endfor %}}
 
 - name: Check existence of syscalls for architecture {{{ arch }}} in /etc/audit/rules.d/
@@ -410,7 +413,7 @@ Note that if there  already exists a rule wit the same key in the /etc/audit/rul
       loop: "{{ audit_syscalls_found_{{{ arch }}}_rules_d.results }}"
       when: item.matched is defined and item.matched == 0
     - name: "Construct rule: add fields and key"
-      set_fact: tmpline="{{ tmpline + '{{{ fields_data.list }}} -k {{{ key }}}' }}"
+      set_fact: tmpline="{{ tmpline + '{{{ fields_data.plain_text }}} -k {{{ key }}}' }}"
     - name: "Insert the line in {{ all_files[0] }}"
       lineinfile:
         path: "{{ all_files[0] }}"
@@ -437,11 +440,14 @@ The macro requires following parameters:
 - name: Declare number of syscalls
   set_fact: audit_syscalls_number_of_syscalls="{{ syscalls|length|int }}"
 
-{{# This dictionary is a Jinja2 trick to allow loops to change variables defined out of its scope #}}
-{{% set fields_data = { 'regex' : "", 'list': "" } %}}
+{{#
+This dictionary is a Jinja2 trick to allow loops to change variables defined out of its scope.
+See official documentation: https://jinja.palletsprojects.com/en/2.11.x/templates/#assignments
+#}}
+{{% set fields_data = { 'regex' : "", 'plain_text': "" } %}}
 {{% for field in fields %}}
     {{% set not_used = fields_data.update({'regex': fields_data.regex + '(?:-F[\s]+' + field + '[\s]+)'}) %}}
-    {{% set not_used = fields_data.update({'list': fields_data.list + ' -F ' + field }) %}}
+    {{% set not_used = fields_data.update({'plain_text': fields_data.plain_text + ' -F ' + field }) %}}
 {{% endfor %}}
 
 - name: Check existence of syscalls for architecture {{{ arch }}} in /etc/audit/audit.rules
@@ -464,7 +470,7 @@ The macro requires following parameters:
       loop: "{{ audit_syscalls_found_{{{ arch }}}_audit_rules.results }}"
       when: item.matched is defined and item.matched == 0
     - name: "Construct rule: add fields and key"
-      set_fact: tmpline="{{ tmpline + '{{{ fields_data.list }}} -k {{{ key }}}' }}"
+      set_fact: tmpline="{{ tmpline + '{{{ fields_data.plain_text }}} -k {{{ key }}}' }}"
     - name: Insert the line in /etc/audit/audit.rules
       lineinfile:
         path: "/etc/audit/audit.rules"