Merge pull request #147 from Jakuje/tests

Improve test coverage with new test cases and new distros, fixing minor issues on the way
This commit is contained in:
Matt Willsher 2020-12-11 18:21:54 +00:00 committed by GitHub
commit e1de59b3c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 601 additions and 88 deletions

View file

@ -0,0 +1,17 @@
name: Run tests on Debian buster (10)
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
# Important: This sets up your GITHUB_WORKSPACE environment variable
- uses: actions/checkout@v2
- name: ansible check with debian:buster (10)
uses: roles-ansible/check-ansible-debian-buster-action@master
with:
group: local
hosts: localhost
targets: "tests/*.yml"

View file

@ -0,0 +1,17 @@
name: Run tests on Debian stretch (9)
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
# Important: This sets up your GITHUB_WORKSPACE environment variable
- uses: actions/checkout@v2
- name: ansible check with debian:stretch (9)
uses: roles-ansible/check-ansible-debian-stretch-action@master
with:
group: local
hosts: localhost
targets: "tests/*.yml"

17
.github/workflows/ansible-debian.yml vendored Normal file
View file

@ -0,0 +1,17 @@
name: Run tests on Debian latest
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
# Important: This sets up your GITHUB_WORKSPACE environment variable
- uses: actions/checkout@v2
- name: ansible check with debian:latest
uses: roles-ansible/check-ansible-debian-latest-action@master
with:
group: local
hosts: localhost
targets: "tests/*.yml"

17
.github/workflows/ansible-ubuntu.yml vendored Normal file
View file

@ -0,0 +1,17 @@
name: Run tests on Ubuntu latest
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
# Important: This sets up your GITHUB_WORKSPACE environment variable
- uses: actions/checkout@v2
- name: ansible check with ubuntu:latest
uses: roles-ansible/check-ansible-ubuntu-latest-action@master
with:
group: local
hosts: localhost
targets: "tests/*.yml"

View file

@ -24,15 +24,18 @@ script:
- wget https://raw.githubusercontent.com/ansible/galaxy/devel/galaxy/importer/linters/yamllint.yaml - wget https://raw.githubusercontent.com/ansible/galaxy/devel/galaxy/importer/linters/yamllint.yaml
- "yamllint -c yamllint.yaml **/*.yml" - "yamllint -c yamllint.yaml **/*.yml"
# Test 0.5: OS defaults: Travis images have heavily updated (even with invalid configuration options)
# sshd_config so it does not make sense to test OS defaults here
# Test 1a: Run the role # Test 1a: Run the role
- "ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_default.yml --connection=local --become -v" - "ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_default.yml --connection=local --become -v"
# Test 1b: Run the role through include # Test 1b: Run the role through include (skipping backup)
- "ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_default_include.yml --connection=local --become -v" - "ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_default_include.yml -e sshd_test_backup_skip=yes --connection=local --become -v"
# Test 2: Run the role/playbook again, checking to make sure it's idempotent. # Test 2: Run the role/playbook again, checking to make sure it's idempotent (skipping backup)
- > - >
ansible-playbook -i tests/inventory tests/tests_default.yml --connection=local --become | grep -q 'changed=0.*failed=0' ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_default.yml --connection=local -e sshd_test_backup_skip=yes --become | grep -q 'changed=0.*failed=0'
&& (echo 'Idempotence test: pass' && exit 0) && (echo 'Idempotence test: pass' && exit 0)
|| (echo 'Idempotence test: fail' && exit 1) || (echo 'Idempotence test: fail' && exit 1)
@ -78,3 +81,21 @@ script:
ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_hostkeys_missing.yml --connection=local --become -v ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_hostkeys_missing.yml --connection=local --become -v
&& (echo 'Missing hostkeys test: pass' && exit 0) && (echo 'Missing hostkeys test: pass' && exit 0)
|| (echo 'Missing hostkeys test: fail' && exit 1) || (echo 'Missing hostkeys test: fail' && exit 1)
# Test 10: Test sshd_enable has effect
- >
ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_sshd_enable.yml --connection=local --become -v
&& (echo 'Test sshd_enable: pass' && exit 0)
|| (echo 'Test sshd_enable: fail' && exit 1)
# Test 11: Test variable precedence
- >
ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_precedence.yml --connection=local --become -v
&& (echo 'Variable precedence test: pass' && exit 0)
|| (echo 'Variable precedence test: fail' && exit 1)
# Test 12: Verify backups are created
- >
ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_backup.yml --connection=local --become -v
&& (echo 'Backup test: pass' && exit 0)
|| (echo 'Backup test: fail' && exit 1)

View file

@ -122,13 +122,11 @@ ListenAddress 0.0.0.0
ListenAddress :: ListenAddress ::
``` ```
* `sshd_match` * `sshd_match`, `sshd_match_1` through `sshd_match_9`
A list of dicts for a match section. See the example playbook. A list of dicts or just a dict for a Match section. Note, that these variables
do not override match blocks as defined in the `sshd` dict. All of the sources
* `sshd_match_1` through `sshd_match_9` will be reflected in the resulting configuration file.
A list of dicts or just a dict for a Match section.
* `sshd_backup` * `sshd_backup`

View file

@ -70,3 +70,7 @@ __sshd_defaults: {}
__sshd_os_supported: no __sshd_os_supported: no
__sshd_sysconfig_supports_crypto_policy: false __sshd_sysconfig_supports_crypto_policy: false
__sshd_sysconfig_supports_use_strong_rng: false __sshd_sysconfig_supports_use_strong_rng: false
__sshd_runtime_directory: false
__sshd_runtime_directory_mode: "0755"

View file

@ -7,6 +7,7 @@
when: when:
- sshd_allow_reload|bool - sshd_allow_reload|bool
- ansible_virtualization_type|default(None) != 'docker' - ansible_virtualization_type|default(None) != 'docker'
- ansible_virtualization_type|default(None) != 'podman'
- ansible_virtualization_type|default(None) != 'VirtualPC' # for Github Actions - ansible_virtualization_type|default(None) != 'VirtualPC' # for Github Actions
- ansible_connection != 'chroot' - ansible_connection != 'chroot'
- ansible_os_family != 'AIX' - ansible_os_family != 'AIX'

View file

@ -19,6 +19,7 @@
backup: "{{ sshd_backup }}" backup: "{{ sshd_backup }}"
when: when:
- sshd_sysconfig|bool - sshd_sysconfig|bool
- __sshd_sysconfig_supports_use_strong_rng or __sshd_sysconfig_supports_crypto_policy
notify: reload_sshd notify: reload_sshd
- name: Make sure hostkeys are available and have expected permissions - name: Make sure hostkeys are available and have expected permissions
@ -39,7 +40,11 @@
{% if not sshd_verify_hostkeys %} {% if not sshd_verify_hostkeys %}
[] []
{% elif sshd_verify_hostkeys == 'auto' %} {% elif sshd_verify_hostkeys == 'auto' %}
{% if sshd_HostKey is string %}
[ {{ __sshd_hostkeys_from_config }} ]
{% else %}
{{ __sshd_hostkeys_from_config }} {{ __sshd_hostkeys_from_config }}
{% endif %}
{% else %} {% else %}
{{ sshd_verify_hostkeys | to_json }} {{ sshd_verify_hostkeys | to_json }}
{% endif %} {% endif %}
@ -80,6 +85,16 @@
changed_when: False changed_when: False
when: sshd_test_hostkey.path is defined when: sshd_test_hostkey.path is defined
- name: Make sure sshd runtime directory is present
file:
path: "{{ __sshd_runtime_directory }}"
state: directory
owner: root
group: root
mode: "{{ __sshd_runtime_directory_mode }}"
when:
- __sshd_runtime_directory | d(false) | bool
- name: Create the configuration file - name: Create the configuration file
template: template:
src: sshd_config.j2 src: sshd_config.j2
@ -143,6 +158,7 @@
when: when:
- sshd_manage_service|bool - sshd_manage_service|bool
- ansible_virtualization_type|default(None) != 'docker' - ansible_virtualization_type|default(None) != 'docker'
- ansible_virtualization_type|default(None) != 'podman'
- ansible_virtualization_type|default(None) != 'VirtualPC' # for Github Actions - ansible_virtualization_type|default(None) != 'VirtualPC' # for Github Actions
- ansible_connection != 'chroot' - ansible_connection != 'chroot'

View file

@ -18,8 +18,8 @@
params: params:
files: files:
- "{{ ansible_distribution }}_{{ ansible_distribution_lts_version }}.yml" - "{{ ansible_distribution }}_{{ ansible_distribution_lts_version }}.yml"
- "{{ ansible_distribution }}.yml"
- "{{ ansible_os_family }}_{{ ansible_distribution_major_version }}.yml" - "{{ ansible_os_family }}_{{ ansible_distribution_major_version }}.yml"
- "{{ ansible_distribution }}.yml"
- "{{ ansible_os_family }}.yml" - "{{ ansible_os_family }}.yml"
- default.yml - default.yml
paths: paths:

23
tests/tasks/backup.yml Normal file
View file

@ -0,0 +1,23 @@
---
- name: Setup
include_tasks: setup.yml
- name: Create a temporary directory for backup files
tempfile:
state: directory
register: __sshd_test_backup
changed_when: False
when:
- sshd_test_backup_skip is not defined
- name: Backup files
shell: >
if test -f {{ item }}; then
mkdir -p {{ __sshd_test_backup.path }}/$(dirname {{ item }});
cp {{ item }} {{ __sshd_test_backup.path }}/$(dirname {{ item }})
fi
changed_when: False
loop: "{{ __sshd_test_backup_files | d([]) }}"
when:
- __sshd_test_backup is defined
- __sshd_test_backup.path is defined

35
tests/tasks/restore.yml Normal file
View file

@ -0,0 +1,35 @@
---
- name: Restore backed up files and remove what was not present
shell: >
if test -f {{ __sshd_test_backup.path }}/{{ item }}; then
cp {{ __sshd_test_backup.path }}/{{ item }} $(dirname {{ item }})
elif test -f {{ item }}; then
rm {{ item }}
fi
changed_when: False
loop: "{{ __sshd_test_backup_files | d([]) }}"
when:
- __sshd_test_backup is defined
- __sshd_test_backup.path is defined
- name: Remove temporary directory for backup files
file:
path: "{{ __sshd_test_backup.path }}"
state: absent
changed_when: False
when:
- __sshd_test_backup is defined
- __sshd_test_backup.path is defined
- name: Restart sshd service
service:
name: sshd
state: reloaded
changed_when: False
when:
- __sshd_test_backup is defined
- ansible_virtualization_type|default(None) != 'docker'
- ansible_virtualization_type|default(None) != 'podman'
- ansible_virtualization_type|default(None) != 'VirtualPC' # for Github Actions
- ansible_connection != 'chroot'
- ansible_os_family != 'AIX'

15
tests/tasks/setup.yml Normal file
View file

@ -0,0 +1,15 @@
---
- name: Make sure openssh is installed before creating backup
package:
name: openssh-server
state: present
- name: Make sure openssh has runtime directory on debian
file:
path: /run/sshd
state: directory
owner: root
group: root
mode: "0755"
when:
- ansible_facts['os_family'] == 'Debian'

View file

@ -1,6 +1,15 @@
--- ---
- hosts: all - hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
- /etc/ssh/sshd_config_custom
- /etc/ssh/sshd_config_custom_second
tasks: tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: Configure alternative sshd_config file - name: Configure alternative sshd_config file
include_role: include_role:
name: ansible-sshd name: ansible-sshd
@ -11,7 +20,7 @@
sshd: sshd:
AcceptEnv: LANG AcceptEnv: LANG
Banner: /etc/issue Banner: /etc/issue
Ciphers: aes256-gcm@openssh.com Ciphers: aes256-ctr
sshd_Compression: no sshd_Compression: no
- name: Configure second alternative sshd_config file - name: Configure second alternative sshd_config file
include_role: include_role:
@ -22,7 +31,7 @@
sshd_skip_defaults: true sshd_skip_defaults: true
sshd: sshd:
Banner: /etc/issue2 Banner: /etc/issue2
Ciphers: aes128-gcm@openssh.com Ciphers: aes128-ctr
sshd_MaxStartups: 100 sshd_MaxStartups: 100
- name: Now configure the main sshd_config file - name: Now configure the main sshd_config file
include_role: include_role:
@ -30,7 +39,7 @@
vars: vars:
sshd: sshd:
Banner: /etc/issue Banner: /etc/issue
Ciphers: aes128-ctr Ciphers: aes192-ctr
HostKey: HostKey:
- /tmp/ssh_host_ecdsa_key - /tmp/ssh_host_ecdsa_key
sshd_PasswordAuthentication: no sshd_PasswordAuthentication: no
@ -66,7 +75,7 @@
that: that:
- "'AcceptEnv LANG' in config.content | b64decode" - "'AcceptEnv LANG' in config.content | b64decode"
- "'Banner /etc/issue' in config.content | b64decode" - "'Banner /etc/issue' in config.content | b64decode"
- "'Ciphers aes256-gcm@openssh.com' in config.content | b64decode" - "'Ciphers aes256-ctr' in config.content | b64decode"
- "'HostKey' not in config.content | b64decode" - "'HostKey' not in config.content | b64decode"
- "'Compression no' in config.content | b64decode" - "'Compression no' in config.content | b64decode"
- "'MaxStartups 100' not in config.content | b64decode" - "'MaxStartups 100' not in config.content | b64decode"
@ -75,7 +84,7 @@
assert: assert:
that: that:
- "'Banner /etc/issue2' in config2.content | b64decode" - "'Banner /etc/issue2' in config2.content | b64decode"
- "'Ciphers aes128-gcm@openssh.com' in config2.content | b64decode" - "'Ciphers aes128-ctr' in config2.content | b64decode"
- "'HostKey' not in config2.content | b64decode" - "'HostKey' not in config2.content | b64decode"
- "'MaxStartups 100' in config2.content | b64decode" - "'MaxStartups 100' in config2.content | b64decode"
- "'Compression no' not in config2.content | b64decode" - "'Compression no' not in config2.content | b64decode"
@ -84,9 +93,12 @@
assert: assert:
that: that:
- "'Banner /etc/issue' in config3.content | b64decode" - "'Banner /etc/issue' in config3.content | b64decode"
- "'Ciphers aes128-ctr' in config3.content | b64decode" - "'Ciphers aes192-ctr' in config3.content | b64decode"
- "'HostKey /tmp/ssh_host_ecdsa_key' in config3.content | b64decode" - "'HostKey /tmp/ssh_host_ecdsa_key' in config3.content | b64decode"
- "'PasswordAuthentication no' in config3.content | b64decode" - "'PasswordAuthentication no' in config3.content | b64decode"
- "'MaxStartups 100' not in config3.content | b64decode" - "'MaxStartups 100' not in config3.content | b64decode"
- "'Compression no' not in config3.content | b64decode" - "'Compression no' not in config3.content | b64decode"
tags: tests::verify tags: tests::verify
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

67
tests/tests_backup.yml Normal file
View file

@ -0,0 +1,67 @@
---
- hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
main_sshd_config: >-
{{
"00-ansible_system_role.conf"
if ansible_facts['distribution'] == 'Fedora'
else "sshd_config"
}}
main_sshd_config_path: >-
{{
"/etc/ssh/sshd_config.d/"
if ansible_facts['distribution'] == 'Fedora'
else "/etc/ssh/"
}}
tasks:
- name: Backup configuration files
include_tasks: tasks/backup.yml
- name: Find old backups files
find:
paths: "{{ main_sshd_config_path }}"
patterns: "{{ main_sshd_config }}.*@*~"
register: backup_files
- name: Remove old backup files
file:
path: "{{ item.path }}"
state: absent
with_items: "{{ backup_files.files }}"
- name: Configure sshd without creating backup
include_role:
name: ansible-sshd
vars:
sshd_backup: false
- name: Find new backups files
find:
paths: "{{ main_sshd_config_path }}"
patterns: "{{ main_sshd_config }}.*@*~"
register: no_backup
- name: Configure sshd again with different configuration and with backup
include_role:
name: ansible-sshd
vars:
sshd_Banner: /tmp/banner
register: second_run
- name: Find new backups files
find:
paths: "{{ main_sshd_config_path }}"
patterns: "{{ main_sshd_config }}.*@*~"
register: new_backup
- name: Verify the backup was not done in the first attempt, but in the second one
assert:
that:
- no_backup.files == []
- new_backup.files != []
- name: Restore configuration files
include_tasks: tasks/restore.yml

View file

@ -1,4 +1,22 @@
--- ---
- hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- hosts: all - hosts: all
roles: roles:
- ansible-sshd - ansible-sshd
- hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
tasks:
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -1,6 +1,16 @@
--- ---
- hosts: all - hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
tasks: tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: "Configure sshd" - name: "Configure sshd"
include_role: include_role:
name: ansible-sshd name: ansible-sshd
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -1,9 +1,17 @@
--- ---
- hosts: all - hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
- /tmp/ssh_host_rsa_key2
tasks: tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: Remove host key before the test - name: Remove host key before the test
file: file:
path: /tmp/ssh_host_ed25519_key path: /tmp/ssh_host_rsa_key2
state: absent state: absent
- name: Ensure group 'nobody' exists - name: Ensure group 'nobody' exists
@ -28,7 +36,7 @@
sshd_hostkey_mode: "0664" sshd_hostkey_mode: "0664"
sshd: sshd:
HostKey: HostKey:
- /tmp/ssh_host_ed25519_key - /tmp/ssh_host_rsa_key2
- name: Verify the options are correctly set - name: Verify the options are correctly set
vars: vars:
@ -47,17 +55,17 @@
register: config register: config
- stat: - stat:
path: /tmp/ssh_host_ed25519_key path: /tmp/ssh_host_rsa_key2
register: privkey register: privkey
- stat: - stat:
path: /tmp/ssh_host_ed25519_key.pub path: /tmp/ssh_host_rsa_key2.pub
register: pubkey register: pubkey
- name: Check the options are in configuration file - name: Check the options are in configuration file
assert: assert:
that: that:
- "'HostKey /tmp/ssh_host_ed25519_key' in config.content | b64decode" - "'HostKey /tmp/ssh_host_rsa_key2' in config.content | b64decode"
- name: Check the generated host key has requested properties - name: Check the generated host key has requested properties
assert: assert:
@ -68,3 +76,6 @@
- privkey.stat.mode == '0664' - privkey.stat.mode == '0664'
- pubkey.stat.exists - pubkey.stat.exists
tags: tests::verify tags: tests::verify
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -1,6 +1,14 @@
--- ---
- hosts: all - hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
- /tmp/missing_ssh_host_rsa_key
tasks: tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: Configure sshd with missing host keys and prevent their creation - name: Configure sshd with missing host keys and prevent their creation
block: block:
- name: Configure missing hostkey - name: Configure missing hostkey
@ -24,6 +32,18 @@
- ansible_failed_result.msg != 'UNREACH' - ansible_failed_result.msg != 'UNREACH'
- not role_result.changed - not role_result.changed
msg: "Role has not failed when it should have" msg: "Role has not failed when it should have"
when:
- ansible_facts['os_family'] != 'Debian'
- not (ansible_facts['distribution'] == 'RedHat' and ansible_facts['distribution_major_version'] == '6')
tags: tests::verify
- name: Make sure the key was not created
file:
path: /tmp/missing_ssh_host_rsa_key
state: missing
register: key
failed_when: key.changed
tags: tests::verify
- name: Make sure service is still running - name: Make sure service is still running
service: service:
@ -31,3 +51,7 @@
state: started state: started
register: result register: result
failed_when: result.changed failed_when: result.changed
tags: tests::verify
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -1,6 +1,13 @@
--- ---
- hosts: all - hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
tasks: tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: Configure sshd - name: Configure sshd
include_role: include_role:
name: ansible-sshd name: ansible-sshd
@ -10,7 +17,7 @@
- /etc/ssh/ssh_host_rsa_key - /etc/ssh/ssh_host_rsa_key
sshd: sshd:
Match: Match:
- Condition: "User xusers" Condition: "User xusers"
X11Forwarding: yes X11Forwarding: yes
Banner: /tmp/xusers-banner Banner: /tmp/xusers-banner
sshd_match: sshd_match:
@ -24,7 +31,7 @@
sshd_match_2: sshd_match_2:
- Condition: "User root" - Condition: "User root"
PasswordAuthentication: no PasswordAuthentication: no
PermitTunnel: yes AllowTcpForwarding: yes
- name: Verify the options are correctly set - name: Verify the options are correctly set
vars: vars:
@ -69,7 +76,7 @@
- "'forcecommand internal-sftp' in sftponly_effective.stdout" - "'forcecommand internal-sftp' in sftponly_effective.stdout"
- "'chrootdirectory /var/uploads/' in sftponly_effective.stdout" - "'chrootdirectory /var/uploads/' in sftponly_effective.stdout"
- "'passwordauthentication no' in root_effective.stdout" - "'passwordauthentication no' in root_effective.stdout"
- "'permittunnel yes' in root_effective.stdout" - "'allowtcpforwarding yes' in root_effective.stdout"
- name: Check the options are in configuration file - name: Check the options are in configuration file
assert: assert:
@ -79,3 +86,6 @@
- "'Match User sftponly' in config.content | b64decode" - "'Match User sftponly' in config.content | b64decode"
- "'Match User root' in config.content | b64decode" - "'Match User root' in config.content | b64decode"
tags: tests::verify tags: tests::verify
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -1,6 +1,13 @@
--- ---
- hosts: all - hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
tasks: tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: Configure sshd - name: Configure sshd
include_role: include_role:
name: ansible-sshd name: ansible-sshd
@ -22,7 +29,7 @@
ChrootDirectory: "/var/uploads/" ChrootDirectory: "/var/uploads/"
- Condition: "User root" - Condition: "User root"
PasswordAuthentication: no PasswordAuthentication: no
PermitTunnel: yes AllowTcpForwarding: yes
- name: Verify the options are correctly set - name: Verify the options are correctly set
vars: vars:
@ -67,7 +74,7 @@
- "'forcecommand internal-sftp' in sftponly_effective.stdout" - "'forcecommand internal-sftp' in sftponly_effective.stdout"
- "'chrootdirectory /var/uploads/' in sftponly_effective.stdout" - "'chrootdirectory /var/uploads/' in sftponly_effective.stdout"
- "'passwordauthentication no' in root_effective.stdout" - "'passwordauthentication no' in root_effective.stdout"
- "'permittunnel yes' in root_effective.stdout" - "'allowtcpforwarding yes' in root_effective.stdout"
- name: Check the options are in configuration file - name: Check the options are in configuration file
assert: assert:
@ -77,3 +84,6 @@
- "'Match User sftponly' in config.content | b64decode" - "'Match User sftponly' in config.content | b64decode"
- "'Match User root' in config.content | b64decode" - "'Match User root' in config.content | b64decode"
tags: tests::verify tags: tests::verify
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -0,0 +1,38 @@
---
- hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
- /etc/ssh/ssh_host_rsa_key
- /etc/ssh/ssh_host_rsa_key.pub
tasks:
- name: Backup configuration files
include_tasks: tasks/backup.yml
- name: Show effective configuration before running role (system defaults)
shell: >
if test ! -f /etc/ssh/ssh_host_rsa_key; then
ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C '' -N ''
fi;
sshd -T
register: runtime_before
- name: Configure sshd
include_role:
name: ansible-sshd
- name: Show effective configuration after running role (role defaults)
shell: sshd -T
register: runtime_after
- debug:
var: ansible_facts['distribution']
- debug:
var: ansible_facts['distribution_major_version']
- name: Check that the effective configuration did not change from OS defaults
assert:
that:
- runtime_before.stdout == runtime_after.stdout
when:
- not (ansible_facts['distribution'] == 'RedHat' and ansible_facts['distribution_major_version'] == '6')
- name: Restore configuration files
include_tasks: tasks/restore.yml

View file

@ -0,0 +1,66 @@
---
- hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
- /tmp/ssh_host_rsa_key
tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: Remove host key before the test
file:
path: /tmp/ssh_host_rsa_key
state: absent
- name: Configure sshd
include_role:
name: ansible-sshd
vars:
sshd:
Banner: /etc/issue
Ciphers: aes256-ctr
HostKey: /etc/ssh/ssh_host_rsa_key
sshd_Ciphers: aes128-ctr
sshd_Banner: /etc/good-issue
sshd_HostKey: /tmp/ssh_host_rsa_key
- name: Verify the options are correctly set
vars:
main_sshd_config: >-
{{
"/etc/ssh/sshd_config.d/00-ansible_system_role.conf"
if ansible_facts['distribution'] == 'Fedora'
else "/etc/ssh/sshd_config"
}}
block:
- meta: flush_handlers
- name: List effective configuration using sshd -T
command: sshd -T
register: runtime
- name: Print current configuration file
slurp:
src: "{{ main_sshd_config }}"
register: config
- name: Check the sshd_* values are effective in runtime
# note, the options are in lower-case here
assert:
that:
- "'banner /etc/good-issue' in runtime.stdout"
- "'ciphers aes128-ctr' in runtime.stdout"
- "'hostkey /tmp/ssh_host_rsa_key' in runtime.stdout"
- name: Check the options are in configuration file
assert:
that:
- "'Banner /etc/good-issue' in config.content | b64decode"
- "'Ciphers aes128-ctr' in config.content | b64decode"
- "'HostKey /tmp/ssh_host_rsa_key' in config.content | b64decode"
tags: tests::verify
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -1,6 +1,13 @@
--- ---
- hosts: all - hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
tasks: tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: Configure sshd - name: Configure sshd
include_role: include_role:
name: ansible-sshd name: ansible-sshd
@ -8,7 +15,7 @@
sshd: sshd:
AcceptEnv: LANG AcceptEnv: LANG
Banner: /etc/issue Banner: /etc/issue
Ciphers: aes256-gcm@openssh.com Ciphers: aes256-ctr
Subsystem: "sftp internal-sftp" Subsystem: "sftp internal-sftp"
sshd_config_file: /etc/ssh/sshd_config sshd_config_file: /etc/ssh/sshd_config
@ -31,7 +38,7 @@
that: that:
- "'acceptenv LANG' in runtime.stdout" - "'acceptenv LANG' in runtime.stdout"
- "'banner /etc/issue' in runtime.stdout" - "'banner /etc/issue' in runtime.stdout"
- "'ciphers aes256-gcm@openssh.com' in runtime.stdout" - "'ciphers aes256-ctr' in runtime.stdout"
- "'subsystem sftp internal-sftp' in runtime.stdout" - "'subsystem sftp internal-sftp' in runtime.stdout"
- name: Check the options are in configuration file - name: Check the options are in configuration file
@ -39,6 +46,9 @@
that: that:
- "'AcceptEnv LANG' in config.content | b64decode" - "'AcceptEnv LANG' in config.content | b64decode"
- "'Banner /etc/issue' in config.content | b64decode" - "'Banner /etc/issue' in config.content | b64decode"
- "'Ciphers aes256-gcm@openssh.com' in config.content | b64decode" - "'Ciphers aes256-ctr' in config.content | b64decode"
- "'Subsystem sftp internal-sftp' in config.content | b64decode" - "'Subsystem sftp internal-sftp' in config.content | b64decode"
tags: tests::verify tags: tests::verify
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -1,6 +1,13 @@
--- ---
- hosts: all - hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
tasks: tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: Configure sshd with uncommon options, making sure it keeps running - name: Configure sshd with uncommon options, making sure it keeps running
block: block:
- name: Configure ssh with unsupported options - name: Configure ssh with unsupported options
@ -48,3 +55,7 @@
state: started state: started
register: result register: result
failed_when: result.changed failed_when: result.changed
tags: tests::verify
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -0,0 +1,47 @@
---
- hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: Configure sshd with the role disabled
include_role:
name: ansible-sshd
vars:
sshd_enable: false
sshd:
AcceptEnv: XDG_*
Banner: /etc/issue
Ciphers: aes256-ctr,aes128-ctr
sshd_config_file: /etc/ssh/sshd_config
- name: Print current configuration file
slurp:
src: /etc/ssh/sshd_config
register: config
- name: Print effective configuration
shell: >
if test ! -f /etc/ssh/ssh_host_rsa_key; then
ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C '' -N ''
fi;
sshd -T
register: runtime
- name: Check the options were not applied
# note, the options are in lower-case here
assert:
that:
- "'Acceptenv XDG_*' not in config.content | b64decode"
- "'Banner /etc/issue' not in config.content | b64decode"
- "'Ciphers aes256-ctr,aes128-ctr' not in config.content | b64decode"
- "'acceptenv XDG_*' not in runtime.stdout"
- "'banner /etc/issue' not in runtime.stdout"
- "'ciphers aes256-ctr,aes128-ctr' not in runtime.stdout"
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -1,6 +1,14 @@
--- ---
- hosts: all - hosts: all
vars:
__sshd_test_backup_files:
- /etc/ssh/sshd_config
- /etc/ssh/sshd_config.d/00-ansible_system_role.conf
- /etc/sysconfig/sshd
tasks: tasks:
- name: "Backup configuration files"
include_tasks: tasks/backup.yml
- name: Configure sshd - name: Configure sshd
include_role: include_role:
name: ansible-sshd name: ansible-sshd
@ -18,12 +26,31 @@
src: /etc/sysconfig/sshd src: /etc/sysconfig/sshd
register: config register: config
- name: Evaluate sysconfig similarly as systemd
shell: |
source /etc/sysconfig/sshd
echo "CP=|$CRYPTO_POLICY|"
echo "RNG=|$SSH_USE_STRONG_RNG|"
register: evaluation
- name: Evaluate sysconfig similarly as systemd on RHEL 8
shell: |
source /etc/crypto-policies/back-ends/opensshserver.config
source /etc/sysconfig/sshd
echo "CP=|$CRYPTO_POLICY|"
echo "RNG=|$SSH_USE_STRONG_RNG|"
register: evaluation8
when:
- ansible_facts['os_family'] == "RedHat"
- ansible_facts['distribution_major_version'] == "8"
- name: Check the crypto policies is overridden in RHEL 8 - name: Check the crypto policies is overridden in RHEL 8
assert: assert:
that: that:
- "'CRYPTO_POLICY=' in config.content | b64decode" - "'CRYPTO_POLICY=' in config.content | b64decode"
# these are string variants in default configuration file # these are string variants in default configuration file
- "'# CRYPTO_POLICY=' not in config.content | b64decode" - "'# CRYPTO_POLICY=' not in config.content | b64decode"
- "'CP=||' in evaluation8.stdout"
when: when:
- ansible_facts['os_family'] == "RedHat" - ansible_facts['os_family'] == "RedHat"
- ansible_facts['distribution_major_version'] == "8" - ansible_facts['distribution_major_version'] == "8"
@ -35,7 +62,11 @@
# these are string variants in default configuration file # these are string variants in default configuration file
- "'SSH_USE_STRONG_RNG=0' not in config.content | b64decode" - "'SSH_USE_STRONG_RNG=0' not in config.content | b64decode"
- "'# SSH_USE_STRONG_RNG=1' not in config.content | b64decode" - "'# SSH_USE_STRONG_RNG=1' not in config.content | b64decode"
- "'RNG=|32|' in evaluation.stdout"
tags: tests::verify
when: when:
- ansible_facts['os_family'] == "RedHat" - ansible_facts['os_family'] == "RedHat"
- ansible_facts['distribution'] != 'Fedora' - ansible_facts['distribution'] != 'Fedora'
tags: tests::verify
- name: "Restore configuration files"
include_tasks: tasks/restore.yml

View file

@ -34,3 +34,4 @@ __sshd_defaults:
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"
UsePAM: yes UsePAM: yes
__sshd_os_supported: yes __sshd_os_supported: yes
__sshd_runtime_directory: /run/sshd

View file

@ -5,30 +5,11 @@ sshd_packages:
- openssh-sftp-server - openssh-sftp-server
sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
Port: 22
Protocol: 2
HostKey:
- /etc/ssh/ssh_host_rsa_key
- /etc/ssh/ssh_host_ed25519_key
HostKeyAlgorithms: ssh-ed25519,ecdsa-sha2-nistp256,ssh-rsa,ssh-ed25519-cert-v01@openssh.com
KexAlgorithms: curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group-exchange-sha256
MACs: umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
SyslogFacility: AUTH
LogLevel: INFO
LoginGraceTime: 120
PermitRootLogin: without-password
StrictModes: yes
PubkeyAuthentication: yes
IgnoreRhosts: yes
HostbasedAuthentication: no
PermitEmptyPasswords: no
ChallengeResponseAuthentication: no ChallengeResponseAuthentication: no
X11Forwarding: yes X11Forwarding: yes
X11DisplayOffset: 10
PrintMotd: no PrintMotd: no
PrintLastLog: yes
TCPKeepAlive: yes
AcceptEnv: LANG LC_* AcceptEnv: LANG LC_*
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"
UsePAM: yes UsePAM: yes
__sshd_os_supported: yes __sshd_os_supported: yes
__sshd_runtime_directory: /run/sshd

View file

@ -36,3 +36,4 @@ __sshd_defaults:
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"
UsePAM: yes UsePAM: yes
__sshd_os_supported: yes __sshd_os_supported: yes
__sshd_runtime_directory: /run/sshd

View file

@ -5,30 +5,11 @@ sshd_packages:
- openssh-sftp-server - openssh-sftp-server
sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
Port: 22
Protocol: 2
HostKey:
- /etc/ssh/ssh_host_rsa_key
- /etc/ssh/ssh_host_dsa_key
- /etc/ssh/ssh_host_ecdsa_key
- /etc/ssh/ssh_host_ed25519_key
UsePrivilegeSeparation: yes
SyslogFacility: AUTH
LogLevel: INFO
LoginGraceTime: 120
PermitRootLogin: without-password
StrictModes: yes
PubkeyAuthentication: yes
IgnoreRhosts: yes
HostbasedAuthentication: no
PermitEmptyPasswords: no
ChallengeResponseAuthentication: no ChallengeResponseAuthentication: no
X11Forwarding: yes X11Forwarding: yes
X11DisplayOffset: 10
PrintMotd: no PrintMotd: no
PrintLastLog: yes
TCPKeepAlive: yes
AcceptEnv: LANG LC_* AcceptEnv: LANG LC_*
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"
UsePAM: yes UsePAM: yes
__sshd_os_supported: yes __sshd_os_supported: yes
__sshd_runtime_directory: /run/sshd

View file

@ -4,6 +4,8 @@ sshd_packages:
- openssh-server - openssh-server
sshd_sftp_server: /usr/libexec/openssh/sftp-server sshd_sftp_server: /usr/libexec/openssh/sftp-server
__sshd_defaults: __sshd_defaults:
HostKey:
- /etc/ssh/ssh_host_rsa_key
Protocol: 2 Protocol: 2
SyslogFacility: AUTHPRIV SyslogFacility: AUTHPRIV
PasswordAuthentication: yes PasswordAuthentication: yes
@ -20,5 +22,3 @@ __sshd_defaults:
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"
__sshd_os_supported: yes __sshd_os_supported: yes
__sshd_sysconfig_supports_use_strong_rng: true __sshd_sysconfig_supports_use_strong_rng: true
sshd_hostkey_group: ssh_keys
sshd_hostkey_mode: "0640"

View file

@ -11,6 +11,7 @@ __sshd_defaults:
SyslogFacility: AUTHPRIV SyslogFacility: AUTHPRIV
AuthorizedKeysFile: .ssh/authorized_keys AuthorizedKeysFile: .ssh/authorized_keys
PasswordAuthentication: yes PasswordAuthentication: yes
PermitRootLogin: yes
ChallengeResponseAuthentication: no ChallengeResponseAuthentication: no
GSSAPIAuthentication: yes GSSAPIAuthentication: yes
GSSAPICleanupCredentials: no GSSAPICleanupCredentials: no

View file

@ -13,3 +13,4 @@ __sshd_defaults:
AcceptEnv: LANG LC_* AcceptEnv: LANG LC_*
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"
__sshd_os_supported: yes __sshd_os_supported: yes
__sshd_runtime_directory: /run/sshd

View file

@ -12,3 +12,4 @@ __sshd_defaults:
AcceptEnv: LANG LC_* AcceptEnv: LANG LC_*
Subsystem: "sftp /usr/lib/openssh/sftp-server" Subsystem: "sftp /usr/lib/openssh/sftp-server"
__sshd_os_supported: yes __sshd_os_supported: yes
__sshd_runtime_directory: /run/sshd