From 6dd766bc330804bef01f9c178a6cde20cb49fa9c Mon Sep 17 00:00:00 2001 From: Ryan Crichton Date: Tue, 9 May 2023 09:57:26 +0200 Subject: [PATCH 1/5] WIP add auditd to monitoring package --- .../ansible/playbooks/provision_servers.yml | 1 + .../ansible/roles/auditd/tasks/main.yml | 15 ++ monitoring/docker-compose.yml | 7 + .../dashboards/security/auditlogs.json | 163 ++++++++++++++++++ monitoring/promtail/promtail-config.yml | 92 ++++++---- 5 files changed, 243 insertions(+), 35 deletions(-) create mode 100644 infrastructure/ansible/roles/auditd/tasks/main.yml create mode 100644 monitoring/grafana/dashboards/security/auditlogs.json diff --git a/infrastructure/ansible/playbooks/provision_servers.yml b/infrastructure/ansible/playbooks/provision_servers.yml index 070a93a2..9d6692e5 100644 --- a/infrastructure/ansible/playbooks/provision_servers.yml +++ b/infrastructure/ansible/playbooks/provision_servers.yml @@ -4,3 +4,4 @@ - common - docker - ufw + - auditd diff --git a/infrastructure/ansible/roles/auditd/tasks/main.yml b/infrastructure/ansible/roles/auditd/tasks/main.yml new file mode 100644 index 00000000..c01e59a8 --- /dev/null +++ b/infrastructure/ansible/roles/auditd/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: "install auditd" + apt: + name: auditd + state: latest + +- name: "fetch best practice Auditd config" + get_url: + url: https://raw.githubusercontent.com/Neo23x0/auditd/master/audit.rules + dest: /etc/audit/rules.d/audit.rules + +- name: "restart auditd service" + ansible.builtin.service: + name: auditd + state: restarted diff --git a/monitoring/docker-compose.yml b/monitoring/docker-compose.yml index 36c40226..e673a56c 100644 --- a/monitoring/docker-compose.yml +++ b/monitoring/docker-compose.yml @@ -51,6 +51,8 @@ services: source: kminion-topic_rev1.json - target: /etc/grafana/provisioning/dashboards/containers/logging-universal-dashboard_rev1.json source: logging-universal-dashboard_rev1.json + - target: /etc/grafana/provisioning/dashboards/security/auditlogs.json + source: auditlogs.json prometheus: image: prom/prometheus:v2.38.0 @@ -189,6 +191,11 @@ configs: name: logging-universal-dashboard_rev1.json-${logging_universal_dashboard_rev1_json_DIGEST:?err} labels: name: grafana + auditlogs.json: + file: ./grafana/dashboards/security/auditlogs.json + name: auditlogs.json-${auditlogs_json_DIGEST:?err} + labels: + name: grafana prometheus.yml: file: ./prometheus/prometheus.yml name: prometheus.yml-${prometheus_yml_DIGEST:?err} diff --git a/monitoring/grafana/dashboards/security/auditlogs.json b/monitoring/grafana/dashboards/security/auditlogs.json new file mode 100644 index 00000000..6e6e6ec3 --- /dev/null +++ b/monitoring/grafana/dashboards/security/auditlogs.json @@ -0,0 +1,163 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "loki", + "uid": "P00201832B18B88C3" + }, + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 3, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": true, + "scale": "exponential", + "scheme": "Oranges", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "show": true, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "9.2.3", + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P00201832B18B88C3" + }, + "editorMode": "code", + "expr": "sum(count_over_time({label=~\"T1219.*|recon|.*susp.*\"} [$__interval]))", + "queryType": "range", + "refId": "A" + } + ], + "title": "Suspicious activity", + "type": "heatmap" + }, + { + "datasource": { + "type": "loki", + "uid": "P00201832B18B88C3" + }, + "description": "Filter for security auditlogs that that are potentially suspicious.", + "gridPos": { + "h": 17, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 1, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": true, + "sortOrder": "Descending", + "wrapLogMessage": true + }, + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "P00201832B18B88C3" + }, + "editorMode": "builder", + "expr": "{job=\"auditlogs\", label=~\"T1219.*|recon|.*susp.*\"}", + "key": "Q-9181c263-cf75-42fe-bf50-036eeff7207a-0", + "queryType": "range", + "refId": "A" + } + ], + "title": "Suspicious activity", + "type": "logs" + } + ], + "refresh": false, + "schemaVersion": 37, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Audit logs", + "uid": "1KG6epL4z", + "version": 1, + "weekStart": "" +} diff --git a/monitoring/promtail/promtail-config.yml b/monitoring/promtail/promtail-config.yml index 1cce8fe2..c9614c60 100644 --- a/monitoring/promtail/promtail-config.yml +++ b/monitoring/promtail/promtail-config.yml @@ -6,42 +6,64 @@ positions: filename: /tmp/positions.yaml clients: -- url: http://loki:3100/loki/api/v1/push + - url: http://loki:3100/loki/api/v1/push scrape_configs: + - job_name: containers + static_configs: + - targets: + - localhost + labels: + job: containerlogs + __path__: /host/containers/*/*log -- job_name: containers - static_configs: - - targets: - - localhost - labels: - job: containerlogs - __path__: /host/containers/*/*log + pipeline_stages: + - json: + expressions: + log: log + stream: stream + time: time + tag: attrs.tag + stack_name: attrs."com.docker.stack.namespace" + swarm_service_name: attrs."com.docker.swarm.service.name" + swarm_task_name: attrs."com.docker.swarm.task.name" + swarm_node_id: attrs."com.docker.swarm.node.id" + - regex: + expression: "^/host/containers/(?P.{12}).+/.+-json.log$" + source: filename + - timestamp: + format: RFC3339Nano + source: time + - labels: + stream: + container_id: + tag: + stack_name: + swarm_service_name: + swarm_task_name: + swarm_node_id: + - output: + source: log - pipeline_stages: - - json: - expressions: - log: log - stream: stream - time: time - tag: attrs.tag - stack_name: attrs."com.docker.stack.namespace" - swarm_service_name: attrs."com.docker.swarm.service.name" - swarm_task_name: attrs."com.docker.swarm.task.name" - swarm_node_id: attrs."com.docker.swarm.node.id" - - regex: - expression: "^/host/containers/(?P.{12}).+/.+-json.log$" - source: filename - - timestamp: - format: RFC3339Nano - source: time - - labels: - stream: - container_id: - tag: - stack_name: - swarm_service_name: - swarm_task_name: - swarm_node_id: - - output: - source: log + - job_name: auditd + static_configs: + - targets: + - localhost # Auditd logs are collected from the local host + labels: + job: auditlogs + __path__: /var/log/audit/audit.log + + pipeline_stages: + - regex: + expression: 'type=(?P\S*)' + - regex: + expression: 'key="(?P