Initial commit
This commit is contained in:
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
# MIT License
|
||||
|
||||
Copyright (c) 2024 André
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
30
README.md
Normal file
30
README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
Common
|
||||
=========
|
||||
|
||||
This is the role that sets some defaults. You might say, a bootstrap role.
|
||||
|
||||
The role will check the basic requirements. It will then determine the correct
|
||||
course of action (mainly, "proper" Debian or Raspberry Pi debian)
|
||||
|
||||
This role should be safe to run on all machines, always
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
It requires a Debian instance, set-up by the preseed.
|
||||
It will also accept a default Raspbian OS.
|
||||
It also presumes a live sudo package.
|
||||
Make sure at least the SSH-key for user ansible is set.
|
||||
|
||||
If you have proxmox-ve servers, for which Dell firmware should NOT be installed,
|
||||
be sure to have them in a group called 'proxmox_servers'
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
MIT
|
||||
20
handlers/main.yml
Normal file
20
handlers/main.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
# file: common/handlers/main.yml
|
||||
- name: Update packages cache
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
|
||||
- name: Restart systemd-journald
|
||||
ansible.builtin.systemd:
|
||||
name: systemd-journald
|
||||
state: restarted
|
||||
|
||||
- name: Restart rrdcached
|
||||
ansible.builtin.systemd_service:
|
||||
name: rrdcached
|
||||
state: restarted
|
||||
|
||||
- name: Restart sshd
|
||||
ansible.builtin.systemd_service:
|
||||
name: sshd
|
||||
state: restarted
|
||||
21
meta/main.yml
Normal file
21
meta/main.yml
Normal file
@@ -0,0 +1,21 @@
|
||||
galaxy_info: # noqa: role-name
|
||||
author: waal70 (Andre)
|
||||
description: Role to set my preferred details on a Debian fresh install
|
||||
company: waal70
|
||||
platforms:
|
||||
- name: Debian
|
||||
versions:
|
||||
- bookworm
|
||||
|
||||
license: MIT
|
||||
|
||||
min_ansible_version: "2.1"
|
||||
|
||||
galaxy_tags: [debian,
|
||||
bootstrap,
|
||||
default
|
||||
]
|
||||
|
||||
dependencies: []
|
||||
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
|
||||
# if you add dependencies to this list.
|
||||
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
|
||||
17
templates/etc/ansible/facts.d/cpu_info.fact
Executable file
17
templates/etc/ansible/facts.d/cpu_info.fact
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
hostname=$(hostname);
|
||||
operating_system=$(hostnamectl | grep "Operating System" | cut -d ' ' -f3-);
|
||||
architecture=$(arch);
|
||||
processor_model=$(cat /proc/cpuinfo | grep -E '^(model name|Model)\s*:' | sort -u | cut -d ':' -f2- | cut -d ' ' -f2-);
|
||||
memory=$(free -h --si --total | grep -oP '^Total:\s+([\d,]+[.]*[\d]*)[ ]*([A-Za-z]+)' | awk '{print $2}');
|
||||
system_main_ip=$(hostname -I);
|
||||
|
||||
# Hacky way to check for multiple possibilities
|
||||
cat /proc/cpuinfo | grep -q 'Raspberry'; rc=$?
|
||||
systemtype=$(if [[ $rc -eq 0 ]]; then echo "Raspberry"; else echo "Generic"; fi)
|
||||
cat /proc/cpuinfo | grep -q 'Intel'; rc=$?
|
||||
systemtype=$(if [[ $rc -eq 0 ]]; then echo "Intel"; else echo "$systemtype"; fi)
|
||||
|
||||
printf '{"systemtype":"%s","hostname":"%s","operating_system":"%s","architecture":"%s","processor_name":"%s","memory":"%s","system_main_ip":"%s"}'\
|
||||
"$systemtype" "$hostname" "$operating_system" "$architecture" "$processor_model" "$memory" "$system_main_ip"
|
||||
17
templates/etc/update-motd.d/11-welcome
Executable file
17
templates/etc/update-motd.d/11-welcome
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
###############################################################
|
||||
# Script : 11-welcome
|
||||
# Author : Petr Všetečka, Andre
|
||||
# Email : vsetecka@cesnet.cz
|
||||
# Date : 27/11/2018, 16/07/2024
|
||||
# Description: prints distro name and kernel version
|
||||
# Args : none
|
||||
###############################################################
|
||||
|
||||
clear
|
||||
|
||||
printf "\nSystem managed by Ansible"
|
||||
|
||||
printf "\nWelcome to "; lsb_release -ds
|
||||
printf " System: "; uname -snrvm
|
||||
13
templates/etc/update-motd.d/13-uptime
Executable file
13
templates/etc/update-motd.d/13-uptime
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
###############################################################
|
||||
# Script : 13-uptime
|
||||
# Author : Petr Všetečka
|
||||
# Email : vsetecka@cesnet.cz
|
||||
# Date : 27/11/2018
|
||||
# Description: prints total uptime in nice format
|
||||
# Args : none
|
||||
###############################################################
|
||||
|
||||
|
||||
printf "System is "; uptime -p
|
||||
31
templates/etc/update-motd.d/15-hwstats
Executable file
31
templates/etc/update-motd.d/15-hwstats
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
|
||||
###############################################################
|
||||
# Script : 15-hwstats
|
||||
# Author : Petr Všetečka
|
||||
# Email : vsetecka@cesnet.cz
|
||||
# Date : 27/11/2018
|
||||
# Description: prints current time and usage of CPU, RAM & HDD
|
||||
# Args : none
|
||||
###############################################################
|
||||
|
||||
|
||||
printf "\nSystem information as of "; date
|
||||
printf "\n"
|
||||
|
||||
# CPU
|
||||
printf " CPU load: "; cat /proc/loadavg | awk '{ printf "%s %s %s", $1, $2, $3; }'
|
||||
printf " ("
|
||||
printf $(($(ps -e --no-headers | wc -l) - 1))
|
||||
printf " processes)\n"
|
||||
# RAM
|
||||
free -m | awk '/Mem/ { printf " Memory: %4sM (%2d%%) out of %2.1fG\n", $3, ($3/$2) * 100, $2/1000; }
|
||||
/Swap/ {
|
||||
if ( $3 == 0 )
|
||||
printf " Swap: not available\n";
|
||||
else
|
||||
printf " Swap: %4sM (%2d%%) out of %2.1fG\n", $3, ($3/$2) * 100, $2/1000;
|
||||
|
||||
}'
|
||||
# Disk
|
||||
df -h | awk '/^\// { printf " Disk: %5s (%3s) out of %4s\n", $3, $5, $2; }'
|
||||
18
templates/etc/update-motd.d/17-users
Executable file
18
templates/etc/update-motd.d/17-users
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
###############################################################
|
||||
# Script : 17-users
|
||||
# Author : Petr Všetečka
|
||||
# Email : vsetecka@cesnet.cz
|
||||
# Date : 27/11/2018
|
||||
# Description: prints names of all users currently logged in
|
||||
# Args : none
|
||||
###############################################################
|
||||
|
||||
|
||||
printf "\n"
|
||||
w -h | awk 'BEGIN { printf "Users logged in:"; }
|
||||
{ printf " %s", $1; }'
|
||||
top -bn1 | awk 'BEGIN { FS=", "; }
|
||||
$2~/user/ { print " (" $2 " total)"; }
|
||||
$3~/user/ { print " (" $3 " total)"; }'
|
||||
19
templates/etc/update-motd.d/19-ipaddresses
Normal file
19
templates/etc/update-motd.d/19-ipaddresses
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
###############################################################
|
||||
# Script : 19-ipaddresses
|
||||
# Author : Andre
|
||||
# Date : 16/07/2024
|
||||
# Description: displays ipv4 and ipv6 addresses
|
||||
# Args : none
|
||||
###############################################################
|
||||
|
||||
printf "\n"
|
||||
|
||||
printf "IPv4 addresses\n"
|
||||
printf "===============================================================================\n"
|
||||
ip -h -br -f inet a
|
||||
printf "===============================================================================\n"
|
||||
printf "IPv6 addresses\n"
|
||||
ip -h -br -f inet6 a
|
||||
printf "===============================================================================\n"
|
||||
Reference in New Issue
Block a user