feat(security): add SSH hardening role
Port Modules/Security/secharden-ssh.sh. Deploys: - Authorized keys for root, localuser, subodev (conditional on existence) - Hardened /etc/ssh/sshd_config (skipped on dev workstations) - ssh-audit hardening drop-in for algorithm restrictions (skipped on Ubuntu where it breaks openssh-server) - Lockdown of sshd_config.d directory permissions SSH service is validated (sshd -t) before restart. 🤖 Generated with [Crush](https://github.com/charmassociates/crush) Assisted-by: GLM-5 via Crush <crush@charm.land>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
---
|
||||
# SSH hardening — port of Modules/Security/secharden-ssh.sh.
|
||||
|
||||
# Per-user authorized_keys. The legacy script wrote localuser's keys into both
|
||||
# localuser and subodev; replicate that mapping here. Deployed conditionally
|
||||
# based on whether each user actually exists (legacy LOCALUSER_CHECK / SUBODEV_CHECK).
|
||||
- name: Ensure root .ssh directory exists
|
||||
ansible.builtin.file:
|
||||
path: /root/.ssh
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0700"
|
||||
|
||||
- name: Ensure localuser .ssh directory exists (if user exists)
|
||||
ansible.builtin.file:
|
||||
path: /home/localuser/.ssh
|
||||
state: directory
|
||||
owner: localuser
|
||||
group: localuser
|
||||
mode: "0700"
|
||||
when: localuser_exists | bool
|
||||
|
||||
- name: Ensure subodev .ssh directory exists (if user exists)
|
||||
ansible.builtin.file:
|
||||
path: /home/subodev/.ssh
|
||||
state: directory
|
||||
owner: subodev
|
||||
group: subodev
|
||||
mode: "0700"
|
||||
when: subodev_exists | bool
|
||||
|
||||
- name: Deploy root authorized_keys
|
||||
ansible.builtin.copy:
|
||||
src: authorized_keys/root
|
||||
dest: /root/.ssh/authorized_keys
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0400"
|
||||
|
||||
- name: Deploy localuser authorized_keys (if user exists)
|
||||
ansible.builtin.copy:
|
||||
src: authorized_keys/localuser
|
||||
dest: /home/localuser/.ssh/authorized_keys
|
||||
owner: localuser
|
||||
group: localuser
|
||||
mode: "0400"
|
||||
when: localuser_exists | bool
|
||||
|
||||
- name: Deploy subodev authorized_keys (same keys as localuser, if user exists)
|
||||
ansible.builtin.copy:
|
||||
src: authorized_keys/localuser
|
||||
dest: /home/subodev/.ssh/authorized_keys
|
||||
owner: subodev
|
||||
group: subodev
|
||||
mode: "0400"
|
||||
when: subodev_exists | bool
|
||||
|
||||
# sshd_config — skipped on dev workstations (matches legacy DEV_WORKSTATION_CHECK).
|
||||
# Uses the is_dev_workstation fact set by the preflight role based on the
|
||||
# 'dev_workstations' inventory group.
|
||||
- name: Deploy hardened /etc/ssh/sshd_config (non-dev hosts)
|
||||
ansible.builtin.copy:
|
||||
src: configs/sshd_config
|
||||
dest: /etc/ssh/sshd_config
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
backup: true
|
||||
when: not (is_dev_workstation | bool)
|
||||
notify: Validate and restart sshd
|
||||
|
||||
# ssh-audit hardening drop-in — breaks OpenSSH server on Ubuntu, so the legacy
|
||||
# script skipped Ubuntu hosts. Replicate that guard.
|
||||
- name: Deploy ssh-audit hardening drop-in (non-Ubuntu only)
|
||||
ansible.builtin.copy:
|
||||
src: configs/ssh-audit-hardening.conf
|
||||
dest: /etc/ssh/sshd_config.d/ssh-audit_hardening.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
backup: true
|
||||
when: not (is_ubuntu | bool)
|
||||
notify: Validate and restart sshd
|
||||
|
||||
- name: Lock down sshd_config.d drop-in permissions
|
||||
ansible.builtin.file:
|
||||
path: /etc/ssh/sshd_config.d
|
||||
mode: "0700"
|
||||
owner: root
|
||||
group: root
|
||||
Reference in New Issue
Block a user