Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions infrastructure/ansible/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,19 @@

## Infrastructure and Servers

Please see the `/inventories/{ENVIRONMENT}/hosts` file for IP details of the designated services. Set these to the server that you created via terraform.
Please see the `/inventories/{ENVIRONMENT}/hosts` file for IP details of the designated services. Set these to the server's domain name/s that you created via terraform.

## Ansible

### SSH Access

To authenticate yourself on the remote servers your ssh key will need to be added to the `sudoers` var in the _/inventories/{ENVIRONMENT}/group_vars/all.yml_.
To authenticate users and to allow them to have sudo access on the remote servers your ssh key will need to be added to the `sudoers` var in the _/inventories/{ENVIRONMENT}/group_vars/all.yml_.

To have docker access you need to add your ssh key to the `docker_users` var in the _/inventories/{ENVIRONMENT}/group_vars/all.yml_.
To authenticate users and to allow them to have docker access you need to add your ssh key to the `docker_users` var in the _/inventories/{ENVIRONMENT}/group_vars/all.yml_.

An authorised user will need to run the `provision_servers.yml` playbook to add your ssh key to the servers.
Ensure that you remove all users that you don't want to have access. The default development files have a bunch of Jembi staff's user credentials.

An pre-authorised user will need to run the `provision_servers.yml` playbook the first time to add your ssh key to the servers.

### Configuration

Expand All @@ -32,6 +34,8 @@ Before running the ansible script add the server to your known hosts file else a
ssh-keyscan -H <host> >> ~/.ssh/known_hosts
```

Next, ensure that you configure the `firewall_subnet_restriction` property of the _/inventories/{ENVIRONMENT}/group_vars/all.yml_ file if you are setting up multiple nodes in a Docker swarm. Docker swarm nodes need to communicate with each other, this property adds a restriction on the software firewall on each node (UFW) which only allow that communication to happen on the particular subset specified by this property.

To run a playbook you should do:

```bash
Expand Down
1 change: 1 addition & 0 deletions infrastructure/ansible/playbooks/provision_servers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
- common
- docker
- ufw
- auditd
22 changes: 22 additions & 0 deletions infrastructure/ansible/roles/auditd/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
- 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: Ensure name_format is set to HOSTNAME
lineinfile:
path: /etc/audit/auditd.conf
regexp: '^name_format\s*='
line: "name_format = HOSTNAME"
state: present

- name: "restart auditd service"
ansible.builtin.service:
name: auditd
state: restarted
6 changes: 3 additions & 3 deletions infrastructure/ansible/roles/docker/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
---
- include: reload_ufw.yml
- include: reload_docker.yml
- include: restart_docker.yml
- import_tasks: reload_ufw.yml
- import_tasks: reload_docker.yml
- import_tasks: restart_docker.yml
7 changes: 7 additions & 0 deletions monitoring/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ services:
source: openhim_transactions_dashboard.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
networks:
keycloak:
reverse-proxy:
Expand Down Expand Up @@ -228,6 +230,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}
Expand Down
277 changes: 277 additions & 0 deletions monitoring/grafana/dashboards/security/auditlogs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
{
"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": "datasource",
"uid": "grafana"
},
"gridPos": {
"h": 4,
"w": 24,
"x": 0,
"y": 0
},
"id": 6,
"options": {
"code": {
"language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "# Notes\n\n* Some `proctitles` are hex encoded due to the posibility of special chars. Use a hex to ascii decoder to view these.\n* Multiple lines might refer to the same event, in that case the audit identifier (i.e. `msg=audit(...:...)`) will be the same. Use the find input to easily see all line for an event by searching for this audit identifier.",
"mode": "markdown"
},
"pluginVersion": "9.2.3",
"title": "Notes",
"type": "text"
},
{
"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": 4
},
"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": "builder",
"expr": "sum(count_over_time({label=~\"T1219.*|recon|.*susp.*\", node=~\"$node\"} |= `$query` [$__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": 10
},
"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.*\", node=~\"$node\"} |= `$query`",
"key": "Q-9181c263-cf75-42fe-bf50-036eeff7207a-0",
"queryType": "range",
"refId": "A"
}
],
"title": "Suspicious activity",
"type": "logs"
},
{
"datasource": {
"type": "loki",
"uid": "P00201832B18B88C3"
},
"description": "All captured logs from auditd",
"gridPos": {
"h": 17,
"w": 24,
"x": 0,
"y": 27
},
"id": 4,
"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\", node=~\"$node\"} |= `$query`",
"key": "Q-9181c263-cf75-42fe-bf50-036eeff7207a-0",
"queryType": "range",
"refId": "A"
}
],
"title": "All audit logs",
"type": "logs"
}
],
"refresh": false,
"schemaVersion": 37,
"style": "dark",
"tags": [],
"templating": {
"list": [
{
"current": {
"selected": false,
"text": "",
"value": ""
},
"hide": 0,
"label": "Find",
"name": "query",
"options": [
{
"selected": true,
"text": "",
"value": ""
}
],
"query": "",
"skipUrlSync": false,
"type": "textbox"
},
{
"current": {
"selected": true,
"text": ["All"],
"value": ["$__all"]
},
"datasource": {
"type": "loki",
"uid": "P00201832B18B88C3"
},
"definition": "",
"hide": 0,
"includeAll": true,
"label": "Hostname",
"multi": true,
"name": "node",
"options": [],
"query": {
"label": "node",
"refId": "LokiVariableQueryEditor-VariableQuery",
"stream": "",
"type": 1
},
"refresh": 1,
"regex": "",
"skipUrlSync": false,
"sort": 0,
"type": "query"
}
]
},
"time": {
"from": "now-15m",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Audit logs",
"uid": "1KG6epL4z",
"version": 1,
"weekStart": ""
}
Loading