Initial commit

This commit is contained in:
waal70
2024-10-26 16:23:45 +02:00
commit b00d31c48d
22 changed files with 475 additions and 0 deletions

14
tasks/color-shell.yml Normal file
View File

@@ -0,0 +1,14 @@
---
# Note the use of "ansible_remote_tmp" - to prevent WARNINGS because of becoming an unprivileged user
- name: Force colors in .bashrc
ansible.builtin.lineinfile:
path: "{{ interactive_home }}/.bashrc"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: present
with_items:
- { regexp: "^#?force_color_prompt", line: force_color_prompt=yes }
become: true
become_user: "{{ interactive_user }}"
vars:
ansible_remote_tmp: /tmp

18
tasks/custom-fact.yml Normal file
View File

@@ -0,0 +1,18 @@
---
- name: Create directory for ansible custom facts
ansible.builtin.file:
state: directory
recurse: true
path: /etc/ansible/facts.d
- name: Install custom CPU fact
ansible.builtin.template:
src: etc/ansible/facts.d/cpu_info.fact
dest: /etc/ansible/facts.d
owner: "{{ ansible_user_id }}"
group: "{{ ansible_user_id }}"
mode: "0777"
- name: Re-read facts after adding custom fact
ansible.builtin.setup:
filter: ansible_local

8
tasks/dell-firmware.yml Normal file
View File

@@ -0,0 +1,8 @@
---
- name: Install Dell firmware
ansible.builtin.apt:
pkg:
- firmware-realtek
- firmware-misc-nonfree
state: present
when: "'proxmox_servers' not in group_names"

18
tasks/edit-journald.yml Normal file
View File

@@ -0,0 +1,18 @@
---
- name: Edit journald.conf
ansible.builtin.lineinfile:
path: /etc/systemd/journald.conf
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: "{{ item.state | default('present') }}"
with_items:
- { regexp: "^#?Storage", line: Storage=volatile }
- { regexp: "^#?ForwardToSyslog", line: ForwardToSyslog=no }
- { regexp: "^#?SystemMaxUse", line: SystemMaxUse=50M }
notify: Restart systemd-journald
# A succesful vacuum does impact log size, but is not considered a change
- name: Vacuum journalctl before
ansible.builtin.command: journalctl --vacuum-size=10M
register: vacuumresult
changed_when: false

37
tasks/main.yml Normal file
View File

@@ -0,0 +1,37 @@
---
# file: common/tasks/main.yml
- name: Ensure required packages are present on systems
ansible.builtin.import_tasks: prereq-packages.yml
- name: Make /tmp non-executable
ansible.builtin.import_tasks: tmp-nonexec.yml
- name: Import tasks to ensure creation of unprivileged user
ansible.builtin.import_tasks: unpriv-user.yml
- name: Import custom fact setting
ansible.builtin.import_tasks: custom-fact.yml
- name: Import color-shell tasks for the common-role
ansible.builtin.import_tasks: color-shell.yml
- name: Firmware block for Dell servers
when: "'Dell' in ansible_board_vendor"
block:
- name: Import firmware tasks for Dell-based servers
ansible.builtin.import_tasks: dell-firmware.yml
- name: Import journald tasks for the common-role
ansible.builtin.import_tasks: edit-journald.yml
- name: Import hostname tasks for the common-role
ansible.builtin.import_tasks: set-hostname.yml
- name: Import sudoers tasks for the common-role
ansible.builtin.import_tasks: sudoers.yml
- name: Set the custom message of the day (motd)
ansible.builtin.import_tasks: motd.yml
- name: Perform SSH daemon hardening
ansible.builtin.import_tasks: ssh-config.yml

24
tasks/motd.yml Normal file
View File

@@ -0,0 +1,24 @@
---
- name: Prepare a custom motd, but do not affect 'proxmox_servers'
when: "'proxmox_servers' not in group_names"
block:
- name: Set a custom motd for all Debian-based systems # noqa: deprecated-bare-vars
ansible.builtin.template:
src: "{{ item.src }}"
dest: "/etc/update-motd.d/{{ item.path }}"
owner: "{{ ansible_user_id }}"
group: "{{ ansible_user_id }}"
mode: "0777"
with_community.general.filetree:
- templates/etc/update-motd.d/
when: item.state == "file"
- name: Check for existence of motd
ansible.builtin.stat:
path: /etc/motd
register: motd_file
- name: Backup current motd
ansible.builtin.command: mv /etc/motd /etc/motd.bak
when: motd_file.stat.exists
changed_when: motd_file.stat.exists

23
tasks/prereq-packages.yml Normal file
View File

@@ -0,0 +1,23 @@
---
- name: Stage packages that are pre-requisites
ansible.builtin.set_fact:
_common_install_packages:
- python3-debian
- python3-requests
- sudo
- name: Update all packages if needed
ansible.builtin.apt:
update_cache: true
cache_valid_time: 86400
upgrade: full
autoclean: true
autoremove: true
timeout: 600 # on slow raspberries, updating may take a long time
- name: Install pre-requisite packages
ansible.builtin.apt:
update_cache: true
cache_valid_time: 86400
name: "{{ _common_install_packages }}"
state: present

17
tasks/set-hostname.yml Normal file
View File

@@ -0,0 +1,17 @@
---
- name: Set the hostname
ansible.builtin.hostname:
name: "{{ inventory_hostname }}"
- name: Replace double home with hostname (if present)
ansible.builtin.replace:
path: /etc/hosts
regexp: 127\.0\.1\.1
replace: "{{ ansible_host }} {{ inventory_hostname }}"
- name: Ensure at least one full hostname entry is present
ansible.builtin.lineinfile:
path: /etc/hosts
regexp: "{{ ansible_host }}.*{{ inventory_hostname }}"
line: "{{ ansible_host }} {{ inventory_hostname }}"
state: present

15
tasks/ssh-config.yml Normal file
View File

@@ -0,0 +1,15 @@
---
- name: Set the appropriate options in sshd_config file
ansible.builtin.lineinfile:
path: "{{ sshd_config_file }}"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: present
with_items:
- { regexp: "^#?PermitRootLogin", line: "PermitRootLogin no" }
- { regexp: "^#?PubkeyAuthentication", line: "PubkeyAuthentication yes" }
- { regexp: "^#?PubkeyAuthOptions", line: "PubkeyAuthOptions verify-required" } # to enable hardware token
- { regexp: "^#?PasswordAuthentication", line: "PasswordAuthentication no" }
- { regexp: "^#?KbdInteractiveAuthentication", line: "KbdInteractiveAuthentication no" }
- { regexp: "^#?UsePAM", line: "UsePAM yes" } # If no, ansible (passwordless) will not be able to perform SSH
notify: Restart sshd

7
tasks/sudoers.yml Normal file
View File

@@ -0,0 +1,7 @@
---
- name: Edit sudoers for passwordless sudo
ansible.builtin.lineinfile:
path: /etc/sudoers
regexp: ^%sudo
line: "%sudo ALL=(ALL:ALL) NOPASSWD: ALL"
state: present

58
tasks/tmp-nonexec.yml Normal file
View File

@@ -0,0 +1,58 @@
---
# These tasks will set nonexec on /tmp
# But only if /tmp is not already nonexec
# Follows: https://waal70blog.wordpress.com/2014/08/08/debian-server-hardening-make-tmp-non-executable/
- name: Get existence of tmpfs file, which resides in /var
ansible.builtin.stat:
path: /var/tmpfs
register: sttmp
- name: Block to create, mount and bind tmpfs
when: not sttmp.stat.exists
block:
- name: Create file to hold tmp
community.general.filesize:
path: /var/tmpfs
size: 1G
owner: root
group: root
- name: Initialize a ext3 filesystem in this file
community.general.filesystem:
dev: /var/tmpfs
fstype: ext3
opts: "-j"
state: present
- name: Move old tmp out of the way
ansible.builtin.command:
cmd: mv /tmp /old_tmp
failed_when: "{{ sttmp.stat.exists }}"
changed_when: true
- name: Make the new file a permanent mount in fstab
ansible.posix.mount:
path: /tmp
src: /var/tmpfs
opts: "loop,nosuid,noexec,rw"
state: mounted
fstype: ext3
- name: Move the old stuff back into the new mountpoint
ansible.builtin.command:
cmd: mv /old_tmp/* /tmp/
failed_when: "{{ sttmp.stat.exists }}"
changed_when: true
- name: Ensure no more /old_tmp
ansible.builtin.file:
path: /old_tmp
state: absent
- name: Make tmp world writeable
ansible.builtin.file:
path: /tmp
state: directory
owner: root
group: root
mode: '1777'

29
tasks/unpriv-user.yml Normal file
View File

@@ -0,0 +1,29 @@
---
- name: Ensure that unprivileged user is present
ansible.builtin.user:
name: "{{ interactive_user }}"
shell: /bin/bash
home: "{{ interactive_home }}"
password: "{{ interactive_password }}"
groups: sudo
create_home: true
skeleton: /etc/skel
append: true
- name: Set the primary key for the unprivileged user, removing any others
ansible.posix.authorized_key:
user: "{{ interactive_user }}"
key: "{{ lookup('file', '../home/ssh-keys/{{ interactive_user }}/{{ interactive_user }}-yubi-1.pub') }}"
state: present
exclusive: true
- name: Set the secondary key for the unprivileged user
ansible.posix.authorized_key:
user: "{{ interactive_user }}"
key: "{{ lookup('file', '../home/ssh-keys/{{ interactive_user }}/{{ interactive_user }}-yubi-2.pub') }}"
state: present
- name: Install required package to become unprivileged users
ansible.builtin.apt:
name: acl
state: present