mirror of
https://github.com/fscotto/infra.git
synced 2026-09-27 19:03:47 +00:00
168 lines
5.8 KiB
YAML
168 lines
5.8 KiB
YAML
---
|
|
- name: Reject incomplete Atlas account configuration
|
|
tags: [atlas, services]
|
|
ansible.builtin.assert:
|
|
that:
|
|
- atlas_admin_username != 'CHANGEME_ATLAS_ADMIN'
|
|
- (atlas_admin_ssh_keys | default([])) | length > 0
|
|
- atlas_admin_password_hash not in ['', '!', '*']
|
|
- atlas_ssh_allow_tcp_forwarding in ['no', 'yes', 'local', 'remote', 'all']
|
|
- "'wheel' not in atlas_immich_supplementary_groups"
|
|
fail_msg: >-
|
|
Define atlas_admin_username, vault_atlas_authorized_ssh_keys and
|
|
vault_atlas_admin_password_hash before applying the Atlas profile.
|
|
no_log: true
|
|
|
|
- name: Create Atlas administrator group
|
|
tags: [atlas, services]
|
|
ansible.builtin.group:
|
|
name: "{{ atlas_admin_group }}"
|
|
gid: "{{ atlas_admin_gid }}"
|
|
state: present
|
|
|
|
- name: Create Atlas administrator account
|
|
tags: [atlas, services]
|
|
ansible.builtin.user:
|
|
name: "{{ atlas_admin_username }}"
|
|
uid: "{{ atlas_admin_uid }}"
|
|
group: "{{ atlas_admin_group }}"
|
|
home: "{{ atlas_admin_home }}"
|
|
shell: /bin/bash
|
|
password: "{{ atlas_admin_password_hash }}"
|
|
create_home: true
|
|
state: present
|
|
no_log: true
|
|
|
|
- name: Create Immich primary group
|
|
tags: [atlas, accounts, containers, immich]
|
|
ansible.builtin.group:
|
|
name: "{{ atlas_immich_group }}"
|
|
gid: "{{ atlas_immich_gid }}"
|
|
state: present
|
|
|
|
- name: Ensure Immich hardware-access groups exist
|
|
tags: [atlas, accounts, containers, immich]
|
|
ansible.builtin.group:
|
|
name: "{{ item }}"
|
|
state: present
|
|
loop: "{{ atlas_immich_supplementary_groups }}"
|
|
loop_control:
|
|
label: "{{ item }}"
|
|
|
|
- name: Create unprivileged Immich account
|
|
tags: [atlas, accounts, containers, immich]
|
|
ansible.builtin.user:
|
|
name: "{{ atlas_immich_username }}"
|
|
uid: "{{ atlas_immich_uid }}"
|
|
group: "{{ atlas_immich_group }}"
|
|
groups: "{{ atlas_immich_supplementary_groups }}"
|
|
append: false
|
|
home: /nonexistent
|
|
create_home: false
|
|
shell: /sbin/nologin
|
|
system: true
|
|
state: present
|
|
|
|
- name: Read Immich hardware-access group IDs
|
|
tags: [atlas, accounts, containers, immich]
|
|
ansible.builtin.getent:
|
|
database: group
|
|
|
|
- name: Grant Atlas administrator passwordless sudo
|
|
tags: [atlas, services]
|
|
ansible.builtin.copy:
|
|
content: "{{ atlas_admin_username }} ALL=(ALL) NOPASSWD: ALL\n"
|
|
dest: "/etc/sudoers.d/{{ atlas_admin_username }}"
|
|
owner: root
|
|
group: root
|
|
mode: "0440"
|
|
validate: "visudo -cf %s"
|
|
|
|
- name: Manage Atlas administrator authorized SSH keys exclusively
|
|
tags: [atlas, services]
|
|
ansible.posix.authorized_key:
|
|
user: "{{ atlas_admin_username }}"
|
|
key: "{{ atlas_admin_ssh_keys | join('\n') }}"
|
|
state: present
|
|
exclusive: true
|
|
|
|
- name: Check whether the Atlas SSH host key exists
|
|
tags: [atlas, services]
|
|
ansible.builtin.stat:
|
|
path: /etc/ssh/ssh_host_ed25519_key
|
|
register: atlas_ssh_host_ed25519_key
|
|
|
|
- name: Generate missing Atlas SSH host keys
|
|
tags: [atlas, services]
|
|
ansible.builtin.command:
|
|
argv:
|
|
- ssh-keygen
|
|
- -A
|
|
changed_when: true
|
|
when: not atlas_ssh_host_ed25519_key.stat.exists
|
|
|
|
- name: Ensure Atlas SSH configuration drop-in directory exists
|
|
tags: [atlas, services]
|
|
ansible.builtin.file:
|
|
path: /etc/ssh/sshd_config.d
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: "0755"
|
|
|
|
- name: Ensure Atlas SSH drop-ins are loaded before other settings
|
|
tags: [atlas, services]
|
|
ansible.builtin.lineinfile:
|
|
path: /etc/ssh/sshd_config
|
|
regexp: '^\s*Include\s+/etc/ssh/sshd_config\.d/\*\.conf\s*$'
|
|
line: Include /etc/ssh/sshd_config.d/*.conf
|
|
insertbefore: BOF
|
|
state: present
|
|
validate: "sshd -t -f %s"
|
|
|
|
- name: Render Atlas SSH hardening drop-in
|
|
tags: [atlas, services]
|
|
ansible.builtin.template:
|
|
src: 00-atlas-hardening.conf.j2
|
|
dest: /etc/ssh/sshd_config.d/00-atlas-hardening.conf
|
|
owner: root
|
|
group: root
|
|
mode: "0600"
|
|
notify: Reload SSH service
|
|
|
|
- name: Read effective Atlas SSH daemon configuration
|
|
tags: [atlas, services]
|
|
ansible.builtin.command:
|
|
argv:
|
|
- sshd
|
|
- -T
|
|
- -C
|
|
- "user={{ atlas_admin_username }},host=atlas,addr=127.0.0.1"
|
|
register: atlas_sshd_effective_configuration
|
|
changed_when: false
|
|
when: not ansible_check_mode
|
|
|
|
- name: Verify effective Atlas SSH hardening
|
|
tags: [atlas, services]
|
|
ansible.builtin.assert:
|
|
that:
|
|
- "'permitrootlogin no' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'pubkeyauthentication yes' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'passwordauthentication no' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'kbdinteractiveauthentication no' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'authenticationmethods publickey' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'x11forwarding no' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "('allowtcpforwarding ' ~ atlas_ssh_allow_tcp_forwarding) in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'allowagentforwarding no' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'gatewayports no' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'permittunnel no' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'permituserenvironment no' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'maxauthtries 3' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'logingracetime 30' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'clientaliveinterval 300' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'clientalivecountmax 2' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "'loglevel VERBOSE' in atlas_sshd_effective_configuration.stdout_lines"
|
|
- "('allowusers ' ~ atlas_admin_username) in atlas_sshd_effective_configuration.stdout_lines"
|
|
fail_msg: The effective Atlas SSH configuration does not match the required hardening.
|
|
when: not ansible_check_mode
|