52bb82f900
Imports backup.yml from setup_linux.yml so the backup play is reachable from the umbrella playbook via --tags backup. Also adds a backup_hosts entry for portainer1-jim.im.lab (5GB, /data/compose). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
110 lines
2.7 KiB
YAML
110 lines
2.7 KiB
YAML
---
|
|
- name: Baseline user setup
|
|
hosts: all
|
|
become: true
|
|
tags: users
|
|
|
|
tasks:
|
|
|
|
- name: Pick sudo group per distro
|
|
set_fact:
|
|
sudo_group: >-
|
|
{{ 'wheel'
|
|
if ansible_facts.os_family in
|
|
['RedHat','Rocky','AlmaLinux','Fedora','OracleLinux','Suse']
|
|
else 'sudo' }}
|
|
|
|
- name: Ensure user exists
|
|
ansible.builtin.user:
|
|
name: "{{ item.name }}"
|
|
shell: "{{ item.shell }}"
|
|
groups: "{{ sudo_group }}"
|
|
append: true
|
|
create_home: true
|
|
loop: "{{ users }}"
|
|
|
|
- name: Enforce authorized SSH keys
|
|
ansible.builtin.authorized_key:
|
|
user: "{{ item.name }}"
|
|
key: "{{ item.ssh_keys | join('\n') }}"
|
|
exclusive: true
|
|
loop: "{{ users }}"
|
|
|
|
- name: Grant passwordless sudo
|
|
ansible.builtin.copy:
|
|
dest: "/etc/sudoers.d/{{ item.name }}"
|
|
mode: '0440'
|
|
content: "{{ item.name }} ALL=(ALL) NOPASSWD:ALL\n"
|
|
validate: 'visudo -cf %s'
|
|
loop: "{{ users }}"
|
|
when: item.sudo_nopasswd
|
|
|
|
# ==============================
|
|
# SECOND PLAY: SSH HARDENING
|
|
# ==============================
|
|
|
|
- name: SSH Hardening
|
|
hosts: all
|
|
become: true
|
|
tags: never,hardening
|
|
|
|
tasks:
|
|
|
|
- name: Detect if system is Proxmox
|
|
ansible.builtin.stat:
|
|
path: /usr/bin/pveversion
|
|
register: proxmox_check
|
|
|
|
- name: Ensure sshd_config.d directory exists
|
|
ansible.builtin.file:
|
|
path: /etc/ssh/sshd_config.d
|
|
state: directory
|
|
|
|
- name: Deploy SSH hardening config
|
|
ansible.builtin.copy:
|
|
dest: /etc/ssh/sshd_config.d/99-ansible-hardening.conf
|
|
mode: '0644'
|
|
content: |
|
|
PasswordAuthentication no
|
|
ChallengeResponseAuthentication no
|
|
PubkeyAuthentication yes
|
|
AuthenticationMethods publickey
|
|
UsePAM yes
|
|
|
|
{% if not proxmox_check.stat.exists %}
|
|
PermitRootLogin no
|
|
{% else %}
|
|
PermitRootLogin prohibit-password
|
|
{% endif %}
|
|
validate: 'sshd -t -f %s'
|
|
notify: Restart SSH
|
|
|
|
handlers:
|
|
- name: Restart SSH
|
|
ansible.builtin.service:
|
|
name: "{{ 'sshd'
|
|
if ansible_facts.os_family in
|
|
['RedHat','Rocky','AlmaLinux','Fedora','OracleLinux','Suse']
|
|
else 'ssh' }}"
|
|
state: restarted
|
|
|
|
# ==============================
|
|
# THIRD PLAY: HOSTNAME
|
|
# ==============================
|
|
|
|
- name: Set hostname from inventory
|
|
hosts: all
|
|
become: true
|
|
tags: never,hostname
|
|
|
|
tasks:
|
|
|
|
- name: Set system hostname to inventory_hostname
|
|
ansible.builtin.hostname:
|
|
name: "{{ inventory_hostname }}"
|
|
|
|
# ==============================
|
|
# FOURTH PLAY: BACKUP
|
|
# ==============================
|
|
|
|
- import_playbook: backup.yml |