Initial commit
This commit is contained in:
14
tasks/color-shell.yml
Normal file
14
tasks/color-shell.yml
Normal 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
18
tasks/custom-fact.yml
Normal 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
8
tasks/dell-firmware.yml
Normal 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
18
tasks/edit-journald.yml
Normal 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
37
tasks/main.yml
Normal 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
24
tasks/motd.yml
Normal 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
23
tasks/prereq-packages.yml
Normal 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
17
tasks/set-hostname.yml
Normal 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
15
tasks/ssh-config.yml
Normal 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
7
tasks/sudoers.yml
Normal 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
58
tasks/tmp-nonexec.yml
Normal 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
29
tasks/unpriv-user.yml
Normal 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
|
||||
Reference in New Issue
Block a user