Merge pull request #95 from corvus-migratorius/sshd-allow-lists
sshd allow lists
This commit is contained in:
@@ -12,3 +12,4 @@ exclude_paths:
|
|||||||
# ansible-lint thinks they're playbooks so gives errors, but they're not
|
# ansible-lint thinks they're playbooks so gives errors, but they're not
|
||||||
- roles/rustdesk/molecule/default/client-binary-existance.yml
|
- roles/rustdesk/molecule/default/client-binary-existance.yml
|
||||||
- roles/borg_server/molecule/default/secrets.yaml
|
- roles/borg_server/molecule/default/secrets.yaml
|
||||||
|
- roles/sshd/molecule/default/mkuser.yml
|
||||||
|
|||||||
@@ -3,3 +3,4 @@
|
|||||||
hosts: all
|
hosts: all
|
||||||
roles:
|
roles:
|
||||||
- role: "genlab.common.sshd"
|
- role: "genlab.common.sshd"
|
||||||
|
sshd_allow_users: "testusr"
|
||||||
|
|||||||
28
roles/sshd/molecule/default/mkuser.yml
Normal file
28
roles/sshd/molecule/default/mkuser.yml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
- name: "Create user account: {{ username }}"
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ username }}"
|
||||||
|
create_home: true
|
||||||
|
shell: /bin/bash
|
||||||
|
|
||||||
|
- name: "Create .ssh directory: {{ username }}"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/home/{{ username }}/.ssh/"
|
||||||
|
state: directory
|
||||||
|
mode: '0700'
|
||||||
|
owner: "{{ username }}"
|
||||||
|
group: "{{ username }}"
|
||||||
|
|
||||||
|
- name: "Generate ssh keys: {{ username }}"
|
||||||
|
community.crypto.openssh_keypair:
|
||||||
|
path: "/home/{{ username }}/.ssh/id_rsa"
|
||||||
|
owner: "{{ username }}"
|
||||||
|
group: "{{ username }}"
|
||||||
|
mode: '0600'
|
||||||
|
register: sshd_key_result
|
||||||
|
|
||||||
|
- name: "Put public key to into the authorized_keys: {{ username }}"
|
||||||
|
ansible.posix.authorized_key:
|
||||||
|
user: "{{ username }}"
|
||||||
|
key: "{{ sshd_key_result.public_key }}"
|
||||||
|
state: present
|
||||||
@@ -5,20 +5,36 @@
|
|||||||
gather_facts: false
|
gather_facts: false
|
||||||
any_errors_fatal: true
|
any_errors_fatal: true
|
||||||
|
|
||||||
tasks:
|
pre_tasks:
|
||||||
- name: Gather service facts
|
- name: Gather service facts
|
||||||
ansible.builtin.service_facts:
|
ansible.builtin.service_facts:
|
||||||
|
|
||||||
|
- name: Set up users and keys for testing
|
||||||
|
loop:
|
||||||
|
- testusr
|
||||||
|
- testusr_notallowed
|
||||||
|
loop_control:
|
||||||
|
loop_var: username
|
||||||
|
ansible.builtin.include_tasks: mkuser.yml
|
||||||
|
|
||||||
|
tasks:
|
||||||
- name: Ensure sshd is running
|
- name: Ensure sshd is running
|
||||||
|
vars:
|
||||||
|
sshd_state: "{{ ansible_facts.services['ssh.service'].state | default('unknown') }}"
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that: sshd_state == 'running'
|
||||||
- ansible_facts.services['ssh.service'].state == 'running'
|
success_msg: "OK, sshd state: '{{ sshd_state }}'"
|
||||||
|
fail_msg: "FAIL, sshd state: '{{ sshd_state }}'"
|
||||||
|
|
||||||
- name: Ensure sshd_config syntax is OK
|
- name: Ensure sshd_config syntax is OK
|
||||||
ansible.builtin.command: sshd -t -f /etc/ssh/sshd_config
|
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: sshd -t -f /etc/ssh/sshd_config
|
||||||
|
|
||||||
- name: Ensure main parameteres are applied
|
- name: Ensure main parameteres are applied
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
changed_when: false
|
||||||
ansible.builtin.shell: |
|
ansible.builtin.shell: |
|
||||||
set -o pipefail ;
|
set -o pipefail ;
|
||||||
sshd -T | egrep -i '
|
sshd -T | egrep -i '
|
||||||
@@ -27,50 +43,45 @@
|
|||||||
^passwordauthentication no|
|
^passwordauthentication no|
|
||||||
^pubkeyauthentication yes
|
^pubkeyauthentication yes
|
||||||
'
|
'
|
||||||
args:
|
|
||||||
executable: /bin/bash
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Get sshd_config stats
|
- name: Get sshd_config stats
|
||||||
|
register: sshd_conf
|
||||||
ansible.builtin.stat:
|
ansible.builtin.stat:
|
||||||
path: /etc/ssh/sshd_config
|
path: /etc/ssh/sshd_config
|
||||||
register: sshd_conf
|
|
||||||
|
|
||||||
- name: Ensure sshd_config file is secure
|
- name: Ensure sshd_config file is secure
|
||||||
|
vars:
|
||||||
|
uid: "{{ sshd_conf.stat.uid }}"
|
||||||
|
gid: "{{ sshd_conf.stat.gid }}"
|
||||||
|
mode: "{{ sshd_conf.stat.mode }}"
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- sshd_conf.stat.uid == 0
|
- uid == '0'
|
||||||
- sshd_conf.stat.gid == 0
|
- gid == '0'
|
||||||
- sshd_conf.stat.mode == '0600'
|
- mode == '0600'
|
||||||
|
success_msg: "OK, sshd_config file uid: '{{ uid }}', gid: '{{ gid }}', mode: '{{ mode }}'"
|
||||||
|
fail_msg: "FAIL, sshd_config file uid: '{{ uid }}', gid: '{{ gid }}', mode: '{{ mode }}'"
|
||||||
|
|
||||||
- name: Create test user
|
- name: Test ssh connection with an allowed 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
|
changed_when: false
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >-
|
||||||
|
ssh
|
||||||
|
-o StrictHostKeyChecking=no
|
||||||
|
-o UserKnownHostsFile=/dev/null
|
||||||
|
-i /home/testusr/.ssh/id_rsa
|
||||||
|
testusr@localhost
|
||||||
|
hostname
|
||||||
|
|
||||||
|
- name: Test ssh connection with a disallowed user
|
||||||
|
register: sshd_verify_conn_result
|
||||||
|
changed_when: false
|
||||||
|
failed_when: sshd_verify_conn_result.rc == 0
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >-
|
||||||
|
ssh
|
||||||
|
-o StrictHostKeyChecking=no
|
||||||
|
-o UserKnownHostsFile=/dev/null
|
||||||
|
-i /home/testusrnotallowed/.ssh/id_rsa
|
||||||
|
testusrnotallowed@localhost
|
||||||
|
hostname
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
- name: "Configure additional restrictions"
|
- name: "Configure additional restrictions"
|
||||||
ansible.builtin.include_tasks: "restrictions.yml"
|
ansible.builtin.include_tasks: "restrictions.yml"
|
||||||
|
|
||||||
|
- name: "Configure whitelists"
|
||||||
|
ansible.builtin.include_tasks: "whitelists.yml"
|
||||||
|
|
||||||
- name: "Log at VERBOSE level"
|
- name: "Log at VERBOSE level"
|
||||||
notify: Restart sshd
|
notify: Restart sshd
|
||||||
ansible.builtin.lineinfile:
|
ansible.builtin.lineinfile:
|
||||||
|
|||||||
18
roles/sshd/tasks/whitelists.yml
Normal file
18
roles/sshd/tasks/whitelists.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
- name: "Configure AllowUsers"
|
||||||
|
when: sshd_allow_users is defined
|
||||||
|
notify: Restart sshd
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: '^#?\s*AllowUsers\s+'
|
||||||
|
line: "AllowUsers {{ sshd_allow_users }}"
|
||||||
|
validate: sshd -f %s -t
|
||||||
|
|
||||||
|
- name: "Configure AllowGroups"
|
||||||
|
when: sshd_allow_groups is defined
|
||||||
|
notify: Restart sshd
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
regexp: '^#?\s*AllowGroups\s+'
|
||||||
|
line: "AllowGroups {{ sshd_allow_groups }}"
|
||||||
|
validate: sshd -f %s -t
|
||||||
Reference in New Issue
Block a user