Merge pull request #146 from Jakuje/github-actions

Run tests with Github Actions and fix things on the way
This commit is contained in:
Matt Willsher 2020-11-16 11:52:56 +00:00 committed by GitHub
commit fb0932c993
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 558 additions and 201 deletions

16
.github/workflows/ansible-centos7.yml vendored Normal file
View file

@ -0,0 +1,16 @@
name: Run tests on CentOS 7
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: ansible check with centos:7
uses: roles-ansible/check-ansible-centos-centos7-action@master
with:
group: local
hosts: localhost
targets: "tests/*.yml"

16
.github/workflows/ansible-centos8.yml vendored Normal file
View file

@ -0,0 +1,16 @@
name: Run tests on CentOS 8
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: ansible check with centos:8
uses: roles-ansible/check-ansible-centos-centos8-action@master
with:
group: local
hosts: localhost
targets: "tests/*.yml"

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

@ -0,0 +1,17 @@
name: Run tests on Fedora 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 fedora:latest
uses: roles-ansible/check-ansible-fedora-latest-action@master
with:
group: local
hosts: localhost
targets: "tests/*.yml"

1
.gitignore vendored
View file

@ -1,3 +1,2 @@
.vagrant .vagrant
tests/roles/ansible-sshd
tests/test.retry tests/test.retry

View file

@ -66,3 +66,15 @@ script:
ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_match_iterate.yml --connection=local --become -v ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_match_iterate.yml --connection=local --become -v
&& (echo 'Match blocks with iteration test: pass' && exit 0) && (echo 'Match blocks with iteration test: pass' && exit 0)
|| (echo 'Match blocks with iteration test: fail' && exit 1) || (echo 'Match blocks with iteration test: fail' && exit 1)
# Test 8: Test hostkeys can be generated by this role
- >
ANSIBLE_FORCE_COLOR=1 ansible-playbook -i tests/inventory tests/tests_hostkeys.yml --connection=local --become -v
&& (echo 'Hostkeys test: pass' && exit 0)
|| (echo 'Hostkeys test: fail' && exit 1)
# Test 9: Test missing hostkeys
- >
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: fail' && exit 1)

View file

@ -6,12 +6,12 @@ OpenSSH Server
This role configures the OpenSSH daemon. It: This role configures the OpenSSH daemon. It:
* By default configures the SSH daemon with the normal OS defaults. * By default configures the SSH daemon with the normal OS defaults.
* Works across a variety of UN*X like distributions * Works across a variety of `UN*X` distributions
* Can be configured by dict or simple variables * Can be configured by dict or simple variables
* Supports Match sets * Supports Match sets
* Supports all sshd_config options. Templates are programmatically generated. * Supports all `sshd_config` options. Templates are programmatically generated.
(see [meta/make_option_list](meta/make_option_list)) (see [`meta/make_option_list`](meta/make_option_list))
* Tests the sshd_config before reloading sshd. * Tests the `sshd_config` before reloading sshd.
**WARNING** Misconfiguration of this role can lock you out of your server! **WARNING** Misconfiguration of this role can lock you out of your server!
Please test your configuration and its interaction with your users configuration Please test your configuration and its interaction with your users configuration
@ -42,51 +42,51 @@ It will likely work on other flavours and more direct support via suitable
Role variables Role variables
--------------- ---------------
Unconfigured, this role will provide a sshd_config that matches the OS default, Unconfigured, this role will provide a `sshd_config` that matches the OS default,
minus the comments and in a different order. minus the comments and in a different order.
* `sshd_enable` * `sshd_enable`
If set to False, the role will be completely disabled. Defaults to True. If set to *false*, the role will be completely disabled. Defaults to *true*.
* `sshd_skip_defaults` * `sshd_skip_defaults`
If set to True, don't apply default values. This means that you must have a If set to *true*, don't apply default values. This means that you must have a
complete set of configuration defaults via either the sshd dict, or sshd_Key complete set of configuration defaults via either the `sshd` dict, or
variables. Defaults to *False*. `sshd_Key` variables. Defaults to *false*.
* `sshd_manage_service` * `sshd_manage_service`
If set to False, the service/daemon won't be **managed** at all, i.e. will not If set to *false*, the service/daemon won't be **managed** at all, i.e. will not
try to enable on boot or start or reload the service. Defaults to *True* try to enable on boot or start or reload the service. Defaults to *true*
unless: Running inside a docker container (it is assumed ansible is used during unless: Running inside a docker container (it is assumed ansible is used during
build phase) or AIX (Ansible `service` module does not currently support `enabled` build phase) or AIX (Ansible `service` module does not currently support `enabled`
for AIX) for AIX)
* `sshd_allow_reload` * `sshd_allow_reload`
If set to False, a reload of sshd wont happen on change. This can help with If set to *false*, a reload of sshd wont happen on change. This can help with
troubleshooting. You'll need to manually reload sshd if you want to apply the troubleshooting. You'll need to manually reload sshd if you want to apply the
changed configuration. Defaults to the same value as ``sshd_manage_service``. changed configuration. Defaults to the same value as `sshd_manage_service`.
(Except on AIX, where `sshd_manage_service` is default *False*, but (Except on AIX, where `sshd_manage_service` is default *false*, but
`sshd_allow_reload` is default *True*) `sshd_allow_reload` is default *true*)
* `sshd_install_service` * `sshd_install_service`
If set to True, the role will install service files for the ssh service. If set to *true*, the role will install service files for the ssh service.
Defaults to False. Defaults to *false*.
The templates for the service files to be used are pointed to by the variables The templates for the service files to be used are pointed to by the variables
- `sshd_service_template_service` (__default__: _templates/sshd.service.j2_) - `sshd_service_template_service` (__default__: `templates/sshd.service.j2`)
- `sshd_service_template_at_service` (__default__: _templates/sshd@.service.j2_) - `sshd_service_template_at_service` (__default__: `templates/sshd@.service.j2`)
- `sshd_service_template_socket` (__default__: _templates/sshd.socket.j2_) - `sshd_service_template_socket` (__default__: `templates/sshd.socket.j2`)
Using these variables, you can use your own custom templates. With the above Using these variables, you can use your own custom templates. With the above
default templates, the name of the installed ssh service will be provided by default templates, the name of the installed ssh service will be provided by
the `sshd_service` variable. the `sshd_service` variable.
* sshd * `sshd`
A dict containing configuration. e.g. A dict containing configuration. e.g.
@ -106,8 +106,8 @@ values. e.g.:
sshd_Compression: off sshd_Compression: off
``` ```
In all cases, booleans correctly rendered as yes and no in sshd configuration. In all cases, booleans are correctly rendered as yes and no in sshd
Lists can be used for multiline configuration items. e.g. configuration. Lists can be used for multiline configuration items. e.g.
```yaml ```yaml
sshd_ListenAddress: sshd_ListenAddress:
@ -130,6 +130,34 @@ A list of dicts for a match section. See the example playbook.
A list of dicts or just a dict for a Match section. A list of dicts or just a dict for a Match section.
* `sshd_backup`
When set to *false*, the original `sshd_config` file is not backed up. Default
is *true*.
* `sshd_sysconfig`
On RHEL-based systems, sysconfig is used for configuring more details of sshd
service. If set to *true*, this role will manage also the `/etc/sysconfig/sshd`
configuration file based on the following configuration. Default is *false*.
* `sshd_sysconfig_override_crypto_policy`
In RHEL8-based systems, this can be used to override system-wide crypto policy
by setting to *true*. Defaults to *false*.
* `sshd_sysconfig_use_strong_rng`
In RHEL-based systems, this can be used to force sshd to reseed openssl random
number generator with the given amount of bytes as an argument. The default is
*0*, which disables this functionality. It is not recommended to turn this on
if the system does not have hardware random number generator.
* `sshd_config_file`
The path where the openssh configuration produced by this role should be saved.
This is useful mostly when generating configuration snippets to Include.
### Secondary role variables ### Secondary role variables
These variables are used by the role internals and can be used to override the These variables are used by the role internals and can be used to override the
@ -144,10 +172,6 @@ Use this variable to override the default list of packages to install.
Use these variables to set the ownership and permissions for the openssh config Use these variables to set the ownership and permissions for the openssh config
file that this role produces. file that this role produces.
* `sshd_config_file`
The path where the openssh configuration produced by this role should be saved.
* `sshd_binary` * `sshd_binary`
The path to the openssh executable The path to the openssh executable
@ -159,6 +183,23 @@ the ssh service that the target platform uses. But it can also be used to set
the name of the custom ssh service when the `sshd_install_service` variable is the name of the custom ssh service when the `sshd_install_service` variable is
used. used.
* `sshd_verify_hostkeys`
By default (*auto*), this list contains all the host keys that are present in
the produced configuration file. The paths are checked for presence and
generated if missing. Additionally, permissions and file owners are set to sane
defaults. This is useful if the role is used in deployment stage to make sure
the service is able to start on the first attempt. To disable this check, set
this to empty list.
* `sshd_hostkey_owner`, `sshd_hostkey_group`, `sshd_hostkey_group`
Use these variables to set the ownership and permissions for the host keys from
the above list.
* `sshd_sftp_server`
Default path to the sftp server binary.
Dependencies Dependencies
------------ ------------
@ -237,9 +278,9 @@ for example:
Template Generation Template Generation
------------------- -------------------
The [sshd_config.j2](templates/sshd_config.j2) template is programatically The [`sshd_config.j2`](templates/sshd_config.j2) template is programatically
generated by the scripts in meta. New options should be added to the generated by the scripts in meta. New options should be added to the
options_body or options_match. `options_body` or `options_match`.
To regenerate the template, from within the meta/ directory run: To regenerate the template, from within the meta/ directory run:
`./make_option_list >../templates/sshd_config.j2` `./make_option_list >../templates/sshd_config.j2`

View file

@ -10,6 +10,9 @@ sshd_skip_defaults: false
# daemon at all # daemon at all
sshd_manage_service: true sshd_manage_service: true
# If the below is false, don't reload the ssh daemon on change
sshd_allow_reload: true
# If the below is true, also install service files from the templates pointed # If the below is true, also install service files from the templates pointed
# to by the `sshd_service_template_*` variables # to by the `sshd_service_template_*` variables
sshd_install_service: false sshd_install_service: false
@ -17,9 +20,6 @@ sshd_service_template_service: sshd.service.j2
sshd_service_template_at_service: sshd@.service.j2 sshd_service_template_at_service: sshd@.service.j2
sshd_service_template_socket: sshd.socket.j2 sshd_service_template_socket: sshd.socket.j2
# If the below is false, don't reload the ssh daemon on change
sshd_allow_reload: true
# If the below is true, create a backup of the config file when the template is copied # If the below is true, create a backup of the config file when the template is copied
sshd_backup: true sshd_backup: true
@ -33,29 +33,40 @@ sshd_sysconfig_override_crypto_policy: false
# If the below is set to non-zero value, the OpenSSL random generator is # If the below is set to non-zero value, the OpenSSL random generator is
# reseeded with the given amount of random bytes (from getrandom(2) # reseeded with the given amount of random bytes (from getrandom(2)
# with GRND_RANDOM or /dev/random). Minimum is 14 bytes when enabled. # with GRND_RANDOM or /dev/random). Minimum is 14 bytes when enabled.
# This is not recommended to enable if you do not have hadware random generator # This is not recommended to enable if you do not have hardware random number
# generator
sshd_sysconfig_use_strong_rng: 0 sshd_sysconfig_use_strong_rng: 0
# Empty dicts to avoid errors # Empty dicts to avoid errors
sshd: {} sshd: {}
# The path to sshd_config file. This is useful when creating an included
# configuration file snippet or configuring second sshd service
sshd_config_file: /etc/ssh/sshd_config
### VARS DEFAULTS ### VARS DEFAULTS
### The following are defaults for OS specific configuration in var files in ### The following are defaults for OS specific configuration in var files in
### this role. They should not be set directly by role users. If you really ### this role. They should not be set directly by role users.
### need to override them, use the corresponding, unprefixed variables (eg sshd_packages: []
### `sshd_packages` to override __sshd_packages). sshd_config_owner: root
__sshd_packages: [] sshd_config_group: root
__sshd_config_owner: root sshd_config_mode: "0600"
__sshd_config_group: root sshd_binary: /usr/sbin/sshd
__sshd_config_mode: "0600" sshd_service: sshd
__sshd_config_file: /etc/ssh/sshd_config sshd_sftp_server: /usr/lib/openssh/sftp-server
__sshd_binary: /usr/sbin/sshd
__sshd_service: sshd # This lists by default all hostkeys as rendered in the generated configuration
# file ("auto"). Before attempting to run sshd (either for verification of
# configuration or restarting), we make sure the keys exist and have correct
# permissions. To disable this check, set sshd_verify_hostkeys to false
sshd_verify_hostkeys: "auto"
sshd_hostkey_owner: root
sshd_hostkey_group: root
sshd_hostkey_mode: "0600"
### These variables are used by role internals and should not be used. ### These variables are used by role internals and should not be used.
__sshd_sftp_server: /usr/lib/openssh/sftp-server
__sshd_defaults: {} __sshd_defaults: {}
__sshd_os_supported: no __sshd_os_supported: no
__sshd_sysconfig: false
__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

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) != 'VirtualPC' # for Github Actions
- ansible_connection != 'chroot' - ansible_connection != 'chroot'
- ansible_os_family != 'AIX' - ansible_os_family != 'AIX'
listen: reload_sshd listen: reload_sshd

View file

@ -9,17 +9,6 @@
name: "{{ sshd_packages }}" name: "{{ sshd_packages }}"
state: present state: present
- name: Configuration
template:
src: sshd_config.j2
dest: "{{ sshd_config_file }}"
owner: "{{ sshd_config_owner }}"
group: "{{ sshd_config_group }}"
mode: "{{ sshd_config_mode }}"
validate: "{{ sshd_binary }} -t -f %s"
backup: "{{ sshd_backup }}"
notify: reload_sshd
- name: Sysconfig configuration - name: Sysconfig configuration
template: template:
src: sysconfig.j2 src: sysconfig.j2
@ -32,6 +21,92 @@
- sshd_sysconfig|bool - sshd_sysconfig|bool
notify: reload_sshd notify: reload_sshd
- name: Make sure hostkeys are available and have expected permissions
vars: &share_vars
# This mimics the macro body_option() in sshd_config.j2
# The explicit to_json filter is needed for Python 2 compatibility
__sshd_hostkeys_from_config: >-
{% if sshd_HostKey is defined %}
{{ sshd_HostKey | to_json }}
{% elif sshd['HostKey'] is defined %}
{{ sshd['HostKey'] | to_json }}
{% elif __sshd_defaults['HostKey'] is defined and not sshd_skip_defaults %}
{{ __sshd_defaults['HostKey'] | to_json }}
{% else %}
[]
{% endif %}
__sshd_verify_hostkeys: >-
{% if not sshd_verify_hostkeys %}
[]
{% elif sshd_verify_hostkeys == 'auto' %}
{{ __sshd_hostkeys_from_config }}
{% else %}
{{ sshd_verify_hostkeys | to_json }}
{% endif %}
block:
- name: Make sure hostkeys are available
shell: >
{% if sshd_sysconfig %}
source /etc/sysconfig/sshd;
{% endif %}
ssh-keygen -q -t {{ item | regex_search('(rsa|dsa|ecdsa|ed25519)') }} -f {{ item }} -C '' -N ''
args:
creates: "{{ item }}"
loop: "{{ __sshd_verify_hostkeys | from_json | list }}"
- name: Make sure private hostkeys have expected permissions
file:
path: "{{ item }}"
owner: "{{ sshd_hostkey_owner }}"
group: "{{ sshd_hostkey_group }}"
mode: "{{ sshd_hostkey_mode }}"
loop: "{{ __sshd_verify_hostkeys | from_json | list }}"
- name: Apply configuration
vars:
<<: *share_vars
block:
- name: Create a temporary hostkey for syntax verification if needed
tempfile:
state: directory
register: sshd_test_hostkey
changed_when: False
when:
- __sshd_hostkeys_from_config | from_json == []
- sshd_config_file != "/etc/ssh/sshd_config"
- name: Generate temporary hostkey
shell: "ssh-keygen -q -t rsa -f {{ sshd_test_hostkey.path }}/rsa_key -C '' -N ''"
changed_when: False
when: sshd_test_hostkey.path is defined
- name: Create the configuration file
template:
src: sshd_config.j2
dest: "{{ sshd_config_file }}"
owner: "{{ sshd_config_owner }}"
group: "{{ sshd_config_group }}"
mode: "{{ sshd_config_mode }}"
validate: >-
{% if sshd_test_hostkey is defined and sshd_test_hostkey.path is defined %}
{{ sshd_binary }} -t -f %s -h {{ sshd_test_hostkey.path }}/rsa_key
{% else %}
{{ sshd_binary }} -t -f %s
{% endif %}
backup: "{{ sshd_backup }}"
notify: reload_sshd
rescue:
- name: re-raise the error
fail:
msg: "{{ ansible_failed_result }}"
always:
- name: Remove temporary host keys
file:
path: "{{ sshd_test_hostkey.path }}"
state: absent
changed_when: False
when: sshd_test_hostkey.path is defined
- name: Install systemd service files - name: Install systemd service files
block: block:
- name: Install service unit file - name: Install service unit file
@ -68,6 +143,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) != 'VirtualPC' # for Github Actions
- ansible_connection != 'chroot' - ansible_connection != 'chroot'
# Due to ansible bug 21026, cannot use service module on RHEL 7 # Due to ansible bug 21026, cannot use service module on RHEL 7

View file

@ -23,44 +23,5 @@
- "{{ ansible_os_family }}.yml" - "{{ ansible_os_family }}.yml"
- default.yml - default.yml
paths: paths:
- '{{ role_path }}/vars' - "{{ role_path }}/vars"
- '{{ playbook_dir }}/vars' - "{{ playbook_dir }}/vars"
- name: Override OS defaults
block:
- name: Define sshd_packages
set_fact:
sshd_packages: "{{ __sshd_packages }}"
when: sshd_packages is not defined
- name: Define sshd_config_owner
set_fact:
sshd_config_owner: "{{ __sshd_config_owner }}"
when: sshd_config_owner is not defined
- name: Define sshd_config_group
set_fact:
sshd_config_group: "{{ __sshd_config_group }}"
when: sshd_config_group is not defined
- name: Define sshd_config_mode
set_fact:
sshd_config_mode: "{{ __sshd_config_mode }}"
when: sshd_config_mode is not defined
- name: Define sshd_config_file
set_fact:
sshd_config_file: "{{ __sshd_config_file }}"
when: sshd_config_file is not defined
- name: Define sshd_binary
set_fact:
sshd_binary: "{{ __sshd_binary }}"
when: sshd_binary is not defined
- name: Define sshd_service
set_fact:
sshd_service: "{{ __sshd_service }}"
when: sshd_service is not defined
- name: Define sshd_sftp_server
set_fact:
sshd_sftp_server: "{{ __sshd_sftp_server }}"
when: sshd_sftp_server is not defined
- name: Define sshd_sysconfig
set_fact:
sshd_sysconfig: "{{ __sshd_sysconfig }}"
when: sshd_sysconfig is not defined

1
tests/roles/ansible-sshd Symbolic link
View file

@ -0,0 +1 @@
../../

View file

@ -12,19 +12,81 @@
AcceptEnv: LANG AcceptEnv: LANG
Banner: /etc/issue Banner: /etc/issue
Ciphers: aes256-gcm@openssh.com Ciphers: aes256-gcm@openssh.com
sshd_Compression: no
- name: Configure second alternative sshd_config file
include_role:
name: ansible-sshd
vars:
# just anything -- will not get processed by sshd
sshd_config_file: /etc/ssh/sshd_config_custom_second
sshd_skip_defaults: true
sshd:
Banner: /etc/issue2
Ciphers: aes128-gcm@openssh.com
sshd_MaxStartups: 100
- name: Now configure the main sshd_config file
include_role:
name: ansible-sshd
vars:
sshd:
Banner: /etc/issue
Ciphers: aes128-ctr
HostKey:
- /tmp/ssh_host_ecdsa_key
sshd_PasswordAuthentication: no
- name: Verify the options are correctly set - 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: block:
- meta: flush_handlers - meta: flush_handlers
- name: Print current configuration file - name: Print current configuration file
command: cat /etc/ssh/sshd_config_custom slurp:
src: /etc/ssh/sshd_config_custom
register: config register: config
- name: Check the options are in configuration file - name: Print second configuration file
slurp:
src: /etc/ssh/sshd_config_custom_second
register: config2
- name: Print the main configuration file
slurp:
src: "{{ main_sshd_config }}"
register: config3
- name: Check content of first configuration file
assert: assert:
that: that:
- "'AcceptEnv LANG' in config.stdout" - "'AcceptEnv LANG' in config.content | b64decode"
- "'Banner /etc/issue' in config.stdout" - "'Banner /etc/issue' in config.content | b64decode"
- "'Ciphers aes256-gcm@openssh.com' in config.stdout" - "'Ciphers aes256-gcm@openssh.com' in config.content | b64decode"
- "'HostKey' not in config.content | b64decode"
- "'Compression no' in config.content | b64decode"
- "'MaxStartups 100' not in config.content | b64decode"
- name: Check content of second configuration file
assert:
that:
- "'Banner /etc/issue2' in config2.content | b64decode"
- "'Ciphers aes128-gcm@openssh.com' in config2.content | b64decode"
- "'HostKey' not in config2.content | b64decode"
- "'MaxStartups 100' in config2.content | b64decode"
- "'Compression no' not in config2.content | b64decode"
- name: Check content of the main configuration file
assert:
that:
- "'Banner /etc/issue' in config3.content | b64decode"
- "'Ciphers aes128-ctr' in config3.content | b64decode"
- "'HostKey /tmp/ssh_host_ecdsa_key' in config3.content | b64decode"
- "'PasswordAuthentication no' in config3.content | b64decode"
- "'MaxStartups 100' not in config3.content | b64decode"
- "'Compression no' not in config3.content | b64decode"
tags: tests::verify tags: tests::verify

70
tests/tests_hostkeys.yml Normal file
View file

@ -0,0 +1,70 @@
---
- hosts: all
tasks:
- name: Remove host key before the test
file:
path: /tmp/ssh_host_ed25519_key
state: absent
- name: Ensure group 'nobody' exists
group:
name: nobody
- name: Ensure the user 'nobody' exists
user:
name: nobody
group: nobody
comment: nobody
create_home: no
shell: /sbin/nologin
- name: Configure sshd with alternative host keys
include_role:
name: ansible-sshd
vars:
# very BAD example
sshd_hostkey_owner: "nobody"
sshd_hostkey_group: "nobody"
sshd_hostkey_mode: "0664"
sshd:
HostKey:
- /tmp/ssh_host_ed25519_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: Print current configuration file
slurp:
src: "{{ main_sshd_config }}"
register: config
- stat:
path: /tmp/ssh_host_ed25519_key
register: privkey
- stat:
path: /tmp/ssh_host_ed25519_key.pub
register: pubkey
- name: Check the options are in configuration file
assert:
that:
- "'HostKey /tmp/ssh_host_ed25519_key' in config.content | b64decode"
- name: Check the generated host key has requested properties
assert:
that:
- privkey.stat.exists
- privkey.stat.gr_name == 'nobody'
- privkey.stat.pw_name == 'nobody'
- privkey.stat.mode == '0664'
- pubkey.stat.exists
tags: tests::verify

View file

@ -0,0 +1,33 @@
---
- hosts: all
tasks:
- name: Configure sshd with missing host keys and prevent their creation
block:
- name: Configure missing hostkey
include_role:
name: ansible-sshd
vars:
sshd_verify_hostkeys: []
sshd:
HostKey:
- /tmp/missing_ssh_host_rsa_key
register: role_result
- name: unreachable task
fail:
msg: UNREACH
rescue:
- name: Check that we failed in the role
assert:
that:
- ansible_failed_result.msg != 'UNREACH'
- not role_result.changed
msg: "Role has not failed when it should have"
- name: Make sure service is still running
service:
name: sshd
state: started
register: result
failed_when: result.changed

View file

@ -5,6 +5,9 @@
include_role: include_role:
name: ansible-sshd name: ansible-sshd
vars: vars:
# For Fedora containers, we need to make sure we have keys for sshd -T below
sshd_verify_hostkeys:
- /etc/ssh/ssh_host_rsa_key
sshd: sshd:
Match: Match:
- Condition: "User xusers" - Condition: "User xusers"
@ -24,27 +27,35 @@
PermitTunnel: yes PermitTunnel: yes
- name: Verify the options are correctly set - 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: block:
- meta: flush_handlers - meta: flush_handlers
- name: List effective configuration using sshd -T for xusers - name: List effective configuration using sshd -T for xusers
command: sshd -T -C user=xusers command: sshd -T -C user=xusers,addr=127.0.0.1,host=example.com
register: xusers_effective register: xusers_effective
- name: List effective configuration using sshd -T for bot - name: List effective configuration using sshd -T for bot
command: sshd -T -C user=bot command: sshd -T -C user=bot,addr=127.0.0.1,host=example.com
register: bot_effective register: bot_effective
- name: List effective configuration using sshd -T for sftponly - name: List effective configuration using sshd -T for sftponly
command: sshd -T -C user=sftponly command: sshd -T -C user=sftponly,addr=127.0.0.1,host=example.com
register: sftponly_effective register: sftponly_effective
- name: List effective configuration using sshd -T for root - name: List effective configuration using sshd -T for root
command: sshd -T -C user=root command: sshd -T -C user=root,addr=127.0.0.1,host=example.com
register: root_effective register: root_effective
- name: Print current configuration file - name: Print current configuration file
command: cat /etc/ssh/sshd_config slurp:
src: "{{ main_sshd_config }}"
register: config register: config
- name: Check the options are effective - name: Check the options are effective
@ -63,8 +74,8 @@
- name: Check the options are in configuration file - name: Check the options are in configuration file
assert: assert:
that: that:
- "'Match User xusers' in config.stdout" - "'Match User xusers' in config.content | b64decode"
- "'Match User bot' in config.stdout" - "'Match User bot' in config.content | b64decode"
- "'Match User sftponly' in config.stdout" - "'Match User sftponly' in config.content | b64decode"
- "'Match User root' in config.stdout" - "'Match User root' in config.content | b64decode"
tags: tests::verify tags: tests::verify

View file

@ -5,6 +5,9 @@
include_role: include_role:
name: ansible-sshd name: ansible-sshd
vars: vars:
# For Fedora containers, we need to make sure we have keys for sshd -T below
sshd_verify_hostkeys:
- /etc/ssh/ssh_host_rsa_key
sshd: sshd:
Match: Match:
- Condition: "User xusers" - Condition: "User xusers"
@ -22,27 +25,35 @@
PermitTunnel: yes PermitTunnel: yes
- name: Verify the options are correctly set - 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: block:
- meta: flush_handlers - meta: flush_handlers
- name: List effective configuration using sshd -T for xusers - name: List effective configuration using sshd -T for xusers
command: sshd -T -C user=xusers command: sshd -T -C user=xusers,addr=127.0.0.1,host=example.com
register: xusers_effective register: xusers_effective
- name: List effective configuration using sshd -T for bot - name: List effective configuration using sshd -T for bot
command: sshd -T -C user=bot command: sshd -T -C user=bot,addr=127.0.0.1,host=example.com
register: bot_effective register: bot_effective
- name: List effective configuration using sshd -T for sftponly - name: List effective configuration using sshd -T for sftponly
command: sshd -T -C user=sftponly command: sshd -T -C user=sftponly,addr=127.0.0.1,host=example.com
register: sftponly_effective register: sftponly_effective
- name: List effective configuration using sshd -T for root - name: List effective configuration using sshd -T for root
command: sshd -T -C user=root command: sshd -T -C user=root,addr=127.0.0.1,host=example.com
register: root_effective register: root_effective
- name: Print current configuration file - name: Print current configuration file
command: cat /etc/ssh/sshd_config slurp:
src: "{{ main_sshd_config }}"
register: config register: config
- name: Check the options are effective - name: Check the options are effective
@ -61,8 +72,8 @@
- name: Check the options are in configuration file - name: Check the options are in configuration file
assert: assert:
that: that:
- "'Match User xusers' in config.stdout" - "'Match User xusers' in config.content | b64decode"
- "'Match User bot' in config.stdout" - "'Match User bot' in config.content | b64decode"
- "'Match User sftponly' in config.stdout" - "'Match User sftponly' in config.content | b64decode"
- "'Match User root' in config.stdout" - "'Match User root' in config.content | b64decode"
tags: tests::verify tags: tests::verify

View file

@ -10,6 +10,7 @@
Banner: /etc/issue Banner: /etc/issue
Ciphers: aes256-gcm@openssh.com Ciphers: aes256-gcm@openssh.com
Subsystem: "sftp internal-sftp" Subsystem: "sftp internal-sftp"
sshd_config_file: /etc/ssh/sshd_config
- name: Verify the options are correctly set - name: Verify the options are correctly set
block: block:
@ -20,7 +21,8 @@
register: runtime register: runtime
- name: Print current configuration file - name: Print current configuration file
command: cat /etc/ssh/sshd_config slurp:
src: /etc/ssh/sshd_config
register: config register: config
- name: Check the options are effective - name: Check the options are effective
@ -35,8 +37,8 @@
- name: Check the options are in configuration file - name: Check the options are in configuration file
assert: assert:
that: that:
- "'AcceptEnv LANG' in config.stdout" - "'AcceptEnv LANG' in config.content | b64decode"
- "'Banner /etc/issue' in config.stdout" - "'Banner /etc/issue' in config.content | b64decode"
- "'Ciphers aes256-gcm@openssh.com' in config.stdout" - "'Ciphers aes256-gcm@openssh.com' in config.content | b64decode"
- "'Subsystem sftp internal-sftp' in config.stdout" - "'Subsystem sftp internal-sftp' in config.content | b64decode"
tags: tests::verify tags: tests::verify

View file

@ -14,16 +14,28 @@
- meta: flush_handlers - meta: flush_handlers
- name: Print current configuration file - name: Print current configuration file
command: cat /etc/sysconfig/sshd slurp:
src: /etc/sysconfig/sshd
register: config register: config
- name: Check the options are in configuration file - name: Check the crypto policies is overridden in RHEL 8
assert: assert:
that: that:
- "'CRYPTO_POLICY=' in config.stdout_lines" - "'CRYPTO_POLICY=' in config.content | b64decode"
- "'SSH_USE_STRONG_RNG=32' in config.stdout_lines"
# these are string variants in default configuration file # these are string variants in default configuration file
- "'# CRYPTO_POLICY=' not in config.stdout_lines" - "'# CRYPTO_POLICY=' not in config.content | b64decode"
- "'SSH_USE_STRONG_RNG=0' not in config.stdout_lines" when:
- "'# SSH_USE_STRONG_RNG=1' not in config.stdout_lines" - ansible_facts['os_family'] == "RedHat"
- ansible_facts['distribution_major_version'] == "8"
- name: Check the RNG options are in configuration file
assert:
that:
- "'SSH_USE_STRONG_RNG=32' in config.content | b64decode"
# these are string variants in default configuration file
- "'SSH_USE_STRONG_RNG=0' not in config.content | b64decode"
- "'# SSH_USE_STRONG_RNG=1' not in config.content | b64decode"
when:
- ansible_facts['os_family'] == "RedHat"
- ansible_facts['distribution'] != 'Fedora'
tags: tests::verify tags: tests::verify

View file

@ -1,10 +1,10 @@
--- ---
__sshd_config_mode: '0644' sshd_config_mode: '0644'
# sshd is not installed by yum / AIX toolbox for Linux. # sshd is not installed by yum / AIX toolbox for Linux.
# You'll need to manually install them using AIX Web Download Packs. # You'll need to manually install them using AIX Web Download Packs.
__sshd_packages: [] sshd_packages: []
__sshd_sftp_server: /usr/sbin/sftp-server sshd_sftp_server: /usr/sbin/sftp-server
__sshd_config_group: system sshd_config_group: system
__sshd_defaults: __sshd_defaults:
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"
__sshd_os_supported: yes __sshd_os_supported: yes

View file

@ -1,9 +1,9 @@
--- ---
__sshd_config_mode: '0644' sshd_config_mode: '0644'
__sshd_packages: sshd_packages:
- openssh - openssh
- openssh-server - openssh-server
__sshd_sftp_server: /usr/libexec/openssh/sftp-server sshd_sftp_server: /usr/libexec/openssh/sftp-server
__sshd_defaults: __sshd_defaults:
SyslogFacility: AUTHPRIV SyslogFacility: AUTHPRIV
PermitRootLogin: forced-commands-only PermitRootLogin: forced-commands-only

View file

@ -1,7 +1,7 @@
--- ---
__sshd_packages: sshd_packages:
- openssh - openssh
__sshd_sftp_server: /usr/lib/ssh/sftp-server sshd_sftp_server: /usr/lib/ssh/sftp-server
__sshd_defaults: __sshd_defaults:
AuthorizedKeysFile: .ssh/authorized_keys AuthorizedKeysFile: .ssh/authorized_keys
ChallengeResponseAuthentication: no ChallengeResponseAuthentication: no

View file

@ -1,8 +1,8 @@
--- ---
# There is no package manager in CoreOS # There is no package manager in CoreOS
__sshd_packages: [] sshd_packages: []
__sshd_service: sshd sshd_service: sshd
__sshd_sftp_server: internal-sftp sshd_sftp_server: internal-sftp
__sshd_defaults: __sshd_defaults:
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"
ClientAliveInterval: 180 ClientAliveInterval: 180

View file

@ -1,8 +1,8 @@
--- ---
__sshd_service: ssh sshd_service: ssh
__sshd_packages: sshd_packages:
- openssh-server - openssh-server
__sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
Port: 22 Port: 22
Protocol: 2 Protocol: 2

View file

@ -1,9 +1,9 @@
--- ---
__sshd_service: ssh sshd_service: ssh
__sshd_packages: sshd_packages:
- openssh-server - openssh-server
- openssh-sftp-server - openssh-sftp-server
__sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
Port: 22 Port: 22
Protocol: 2 Protocol: 2

View file

@ -1,9 +1,9 @@
--- ---
__sshd_service: ssh sshd_service: ssh
__sshd_packages: sshd_packages:
- openssh-server - openssh-server
- openssh-sftp-server - openssh-sftp-server
__sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
Port: 22 Port: 22
Protocol: 2 Protocol: 2

View file

@ -1,9 +1,9 @@
--- ---
__sshd_service: ssh sshd_service: ssh
__sshd_packages: sshd_packages:
- openssh-server - openssh-server
- openssh-sftp-server - openssh-sftp-server
__sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
Port: 22 Port: 22
Protocol: 2 Protocol: 2

View file

@ -1,11 +1,13 @@
--- ---
__sshd_packages: sshd_packages:
- openssh - openssh
- openssh-server - openssh-server
__sshd_sftp_server: /usr/libexec/openssh/sftp-server sshd_sftp_server: /usr/libexec/openssh/sftp-server
# Fedora 32 ships with drop-in directory support so we touch # Fedora 32 ships with drop-in directory support so we touch
# just included file with highest priority by default and have # just included file with highest priority by default and have
# empty defaults # empty defaults
__sshd_config_file: /etc/ssh/sshd_config.d/00-ansible_system_role.conf sshd_config_file: /etc/ssh/sshd_config.d/00-ansible_system_role.conf
__sshd_defaults: __sshd_defaults:
__sshd_os_supported: yes __sshd_os_supported: yes
sshd_hostkey_group: ssh_keys
sshd_hostkey_mode: "0640"

View file

@ -1,8 +1,8 @@
--- ---
__sshd_packages: sshd_packages:
- openssh - openssh
- 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: HostKey:
- /etc/ssh/ssh_host_rsa_key - /etc/ssh/ssh_host_rsa_key
@ -24,3 +24,5 @@ __sshd_defaults:
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"
__sshd_os_supported: yes __sshd_os_supported: yes
__sshd_sysconfig_supports_crypto_policy: true __sshd_sysconfig_supports_crypto_policy: true
sshd_hostkey_group: ssh_keys
sshd_hostkey_mode: "0640"

View file

@ -1,5 +1,5 @@
--- ---
__sshd_config_group: wheel sshd_config_group: wheel
__sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_sftp_server: /usr/libexec/sftp-server sshd_sftp_server: /usr/libexec/sftp-server
__sshd_os_supported: yes __sshd_os_supported: yes

View file

@ -1,19 +1,14 @@
--- ---
__sshd_packages: sshd_packages:
- net-misc/openssh - net-misc/openssh
__sshd_config_owner: root sshd_sftp_server: /usr/lib64/misc/sftp-server
__sshd_config_group: root
__sshd_config_mode: "0600"
__sshd_config_file: /etc/ssh/sshd_config
__sshd_sftp_server: /usr/lib64/misc/sftp-server
__sshd_binary: /usr/sbin/sshd
__sshd_defaults: __sshd_defaults:
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"
# Replace tcp keepalive with unspoofable keepalive # Replace tcp keepalive with unspoofable keepalive
TCPKeepAlive: no TCPKeepAlive: no
ClientAliveInterval: 300 ClientAliveInterval: 300
ClientAliveCountMax: 2 ClientAliveCountMax: 2
# Secure chipher and algorithm settings # Secure cipher and algorithm settings
HostKey: HostKey:
- /etc/ssh/ssh_host_ed25519_key - /etc/ssh/ssh_host_ed25519_key
- /etc/ssh/ssh_host_rsa_key - /etc/ssh/ssh_host_rsa_key

View file

@ -1,7 +1,7 @@
--- ---
__sshd_config_group: wheel sshd_config_group: wheel
__sshd_config_mode: "0600" sshd_config_mode: "0600"
__sshd_sftp_server: /usr/libexec/sftp-server sshd_sftp_server: /usr/libexec/sftp-server
__sshd_defaults: __sshd_defaults:
AuthorizedKeysFile: .ssh/authorized_keys AuthorizedKeysFile: .ssh/authorized_keys
Subsystem: "sftp {{ sshd_sftp_server }}" Subsystem: "sftp {{ sshd_sftp_server }}"

View file

@ -1,8 +1,8 @@
--- ---
__sshd_packages: sshd_packages:
- openssh - openssh
- openssh-server - openssh-server
__sshd_sftp_server: /usr/libexec/openssh/sftp-server sshd_sftp_server: /usr/libexec/openssh/sftp-server
__sshd_defaults: __sshd_defaults:
Protocol: 2 Protocol: 2
SyslogFacility: AUTHPRIV SyslogFacility: AUTHPRIV
@ -20,3 +20,5 @@ __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

@ -1,8 +1,8 @@
--- ---
__sshd_packages: sshd_packages:
- openssh - openssh
- 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: HostKey:
- /etc/ssh/ssh_host_rsa_key - /etc/ssh/ssh_host_rsa_key
@ -27,3 +27,5 @@ __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

@ -1,8 +1,8 @@
--- ---
__sshd_packages: sshd_packages:
- openssh - openssh
- 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: HostKey:
- /etc/ssh/ssh_host_rsa_key - /etc/ssh/ssh_host_rsa_key
@ -28,3 +28,5 @@ __sshd_defaults:
__sshd_os_supported: yes __sshd_os_supported: yes
__sshd_sysconfig_supports_use_strong_rng: true __sshd_sysconfig_supports_use_strong_rng: true
__sshd_sysconfig_supports_crypto_policy: true __sshd_sysconfig_supports_crypto_policy: true
sshd_hostkey_group: ssh_keys
sshd_hostkey_mode: "0640"

View file

@ -1,7 +1,7 @@
--- ---
__sshd_packages: sshd_packages:
- openssh - openssh
__sshd_sftp_server: /usr/lib/ssh/sftp-server sshd_sftp_server: /usr/lib/ssh/sftp-server
__sshd_defaults: __sshd_defaults:
HostKey: HostKey:
- /etc/ssh/ssh_host_rsa_key - /etc/ssh/ssh_host_rsa_key

View file

@ -1,8 +1,8 @@
--- ---
__sshd_service: ssh sshd_service: ssh
__sshd_packages: sshd_packages:
- openssh-server - openssh-server
__sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
Port: 22 Port: 22
Protocol: 2 Protocol: 2

View file

@ -1,9 +1,9 @@
--- ---
__sshd_service: ssh sshd_service: ssh
__sshd_packages: sshd_packages:
- openssh-server - openssh-server
- openssh-sftp-server - openssh-sftp-server
__sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
Port: 22 Port: 22
Protocol: 2 Protocol: 2

View file

@ -1,9 +1,9 @@
--- ---
__sshd_service: ssh sshd_service: ssh
__sshd_packages: sshd_packages:
- openssh-server - openssh-server
- openssh-sftp-server - openssh-sftp-server
__sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
Port: 22 Port: 22
Protocol: 2 Protocol: 2

View file

@ -1,9 +1,9 @@
--- ---
__sshd_service: ssh sshd_service: ssh
__sshd_packages: sshd_packages:
- openssh-server - openssh-server
- openssh-sftp-server - openssh-sftp-server
__sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
PasswordAuthentication: no PasswordAuthentication: no
ChallengeResponseAuthentication: no ChallengeResponseAuthentication: no

View file

@ -1,9 +1,9 @@
--- ---
__sshd_service: ssh sshd_service: ssh
__sshd_packages: sshd_packages:
- openssh-server - openssh-server
- openssh-sftp-server - openssh-sftp-server
__sshd_config_mode: "0644" sshd_config_mode: "0644"
__sshd_defaults: __sshd_defaults:
ChallengeResponseAuthentication: no ChallengeResponseAuthentication: no
UsePAM: yes UsePAM: yes

View file

@ -1,7 +1,7 @@
--- ---
__sshd_packages: sshd_packages:
- openssh - openssh
__sshd_sftp_server: /usr/lib/ssh/sftp-server sshd_sftp_server: /usr/lib/ssh/sftp-server
__sshd_defaults: __sshd_defaults:
AuthorizedKeysFile: .ssh/authorized_keys AuthorizedKeysFile: .ssh/authorized_keys
UsePAM: yes UsePAM: yes