Files
KNELIAC/roles/security_ssh/tasks/main.yml
T
mrcharles cefe2f7cfa 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>
2026-07-30 12:16:13 -05:00

92 lines
2.7 KiB
YAML

---
# 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