diff --git a/.github/actions/default/Dockerfile b/.github/actions/default/Dockerfile new file mode 100644 index 00000000..9dffbde8 --- /dev/null +++ b/.github/actions/default/Dockerfile @@ -0,0 +1,7 @@ +FROM quay.io/ansible/molecule:2.20 + +VOLUME [ "/sys/fs/cgroup", "/run", "/run/lock" ] + +COPY ./entrypoint.sh /entrypoint.sh +RUN chmod 755 /entrypoint.sh +ENTRYPOINT ["/entrypoint.sh"] diff --git a/.github/actions/default/action.yml b/.github/actions/default/action.yml new file mode 100644 index 00000000..a9b38478 --- /dev/null +++ b/.github/actions/default/action.yml @@ -0,0 +1,6 @@ +name: molecule-test +description: Molecule tests for Wazuh Ansible +runs: + using: docker + image: 'Dockerfile' + diff --git a/.github/actions/default/entrypoint.sh b/.github/actions/default/entrypoint.sh new file mode 100644 index 00000000..158e9f08 --- /dev/null +++ b/.github/actions/default/entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh -eu + +molecule test \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..26cb0e32 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,13 @@ + +name: Molecule tests for Wazuh Ansible + +on: [push] + +jobs: + default: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v2 + - name: Default scenario + uses: './.github/actions/default' diff --git a/molecule/default/Dockerfile.j2 b/molecule/default/Dockerfile.j2 new file mode 100644 index 00000000..19692c20 --- /dev/null +++ b/molecule/default/Dockerfile.j2 @@ -0,0 +1,14 @@ +# Molecule managed + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get upgrade -y && apt-get install -y python sudo bash ca-certificates && apt-get clean; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python2-dnf bash && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum update -y && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper update -y && zypper install -y python sudo bash python-xml && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates && xbps-remove -O; fi diff --git a/molecule/default/INSTALL.rst b/molecule/default/INSTALL.rst new file mode 100644 index 00000000..e26493b8 --- /dev/null +++ b/molecule/default/INSTALL.rst @@ -0,0 +1,16 @@ +******* +Install +******* + +Requirements +============ + +* Docker Engine +* docker-py + +Install +======= + +.. code-block:: bash + + $ sudo pip install docker-py diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml new file mode 100644 index 00000000..cd184961 --- /dev/null +++ b/molecule/default/molecule.yml @@ -0,0 +1,53 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint + enabled: false +platforms: + + - name: manager_centos7 + image: milcom/centos7-systemd + command: /sbin/init + ulimits: + - nofile:262144:262144 + privileged: true + memory_reservation: 2048m + + - name: ubuntu20 + image: jrei/systemd-ubuntu:20.04 + privileged: true + + - name: debian9 + image: jrei/systemd-debian:9 + privileged: true + +provisioner: + name: ansible + config_options: + defaults: + hash_behaviour: merge + env: + ANSIBLE_ROLES_PATH: ./roles + lint: + name: ansible-lint + enabled: false +scenario: + name: default + test_sequence: + - dependency + - syntax + - create + - prepare + - converge + #- idempotence + - verify + - cleanup + - destroy +verifier: + name: testinfra + lint: + name: flake8 + enabled: false diff --git a/molecule/default/playbook.yml b/molecule/default/playbook.yml new file mode 100644 index 00000000..0e6bf98d --- /dev/null +++ b/molecule/default/playbook.yml @@ -0,0 +1,7 @@ +--- +- name: Converge + hosts: all + roles: + - role: ../../roles/wazuh/ansible-wazuh-manager + vars: + - { role: ../../roles/wazuh/ansible-filebeat, filebeat_output_elasticsearch_hosts: "elasticsearch_centos7:9200" } diff --git a/molecule/default/tests/test_default.py b/molecule/default/tests/test_default.py new file mode 100644 index 00000000..5d5f6655 --- /dev/null +++ b/molecule/default/tests/test_default.py @@ -0,0 +1,63 @@ +import os +import pytest +import testinfra.utils.ansible_runner +import re + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + +def get_wazuh_version(): + """This returns the version of Wazuh.""" + return "3.13.1" + +def test_wazuh_packages_are_installed(host): + """Test the main packages are installed.""" + manager = host.package("wazuh-manager") + api = host.package("wazuh-api") + assert manager.is_installed + assert manager.version.startswith(get_wazuh_version()) + assert api.is_installed + assert api.version.startswith(get_wazuh_version()) + +def test_wazuh_services_are_running(host): + """Test the services are enabled and running. + + When assert commands are commented, this means that the service command has + a wrong exit code: https://github.com/wazuh/wazuh-ansible/issues/107 + """ + # This currently doesn't work with out current Docker base images + # manager = host.service("wazuh-manager") + # api = host.service("wazuh-api") + # assert manager.is_running + # assert api.is_running + output = host.check_output('ps aux | grep ossec | tr -s " " | cut -d" " -f11') + assert 'ossec-authd' in output + assert 'wazuh-modulesd' in output + assert 'wazuh-db' in output + assert 'ossec-execd' in output + assert 'ossec-monitord' in output + assert 'ossec-remoted' in output + assert 'ossec-logcollector' in output + assert 'ossec-analysisd' in output + assert 'ossec-syscheckd' in output + + +@pytest.mark.parametrize("wazuh_file, wazuh_owner, wazuh_group, wazuh_mode", [ + ("/var/ossec/etc/sslmanager.cert", "root", "root", 0o640), + ("/var/ossec/etc/sslmanager.key", "root", "root", 0o640), + ("/var/ossec/etc/rules/local_rules.xml", "ossec", "ossec", 0o640), + ("/var/ossec/etc/lists/audit-keys", "ossec", "ossec", 0o660), +]) + +def test_wazuh_files(host, wazuh_file, wazuh_owner, wazuh_group, wazuh_mode): + """Test Wazuh related files exist and have proper owners and mode.""" + wazuh_file_host = host.file(wazuh_file) + assert wazuh_file_host.user == wazuh_owner + assert wazuh_file_host.group == wazuh_group + assert wazuh_file_host.mode == wazuh_mode + +def test_filebeat_is_installed(host): + """Test the elasticsearch package is installed.""" + filebeat = host.package("filebeat") + assert filebeat.is_installed + assert filebeat.version.startswith('7.8.0') diff --git a/roles/elastic-stack/ansible-kibana/tasks/main.yml b/roles/elastic-stack/ansible-kibana/tasks/main.yml index cf330640..78d15630 100755 --- a/roles/elastic-stack/ansible-kibana/tasks/main.yml +++ b/roles/elastic-stack/ansible-kibana/tasks/main.yml @@ -14,16 +14,6 @@ - import_tasks: Debian.yml when: ansible_os_family == 'Debian' -- name: Reload systemd - systemd: - daemon_reload: true - ignore_errors: true - when: - - not (ansible_distribution == "Amazon" and ansible_distribution_version == "(Karoo)") - - not (ansible_distribution == "Ubuntu" and ansible_distribution_version is version('15.04', '<')) - - not (ansible_distribution == "Debian" and ansible_distribution_version is version('8', '<')) - - not (ansible_os_family == "RedHat" and ansible_distribution_version is version('7', '<')) - - name: Copying node's certificate from master copy: src: "{{ item }}" @@ -177,10 +167,6 @@ mode: 0751 changed_when: False -- name: Reload systemd configuration - systemd: - daemon_reload: true - - name: Ensure Kibana is started and enabled service: name: kibana diff --git a/roles/opendistro/opendistro-kibana/tasks/main.yml b/roles/opendistro/opendistro-kibana/tasks/main.yml index 006b7cd7..e127f2f9 100755 --- a/roles/opendistro/opendistro-kibana/tasks/main.yml +++ b/roles/opendistro/opendistro-kibana/tasks/main.yml @@ -11,16 +11,6 @@ - import_tasks: RedHat.yml when: ansible_os_family == 'RedHat' -- name: Reload systemd - systemd: - daemon_reload: true - ignore_errors: true - when: - - not (ansible_distribution == "Amazon" and ansible_distribution_version == "(Karoo)") - - not (ansible_distribution == "Ubuntu" and ansible_distribution_version is version('15.04', '<')) - - not (ansible_distribution == "Debian" and ansible_distribution_version is version('8', '<')) - - not (ansible_os_family == "RedHat" and ansible_distribution_version is version('7', '<')) - - name: Install Kibana package: name: "opendistroforelasticsearch-kibana{{ kibana_opendistro_version }}" @@ -119,10 +109,6 @@ mode: 0751 changed_when: False -- name: Reload systemd configuration - systemd: - daemon_reload: true - - name: Ensure Kibana started and enabled service: name: kibana diff --git a/roles/wazuh/ansible-filebeat/tasks/main.yml b/roles/wazuh/ansible-filebeat/tasks/main.yml index 71d57a6d..f4e30a77 100644 --- a/roles/wazuh/ansible-filebeat/tasks/main.yml +++ b/roles/wazuh/ansible-filebeat/tasks/main.yml @@ -111,15 +111,6 @@ when: filebeat_create_config notify: restart filebeat -- name: Reload systemd - systemd: daemon_reload=yes - ignore_errors: true - when: - - not (ansible_distribution == "Amazon" and ansible_distribution_major_version == "NA") - - not (ansible_distribution == "Ubuntu" and ansible_distribution_version is version('15.04', '<')) - - not (ansible_distribution == "Debian" and ansible_distribution_version is version('8', '<')) - - not (ansible_os_family == "RedHat" and ansible_distribution_version is version('7', '<')) - - name: Ensure Filebeat is started and enabled at boot. service: name: filebeat diff --git a/roles/wazuh/ansible-wazuh-manager/tasks/Debian.yml b/roles/wazuh/ansible-wazuh-manager/tasks/Debian.yml index da27042f..9247543e 100644 --- a/roles/wazuh/ansible-wazuh-manager/tasks/Debian.yml +++ b/roles/wazuh/ansible-wazuh-manager/tasks/Debian.yml @@ -102,10 +102,6 @@ name: - "wazuh-manager={{ wazuh_manager_version }}" state: present - cache_valid_time: 3600 - install_recommends: false - register: wazuh_manager_main_packages_installed - until: wazuh_manager_main_packages_installed is succeeded tags: init when: - not wazuh_manager_sources_installation.enabled