diff --git a/defaults/main.yml b/defaults/main.yml index 5b79433..c2aa5d5 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -11,3 +11,4 @@ theo_agent_public_key_path: "{{ theo_agent_config_dir }}/public.pem" theo_agent_sshd_authorized_keys_command: "{{ theo_agent_path }}" theo_agent_hostname_prefix: "" theo_agent_hostname_suffix: "" +theo_agent_with_password_authentication: false diff --git a/molecule/passwordauthentication/Dockerfile.j2 b/molecule/passwordauthentication/Dockerfile.j2 new file mode 100644 index 0000000..e6aa95d --- /dev/null +++ b/molecule/passwordauthentication/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 install -y python sudo bash ca-certificates && apt-get clean; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && 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 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/passwordauthentication/INSTALL.rst b/molecule/passwordauthentication/INSTALL.rst new file mode 100644 index 0000000..6a44bde --- /dev/null +++ b/molecule/passwordauthentication/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 + + $ pip install 'molecule[docker]' diff --git a/molecule/passwordauthentication/molecule.yml b/molecule/passwordauthentication/molecule.yml new file mode 100644 index 0000000..0d05294 --- /dev/null +++ b/molecule/passwordauthentication/molecule.yml @@ -0,0 +1,23 @@ +--- +dependency: + name: galaxy +driver: + name: docker +lint: + name: yamllint +platforms: + - name: instance + image: "${REGISTRY_USER:-geerlingguy}/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + privileged: true + pre_build_image: true +provisioner: + name: ansible + lint: + name: ansible-lint +verifier: + name: testinfra + lint: + name: flake8 diff --git a/molecule/passwordauthentication/playbook.yml b/molecule/passwordauthentication/playbook.yml new file mode 100644 index 0000000..c03210c --- /dev/null +++ b/molecule/passwordauthentication/playbook.yml @@ -0,0 +1,34 @@ +--- +- name: Converge + hosts: all + vars: + - theo_url: https://theo.example.com + - theo_client_token: zdOPNza4jjtceH5F2rU0iOkIJ2xlV4hGUauKT4cNe8HAp+AMnzYEzSc0EIBGM+MJuqL7gLd6bwIP + - theo_agent_with_password_authentication: true + pre_tasks: + - name: Update apt cache + apt: + update_cache: yes + cache_valid_time: 600 + when: ansible_os_family == 'Debian' + + - name: Ensure sshd is installed + package: + name: + - openssh-server + state: present + + - name: Ensure sshd service is started + service: + name: ssh + state: started + when: ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04' + + - name: Ensure sshd service is started + service: + name: sshd + state: started + when: not (ansible_distribution == 'Ubuntu' and ansible_distribution_version == '14.04') + + roles: + - role: ansible-theo-agent diff --git a/molecule/passwordauthentication/tests/test_default.py b/molecule/passwordauthentication/tests/test_default.py new file mode 100644 index 0000000..c61eaef --- /dev/null +++ b/molecule/passwordauthentication/tests/test_default.py @@ -0,0 +1,66 @@ +import os + +import testinfra.utils.ansible_runner + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_sshd_config(host): + distro = os.getenv('MOLECULE_DISTRO', 'centos7') + if distro == 'centos6': + expected = get_sshd_config_centos6() + elif distro == 'debian8': + expected = get_sshd_config_pre_v69() + elif distro == 'ubuntu1404': + expected = get_sshd_config_pre_v69() + else: + expected = get_sshd_config_v69() + f = host.file('/etc/ssh/sshd_config') + config = f.content + configlines = [] + for line in config.splitlines(): + if not line.startswith(b'#'): + configlines.append(line) + ''' + I don't want to use something like: + assert set(expected).issubset(configlines) + Because there's no detail of the missing line(s) + ''' + errors = [] + for line in expected: + if line not in configlines: + errors.append(line) + + if(len(errors)): + print('Failed test_sshd_config, missing line(s)') + for error in errors: + print(error) + assert False + + +def get_sshd_config_centos6(): + return [ + b'PasswordAuthentication yes', + b'AuthorizedKeysCommandRunAs theo-agent', + b'AuthorizedKeysCommand /usr/sbin/theo-agent', + b'AuthorizedKeysFile /var/cache/theo-agent/%u' + ] + + +def get_sshd_config_pre_v69(): + return [ + b'PasswordAuthentication yes', + b'AuthorizedKeysCommandUser theo-agent', + b'AuthorizedKeysCommand /usr/sbin/theo-agent', + b'AuthorizedKeysFile /var/cache/theo-agent/%u' + ] + + +def get_sshd_config_v69(): + return [ + b'PasswordAuthentication yes', + b'AuthorizedKeysCommandUser theo-agent', + b'AuthorizedKeysCommand /usr/sbin/theo-agent -fingerprint %f %u', + b'AuthorizedKeysFile /var/cache/theo-agent/%u' + ] diff --git a/tasks/sshd.yml b/tasks/sshd.yml index 294e361..f3dbeda 100644 --- a/tasks/sshd.yml +++ b/tasks/sshd.yml @@ -35,6 +35,20 @@ line: "AuthorizedKeysCommandRunAs {{ theo_agent_user }}" when: ( ansible_os_family == "RedHat" and ansible_distribution_major_version|int == 6 ) +- name: Set PasswordAuthentication on config snippet + set_fact: + sshd_password_authentication_options: + - regexp: "^PasswordAuthentication" + line: "PasswordAuthentication yes" + when: theo_agent_with_password_authentication|bool + +- name: Set PasswordAuthentication off config snippet + set_fact: + sshd_password_authentication_options: + - regexp: "^PasswordAuthentication" + line: "PasswordAuthentication no" + when: not theo_agent_with_password_authentication|bool + - name: Update sshd configuration options lineinfile: path: /etc/ssh/sshd_config @@ -43,8 +57,7 @@ state: present validate: "/usr/sbin/sshd -T -f %s" with_items: - - regexp: "^PasswordAuthentication" - line: "PasswordAuthentication no" + - "{{ sshd_password_authentication_options }}" - "{{ sshd_authorized_keys_command_user_options }}" - regexp: "^AuthorizedKeysCommand " line: "AuthorizedKeysCommand {{ theo_agent_sshd_authorized_keys_command }}"