From a430a0c85fe7fdd9b542e4316a4b434c340178ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Sachse?= <Joerg.Sachse@slub-dresden.de> Date: Fri, 5 Aug 2022 14:38:06 +0200 Subject: [PATCH] test: implement all necessary changes for using GitLab-CI, including Linter recommendations and idempotency changes --- .ansible-lint | 45 +++++----- .config/molecule/config.yml | 2 + .gitignore | 13 ++- .gitlab-ci.yml | 33 +++++++ .yamllint | 32 ++++--- ansible.cfg | 3 +- handlers/main.yml | 28 +++--- meta/main.yml | 46 +++++----- molecule/README.md | 85 ------------------- molecule/default | 1 + molecule/default/converge.yml | 5 -- molecule/default/molecule.yml | 36 -------- molecule/default/prepare.yml | 39 --------- molecule/default/tests/conftest.py | 20 ----- molecule/default/tests/test_default.py | 6 -- molecule/resources/playbooks/Dockerfile | 20 +++++ .../playbooks}/INSTALL.rst | 6 +- molecule/resources/playbooks/README.md | 3 + molecule/resources/playbooks/converge.yml | 17 ++++ molecule/resources/playbooks/prepare.yml | 22 +++++ molecule/resources/playbooks/verify.yml | 10 +++ molecule/virtualbox/molecule.yml | 41 +++++++++ requirements.yml => requirements.yml.example | 0 site.yml | 1 - ...re-fail2ban.yml => configure_fail2ban.yml} | 24 +++--- ...ons.yml => configure_home_permissions.yml} | 6 +- ...re-iptables.yml => configure_iptables.yml} | 33 +++---- ...rs.yml => configure_kernel_parameters.yml} | 2 +- .../{configure-pam.yml => configure_pam.yml} | 12 +-- ...age.yml => configure_portable_storage.yml} | 6 +- ...{configure-root.yml => configure_root.yml} | 6 +- ...dening.yml => configure_ssh_hardening.yml} | 2 +- ...onfigure-umask.yml => configure_umask.yml} | 18 ++-- tasks/install-debsecan.yml | 26 ------ ...{install-auditd.yml => install_auditd.yml} | 6 +- ...{install-clamav.yml => install_clamav.yml} | 31 ++++--- tasks/install_debsecan.yml | 25 ++++++ ...tall-rkhunter.yml => install_rkhunter.yml} | 76 +++++++++++------ tasks/main.yml | 37 ++++---- 39 files changed, 410 insertions(+), 414 deletions(-) create mode 100644 .config/molecule/config.yml create mode 100644 .gitlab-ci.yml delete mode 100644 molecule/README.md create mode 120000 molecule/default delete mode 100644 molecule/default/converge.yml delete mode 100644 molecule/default/molecule.yml delete mode 100644 molecule/default/prepare.yml delete mode 100644 molecule/default/tests/conftest.py delete mode 100644 molecule/default/tests/test_default.py create mode 100644 molecule/resources/playbooks/Dockerfile rename molecule/{default => resources/playbooks}/INSTALL.rst (84%) create mode 100644 molecule/resources/playbooks/README.md create mode 100644 molecule/resources/playbooks/converge.yml create mode 100644 molecule/resources/playbooks/prepare.yml create mode 100644 molecule/resources/playbooks/verify.yml create mode 100644 molecule/virtualbox/molecule.yml rename requirements.yml => requirements.yml.example (100%) rename tasks/{configure-fail2ban.yml => configure_fail2ban.yml} (89%) rename tasks/{configure-home-permissions.yml => configure_home_permissions.yml} (87%) rename tasks/{configure-iptables.yml => configure_iptables.yml} (90%) rename tasks/{configure-kernel-parameters.yml => configure_kernel_parameters.yml} (99%) rename tasks/{configure-pam.yml => configure_pam.yml} (93%) rename tasks/{configure-portable-storage.yml => configure_portable_storage.yml} (90%) rename tasks/{configure-root.yml => configure_root.yml} (64%) rename tasks/{configure-ssh-hardening.yml => configure_ssh_hardening.yml} (99%) rename tasks/{configure-umask.yml => configure_umask.yml} (85%) delete mode 100644 tasks/install-debsecan.yml rename tasks/{install-auditd.yml => install_auditd.yml} (89%) rename tasks/{install-clamav.yml => install_clamav.yml} (92%) create mode 100644 tasks/install_debsecan.yml rename tasks/{install-rkhunter.yml => install_rkhunter.yml} (69%) diff --git a/.ansible-lint b/.ansible-lint index 9c9323e..f18a647 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -6,7 +6,7 @@ # and not relative to the CWD of execution. CLI arguments passed to the --exclude # option will be parsed relative to the CWD of execution. exclude_paths: - - .cache/ # implicit unless exclude_paths is defined in config + - .cache/ # implicit unless exclude_paths is defined in config - .git/ - .githooks/ - backups/ @@ -15,24 +15,19 @@ exclude_paths: # verbosity: 1 # Mock modules or roles in order to pass ansible-playbook --syntax-check -#mock_modules: -# - zuul_return -# # note the foo.bar is invalid as being neither a module or a collection -# - fake_namespace.fake_collection.fake_module -# - fake_namespace.fake_collection.fake_module.fake_submodule -#mock_roles: -# - mocked_role -# - author.role_name # old standalone galaxy role -# - fake_namespace.fake_collection.fake_role # role within a collection +# mock_modules: +# - zuul_return +# # note the foo.bar is invalid as being neither a module or a collection +# - fake_namespace.fake_collection.fake_module +# - fake_namespace.fake_collection.fake_module.fake_submodule +# mock_roles: +# - mocked_role +# - author.role_name # old standalone galaxy role +# - fake_namespace.fake_collection.fake_role # role within a collection # Enable checking of loop variable prefixes in roles loop_var_prefix: "{role}_" -# Enforce variable names to follow pattern below, in addition to Ansible own -# requirements, like avoiding python identifiers. To disable add `var-naming` -# to skip_list. -var_naming_pattern: "^[a-z_][a-z0-9_]*$" - use_default_rules: true # Load custom rules from this specific folder # rulesdir: @@ -46,9 +41,9 @@ skip_list: # Any rule that has the 'opt-in' tag will not be loaded unless its 'id' is # mentioned in the enable_list: enable_list: - - empty-string-compare # opt-in - - no-log-password # opt-in - - no-same-owner # opt-in + - empty-string-compare # opt-in + - no-log-password # opt-in + - no-same-owner # opt-in # add yaml here if you want to avoid ignoring yaml checks when yamllint # library is missing. Normally its absence just skips using that rule. - yaml @@ -60,19 +55,19 @@ enable_list: warn_list: - skip_this_tag - git-latest - - experimental # experimental is included in the implicit list + - experimental # experimental is included in the implicit list # - role-name # Offline mode disables installation of requirements.yml offline: false # Define required Ansible's variables to satisfy syntax check -#extra_vars: -# foo: bar -# multiline_string_variable: | -# line1 -# line2 -# complex_variable: ":{;\t$()" +# extra_vars: +# foo: bar +# multiline_string_variable: | +# line1 +# line2 +# complex_variable: ":{;\t$()" # Uncomment to enforce action validation with tasks, usually is not # needed as Ansible syntax check also covers it. diff --git a/.config/molecule/config.yml b/.config/molecule/config.yml new file mode 100644 index 0000000..ece7ff6 --- /dev/null +++ b/.config/molecule/config.yml @@ -0,0 +1,2 @@ +--- +prerun: false diff --git a/.gitignore b/.gitignore index 4ac23e9..ed78332 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,8 @@ Thumbs.db *.retry *.vault +inventory.* +inv.* # Vim # ####### @@ -73,7 +75,14 @@ tags .vagrant/ *.box -# Backups # -########### +# Temporary/Build/Backup # +########################## backups/ +build/ + +# CONFIDENTIAL # +################ + +ssh_host_* + diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..df4e06f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,33 @@ +--- +# A pipeline is composed of independent jobs that run scripts, grouped into stages. +# Stages run in sequential order, but jobs within stages run in parallel. +# +# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages + +stages: # List of stages for jobs, and their order of execution + - test + +default: + before_script: + - source /opt/molecule/bin/activate + - ansible --version + - molecule --version + +test-job: + stage: test + tags: + - "shell" + script: + # make sure that Ansible Vaults are present and can be decrypted + - echo "${VAULT_SERVER_HARDENING}" > ../lza_server_hardening.pass + - export ANSIBLE_VAULT_PASSWORD_FILE=../lza_server_hardening.pass + - rm -rf ../ansible_vaults/ + - git clone https://gitlab+deploy-token-25:${VAULT_ACCESS_TOKEN}@git.slub-dresden.de/slub-referat-2-3/ansible_vaults.git ../ansible_vaults/; \ + # run Molecule tests + - molecule syntax --scenario-name default + - molecule lint --scenario-name default + - molecule create --scenario-name default + - molecule converge --scenario-name default + - molecule idempotence --scenario-name default + # - molecule verify --scenario-name default + - molecule destroy --scenario-name default diff --git a/.yamllint b/.yamllint index 7c0f15c..8827676 100644 --- a/.yamllint +++ b/.yamllint @@ -1,7 +1,5 @@ --- -# based on documentation available at -# https://yamllint.readthedocs.io/en/stable/rules.html - +# Based on ansible-lint config extends: default rules: @@ -11,13 +9,25 @@ rules: brackets: max-spaces-inside: 1 level: error - comments: - min-spaces-from-content: 4 + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable comments-indentation: disable - document-end: disable - document-start: - level: warning - octal-values: - forbid-explicit-octal: false + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable line-length: disable - truthy: enable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/ansible.cfg b/ansible.cfg index c43f9b3..5c000f2 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -1,7 +1,8 @@ [defaults] # If set, configures the path to the Vault password file as an alternative to # specifying --vault-password-file on the command line. -vault_identity_list = ../lza_install_common.pass, ../lza_server_hardening.pass, ../slub_osquery.pass +# vault_identity_list = ../lza_install_common.pass, ../lza_server_hardening.pass, ../slub_osquery.pass +vault_identity_list = ../lza_server_hardening.pass # Path to default inventory file # Administrators can override this by using the "-i <inventoryfile>" CLI diff --git a/handlers/main.yml b/handlers/main.yml index ada4777..702d766 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -2,7 +2,7 @@ - name: save iptables rules (Debian) block: - name: Ordner für iptables-Config erstellen - file: + ansible.builtin.file: path: "/etc/iptables" state: directory owner: "root" @@ -10,19 +10,20 @@ mode: 0755 listen: "save iptables rules" - name: install netfilter-persistent to be able to save iptables rules - apt: + ansible.builtin.apt: name: netfilter-persistent state: present listen: "save iptables rules" - name: save iptables rules - command: 'netfilter-persistent save' + ansible.builtin.command: 'netfilter-persistent save' listen: "save iptables rules" + changed_when: false when: ansible_os_family == "Debian" - name: save iptables rules (RedHat) block: - name: make sure iptables config file exists - file: + ansible.builtin.file: path: "/etc/sysconfig/iptables" state: touch owner: "root" @@ -30,33 +31,34 @@ mode: 0600 listen: "save iptables rules" - name: save rules - command: /usr/sbin/iptables-save # noqa 303 + ansible.builtin.command: /usr/sbin/iptables-save # noqa 303 listen: "save iptables rules" + changed_when: false when: ansible_os_family == "RedHat" - name: activate kernel parameter changes - command: sysctl -p - ignore_errors: true + ansible.builtin.command: sysctl -p + changed_when: false - name: restart fail2ban.service - service: + ansible.builtin.service: name: "fail2ban" state: restarted - name: restart sshd - service: + ansible.builtin.service: name: "sshd" state: restarted - name: restart auditd.service - service: + ansible.builtin.service: name: "auditd" state: restarted when: ansible_os_family == "Debian" listen: restart auditd.service - name: restart auditd.service - service: + ansible.builtin.service: name: "auditd" state: restarted use: "service" @@ -64,13 +66,13 @@ listen: restart auditd.service - name: restart clamav-daemon service - service: + ansible.builtin.service: name: "clamav-daemon" state: restarted when: ansible_os_family == "Debian" - name: restart clamd service - service: + ansible.builtin.service: name: "clamd@{{ ansible_hostname }}.service" state: restarted when: ansible_os_family == "RedHat" diff --git a/meta/main.yml b/meta/main.yml index a798dd1..cf10295 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,16 +1,24 @@ --- galaxy_info: - author: Jörg Sachse - description: role to deploy a hardened install of Debian for use in the SLUBarchiv digital preservation repository + author: Jörg Sachse <Joerg.Sachse@slub-dresden.de> company: SLUB Dresden - # If the issue tracker for your role is not on github, uncomment the next line and provide a value issue_tracker_url: http://example.com/issue/tracker Some suggested licenses: - BSD - # (default) - MIT - GPLv2 - GPLv3 - Apache - CC-BY - license: public domain - min_ansible_version: 2.4 - # If this a Container Enabled role, provide the minimum Ansible Container version. min_ansible_container_version: Optionally specify the branch Galaxy will use when accessing the GitHub repo - # for this role. During role install, if no tags are available, Galaxy will use this branch. During import Galaxy will access files on this branch. If Travis integration is configured, only - # notifications for this branch will be accepted. Otherwise, in all cases, the repo's default branch (usually master) will be used. github_branch: - # + description: role to deploy a hardened install of Debian for use in the SLUBarchiv digital preservation repository + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes and categorizes the role. Users find roles by searching for tags. Be sure to remove the '[]' above, if you + # add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + # issue_tracker_url: "https://example.com/" + # If the issue tracker for your role is not on github, uncomment the next line and provide a value issue_tracker_url: http://example.com/issue/tracker + license: GPLv3 + # Some suggested licenses: - BSD + # (default) - MIT - GPLv2 - GPLv3 - Apache - CC-BY + min_ansible_version: "2.5" + # If this a Container Enabled role, provide the minimum Ansible Container version. min_ansible_container_version: Optionally specify the branch Galaxy will use when accessing the GitHub repo + # for this role. During role install, if no tags are available, Galaxy will use this branch. During import Galaxy will access files on this branch. If Travis integration is configured, only + # notifications for this branch will be accepted. Otherwise, in all cases, the repo's default branch (usually master) will be used. github_branch: + namespace: "slub" # Provide a list of supported platforms, and for each platform a list of versions. If you don't wish to enumerate all versions for a particular platform, use 'all'. To view available # platforms and versions (or releases), visit: https://galaxy.ansible.com/api/v1/platforms/ # @@ -19,16 +27,10 @@ galaxy_info: platforms: - name: Debian versions: - - 9 - - 10 - - name: RedHat + - "buster" + - "bullseye" + - name: EL versions: - - 6 - - 7 - galaxy_tags: [] - # List tags for your role here, one per line. A tag is a keyword that describes and categorizes the role. Users find roles by searching for tags. Be sure to remove the '[]' above, if you - # add tags to this list. - # - # NOTE: A tag is limited to a single word comprised of alphanumeric characters. - # Maximum 20 tags per role. -# dependencies: [] + - "7" + - "8" +dependencies: [] diff --git a/molecule/README.md b/molecule/README.md deleted file mode 100644 index 33a7eb5..0000000 --- a/molecule/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# Testing with Molecule - -## Prerequisites - -In order to be able to use the tests, you need to have some software packages installed. You may need sudo privileges for some of these operations. - - ### install VirtualBox - # do NOT use distribution packages - # process documented at https://www.virtualbox.org/wiki/Linux_Downloads - # - # add repository URL - sudo echo "deb [arch=amd64] https://download.virtualbox.org/virtualbox/debian stretch contrib" > /etc/apt/sources.d/virtualbox.list - # add GPG key - wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add - - # update sources - sudo apt update - # install VirtualBox - sudo apt-get install virtualbox-6.1 - - ### install Vagrant - # do NOT use distribution packages - # - # download Debian package from Hashicorp - wget https://releases.hashicorp.com/vagrant/2.2.9/vagrant_2.2.9_x86_64.deb - # install package - sudo dpkg -i vagrant_2.2.9_x86_64.deb - - ### install Molecule et. al. - # prepare directories - mkdir ~/python-envs/ && cd ~/python-env/ - # create Python Virtual Environment with Python3 interpreter (Python2 is deprecated!) - virtualenv -p python3 molecule-env - # enter the Virtual Environment in your current shell (other shells will be unaffected) - source molecule-env/bin/activate - # install packages - pip3 install molecule ansible testinfra ansible-lint molecule-vagrant molecule-docker - - # leave the Virtual Environment only when you're done - deactivate - -You can find suitable documentation at the respective vendors' websites. -* [Vagrant Installation Guide](https://www.vagrantup.com/docs/installation/) -* [VirtualBox Installation Guide](https://www.virtualbox.org/wiki/Downloads) -* [Molecule Installation Guide](https://molecule.readthedocs.io/en/stable/installation.html) - -## Initialising a new Molecule scenario - -If you have already created a role without the Molecule test framework or you want to add test scenarios, you can use: - molecule init scenario --scenario-name <my_scenario> --driver [azure|delegated|docker|ec2|gce|linode|lxc|lxd|openstack|vagrant] --verifier-name [ansible|testinfra] - -If you need any help with the options, please use: - molecule init role --help - -## Running Tests - -Molecule helps with creating a test infrastructure, running tests against it and removing the test infrastructure afterwards. - -Various test environments are separated into so-called "scenarios" that can be based on different OSses, drivers, verifiers or might just differ in a minor detail. - -In the simplest configuration, the `molecule/` directory only contains one `default/` directory that contains the default scenario. This scenario is run if no other scenario is chosen using the `-s` CLI option. - -This is the basic usage of Molecule: - # create test infrastructure - cd <role_directory> - molecule create - # run playbooks against test infrastructure - molecule converge - # run Testinfra tests - molecule verify - # remove test infrastructure - molecule destroy - - # run all steps at once: - molecule test - -It has proven helpful to use Vagrant to create a snapshot of the VM after the creation phase has completed. - # First, get UUID of the VM - vagrant global-status - # Then, create the snapshot - vagrant snapshot save <uuid> <snapshot_name> - # To restore the snapshot, use - vagrant snapshot restore <uuid> <snapshot_name> - # And to remove the snapshot, use - vagrant snapshot delete <uuid> <snapshot_name> - diff --git a/molecule/default b/molecule/default new file mode 120000 index 0000000..3841ab1 --- /dev/null +++ b/molecule/default @@ -0,0 +1 @@ +./virtualbox \ No newline at end of file diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml deleted file mode 100644 index 489d40a..0000000 --- a/molecule/default/converge.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -- name: Converge - hosts: all - roles: - - {role: "ansible_lza_server_hardening", become: true} diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml deleted file mode 100644 index f435b3f..0000000 --- a/molecule/default/molecule.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- -dependency: - name: galaxy -driver: - name: vagrant - provider: - name: virtualbox -lint: | - set -e - yamllint . - ansible-lint -x formatting - flake8 --ignore=E501 -platforms: - - name: molecule-server-hardening-debian - box: debian/buster64 - memory: 512 - cpus: 1 -provisioner: - name: ansible - log: true - config_options: - defaults: - vault_identity_list: "@$HOME/.ansible/roles/molecule_prepare.pass, @$HOME/.ansible/roles/lza_install_common.pass, @$HOME/.ansible/roles/lza_server_hardening.pass" - lint: | - set -e - ansible-lint - vvv: false -verifier: - name: testinfra - env: - PYTHONWARNINGS: "ignore:.*U.*mode is deprecated:DeprecationWarning" - lint: | - set -e - flake8 - options: - v: 1 diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml deleted file mode 100644 index ee22e99..0000000 --- a/molecule/default/prepare.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- -- name: Prepare - hosts: all - gather_facts: true - pre_tasks: - - name: include vars - include_vars: "../../../ansible_vaults/molecule_prepare/{{ item }}" - loop: - - "prepare.vault" - - name: Install python for Ansible - raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal) - become: true - changed_when: false - - name: create users (as deployed in production) - user: - name: "{{ item.name }}" - uid: "{{ item.uid }}" - create_home: "yes" - shell: "/bin/bash" - loop: "{{ vault_molecule_users | flatten(levels=1) }}" - become: true - - name: add nonfree repos - apt_repository: - repo: "deb http://ftp2.de.debian.org/debian/ buster main non-free contrib" - state: present - update-cache: "yes" - become: true - - name: Install required packages - apt: - name: [ - 'aptitude', - 'gpg', - 'less', - 'libuser' - ] - state: present - become: true - roles: - - {role: ansible_lza_install_common, become: true} diff --git a/molecule/default/tests/conftest.py b/molecule/default/tests/conftest.py deleted file mode 100644 index ba0f1e8..0000000 --- a/molecule/default/tests/conftest.py +++ /dev/null @@ -1,20 +0,0 @@ -"""PyTest Fixtures.""" -from __future__ import absolute_import -import os -import pytest - - -def pytest_runtest_setup(item): - """Run tests only when under molecule with testinfra installed.""" - try: - import testinfra - except ImportError: - pytest.skip("Test requires testinfra", allow_module_level=True) - if "MOLECULE_INVENTORY_FILE" in os.environ: - pytest.testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( - os.environ["MOLECULE_INVENTORY_FILE"] - ).get_hosts("all") - else: - pytest.skip( - "Test should run only from inside molecule.", allow_module_level=True - ) diff --git a/molecule/default/tests/test_default.py b/molecule/default/tests/test_default.py deleted file mode 100644 index 39da80a..0000000 --- a/molecule/default/tests/test_default.py +++ /dev/null @@ -1,6 +0,0 @@ -def test_hosts_file(host): - f = host.file('/etc/hosts') - - assert f.exists - assert f.user == 'root' - assert f.group == 'root' diff --git a/molecule/resources/playbooks/Dockerfile b/molecule/resources/playbooks/Dockerfile new file mode 100644 index 0000000..da596e7 --- /dev/null +++ b/molecule/resources/playbooks/Dockerfile @@ -0,0 +1,20 @@ +FROM debian:stable-slim + +RUN adduser lza; + +### configure SLUB Debian Repository +RUN apt-get update; \ + apt-get install -y --no-install-recommends gnupg wget git python3 ansible sudo; \ + wget -O - http://sdvdebianrepo.slub-dresden.de/deb-repository/pub.gpg.key | apt-key add - ; \ + echo "deb http://sdvdebianrepo.slub-dresden.de/deb-repository bullseye main" > /etc/apt/sources.list.d/slub.list; \ + apt-get update; + #apt-get -y --no-install-recommends install python3-pip python3-virtualenv; + +RUN echo "lza ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/lza-user + +#RUN mkdir /opt/venv/ && cd /opt/venv/; \ +# virtualenv -p python3 molecule; \ +# . /opt/venv/molecule/bin/activate; \ +# pip3 install ansible molecule molecule-docker; + +USER lza diff --git a/molecule/default/INSTALL.rst b/molecule/resources/playbooks/INSTALL.rst similarity index 84% rename from molecule/default/INSTALL.rst rename to molecule/resources/playbooks/INSTALL.rst index 4f44b67..0c4bf5c 100644 --- a/molecule/default/INSTALL.rst +++ b/molecule/resources/playbooks/INSTALL.rst @@ -1,6 +1,6 @@ -******* +********************************* Vagrant driver installation guide -******* +********************************* Requirements ============ @@ -20,4 +20,4 @@ widely recommended `'--user' flag`_ when invoking ``pip``. .. code-block:: bash - $ pip install 'molecule[vagrant]' + $ pip install 'molecule_vagrant' diff --git a/molecule/resources/playbooks/README.md b/molecule/resources/playbooks/README.md new file mode 100644 index 0000000..0c91883 --- /dev/null +++ b/molecule/resources/playbooks/README.md @@ -0,0 +1,3 @@ +This drectory contains shared playbooks and a shared Dockerfile. + +Visit https://molecule.readthedocs.io/en/latest/examples.html#sharing-across-scenarios for details on sharing playbooks, tests etc. across multiple scenarios. diff --git a/molecule/resources/playbooks/converge.yml b/molecule/resources/playbooks/converge.yml new file mode 100644 index 0000000..4a49614 --- /dev/null +++ b/molecule/resources/playbooks/converge.yml @@ -0,0 +1,17 @@ +--- +- name: Converge + hosts: all + pre_tasks: + - name: update apt cache + ansible.builtin.apt: + update_cache: true + upgrade: dist + become: true + when: ansible_os_family == "Debian" + - name: update yum cache + ansible.builtin.yum: + update_cache: true + become: true + when: ansible_os_family == "RedHat" + roles: + - {role: "ansible_lza_server_hardening", become: true} diff --git a/molecule/resources/playbooks/prepare.yml b/molecule/resources/playbooks/prepare.yml new file mode 100644 index 0000000..a20ecff --- /dev/null +++ b/molecule/resources/playbooks/prepare.yml @@ -0,0 +1,22 @@ +--- +- name: Prepare + hosts: "*" + tasks: + - name: install GPG + ansible.builtin.apt: + name: "gnupg" + state: latest + update_cache: true + become: true + - name: add GPG key for SLUB Debian repository + ansible.builtin.apt_key: + url: "https://sdvdebianrepo.slub-dresden.de/deb-repository/pub.gpg.key" + state: present + become: true + - name: add repo URL to sources.list + ansible.builtin.apt_repository: + repo: "deb https://sdvdebianrepo.slub-dresden.de/deb-repository bullseye main" + state: present + update_cache: true + mode: "0644" + become: true diff --git a/molecule/resources/playbooks/verify.yml b/molecule/resources/playbooks/verify.yml new file mode 100644 index 0000000..e707420 --- /dev/null +++ b/molecule/resources/playbooks/verify.yml @@ -0,0 +1,10 @@ +--- +# This is an example playbook to execute Ansible tests. + +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Example assertion + ansible.builtin.assert: + that: true diff --git a/molecule/virtualbox/molecule.yml b/molecule/virtualbox/molecule.yml new file mode 100644 index 0000000..6f084c7 --- /dev/null +++ b/molecule/virtualbox/molecule.yml @@ -0,0 +1,41 @@ +--- +dependency: + name: galaxy + enabled: false +driver: + name: vagrant +lint: | + set -e + yamllint . + ansible-lint -x no-loop-var-prefix,command-instead-of-module,package-latest +platforms: + # Check out the documentation at + # https://github.com/ansible-community/molecule-vagrant#documentation + # for more platform parameters. + - name: vm-runner + box: debian/bullseye64 + memory: 1024 + # List of raw Vagrant `config` options. + # provider_raw_config_args: + # - "customize [ 'modifyvm', :id, '--natdnshostresolver1', 'on' ]" + # Dictionary of `config` options. + config_options: + ssh.keep_alive: yes + ssh.remote_user: "'lza'" +provisioner: + name: ansible + log: true + config_options: + defaults: + # https://stackoverflow.com/questions/57435811/ansible-molecule-pass-multiple-vault-ids + #vault_identity_list: "@$HOME/.ansible/roles/lza_install_common.pass, @$HOME/.ansible/roles/passfile_1.pass" + vault_identity_list: "../lza_server_hardening.pass" + vvv: false + playbooks: + # create: ../resources/playbooks/create.yml + # destroy: ../resources/playbooks/destroy.yml + converge: ../resources/playbooks/converge.yml + # prepare: ../resources/playbooks/prepare.yml + verify: ../resources/playbooks/verify.yml +verifier: + name: ansible diff --git a/requirements.yml b/requirements.yml.example similarity index 100% rename from requirements.yml rename to requirements.yml.example diff --git a/site.yml b/site.yml index 9dd4661..5cac957 100644 --- a/site.yml +++ b/site.yml @@ -24,5 +24,4 @@ strategy: linear roles: - - { role: ansible_lza_install_common, become: true } - { role: ansible_lza_server_hardening, become: true } diff --git a/tasks/configure-fail2ban.yml b/tasks/configure_fail2ban.yml similarity index 89% rename from tasks/configure-fail2ban.yml rename to tasks/configure_fail2ban.yml index 7208bc8..8836af2 100644 --- a/tasks/configure-fail2ban.yml +++ b/tasks/configure_fail2ban.yml @@ -1,17 +1,17 @@ --- ### Fail2Ban einrichten ### - name: fail2ban IDS installieren - package: + ansible.builtin.package: name: "fail2ban" state: present tags: [apt, yum] # neue Konfiguration einspielen - name: Konfiguration fuer fail2ban einspielen (1/4) - blockinfile: + ansible.builtin.blockinfile: path: "/etc/fail2ban/jail.local" backup: "no" - create: "yes" + create: true owner: "root" group: "root" mode: 0644 @@ -80,10 +80,10 @@ notify: restart fail2ban.service - name: Konfiguration fuer fail2ban einspielen (2/4) - blockinfile: + ansible.builtin.blockinfile: path: "/etc/fail2ban/filter.d/f2b-loop.conf" backup: "no" - create: "yes" + create: true owner: "root" group: "root" mode: "0644" @@ -100,22 +100,23 @@ notify: restart fail2ban.service - name: see if fail2ban.local exists - stat: + ansible.builtin.stat: path: "/etc/fail2ban/fail2ban.local" register: old_fail2ban_local - name: fail2ban.local bereinigen - file: + ansible.builtin.file: path: "/etc/fail2ban/fail2ban.local" state: absent when: old_fail2ban_local.stat.exists + changed_when: false # we cannot make this task idempotent in any other way, because we previously deleted the file to get a clean state notify: restart fail2ban.service - name: Konfiguration fuer fail2ban einspielen (4/4) - blockinfile: + ansible.builtin.blockinfile: path: "/etc/fail2ban/fail2ban.local" backup: "no" - create: "yes" + create: true owner: "root" group: "root" mode: "0644" @@ -131,11 +132,12 @@ pidfile = /var/run/fail2ban/fail2ban.pid dbfile = /var/lib/fail2ban/fail2ban.sqlite3 dbpurgeage = 86400 + changed_when: false # we cannot make this task idempotent in any other way, because we previously deleted the file to get a clean state notify: restart fail2ban.service # Ordner für Check_MK-Plugin anlegen - name: Ordner für Check_MK-Plugin anlegen - file: + ansible.builtin.file: path: "/usr/lib/check_mk_agent/plugins" state: directory owner: "root" @@ -144,7 +146,7 @@ # Plugin bereitstellen - name: Check_MK-Plugin installieren (fail2ban-Zustand) - copy: + ansible.builtin.copy: src: "usr/lib/check_mk_agent/plugins/check_fail2ban_status.sh" dest: "/usr/lib/check_mk_agent/plugins/check_fail2ban_status.sh" owner: "root" diff --git a/tasks/configure-home-permissions.yml b/tasks/configure_home_permissions.yml similarity index 87% rename from tasks/configure-home-permissions.yml rename to tasks/configure_home_permissions.yml index 3624d1a..0343af6 100644 --- a/tasks/configure-home-permissions.yml +++ b/tasks/configure_home_permissions.yml @@ -2,16 +2,16 @@ - name: $HOME-Verzeichnisse von Usern mit gleichen Gruppen schützen block: - name: $HOME-Verzeichnisse sammeln - find: + ansible.builtin.find: file_type: directory paths: "/home/" excludes: 'import' register: ls_out - name: striktere Berechtigungen für Homeverzeichnisse setzen - file: + ansible.builtin.file: path: "{{ item.path }}/" mode: "0700" - with_items: + loop: # - "{{ ls_out.files | difference(['import','zih']) }}" - "{{ ls_out.files }}" when: item.path not in "import" diff --git a/tasks/configure-iptables.yml b/tasks/configure_iptables.yml similarity index 90% rename from tasks/configure-iptables.yml rename to tasks/configure_iptables.yml index 75a32a8..00b634e 100644 --- a/tasks/configure-iptables.yml +++ b/tasks/configure_iptables.yml @@ -1,6 +1,6 @@ --- - name: stop and disable firewalld on RHEL systems (until we have a decent config) - systemd: + ansible.builtin.systemd: name: "{{ item.service }}" state: "{{ item.state }}" enabled: "{{ item.enabled }}" @@ -11,7 +11,7 @@ when: ansible_os_family == "RedHat" # - name: clean IPtables rules (1) -# iptables: +# ansible.builtin.iptables: # chain: "INPUT" # ip_version: "{{ item }}" # policy: "ACCEPT" @@ -20,19 +20,17 @@ # - "ipv6" # notify: # - save iptables rules -# tags: [molecule-notest] # # - name: clean IPtables rules (2) -# iptables: +# ansible.builtin.iptables: # chain: "INPUT" # flush: "true" # notify: # - save iptables rules -# tags: [molecule-notest] - name: Allow related and established IPv4 connections - iptables: + ansible.builtin.iptables: chain: "INPUT" ctstate: "ESTABLISHED,RELATED" jump: "ACCEPT" @@ -42,7 +40,7 @@ - save iptables rules # - name: Allow related and established IPv4 connections -# iptables: +# ansible.builtin.iptables: # chain: "OUTPUT" # comment: 'allow related and established connections' # ctstate: "ESTABLISHED,RELATED" @@ -52,7 +50,7 @@ # - save iptables rules - name: Allow all loop back traffic - iptables: + ansible.builtin.iptables: action: "insert" chain: "INPUT" comment: 'allow all loop back traffic' @@ -62,7 +60,7 @@ - save iptables rules # - name: Allow all loop back traffic -# iptables: +# ansible.builtin.iptables: # action: "insert" # chain: "OUTPUT" # comment: 'allow all loop back traffic' @@ -73,7 +71,7 @@ # Set default policy for INPUT chain - name: iptables-Policy für INPUT-Chain setzen - iptables: + ansible.builtin.iptables: chain: "INPUT" ip_version: "{{ item }}" policy: "DROP" @@ -82,11 +80,10 @@ - "ipv6" notify: - save iptables rules - tags: [molecule-notest] ## Set default policy for OUTPUT chain # - name: iptables-Policy für OUTPUT-Chain setzen -# iptables: +# ansible.builtin.iptables: # chain: "OUTPUT" # ip_version: "{{ item }}" # policy: "DROP" @@ -95,11 +92,10 @@ # - "ipv6" # notify: # - save iptables rules -# tags: [molecule-notest] # Configure specific rules - Chain INPUT - name: iptables-Regeln (IPv4) setzen - Chain INPUT - iptables: + ansible.builtin.iptables: action: "insert" chain: "INPUT" comment: "{{ item.comment | default(omit) }}" @@ -116,17 +112,16 @@ source_port: "{{ item.src_port | default(omit) }}" state: "{{ item.state }}" table: "filter" - loop: "{{ vault_iptables_input|flatten(levels=1) }}" + loop: "{{ vault_iptables_input | flatten(levels=1) }}" notify: - save iptables rules - tags: [molecule-notest] # http://shouldiblockicmp.com # TODO: Outgoing iptables Regeln erstellen, und bloß keine vergessen!!! ## Configure specific rules - Chain OUTPUT # - name: iptables-Regeln (IPv4) setzen - Chain OUTPUT -# iptables: +# ansible.builtin.iptables: # action: "insert" # chain: OUTPUT # comment: "{{ item.comment }}" @@ -146,11 +141,10 @@ # loop: "{{ vault_iptables_output|flatten(levels=1) }}" # notify: # - save iptables rules -# tags: [molecule-notest] # THESE NEED TO BE THE LAST RULES IN IPTABLES' RULE LIST!!! - name: iptables-Regeln (IPv4) setzen - REJECT - iptables: + ansible.builtin.iptables: action: "append" chain: "{{ item.chain }}" jump: "REJECT" @@ -163,4 +157,3 @@ - chain: "FORWARD" notify: - save iptables rules - tags: [molecule-notest] diff --git a/tasks/configure-kernel-parameters.yml b/tasks/configure_kernel_parameters.yml similarity index 99% rename from tasks/configure-kernel-parameters.yml rename to tasks/configure_kernel_parameters.yml index daf4440..8dae33c 100644 --- a/tasks/configure-kernel-parameters.yml +++ b/tasks/configure_kernel_parameters.yml @@ -3,7 +3,7 @@ - name: set custom kernel parameters block: - name: write kernel parameter changes - blockinfile: + ansible.builtin.blockinfile: insertafter: EOF marker: '### {mark} ANSIBLE MANAGED BLOCK - SERVER HARDENING' path: "/etc/sysctl.conf" diff --git a/tasks/configure-pam.yml b/tasks/configure_pam.yml similarity index 93% rename from tasks/configure-pam.yml rename to tasks/configure_pam.yml index b2ffa7a..de65f78 100644 --- a/tasks/configure-pam.yml +++ b/tasks/configure_pam.yml @@ -2,9 +2,9 @@ # Documentation: http://www.linux-pam.org/Linux-PAM-html/sag-module-reference.html "The Linux-PAM System Administrators' Guide - Chapter 6. A reference guide for available modules" - name: configure 'su' usage restrictions through PAM - blockinfile: + ansible.builtin.blockinfile: path: "/etc/pam.d/su" - create: "yes" + create: true owner: "root" group: "root" insertafter: EOF @@ -18,9 +18,9 @@ account requisite pam_time.so - name: configure times for certain system actions - blockinfile: + ansible.builtin.blockinfile: path: "/etc/security/time.conf" - create: "yes" + create: true owner: "root" group: "root" insertafter: EOF @@ -42,9 +42,9 @@ login;tty*;operator;!Al2300-0500 - name: configure login actions - blockinfile: + ansible.builtin.blockinfile: path: "/etc/pam.d/login" - create: "yes" + create: true owner: "root" group: "root" insertafter: EOF diff --git a/tasks/configure-portable-storage.yml b/tasks/configure_portable_storage.yml similarity index 90% rename from tasks/configure-portable-storage.yml rename to tasks/configure_portable_storage.yml index df8abdf..d4d9558 100644 --- a/tasks/configure-portable-storage.yml +++ b/tasks/configure_portable_storage.yml @@ -1,15 +1,15 @@ --- - name: disable USB storage support - lineinfile: + ansible.builtin.lineinfile: state: present - create: "yes" + create: true owner: "root" group: "root" mode: "0700" insertafter: EOF path: "/etc/modprobe.d/{{ item.path }}" line: "{{ item.line }}" - with_items: + loop: - path: "disable-usb-storage.conf" line: "blacklist usb-storage" # Alternative: "fake install" (https://linuxtechlab.com/disable-usb-storage-linux/) diff --git a/tasks/configure-root.yml b/tasks/configure_root.yml similarity index 64% rename from tasks/configure-root.yml rename to tasks/configure_root.yml index 09c75f5..f501d77 100644 --- a/tasks/configure-root.yml +++ b/tasks/configure_root.yml @@ -1,9 +1,9 @@ --- - name: prevent root login - user: + ansible.builtin.user: name: "root" shell: "/bin/bash" comment: "root user disabled" - # local: "yes" + # local: true local: false - password_lock: "yes" + password_lock: true diff --git a/tasks/configure-ssh-hardening.yml b/tasks/configure_ssh_hardening.yml similarity index 99% rename from tasks/configure-ssh-hardening.yml rename to tasks/configure_ssh_hardening.yml index e7e235e..cbc8cdc 100644 --- a/tasks/configure-ssh-hardening.yml +++ b/tasks/configure_ssh_hardening.yml @@ -2,7 +2,7 @@ - name: Konfiguration für OpenSSH einspielen - gehärtete Config ansible.builtin.blockinfile: path: "/etc/ssh/sshd_config" - backup: "yes" + backup: true insertbefore: "### BEGIN ANSIBLE MANAGED BLOCK - SFTP SERVER" marker: "### {mark} ANSIBLE MANAGED BLOCK - HARDENED SSH SERVER" validate: /usr/sbin/sshd -T -f %s diff --git a/tasks/configure-umask.yml b/tasks/configure_umask.yml similarity index 85% rename from tasks/configure-umask.yml rename to tasks/configure_umask.yml index f5a5233..66f7b1c 100644 --- a/tasks/configure-umask.yml +++ b/tasks/configure_umask.yml @@ -1,8 +1,8 @@ --- - name: set more secure umask (block everything for 'other' users) - blockinfile: + ansible.builtin.blockinfile: state: present - create: "yes" + create: true owner: "root" group: "root" mode: "0644" @@ -15,15 +15,15 @@ - name: libpam-umask installieren (Debian) block: - name: Paket installieren - apt: + ansible.builtin.apt: name: "libpam-umask" state: present tags: [apt] - name: Standard-umask mit PAM anpassen - blockinfile: + ansible.builtin.blockinfile: path: "/etc/pam.d/common-session" - create: "yes" + create: true owner: "root" group: "root" insertafter: EOF @@ -37,14 +37,14 @@ tags: [apt] - name: set default login umask - lineinfile: + ansible.builtin.lineinfile: path: "/etc/login.defs" regex: "{{ umask[ansible_os_family] }}" line: "UMASK 026" vars: - - umask: - Debian: "UMASK 022" - RedHat: "UMASK 077" + umask: + Debian: "UMASK 022" + RedHat: "UMASK 077" # umask could also be set in: # - /etc/profile.d/umask (Setting umask in profile.d sets it for all users who diff --git a/tasks/install-debsecan.yml b/tasks/install-debsecan.yml deleted file mode 100644 index 8ae3ea1..0000000 --- a/tasks/install-debsecan.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- -- block: - - name: include vars debsecan - include_vars: debsecan_preseed.yml - - - name: install debsecan package - apt: - name: "debsecan" - state: present - - - name: reconfigure debsecan package (dpkg-reconfigure) - debconf: - name: "debsecan" - question: "{{ item.question }}" - value: "{{ item.value }}" - vtype: "{{ item.vtype }}" - loop: "{{ debsecan_dpkg | flatten(levels=1) }}" - - - name: reconfigure debsecan package (/etc/default/debsecan) - template: - src: "debsecan.j2" - dest: "/etc/default/debsecan" - owner: "root" - group: "root" - mode: "0644" - force: "yes" diff --git a/tasks/install-auditd.yml b/tasks/install_auditd.yml similarity index 89% rename from tasks/install-auditd.yml rename to tasks/install_auditd.yml index 62ecb17..ce245c1 100644 --- a/tasks/install-auditd.yml +++ b/tasks/install_auditd.yml @@ -2,21 +2,21 @@ # install & configure auditd - name: install auditd package (Debian) - apt: + ansible.builtin.apt: name: "auditd" state: present when: ansible_os_family == "Debian" tags: [apt] - name: install auditd package (RedHat) - yum: + ansible.builtin.yum: name: "audit" state: present when: ansible_os_family == "RedHat" tags: [yum] - name: configure auditd rules - copy: + ansible.builtin.copy: src: "etc/audit/rules.d/audit.rules" dest: "/etc/audit/rules.d/audit.rules" mode: "0640" diff --git a/tasks/install-clamav.yml b/tasks/install_clamav.yml similarity index 92% rename from tasks/install-clamav.yml rename to tasks/install_clamav.yml index 1ea310d..dfa9548 100644 --- a/tasks/install-clamav.yml +++ b/tasks/install_clamav.yml @@ -2,20 +2,20 @@ # based on https://www.golinuxcloud.com/steps-install-configure-clamav-antivirus-centos-linux/ - name: include vars clamav - include_vars: "clamav.yml" + ansible.builtin.include_vars: "clamav.yml" tags: [apt] - name: install clamav packages (Debian) - apt: + ansible.builtin.apt: name: "clamav-daemon" state: present when: ansible_os_family == "Debian" tags: [apt] - name: install clamav packages (RedHat) - yum: + ansible.builtin.yum: name: [ 'clamav-server', 'clamav', @@ -34,9 +34,10 @@ - name: create ClamAV log directory - file: + ansible.builtin.file: path: "/var/log/clamav/" state: directory + mode: "0755" owner: "{{ 'clamav' if ansible_os_family == 'Debian' else 'clamupdate' }}" group: "adm" @@ -44,12 +45,12 @@ # clamav-freshclam.service und clamav-daemon.service laufen nach der Installation sofort los - name: configure freshclam - blockinfile: + ansible.builtin.blockinfile: name: "{{ clamav_cfg_path }}/freshclam.conf" mode: "0444" owner: "{{ 'clamav' if ansible_os_family == 'Debian' else 'clamupdate' }}" group: "adm" - create: "yes" + create: true block: | # Automatically created by the clamav-freshclam postinst # Comments will get lost when you reconfigure the clamav-freshclam package @@ -92,13 +93,14 @@ # when: ansible_os_family == "RedHat" - name: install Freshclam timer - copy: + ansible.builtin.copy: src: "etc/systemd/system/clamav-freshclam.timer" dest: "/etc/systemd/system/clamav-freshclam.timer" + mode: "0644" when: ansible_os_family == "RedHat" - name: start and enable Freshclam timer - systemd: + ansible.builtin.systemd: service: "clamav-freshclam.timer" enabled: true state: started @@ -107,7 +109,7 @@ - name: configure ClamD - blockinfile: + ansible.builtin.blockinfile: name: "{{ clamav_cfg_path }}/{{ 'clamd' if ansible_os_family == 'Debian' else ansible_hostname }}.conf" mode: "0444" owner: "{{ 'clamav' if ansible_os_family == 'Debian' else 'clamscan' }}" @@ -137,7 +139,7 @@ notify: restart clamd service - name: configure ClamD exclude paths - blockinfile: + ansible.builtin.blockinfile: name: "{{ clamav_cfg_path }}/{{ 'clamd' if ansible_os_family == 'Debian' else ansible_hostname }}.conf" mode: "0444" owner: "{{ 'clamav' if ansible_os_family == 'Debian' else 'clamscan' }}" @@ -154,12 +156,12 @@ - restart clamd service - name: configure ClamD to refresh rkhunter after DB updates - blockinfile: + ansible.builtin.blockinfile: name: "/usr/local/bin/refresh_rkhunter.sh" mode: "0755" owner: "{{ 'clamav' if ansible_os_family == 'Debian' else 'clamupdate' }}" group: "adm" - create: "yes" + create: true insertafter: EOF block: | #!/usr/bin/env bash @@ -170,14 +172,15 @@ fi - name: copy systemd service - copy: + ansible.builtin.copy: src: "/usr/lib/systemd/system/clamd@.service" dest: "/etc/systemd/system/" + mode: "0644" remote_src: true when: ansible_os_family == "RedHat" - name: enable ClamD systemd service - systemd: + ansible.builtin.systemd: service: "clamd@{{ ansible_hostname }}.service" enabled: true state: "started" diff --git a/tasks/install_debsecan.yml b/tasks/install_debsecan.yml new file mode 100644 index 0000000..52ff558 --- /dev/null +++ b/tasks/install_debsecan.yml @@ -0,0 +1,25 @@ +--- +- name: include vars debsecan + ansible.builtin.include_vars: debsecan_preseed.yml + +- name: install debsecan package + ansible.builtin.apt: + name: "debsecan" + state: present + +- name: reconfigure debsecan package (dpkg-reconfigure) + ansible.builtin.debconf: + name: "debsecan" + question: "{{ item.question }}" + value: "{{ item.value }}" + vtype: "{{ item.vtype }}" + loop: "{{ debsecan_dpkg | flatten(levels=1) }}" + +- name: reconfigure debsecan package (/etc/default/debsecan) + ansible.builtin.template: + src: "debsecan.j2" + dest: "/etc/default/debsecan" + owner: "root" + group: "root" + mode: "0644" + force: true diff --git a/tasks/install-rkhunter.yml b/tasks/install_rkhunter.yml similarity index 69% rename from tasks/install-rkhunter.yml rename to tasks/install_rkhunter.yml index 410c1c7..4a2dd99 100644 --- a/tasks/install-rkhunter.yml +++ b/tasks/install_rkhunter.yml @@ -2,33 +2,40 @@ # install rkhunter 1.4.4 due to CVE-2017-7480 (https://www.cvedetails.com/cve/CVE-2017-7480/) # version restriction can be removed once a higher version becomes available - name: install rkhunter - package: + ansible.builtin.package: name: "rkhunter" state: present tags: [apt] +- name: create rkhunter log dir + ansible.builtin.file: + path: "/var/log/rkhunter/" + state: directory + owner: "root" + group: "root" + mode: "0750" + +- name: check if rkhunter logfile exists + ansible.builtin.stat: + path: "/var/log/rkhunter/rkhunter.log" + register: rkhunter_log_exists + - name: create /var/log/rkhunter/rkhunter.log if it doesn't exist, so logrotate doesn't fail - file: - path: "{{ item.path }}" - state: "{{ item.state }}" + ansible.builtin.file: + path: "/var/log/rkhunter/rkhunter.log" + state: touch # "touch" is never idempotent, so we have to rely on a precheck to see if we need to run this task owner: "root" group: "root" - mode: "{{ item.mode }}" - loop: - - path: "/var/log/rkhunter/" - mode: "0750" - state: directory - - path: "/var/log/rkhunter/rkhunter.log" - mode: "0640" - state: touch + mode: "0640" + when: not rkhunter_log_exists.stat.exists - name: configure /etc/default/rkhunter - lineinfile: + ansible.builtin.lineinfile: path: "/etc/default/rkhunter" regexp: "{{ item.regexp }}" line: "{{ item.line }}" # validate: rkhunter --config-check --configfile %s - with_items: + loop: # - regexp: '^# APT_AUTOGEN="false"' # line: 'APT_AUTOGEN="yes"' - regexp: '^APT_AUTOGEN="false"' @@ -38,7 +45,7 @@ when: ansible_distribution == "Debian" - name: create rkhunter config directory - file: + ansible.builtin.file: path: "/etc/rkhunter.d" state: "directory" owner: "root" @@ -46,9 +53,10 @@ mode: 0755 - name: configure /etc/rkhunter.d/rkhunter.local.conf - blockinfile: + ansible.builtin.blockinfile: path: "/etc/rkhunter.d/rkhunter.local.conf" - create: "yes" + mode: "0644" + create: true block: | # Default: UPDATE_MIRRORS=0 UPDATE_MIRRORS=1 @@ -103,20 +111,34 @@ WEB_CMD="" # validate: rkhunter --config-check --configfile %s +- name: find rkhunter systemd units so we don't have to hardcode their names in the loops + ansible.builtin.find: + path: "/etc/systemd/user/" + pattern: "rkhunter.*" + register: rkhunter_units + +- name: check if rkhunter Systemd units are already disabled + ansible.builtin.command: "systemctl is-enabled rkhunter.{{ item.path | basename }}" + loop: "{{ rkhunter_units.files }}" + register: rkhunter_disabled + changed_when: false + failed_when: + - rkhunter_disabled.stdout != "enabled" + - rkhunter_disabled.stdout != "disabled" + - '"No such file or directory" not in rkhunter_disabled.stderr"' + - name: stop & disable RKhunter service unit & timer - systemd: - name: "rkhunter.{{ item }}" + ansible.builtin.systemd: + name: "{{ item.item.path }}" enabled: "false" state: stopped - loop: - - "service" - - "timer" - when: ansible_distribution == "Debian" - tags: [molecule-notest] - ignore_errors: "yes" + loop: "{{ rkhunter_disabled.results }}" + when: + - ansible_distribution == "Debian" + - item.stdout != "disabled" - name: remove Rkhunter service unit & timer - file: + ansible.builtin.file: path: "/etc/systemd/user/rkhunter.{{ item }}" state: absent loop: @@ -126,7 +148,7 @@ # Unitfiles neu einlesen (implizit mit enable), Services sofort starten & automatisch bei jedem Booten starten # - name: Service automatisch bei jedem Booten starten - rkhunter.service -# command: systemctl enable "{{ item }}" +# ansible.builtin.command: systemctl enable "{{ item }}" # loop: # - "/etc/systemd/user/rkhunter.service" # - "/etc/systemd/user/rkhunter.timer" diff --git a/tasks/main.yml b/tasks/main.yml index ada0022..52ab1ea 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,6 +1,6 @@ --- - name: include Ansible Vaults - include_vars: "{{ role_path }}/../ansible_vaults/{{ role_name }}/{{ item }}" + ansible.builtin.include_vars: "{{ role_path }}/../ansible_vaults/{{ role_name }}/{{ item }}" loop: - "fail2ban.vault" - "iptables.vault" @@ -13,56 +13,56 @@ # install hardened server configuration - name: configure root - import_tasks: configure-root.yml + ansible.builtin.import_tasks: "configure_root.yml" tags: [users] - name: configure kernel parameters - import_tasks: ./configure-kernel-parameters.yml + ansible.builtin.import_tasks: "configure_kernel_parameters.yml" tags: [kernel] - name: configure portable storage drivers - import_tasks: ./configure-portable-storage.yml + ansible.builtin.import_tasks: "configure_portable_storage.yml" tags: [usb] - name: configute SSH hardening - import_tasks: ./configure-ssh-hardening.yml + ansible.builtin.import_tasks: "configure_ssh_hardening.yml" tags: [ssh] - name: configure fail2ban - import_tasks: ./configure-fail2ban.yml + ansible.builtin.import_tasks: "configure_fail2ban.yml" tags: [fail2ban, ssh] - name: configure $HOME permissions - import_tasks: ./configure-home-permissions.yml + ansible.builtin.import_tasks: "configure_home_permissions.yml" tags: [users] - name: configure PAM - import_tasks: ./configure-pam.yml + ansible.builtin.import_tasks: "configure_pam.yml" tags: [pam] - name: install iptables filter rules - import_tasks: ./configure-iptables.yml + ansible.builtin.import_tasks: "configure_iptables.yml" tags: [iptables] - name: include rkhunter install task - import_tasks: ./install-rkhunter.yml + ansible.builtin.import_tasks: "install_rkhunter.yml" tags: [rkhunter] - name: include ClamAV install task - import_tasks: ./install-clamav.yml + ansible.builtin.import_tasks: "install_clamav.yml" tags: [clamav] - name: include auditd install task - import_tasks: ./install-auditd.yml + ansible.builtin.import_tasks: "install_auditd.yml" tags: [auditd] - name: install debsecan - import_tasks: ./install-debsecan.yml + ansible.builtin.import_tasks: "install_debsecan.yml" when: ansible_os_family == "Debian" tags: [debsecan] - name: install security-related packages (debian-goodies, debsums, libpam-cracklib, libpam-tmpdir) - apt: + ansible.builtin.apt: name: [ 'debian-goodies', 'debsums', @@ -74,12 +74,13 @@ tags: [apt] - name: autoclean & autoremove - apt: - autoclean: "yes" - autoremove: "yes" + ansible.builtin.apt: + autoclean: true + autoremove: true when: ansible_os_family == "Debian" tags: [apt] - name: Flush handlers am Ende der Rolle - meta: flush_handlers + ansible.builtin.meta: flush_handlers + changed_when: false tags: [always] -- GitLab