From bbc827e4a12cfad2e357d75c3397797f859fc26f Mon Sep 17 00:00:00 2001 From: rndmh3ro Date: Mon, 18 Oct 2021 21:33:45 +0200 Subject: [PATCH] use second molecule scenario for custom ssh tests Signed-off-by: rndmh3ro --- .github/workflows/ssh_hardening.yml | 1 + molecule/ssh_hardening/converge.yml | 104 ----------------- .../ssh_hardening_custom_tests/INSTALL.rst | 22 ++++ .../ssh_hardening_custom_tests/converge.yml | 107 ++++++++++++++++++ .../ssh_hardening_custom_tests/molecule.yml | 64 +++++++++++ .../ssh_hardening_custom_tests/prepare.yml | 76 +++++++++++++ .../requirements.yml | 3 + .../ssh_hardening_custom_tests/verify.yml | 57 ++++++++++ 8 files changed, 330 insertions(+), 104 deletions(-) create mode 100644 molecule/ssh_hardening_custom_tests/INSTALL.rst create mode 100644 molecule/ssh_hardening_custom_tests/converge.yml create mode 100644 molecule/ssh_hardening_custom_tests/molecule.yml create mode 100644 molecule/ssh_hardening_custom_tests/prepare.yml create mode 100644 molecule/ssh_hardening_custom_tests/requirements.yml create mode 100644 molecule/ssh_hardening_custom_tests/verify.yml diff --git a/.github/workflows/ssh_hardening.yml b/.github/workflows/ssh_hardening.yml index df755ce5..f5722705 100644 --- a/.github/workflows/ssh_hardening.yml +++ b/.github/workflows/ssh_hardening.yml @@ -63,6 +63,7 @@ jobs: export MOLECULE_DOCKER_COMMAND="/usr/lib/systemd/systemd" fi molecule --version + molecule test -s ssh_hardening_custom_tests molecule test -s ssh_hardening env: MOLECULE_DISTRO: ${{ matrix.molecule_distro }} diff --git a/molecule/ssh_hardening/converge.yml b/molecule/ssh_hardening/converge.yml index b8e239b6..a34bc5c7 100644 --- a/molecule/ssh_hardening/converge.yml +++ b/molecule/ssh_hardening/converge.yml @@ -1,108 +1,4 @@ --- -- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings - hosts: all - become: true - environment: - http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}" - https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}" - no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}" - collections: - - devsec.hardening - tasks: - - include_role: - name: ssh_hardening - vars: - ssh_trusted_user_ca_keys_file: '/etc/ssh/ca.pub' - ssh_trusted_user_ca_keys: - - '# ssh-rsa ...' - ssh_authorized_principals_file: '/etc/ssh/auth_principals/%u' - ssh_authorized_principals: - - path: "/etc/ssh/auth_principals/root" - principals: - - "root" - owner: "{{ ssh_owner }}" - group: "{{ ssh_group }}" - directoryowner: "{{ ssh_owner }}" - directorygroup: "{{ ssh_group }}" - directorymode: "0700" - network_ipv6_enable: true - ssh_allow_tcp_forwarding: 'yes' - ssh_gateway_ports: true - ssh_allow_agent_forwarding: true - ssh_server_permit_environment_vars: 'yes' - ssh_server_accept_env_vars: 'PWD HTTP_PROXY' - ssh_client_alive_interval: 100 - ssh_client_alive_count: 10 - ssh_client_password_login: true - ssh_challengeresponseauthentication: true - ssh_compression: true - ssh_allow_users: 'root kitchen vagrant' - ssh_allow_groups: 'root kitchen vagrant' - ssh_deny_users: 'foo bar' - ssh_deny_groups: 'foo bar' - ssh_authorized_keys_file: '/etc/ssh/authorized_keys/%u' - ssh_max_auth_retries: 10 - ssh_permit_root_login: "without-password" - ssh_permit_tunnel: true - ssh_print_motd: true - ssh_print_last_log: true - ssh_banner: true - ssh_server_password_login: true - sftp_enabled: true - sftp_chroot: true - # ssh_server_enabled: false - ssh_server_ports: - - 22 - - 222 - ssh_server_match_address: - - address: '192.168.1.1/24' - rules: - - 'AllowTcpForwarding yes' - - 'AllowAgentForwarding no' - ssh_server_match_group: - - group: 'root' - rules: - - 'AllowTcpForwarding yes' - - 'AllowAgentForwarding no' - ssh_server_match_user: - - user: 'root' - rules: - - 'AllowTcpForwarding yes' - - 'AllowAgentForwarding no' - ssh_server_match_local_port: - - port: 222 - rules: - - 'AllowTcpForwarding yes' - - 'AllowAgentForwarding no' - ssh_remote_hosts: - - names: ['example.com', 'example2.com'] - options: ['Port 2222', 'ForwardAgent yes'] - - names: ['example3.com'] - options: ['StrictHostKeyChecking no'] - ssh_use_dns: true - ssh_use_pam: true - ssh_max_startups: '10:30:60' - ssh_host_key_algorithms: - - ssh-ed25519 - - rsa-sha2-512 - - rsa-sha2-256 - - ssh-rsa - ssh_macs: - - hmac-sha2-512 - - hmac-sha2-256 - ssh_ciphers: - - aes256-ctr - - aes192-ctr - - aes128-ctr - - aes256-cbc - ssh_kex: - - diffie-hellman-group-exchange-sha256 - - diffie-hellman-group-exchange-sha1 - ssh_custom_options: - - "Include /etc/ssh/ssh_config.d/*" - sshd_custom_options: - - "AcceptEnv LANG" - - name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings hosts: all become: true diff --git a/molecule/ssh_hardening_custom_tests/INSTALL.rst b/molecule/ssh_hardening_custom_tests/INSTALL.rst new file mode 100644 index 00000000..d926ca25 --- /dev/null +++ b/molecule/ssh_hardening_custom_tests/INSTALL.rst @@ -0,0 +1,22 @@ +******* +Docker driver installation guide +******* + +Requirements +============ + +* Docker Engine + +Install +======= + +Please refer to the `Virtual environment`_ documentation for installation best +practices. If not using a virtual environment, please consider passing the +widely recommended `'--user' flag`_ when invoking ``pip``. + +.. _Virtual environment: https://virtualenv.pypa.io/en/latest/ +.. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site + +.. code-block:: bash + + $ python3 -m pip install 'molecule[docker]' diff --git a/molecule/ssh_hardening_custom_tests/converge.yml b/molecule/ssh_hardening_custom_tests/converge.yml new file mode 100644 index 00000000..9c3a961d --- /dev/null +++ b/molecule/ssh_hardening_custom_tests/converge.yml @@ -0,0 +1,107 @@ +--- +- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with custom settings + hosts: all + become: true + tags: + - custom_tests + - never + environment: + http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}" + https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}" + no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}" + collections: + - devsec.hardening + tasks: + - include_role: + name: ssh_hardening + vars: + ssh_trusted_user_ca_keys_file: '/etc/ssh/ca.pub' + ssh_trusted_user_ca_keys: + - '# ssh-rsa ...' + ssh_authorized_principals_file: '/etc/ssh/auth_principals/%u' + ssh_authorized_principals: + - path: "/etc/ssh/auth_principals/root" + principals: + - "root" + owner: "{{ ssh_owner }}" + group: "{{ ssh_group }}" + directoryowner: "{{ ssh_owner }}" + directorygroup: "{{ ssh_group }}" + directorymode: "0700" + network_ipv6_enable: true + ssh_allow_tcp_forwarding: 'yes' + ssh_gateway_ports: true + ssh_allow_agent_forwarding: true + ssh_server_permit_environment_vars: 'yes' + ssh_server_accept_env_vars: 'PWD HTTP_PROXY' + ssh_client_alive_interval: 100 + ssh_client_alive_count: 10 + ssh_client_password_login: true + ssh_challengeresponseauthentication: true + ssh_compression: true + ssh_allow_users: 'root kitchen vagrant' + ssh_allow_groups: 'root kitchen vagrant' + ssh_deny_users: 'foo bar' + ssh_deny_groups: 'foo bar' + ssh_authorized_keys_file: '/etc/ssh/authorized_keys/%u' + ssh_max_auth_retries: 10 + ssh_permit_root_login: "without-password" + ssh_permit_tunnel: true + ssh_print_motd: true + ssh_print_last_log: true + ssh_banner: true + ssh_server_password_login: true + sftp_enabled: true + sftp_chroot: true + # ssh_server_enabled: false + ssh_server_ports: + - 22 + - 222 + ssh_server_match_address: + - address: '192.168.1.1/24' + rules: + - 'AllowTcpForwarding yes' + - 'AllowAgentForwarding no' + ssh_server_match_group: + - group: 'root' + rules: + - 'AllowTcpForwarding yes' + - 'AllowAgentForwarding no' + ssh_server_match_user: + - user: 'root' + rules: + - 'AllowTcpForwarding yes' + - 'AllowAgentForwarding no' + ssh_server_match_local_port: + - port: 222 + rules: + - 'AllowTcpForwarding yes' + - 'AllowAgentForwarding no' + ssh_remote_hosts: + - names: ['example.com', 'example2.com'] + options: ['Port 2222', 'ForwardAgent yes'] + - names: ['example3.com'] + options: ['StrictHostKeyChecking no'] + ssh_use_dns: true + ssh_use_pam: true + ssh_max_startups: '10:30:60' + ssh_host_key_algorithms: + - ssh-ed25519 + - rsa-sha2-512 + - rsa-sha2-256 + - ssh-rsa + ssh_macs: + - hmac-sha2-512 + - hmac-sha2-256 + ssh_ciphers: + - aes256-ctr + - aes192-ctr + - aes128-ctr + - aes256-cbc + ssh_kex: + - diffie-hellman-group-exchange-sha256 + - diffie-hellman-group-exchange-sha1 + ssh_custom_options: + - "Include /etc/ssh/ssh_config.d/*" + sshd_custom_options: + - "AcceptEnv LANG" diff --git a/molecule/ssh_hardening_custom_tests/molecule.yml b/molecule/ssh_hardening_custom_tests/molecule.yml new file mode 100644 index 00000000..fb5cd511 --- /dev/null +++ b/molecule/ssh_hardening_custom_tests/molecule.yml @@ -0,0 +1,64 @@ +--- +dependency: + name: galaxy + options: + role-file: molecule/ssh_hardening/requirements.yml +driver: + name: docker +platforms: + - name: instance + image: "rndmh3ro/docker-${MOLECULE_DISTRO}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-/lib/systemd/systemd} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + tmpfs: + - /tmp + - /run + capabilities: + - SYS_ADMIN + tty: true + env: + http_proxy: "${http_proxy}" + https_proxy: "${https_proxy}" + no_proxy: "${no_proxy}" + container: docker +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + callback_whitelist: profile_tasks, timer, yaml +verifier: + name: ansible + +scenario: + create_sequence: + - dependency + - create + - prepare + check_sequence: + - dependency + - destroy + - create + - prepare + - converge + - check + - destroy + converge_sequence: + - dependency + - create + - prepare + - converge + destroy_sequence: + - destroy + test_sequence: + - dependency + - destroy + - syntax + - create + - prepare + - converge + - idempotence + - verify + - destroy diff --git a/molecule/ssh_hardening_custom_tests/prepare.yml b/molecule/ssh_hardening_custom_tests/prepare.yml new file mode 100644 index 00000000..28a4d77e --- /dev/null +++ b/molecule/ssh_hardening_custom_tests/prepare.yml @@ -0,0 +1,76 @@ +--- +- name: wrapper playbook for kitchen testing "ansible-ssh-hardening" with default settings + hosts: all + become: true + environment: + http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}" + https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}" + no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}" + tasks: + - name: use python3 + set_fact: + ansible_python_interpreter: /usr/bin/python3 + when: ansible_facts.distribution == 'Fedora' + + - name: install packages + yum: + name: + - openssh-clients + - openssh-server + - libselinux-python + state: present + update_cache: true + ignore_errors: true + + - name: install packages + dnf: + name: + - openssh-clients + - openssh-server + - procps-ng + state: present + update_cache: true + ignore_errors: true + + - name: install packages + apt: + name: + - openssh-client + - openssh-server + state: present + update_cache: true + ignore_errors: true + + - name: install required tools on SuSE + # cannot use zypper module, since it depends on python-xml + shell: "zypper -n install python-xml" + when: ansible_facts.os_family == 'Suse' + + - name: install packages + zypper: + name: + - "openssh" + when: ansible_facts.os_family == 'Suse' + + - name: install packages + pacman: + name: + - "openssh" + - "awk" + state: present + update_cache: true + ignore_errors: true + + - name: created needed directory + file: + path: "/var/run/sshd" + state: directory + + - name: create ssh host keys + command: "ssh-keygen -A" + when: not ((ansible_facts.os_family in ['Oracle Linux', 'RedHat']) and ansible_facts.distribution_major_version < '7') or + ansible_facts.distribution == "Fedora" or + ansible_facts.distribution == "Amazon" or + ansible_facts.os_family == "Suse" + changed_when: false + ignore_errors: true diff --git a/molecule/ssh_hardening_custom_tests/requirements.yml b/molecule/ssh_hardening_custom_tests/requirements.yml new file mode 100644 index 00000000..53fa9b49 --- /dev/null +++ b/molecule/ssh_hardening_custom_tests/requirements.yml @@ -0,0 +1,3 @@ +--- +roles: + - geerlingguy.git diff --git a/molecule/ssh_hardening_custom_tests/verify.yml b/molecule/ssh_hardening_custom_tests/verify.yml new file mode 100644 index 00000000..159c7617 --- /dev/null +++ b/molecule/ssh_hardening_custom_tests/verify.yml @@ -0,0 +1,57 @@ +--- +- name: Verify + hosts: all + become: true + environment: + http_proxy: "{{ lookup('env', 'http_proxy') | default(omit) }}" + https_proxy: "{{ lookup('env', 'https_proxy') | default(omit) }}" + no_proxy: "{{ lookup('env', 'no_proxy') | default(omit) }}" + roles: + - geerlingguy.git + tasks: + - name: install fake SuSE-release for cinc compatibility + copy: + content: | + openSUSE Faked Enterprise 2020 (x86_64) + VERSION = 2020 + CODENAME = Faked Feature + dest: /etc/SuSE-release + owner: root + group: root + mode: '0444' + when: ansible_facts.os_family == 'Suse' + + - name: install git for SuSE since geerlinguy.git does not support it + zypper: + name: git + state: present + when: ansible_facts.os_family == 'Suse' + + - name: install crypto compat modules on fedora + dnf: + name: libxcrypt-compat + when: ansible_facts.distribution == 'Fedora' + + - name: download cinc-auditor + get_url: + url: https://omnitruck.cinc.sh/install.sh + dest: /tmp/install.sh + mode: '0775' + + - name: install cinc-auditor + shell: "bash /tmp/install.sh -s -- -P cinc-auditor -v 4" + + - name: Execute cinc-auditor tests + command: "/opt/cinc-auditor/bin/cinc-auditor exec --no-show-progress --no-color --no-distinct-exit https://github.com/dev-sec/ssh-baseline/archive/refs/heads/master.zip" + register: test_results + changed_when: false + ignore_errors: true + + - name: Display details about the cinc-auditor results + debug: + msg: "{{ test_results.stdout_lines }}" + + - name: Fail when tests fail + fail: + msg: "Inspec failed to validate" + when: test_results.rc != 0