From 30945d5a2f101822c8c4ef062c6b759cb114287b Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Thu, 18 Dec 2025 11:39:09 +0300 Subject: [PATCH 1/7] add sshd role --- roles/sshd/README.md | 37 +++++++++++++++++++++++++++++ roles/sshd/defaults/main.yml | 5 ++++ roles/sshd/handlers/main.yml | 7 ++++++ roles/sshd/meta/main.yml | 17 +++++++++++++ roles/sshd/tasks/algorithms.yml | 33 +++++++++++++++++++++++++ roles/sshd/tasks/authentication.yml | 31 ++++++++++++++++++++++++ roles/sshd/tasks/encryption.yml | 11 +++++++++ roles/sshd/tasks/install.yml | 12 ++++++++++ roles/sshd/tasks/main.yml | 23 ++++++++++++++++++ roles/sshd/tasks/restrictions.yml | 30 +++++++++++++++++++++++ roles/sshd/vars/main.yml | 1 + 11 files changed, 207 insertions(+) create mode 100644 roles/sshd/README.md create mode 100644 roles/sshd/defaults/main.yml create mode 100644 roles/sshd/handlers/main.yml create mode 100644 roles/sshd/meta/main.yml create mode 100644 roles/sshd/tasks/algorithms.yml create mode 100644 roles/sshd/tasks/authentication.yml create mode 100644 roles/sshd/tasks/encryption.yml create mode 100644 roles/sshd/tasks/install.yml create mode 100644 roles/sshd/tasks/main.yml create mode 100644 roles/sshd/tasks/restrictions.yml create mode 100644 roles/sshd/vars/main.yml diff --git a/roles/sshd/README.md b/roles/sshd/README.md new file mode 100644 index 0000000..1c4d1d9 --- /dev/null +++ b/roles/sshd/README.md @@ -0,0 +1,37 @@ +ansible-sshd +========= + +Deploy a hardened sshd server + +Requirements +------------ + +None + +Role Variables +-------------- + +None + +Dependencies +------------ + +None + +Example Playbook +---------------- + +```yaml +roles: + - role: genlab.sshd +``` + +License +------- + +BSD + +Author Information +------------------ + +corvus-migratorius@proton.me diff --git a/roles/sshd/defaults/main.yml b/roles/sshd/defaults/main.yml new file mode 100644 index 0000000..7f8dce0 --- /dev/null +++ b/roles/sshd/defaults/main.yml @@ -0,0 +1,5 @@ +--- +disable_pam: false +password_auth: false +challenge_response_auth: false +gss_api_auth: false diff --git a/roles/sshd/handlers/main.yml b/roles/sshd/handlers/main.yml new file mode 100644 index 0000000..9f08055 --- /dev/null +++ b/roles/sshd/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: "Restart sshd" + ansible.builtin.service: + name: ssh + state: restarted + enabled: true + daemon_reload: true diff --git a/roles/sshd/meta/main.yml b/roles/sshd/meta/main.yml new file mode 100644 index 0000000..45b38d2 --- /dev/null +++ b/roles/sshd/meta/main.yml @@ -0,0 +1,17 @@ +--- +galaxy_info: + role_name: sshd + namespace: genlab + author: "Alexander Gorelyshev" + company: "Genlab, LLC" + description: "Deploy a hardened sshd server" + license: "MIT" + min_ansible_version: "2.1" + + platforms: + - name: "Ubuntu" + versions: [ "focal", "jammy" ] + + galaxy_tags: [ ] + +dependencies: [] diff --git a/roles/sshd/tasks/algorithms.yml b/roles/sshd/tasks/algorithms.yml new file mode 100644 index 0000000..3eb0150 --- /dev/null +++ b/roles/sshd/tasks/algorithms.yml @@ -0,0 +1,33 @@ +--- +# NOTE: order of preference for openssh-server ed25519 -> rsa +- name: "Algorithms | enable ed25519 authentication algorithm" + notify: Restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^HostKey /etc/ssh/ssh_host_ed25519_key' + line: 'HostKey /etc/ssh/ssh_host_ed25519_key' + validate: sshd -f %s -t + +- name: "Algorithms | enable the RSA authentication algorithm" + notify: Restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^HostKey /etc/ssh/ssh_host_rsa_key' + line: 'HostKey /etc/ssh/ssh_host_rsa_key' + validate: sshd -f %s -t + +- name: "Algorithms | disable the ECDSA algorithm (deemed to be less safe)" + notify: Restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^HostKey /etc/ssh/ssh_host_ecdsa_key' + state: absent + validate: sshd -f %s -t + +- name: "Algorithms | disable the DSA algorithm (considered to be defunct)" + notify: Restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^HostKey /etc/ssh/ssh_host_dsa_key' + state: absent + validate: sshd -f %s -t diff --git a/roles/sshd/tasks/authentication.yml b/roles/sshd/tasks/authentication.yml new file mode 100644 index 0000000..26b690a --- /dev/null +++ b/roles/sshd/tasks/authentication.yml @@ -0,0 +1,31 @@ +--- +- name: "Authentication | Configure SSH authentication settings" + notify: Restart sshd + loop: + - { regexp: '^#?\s*PubkeyAuthentication\s+', line: 'PubkeyAuthentication yes' } + - { regexp: '^#?\s*PasswordAuthentication\s+', line: 'PasswordAuthentication {{ password_auth | ternary("yes", "no") }}' } + - { regexp: '^#?\s*PermitEmptyPasswords\s+', line: 'PermitEmptyPasswords no' } + - { regexp: '^#?\s*ChallengeResponseAuthentication\s+', line: 'ChallengeResponseAuthentication {{ challenge_response_auth | ternary("yes", "no") }}' } + - { regexp: '^#?\s*GSSAPIAuthentication\s+', line: 'GSSAPIAuthentication {{ gss_api_auth | ternary("yes", "no") }}' } + - { + regexp: '^#?\s*AuthenticationMethods\s+', + line: "{{ 'AuthenticationMethods publickey password' if password_auth else 'AuthenticationMethods publickey' }}" + } + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + validate: /usr/sbin/sshd -t -f %s + +- name: "Check if there is an SSH config forced by cloud-init" + register: sshd_cloud_init + ansible.builtin.stat: + path: "/etc/ssh/sshd_config.d/50-cloud-init.conf" + +- name: "Authentication | override password authentication by cloud-init to '{{ password_auth | ternary('yes', 'no') }}'" + when: sshd_cloud_init.stat.exists + notify: Restart sshd + ansible.builtin.lineinfile: + path: "/etc/ssh/sshd_config.d/50-cloud-init.conf" + regexp: '^#?PasswordAuthentication' + line: 'PasswordAuthentication {{ password_auth | ternary("yes", "no") }}' diff --git a/roles/sshd/tasks/encryption.yml b/roles/sshd/tasks/encryption.yml new file mode 100644 index 0000000..660a369 --- /dev/null +++ b/roles/sshd/tasks/encryption.yml @@ -0,0 +1,11 @@ +--- +- name: "Encryption | remove unsafe host keys" + loop: + - /etc/ssh/ssh_host_ecdsa_key + - /etc/ssh/ssh_host_ecdsa_key.pub + - /etc/ssh/ssh_host_dsa_key + - /etc/ssh/ssh_host_dsa_key.pub + notify: Restart sshd + ansible.builtin.file: + path: "{{ item }}" + state: absent diff --git a/roles/sshd/tasks/install.yml b/roles/sshd/tasks/install.yml new file mode 100644 index 0000000..1940c90 --- /dev/null +++ b/roles/sshd/tasks/install.yml @@ -0,0 +1,12 @@ +--- +- name: "Install | install OpenSSH (RHEL flavours)" + when: ansible_os_family == "RHEL" + ansible.builtin.dnf: + name: openssh + state: installed + +- name: "Install | Install OpenSSH (Debian flavours)" + when: ansible_os_family == "Debian" + ansible.builtin.apt: + name: openssh-server + state: present diff --git a/roles/sshd/tasks/main.yml b/roles/sshd/tasks/main.yml new file mode 100644 index 0000000..d35222a --- /dev/null +++ b/roles/sshd/tasks/main.yml @@ -0,0 +1,23 @@ +--- +- name: "Install an OpenSSH server" + ansible.builtin.include_tasks: "install.yml" + +- name: "Configure SSH algorithms" + ansible.builtin.include_tasks: "algorithms.yml" + +- name: "Configure authentication methods" + ansible.builtin.include_tasks: "authentication.yml" + +- name: "Configure SSH encryption keys" + ansible.builtin.include_tasks: "encryption.yml" + +- name: "Configure additional restrictions" + ansible.builtin.include_tasks: "restrictions.yml" + +- name: "Log at VERBOSE level" + notify: Restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^#?LogLevel' + line: 'LogLevel VERBOSE' + validate: sshd -f %s -t diff --git a/roles/sshd/tasks/restrictions.yml b/roles/sshd/tasks/restrictions.yml new file mode 100644 index 0000000..723a007 --- /dev/null +++ b/roles/sshd/tasks/restrictions.yml @@ -0,0 +1,30 @@ +--- +- name: "Restrictions | Configure SSH security restrictions" + loop: + - { regexp: '^#?Protocol\s+', line: 'Protocol 2' } + - { regexp: '^PermitRootLogin yes', line: 'PermitRootLogin no' } + - { regexp: '^#?X11Forwarding', line: 'X11Forwarding no' } + - { regexp: '^#?IgnoreRhosts', line: 'IgnoreRhosts yes' } + - { regexp: '^#?DebianBanner\s+', line: 'DebianBanner no' } + notify: Restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + validate: /usr/sbin/sshd -t -f %s + +- name: "Restrictions | toggle PAM" + notify: Restart sshd + ansible.builtin.lineinfile: + path: /etc/ssh/sshd_config + regexp: '^#?UsePAM' + line: "UsePAM {{ disable_pam | ternary('no', 'yes') }}" + validate: sshd -f %s -t + +- name: "Restrictions | ensure the SSHD config is restricted to the root user" + notify: Restart sshd + ansible.builtin.file: + path: /etc/ssh/sshd_config + owner: root + group: root + mode: "0600" diff --git a/roles/sshd/vars/main.yml b/roles/sshd/vars/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/sshd/vars/main.yml @@ -0,0 +1 @@ +--- From 2c4b30314b66b22205ab2f5eb86efe7132464b7c Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Thu, 18 Dec 2025 11:39:21 +0300 Subject: [PATCH 2/7] add molecule files --- roles/sshd/molecule/default/converge.yml | 5 +++++ roles/sshd/molecule/default/molecule.yml | 27 ++++++++++++++++++++++++ roles/sshd/molecule/default/verify.yml | 10 +++++++++ 3 files changed, 42 insertions(+) create mode 100644 roles/sshd/molecule/default/converge.yml create mode 100644 roles/sshd/molecule/default/molecule.yml create mode 100644 roles/sshd/molecule/default/verify.yml diff --git a/roles/sshd/molecule/default/converge.yml b/roles/sshd/molecule/default/converge.yml new file mode 100644 index 0000000..bea06f8 --- /dev/null +++ b/roles/sshd/molecule/default/converge.yml @@ -0,0 +1,5 @@ +--- +- name: Converge + hosts: all + roles: + - role: "genlab.common.sshd" diff --git a/roles/sshd/molecule/default/molecule.yml b/roles/sshd/molecule/default/molecule.yml new file mode 100644 index 0000000..d82158e --- /dev/null +++ b/roles/sshd/molecule/default/molecule.yml @@ -0,0 +1,27 @@ +--- +dependency: + name: galaxy + +driver: + name: docker + +platforms: + - name: ubuntu + image: geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2404}-ansible:latest + pre_build_image: true + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + cgroupns_mode: host + privileged: true + +provisioner: + name: ansible + +verifier: + name: ansible + +lint: | + set -e + yamllint . + ansible-lint . diff --git a/roles/sshd/molecule/default/verify.yml b/roles/sshd/molecule/default/verify.yml new file mode 100644 index 0000000..50508d7 --- /dev/null +++ b/roles/sshd/molecule/default/verify.yml @@ -0,0 +1,10 @@ +--- + +- name: Verify + hosts: all + gather_facts: false + any_errors_fatal: true + + tasks: + - name: blank + ansible.builtin.command: echo From 14bcc89e5d5052f2e56ac71611dafd7ce8b3d6ca Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Thu, 18 Dec 2025 11:54:32 +0300 Subject: [PATCH 3/7] fix role and ansible-lint errors --- roles/sshd/defaults/main.yml | 8 ++++---- roles/sshd/meta/main.yml | 4 ++-- roles/sshd/molecule/default/verify.yml | 3 ++- roles/sshd/tasks/algorithms.yml | 9 +++++++++ roles/sshd/tasks/authentication.yml | 12 ++++++------ roles/sshd/tasks/install.yml | 1 + roles/sshd/tasks/restrictions.yml | 2 +- 7 files changed, 25 insertions(+), 14 deletions(-) diff --git a/roles/sshd/defaults/main.yml b/roles/sshd/defaults/main.yml index 7f8dce0..5354282 100644 --- a/roles/sshd/defaults/main.yml +++ b/roles/sshd/defaults/main.yml @@ -1,5 +1,5 @@ --- -disable_pam: false -password_auth: false -challenge_response_auth: false -gss_api_auth: false +sshd_disable_pam: false +sshd_password_auth: false +sshd_challenge_response_auth: false +sshd_gss_api_auth: false diff --git a/roles/sshd/meta/main.yml b/roles/sshd/meta/main.yml index 45b38d2..7158cf1 100644 --- a/roles/sshd/meta/main.yml +++ b/roles/sshd/meta/main.yml @@ -10,8 +10,8 @@ galaxy_info: platforms: - name: "Ubuntu" - versions: [ "focal", "jammy" ] + versions: ["focal", "jammy"] - galaxy_tags: [ ] + galaxy_tags: [] dependencies: [] diff --git a/roles/sshd/molecule/default/verify.yml b/roles/sshd/molecule/default/verify.yml index 50508d7..6287e65 100644 --- a/roles/sshd/molecule/default/verify.yml +++ b/roles/sshd/molecule/default/verify.yml @@ -6,5 +6,6 @@ any_errors_fatal: true tasks: - - name: blank + - name: Blank ansible.builtin.command: echo + changed_when: false diff --git a/roles/sshd/tasks/algorithms.yml b/roles/sshd/tasks/algorithms.yml index 3eb0150..a43581d 100644 --- a/roles/sshd/tasks/algorithms.yml +++ b/roles/sshd/tasks/algorithms.yml @@ -1,4 +1,13 @@ --- +# next task requires this directory to exist for sshd -t flag +- name: Ensure /run/sshd exists + ansible.builtin.file: + path: /run/sshd + state: directory + owner: root + group: root + mode: '0755' + # NOTE: order of preference for openssh-server ed25519 -> rsa - name: "Algorithms | enable ed25519 authentication algorithm" notify: Restart sshd diff --git a/roles/sshd/tasks/authentication.yml b/roles/sshd/tasks/authentication.yml index 26b690a..8b4e63b 100644 --- a/roles/sshd/tasks/authentication.yml +++ b/roles/sshd/tasks/authentication.yml @@ -3,13 +3,13 @@ notify: Restart sshd loop: - { regexp: '^#?\s*PubkeyAuthentication\s+', line: 'PubkeyAuthentication yes' } - - { regexp: '^#?\s*PasswordAuthentication\s+', line: 'PasswordAuthentication {{ password_auth | ternary("yes", "no") }}' } + - { regexp: '^#?\s*PasswordAuthentication\s+', line: 'PasswordAuthentication {{ sshd_password_auth | ternary("yes", "no") }}' } - { regexp: '^#?\s*PermitEmptyPasswords\s+', line: 'PermitEmptyPasswords no' } - - { regexp: '^#?\s*ChallengeResponseAuthentication\s+', line: 'ChallengeResponseAuthentication {{ challenge_response_auth | ternary("yes", "no") }}' } - - { regexp: '^#?\s*GSSAPIAuthentication\s+', line: 'GSSAPIAuthentication {{ gss_api_auth | ternary("yes", "no") }}' } + - { regexp: '^#?\s*ChallengeResponseAuthentication\s+', line: 'ChallengeResponseAuthentication {{ sshd_challenge_response_auth | ternary("yes", "no") }}' } + - { regexp: '^#?\s*GSSAPIAuthentication\s+', line: 'GSSAPIAuthentication {{ sshd_gss_api_auth | ternary("yes", "no") }}' } - { regexp: '^#?\s*AuthenticationMethods\s+', - line: "{{ 'AuthenticationMethods publickey password' if password_auth else 'AuthenticationMethods publickey' }}" + line: "{{ 'AuthenticationMethods publickey password' if sshd_password_auth else 'AuthenticationMethods publickey' }}" } ansible.builtin.lineinfile: path: /etc/ssh/sshd_config @@ -22,10 +22,10 @@ ansible.builtin.stat: path: "/etc/ssh/sshd_config.d/50-cloud-init.conf" -- name: "Authentication | override password authentication by cloud-init to '{{ password_auth | ternary('yes', 'no') }}'" +- name: "Authentication | override password authentication by cloud-init to '{{ sshd_password_auth | ternary('yes', 'no') }}'" when: sshd_cloud_init.stat.exists notify: Restart sshd ansible.builtin.lineinfile: path: "/etc/ssh/sshd_config.d/50-cloud-init.conf" regexp: '^#?PasswordAuthentication' - line: 'PasswordAuthentication {{ password_auth | ternary("yes", "no") }}' + line: 'PasswordAuthentication {{ sshd_password_auth | ternary("yes", "no") }}' diff --git a/roles/sshd/tasks/install.yml b/roles/sshd/tasks/install.yml index 1940c90..ff03595 100644 --- a/roles/sshd/tasks/install.yml +++ b/roles/sshd/tasks/install.yml @@ -10,3 +10,4 @@ ansible.builtin.apt: name: openssh-server state: present + update_cache: true diff --git a/roles/sshd/tasks/restrictions.yml b/roles/sshd/tasks/restrictions.yml index 723a007..6d14920 100644 --- a/roles/sshd/tasks/restrictions.yml +++ b/roles/sshd/tasks/restrictions.yml @@ -18,7 +18,7 @@ ansible.builtin.lineinfile: path: /etc/ssh/sshd_config regexp: '^#?UsePAM' - line: "UsePAM {{ disable_pam | ternary('no', 'yes') }}" + line: "UsePAM {{ sshd_disable_pam | ternary('no', 'yes') }}" validate: sshd -f %s -t - name: "Restrictions | ensure the SSHD config is restricted to the root user" From 30436311aa8f96586b4c21b4abdc9cd1fec0e62f Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Thu, 18 Dec 2025 11:55:29 +0300 Subject: [PATCH 4/7] update meta --- README.md | 1 + galaxy.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bd37b07..6386f43 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ - [rustdesk](roles/rustdesk/README.md) - [sftp_share](roles/sftp_share/README.md) - [smartctl_exporter](roles/smartctl_exporter/README.md) +- [sshd](roles/sshd/README.md) - [swapfile](roles/swapfile/README.md) - [ufw](roles/ufw/README.md) - [wg_hub](roles/wg_hub/README.md) diff --git a/galaxy.yml b/galaxy.yml index c26b9f9..8c51504 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: genlab name: common -version: 0.22.0 +version: 0.23.0 readme: README.md authors: - Alexander Gorelyshev (corvus-migratorius@proton.me) From 3f7602cc704308cb71d47e7293fa372079294533 Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Thu, 18 Dec 2025 13:09:02 +0300 Subject: [PATCH 5/7] add verify tasks --- roles/sshd/molecule/default/verify.yml | 37 ++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/roles/sshd/molecule/default/verify.yml b/roles/sshd/molecule/default/verify.yml index 6287e65..5e1bb57 100644 --- a/roles/sshd/molecule/default/verify.yml +++ b/roles/sshd/molecule/default/verify.yml @@ -6,6 +6,39 @@ any_errors_fatal: true tasks: - - name: Blank - ansible.builtin.command: echo + - name: Gather service facts + ansible.builtin.service_facts: + + - name: Ensure sshd is running + ansible.builtin.assert: + that: + - ansible_facts.services['ssh.service'].state == 'running' + + - name: Ensure sshd_config syntax is OK + ansible.builtin.command: sshd -t -f /etc/ssh/sshd_config changed_when: false + + - name: Ensure main parameteres are applied + ansible.builtin.shell: | + set -o pipefail ; + sshd -T | egrep -i ' + ^protocol 2| + ^permitrootlogin no| + ^passwordauthentication no| + ^pubkeyauthentication yes + ' + args: + executable: /bin/bash + changed_when: false + + - name: Get sshd_config stats + ansible.builtin.stat: + path: /etc/ssh/sshd_config + register: sshd_conf + + - name: Ensure sshd_config file is secure + ansible.builtin.assert: + that: + - sshd_conf.stat.uid == 0 + - sshd_conf.stat.gid == 0 + - sshd_conf.stat.mode == '0600' From a27c38e712d4d7e962eb6d88004d8d1c0fb7fc6d Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Thu, 18 Dec 2025 13:26:56 +0300 Subject: [PATCH 6/7] update meta --- galaxy.yml | 2 +- roles/sshd/README.md | 2 +- roles/sshd/meta/main.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/galaxy.yml b/galaxy.yml index 8c51504..a18146b 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: genlab name: common -version: 0.23.0 +version: 0.24.0 readme: README.md authors: - Alexander Gorelyshev (corvus-migratorius@proton.me) diff --git a/roles/sshd/README.md b/roles/sshd/README.md index 1c4d1d9..3f3962d 100644 --- a/roles/sshd/README.md +++ b/roles/sshd/README.md @@ -23,7 +23,7 @@ Example Playbook ```yaml roles: - - role: genlab.sshd + - role: genlab.common.sshd ``` License diff --git a/roles/sshd/meta/main.yml b/roles/sshd/meta/main.yml index 7158cf1..a365305 100644 --- a/roles/sshd/meta/main.yml +++ b/roles/sshd/meta/main.yml @@ -10,7 +10,7 @@ galaxy_info: platforms: - name: "Ubuntu" - versions: ["focal", "jammy"] + versions: ["jammy", "noble"] galaxy_tags: [] From ee4cec563a9ff77901c3547c0d9519c867acab87 Mon Sep 17 00:00:00 2001 From: Sergey Malyuk Date: Thu, 18 Dec 2025 14:59:07 +0300 Subject: [PATCH 7/7] add ssh connection test --- roles/sshd/molecule/default/verify.yml | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/roles/sshd/molecule/default/verify.yml b/roles/sshd/molecule/default/verify.yml index 5e1bb57..29b09d7 100644 --- a/roles/sshd/molecule/default/verify.yml +++ b/roles/sshd/molecule/default/verify.yml @@ -42,3 +42,35 @@ - sshd_conf.stat.uid == 0 - sshd_conf.stat.gid == 0 - sshd_conf.stat.mode == '0600' + + - name: Create test user + ansible.builtin.user: + name: test + create_home: true + shell: /bin/bash + + - name: Create .ssh directory + ansible.builtin.file: + path: /home/test/.ssh/ + state: directory + mode: '0700' + owner: test + group: test + + - name: Generate ssh keys + community.crypto.openssh_keypair: + path: /home/test/.ssh/id_rsa + owner: test + group: test + mode: '0600' + register: sshd_key_result + + - name: Put public key to test user + ansible.posix.authorized_key: + user: test + key: "{{ sshd_key_result.public_key }}" + state: present + + - name: Test ssh connection + ansible.builtin.command: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /home/test/.ssh/id_rsa test@localhost hostname + changed_when: false