commited current state (new functions, may not work by now)

This commit is contained in:
Ansible Servercow
2025-10-08 09:32:02 +02:00
parent e5f83941b9
commit b21a80af07
54 changed files with 1381 additions and 74 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
.vault_pass

View File

@@ -0,0 +1,52 @@
backupcow__repo_url: "git@gitea.servercow.de:Servercow-Internal/backupcow-dockerized.git" # Or else
backupcow__install_path: "/opt/backupcow-dockerized"
opnsense_host: "45.85.48.5"
pdnsadmin_api_host: "pde.servercow.com"
deploy_keys: True
use_docker_image_mirror: true
docker_mirror_location: "tinc" # or "tinc" based on your preference
docker_install_source: "tinc"
crowdsec_install_source: "tinc" # or "official" based on your preference
crowdsec_lapi_url: "https://45.85.49.1:8080"
# Basic server and authentication information.
# You have to provide the distributed setup yourself.
checkmk_agent_version: "2.3.0p34"
checkmk_agent_edition: "cee"
checkmk_agent_user: "{{ checkmk_automation_user }}"
checkmk_agent_pass: "{{ checkmk_automation_pass }}"
# Here comes the part, where we get into remote registration
checkmk_agent_server_protocol: https
# The following should be set to the central site.
# This where you configure the host objects.
# Currently the agent package is also pulled from here.
checkmk_agent_server: servercow.observer
checkmk_agent_site: "scowmon"
checkmk_server_url: "https://servercow.observer"
checkmk_monitoring_site: "scowmon"
checkmk_host_folder: "backupmx"
# The following should be pointed to the respective remote site.
# This is where the registration will happen.
checkmk_agent_registration_server: "{{ checkmk_agent_server }}"
checkmk_agent_registration_site: "{{ checkmk_agent_site }}"
# These options need to be enabled for all registrations to work.
# You can however disable the one you do not want to perform.
# But the host needs to be added and changes activated in any case.
checkmk_agent_auto_activate: 'true'
checkmk_agent_update: 'true'
checkmk_agent_tls: 'true'
# checkmk_agent_server_validate_certs: 'true'
# These are some generic agent options you might want to configure.
checkmk_agent_discover: 'true'
checkmk_agent_discover_max_parallel_tasks: 2
checkmk_agent_force_install: 'true'
checkmk_agent_delegate_api_calls: localhost
checkmk_agent_delegate_download: localhost
checkmk_agent_host_name: "{{ backupcow__hostname }}"
checkmk_agent_host_folder: "{{ checkmk_agent_folder }}"
checkmk_agent_host_ip: "{{ bmx_ipv4_public }}"

View File

@@ -0,0 +1,47 @@
# Standardwerte, die überschrieben werden können
os_update_auto_upgrade: true
os_also_update_mirror: true # Can either be true or false | Use this to enable mirror changes. Useful for first runs.
os_update_mirrors:
- mirror: "http://mirror.tinc.gmbh/debian" # Enter a main mirror here (not security)
type: "main"
- mirror: "http://mirror.tinc.gmbh/debian-security" # Enter a security mirror here
type: "security"
os_update_major_version: false # Can either be true or false | To toggle if systems need to be upgraded to newer codename
os_update_version_codename: "bookworm" # Change to switch major release (e.g. bookworm or trixie) | Used for jinja2 Template fill in as it determines the current codename of system where ansible is run on
# Basic server and authentication information.
# You have to provide the distributed setup yourself.
checkmk_agent_version: "2.3.0p34"
checkmk_agent_edition: "cee"
checkmk_agent_user: "{{ checkmk_automation_user }}"
checkmk_agent_pass: "{{ checkmk_automation_pass }}"
# Here comes the part, where we get into remote registration
checkmk_agent_server_protocol: https
# The following should be set to the central site.
# This where you configure the host objects.
# Currently the agent package is also pulled from here.
checkmk_agent_server: servercow.observer
checkmk_agent_site: "scowmon"
checkmk_server_url: "https://servercow.observer"
checkmk_monitoring_site: "scowmon"
checkmk_host_folder: "backupmx"
# The following should be pointed to the respective remote site.
# This is where the registration will happen.
checkmk_agent_registration_server: "{{ checkmk_agent_server }}"
checkmk_agent_registration_site: "{{ checkmk_agent_site }}"
# These options need to be enabled for all registrations to work.
# You can however disable the one you do not want to perform.
# But the host needs to be added and changes activated in any case.
checkmk_agent_auto_activate: 'true'
checkmk_agent_update: 'true'
checkmk_agent_tls: 'true'
# checkmk_agent_server_validate_certs: 'true'
# These are some generic agent options you might want to configure.
checkmk_agent_discover: 'true'
checkmk_agent_discover_max_parallel_tasks: 2
checkmk_agent_force_install: 'true'
checkmk_agent_delegate_api_calls: localhost
checkmk_agent_delegate_download: localhost
checkmk_agent_host_name: "{{ backupcow__hostname }}"
checkmk_agent_host_folder: "{{ checkmk_agent_folder }}"
checkmk_agent_host_ip: "{{ bmx_ipv4_public }}"

View File

@@ -0,0 +1,36 @@
# Basic server and authentication information.
# You have to provide the distributed setup yourself.
checkmk_agent_version: "2.4.0p8"
checkmk_agent_edition: "cee"
checkmk_agent_user: "{{ checkmk_automation_user }}"
checkmk_agent_pass: "{{ checkmk_automation_pass }}"
# Here comes the part, where we get into remote registration
checkmk_agent_server_protocol: https
# The following should be set to the central site.
# This where you configure the host objects.
# Currently the agent package is also pulled from here.
checkmk_agent_server: servercow.observer
checkmk_agent_site: "scowmon"
checkmk_server_url: "https://servercow.observer"
checkmk_monitoring_site: "scowmon"
checkmk_host_folder: "pves/icp-fra-pve1"
# The following should be pointed to the respective remote site.
# This is where the registration will happen.
checkmk_agent_registration_server: "{{ checkmk_agent_server }}"
checkmk_agent_registration_site: "{{ checkmk_agent_site }}"
# These options need to be enabled for all registrations to work.
# You can however disable the one you do not want to perform.
# But the host needs to be added and changes activated in any case.
checkmk_agent_auto_activate: 'true'
checkmk_agent_update: 'true'
checkmk_agent_tls: 'true'
checkmk_agent_server_validate_certs: 'true'
# These are some generic agent options you might want to configure.
checkmk_agent_discover: 'true'
checkmk_agent_discover_max_parallel_tasks: 2
checkmk_agent_force_install: 'true'
checkmk_agent_delegate_api_calls: localhost
checkmk_agent_delegate_download: localhost
checkmk_agent_host_name: "{{ ansible_hostname }}"
checkmk_agent_host_folder: "{{ checkmk_agent_folder }}"
checkmk_agent_host_ip: "{{ hostvars[inventory_hostname]['ansible_default_ipv6']['address'] }}"

View File

@@ -0,0 +1,20 @@
icp-fra-pve1:
hosts:
icp-fra-pve1-01:
ansible_host: "2a07:6fc0:b:2808::81"
ansible_user: "tincadmin"
icp-fra-pve1-02:
ansible_host: "2a07:6fc0:b:2808::82"
ansible_user: "tincadmin"
icp-fra-pve1-03:
ansible_host: "2a07:6fc0:b:2808::83"
ansible_user: "tincadmin"
icp-fra-pve1-04:
ansible_host: "2a07:6fc0:b:2808::84"
ansible_user: "tincadmin"
icp-fra-pve1-05:
ansible_host: "2a07:6fc0:b:2808::85"
ansible_user: "tincadmin"
icp-fra-pve1-06:
ansible_host: "2a07:6fc0:b:2808::86"
ansible_user: "tincadmin"

View File

@@ -0,0 +1,4 @@
icp-frav-packer01:
ansible_host: "2a07:6fc0:b:2817::70"
ansible_user: "root"

View File

@@ -0,0 +1,4 @@
---
- hosts: clamav-servers
roles:
- deploy-clamd

View File

@@ -1,6 +1,6 @@
- hosts: all
vars:
good_keys: "{{ lookup('env', 'good_keys') | from_json }}"
bad_keys: "{{ lookup('env', 'bad_keys') | from_json }}"
# vars:
# good_keys: "{{ lookup('env', 'good_keys') | from_json }}"
# bad_keys: "{{ lookup('env', 'bad_keys') | from_json }}"
roles:
- role: manage-ssh-keys

View File

@@ -0,0 +1,43 @@
---
- name: Mailcow Mailbox Counter
hosts: all
gather_facts: no
tasks:
- import_role:
name: managed-mailcow
tasks_from: find-mailcow-composedir.yml
- name: Read mailcow.conf and extract DBROOT
ansible.builtin.shell: |
bash -c 'source {{ mailcow_dir_result.files[0].path }}/mailcow.conf && echo $DBROOT'
register: dbroot_output
- name: Count active mailboxes from mailcow database
ansible.builtin.shell: |
docker compose exec mysql-mailcow \
mysql -u root -p{{ dbroot_output.stdout }} -D mailcow -N -e \
"SELECT COUNT(*) FROM mailbox WHERE active=1;"
args:
chdir: "{{ mailcow_dir_result.files[0].path }}"
register: mailbox_count
changed_when: false
- name: Set fact with mailbox count as integer
ansible.builtin.set_fact:
mailbox_count_int: "{{ mailbox_count.stdout | int }}"
- name: Summiere alle Mailboxen über alle Hosts
hosts: all
gather_facts: false
run_once: true
tasks:
- name: Summiere aktive Mailboxen
ansible.builtin.set_fact:
total_mailboxes: "{{ (total_mailboxes | default(0) | int) + (item.value.mailbox_count_int | default(0) | int) }}"
loop: "{{ hostvars | dict2items }}"
when: "'mailbox_count_int' in item.value"
- name: Zeige Gesamtsumme
ansible.builtin.debug:
msg: "Gesamtanzahl aktiver Mailboxen: {{ total_mailboxes }}"

View File

@@ -0,0 +1,69 @@
---
- name: Prüfe mailcow-Installation und extrahiere Roundcube-Version aus CHANGELOG.md
hosts: all
become: true
vars:
mailcow_search_paths:
- /opt
- /data
- /root
- /storage
rc_dirs:
- rc
- roundcube
- roundcubemail
tasks:
- name: Finde mailcow-dockerized Verzeichnis
ansible.builtin.find:
file_type: directory
paths: "{{ mailcow_search_paths }}"
patterns: mailcow-dockerized
recurse: yes
register: mailcow_dir_result
ignore_errors: true
- name: Setze mailcow_root wenn gefunden
ansible.builtin.set_fact:
mailcow_root: "{{ mailcow_dir_result.files[0].path }}"
when: mailcow_dir_result.matched > 0
- name: Prüfe auf Roundcube-Ordner unter data/web
ansible.builtin.stat:
path: "{{ mailcow_root }}/data/web/{{ item }}"
loop: "{{ rc_dirs }}"
register: rc_stat
when: mailcow_root is defined
- name: Bestimme den tatsächlichen Roundcube-Pfad
ansible.builtin.set_fact:
rc_path: "{{ mailcow_root }}/data/web/{{ item.item }}"
loop: "{{ rc_stat.results }}"
when: item.stat.exists and item.stat.isdir
- name: Prüfe ob CHANGELOG.md existiert
ansible.builtin.stat:
path: "{{ rc_path }}/CHANGELOG.md"
register: changelog_stat
when: rc_path is defined
- name: Extrahiere Version aus CHANGELOG.md
ansible.builtin.shell: |
grep -m1 -Po '(?<=## Release )\S+' {{ rc_path }}/CHANGELOG.md
register: rc_version
changed_when: false
when:
- changelog_stat.stat.exists
- changelog_stat.stat.isfile
- name: Gib gefundene Roundcube-Version aus
ansible.builtin.debug:
msg: "Roundcube-Version (laut CHANGELOG.md): {{ rc_version.stdout }}"
when: rc_version.stdout != ""
- name: Warnung wenn keine CHANGELOG.md gefunden wurde
ansible.builtin.debug:
msg: "Keine CHANGELOG.md unter {{ rc_path }} gefunden."
when:
- rc_path is defined
- not changelog_stat.stat.exists

View File

@@ -0,0 +1,44 @@
- name: "Register hosts against a remote site. Both for updates and TLS."
hosts: all
strategy: linear
vars:
# Basic server and authentication information.
# You have to provide the distributed setup yourself.
checkmk_agent_version: "2.3.0p14"
checkmk_agent_edition: "cee"
checkmk_agent_user: "automation"
checkmk_agent_pass: "@JQVEOANOYTUKWGALS@E"
# Here comes the part, where we get into remote registration
checkmk_agent_server_protocol: https
# The following should be set to the central site.
# This where you configure the host objects.
# Currently the agent package is also pulled from here.
checkmk_agent_server: servercow.observer
checkmk_agent_site: "scowmon"
# The following should be pointed to the respective remote site.
# This is where the registration will happen.
checkmk_agent_registration_server: "{{ checkmk_agent_server }}"
checkmk_agent_registration_site: "{{ checkmk_agent_site }}"
# The folder might differ from your remote site name,
# as it is the technical path. Check your configuration for this information.
checkmk_agent_folder: "/managed_mailcows"
# These options need to be enabled for all registrations to work.
# You can however disable the one you do not want to perform.
# But the host needs to be added and changes activated in any case.
checkmk_agent_auto_activate: 'true'
checkmk_agent_update: 'true'
checkmk_agent_tls: 'true'
checkmk_agent_add_host: 'true'
# These are some generic agent options you might want to configure.
checkmk_agent_discover: 'true'
checkmk_agent_discover_max_parallel_tasks: 2
checkmk_agent_force_install: 'true'
checkmk_agent_delegate_api_calls: localhost
checkmk_agent_delegate_download: "{{ inventory_hostname }}"
checkmk_agent_host_name: "{{ inventory_hostname }}"
checkmk_agent_host_folder: "{{ checkmk_agent_folder }}"
checkmk_agent_host_ip: "{{ ansible_host }}"
checkmk_agent_host_attributes:
ipaddress: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}"
roles:
- checkmk.general.agent

View File

@@ -1,14 +1,27 @@
- name: Update mailcow (update.sh)
hosts: all
vars:
github_mailcow_ver: "2025-09b" # GitHub Version Tag | Value to compare the current running mailcow version to.
disk_space_percent_max: "97" # Number in percent | Defines the max allowed disk utilization until ansible is not updating mailcow automatically
debug: true # Or False if you dont' wanna see verbose outputs of role outputs
tasks:
- import_role:
name: roles/managed-mailcow
tasks_from: find-mailcow-composedir.yml
- import_role:
name: roles/managed-mailcow
tasks_from: install-mailcow-components.yml
- import_role:
name: roles/managed-mailcow
tasks_from: update-mailcow.yml
vars:
github_mailcow_ver: "2024-11b" # GitHub Version Tag | Value to compare the current running mailcow version to.
disk_space_percent_max: "97" # Number in percent | Defines the max allowed disk utilization until ansible is not updating mailcow automatically
debug: true # Or False if you dont' wanna see verbose outputs of role outputs
- import_role:
name: roles/docker
tasks_from: restart-daemon.yml
when: github_mailcow_ver == "2025-09b" # Only restart docker if mailcow was updated
- import_role:
name: roles/docker
tasks_from: cleanup-all.yml

View File

@@ -0,0 +1,17 @@
- name: "Change Mirror"
hosts: all
tasks:
- name: Verify if system is Debian
ansible.builtin.debug:
msg: "This playbook is running on a Debian system."
when: ansible_os_family == "Debian"
- name: Stop playbook if system is not Debian
ansible.builtin.fail:
msg: "This playbook only supports Debian."
when: ansible_os_family != "Debian"
- name: Include OS change mirror role
ansible.builtin.include_role:
name: os-updates
tasks_from: update_mirrors

View File

@@ -0,0 +1,20 @@
- hosts: all
vars:
os_update_major_version: true # Can either be true or false | To toggle if systems need to be upgraded to newer codename
os_update_version_codename: "trixie" # Change to switch major release (e.g. bookworm or trixie) | Used for jinja2 Template fill in as it determines the current codename of system where ansible is run on
tasks:
- name: Verify if system is Debian
debug:
msg: "This playbook is running on a Debian system."
when: ansible_os_family == "Debian"
- name: Stop playbook if system is not Debian
fail:
msg: "This playbook only supports Debian."
when: ansible_os_family != "Debian"
- name: Include OS update role
ansible.builtin.include_role:
name: os-updates
tasks_from: update_major_version
when: ansible_os_family == "Debian"

View File

@@ -1,4 +1,7 @@
- hosts: all
vars:
os_update_major_version: true # Can either be true or false | To toggle if systems need to be upgraded to newer codename
os_update_version_codename: "trixie" # Change to switch major release (e.g. bookworm or trixie) | Used for jinja2 Template fill in as it determines the current codename of system where ansible is run on
tasks:
- name: Verify if system is Debian
debug:

View File

@@ -0,0 +1,35 @@
- name: "Setup CheckMK Monitoring"
hosts: all
vars_files:
- ../vault.yml
tasks:
- name: "Import create Host Task"
become: true
ansible.builtin.import_role:
name: checkmk-monitoring
tasks_from: create-host.yaml
- name: "Import sign-bake-agents Task"
become: true
ansible.builtin.import_role:
name: checkmk-monitoring
tasks_from: sign-bake-agents.yaml
ignore_errors: true
- name: "Register hosts against a remote site. Both for updates and TLS."
import_role:
name: checkmk.general.agent
tags:
- checkmk-deploy
- name: "Wait 2 Minutes for CheckMK Agent to be ready"
ansible.builtin.pause:
minutes: 2
tags:
- checkmk-deploy
- name: "Import discover-host Task"
become: true
ansible.builtin.import_role:
name: checkmk-monitoring
tasks_from: discover-host.yaml

View File

@@ -0,0 +1,12 @@
- name: "Setup chronyd"
hosts: all
tasks:
- name: Verify if system is Debian or Ubuntu
ansible.builtin.debug:
msg: "This playbook is running on a Debian or Ubuntu system."
when: ansible_os_family in ["Debian", "Ubuntu"]
- name: Import chronyd role
ansible.builtin.include_role:
name: system
tasks_from: setup-timeserver

View File

@@ -0,0 +1,20 @@
- name: "Activate Changes"
checkmk.general.activation:
server_url: "{{ checkmk_server_url }}"
site: "{{ checkmk_monitoring_site }}"
automation_user: "{{ checkmk_automation_user }}"
automation_secret: "{{ checkmk_automation_pass }}"
run_once: true
delegate_to: localhost
- name: "Sign and bake pending agent jobs"
checkmk.general.bakery:
server_url: "{{ checkmk_server_url }}"
site: "{{ checkmk_monitoring_site }}"
automation_user: "{{ checkmk_automation_user }}"
automation_secret: "{{ checkmk_automation_pass }}"
signature_key_id: 1
signature_key_passphrase: "{{ checkmk_agent_bakery_passphrase }}"
state: "baked_signed"
delegate_to: localhost
run_once: true

View File

@@ -0,0 +1,15 @@
- name: "Create new Host at CheckMK Server"
checkmk.general.host:
server_url: "{{ checkmk_server_url }}"
site: "{{ checkmk_monitoring_site }}"
automation_user: "{{ checkmk_automation_user }}"
automation_secret: "{{ checkmk_automation_pass }}"
name: "{{ checkmk_agent_host_name }}"
folder: "{{ checkmk_host_folder }}"
attributes:
ipv6address: "{{ ansible_host }}"
state: present
delegate_to: localhost
notify:
- Activate Changes
- Sign and bake pending agent jobs

View File

@@ -0,0 +1,28 @@
- name: "Delete Host at CheckMK Server"
checkmk.general.host:
server_url: "{{ checkmk_server_url }}"
site: "{{ checkmk_monitoring_site }}"
automation_user: "{{ checkmk_automation_user }}"
automation_secret: "{{ checkmk_automation_pass }}"
name: "{{ backupcow__hostname }}"
folder: "{{ checkmk_host_folder }}"
attributes:
ipaddress: "{{ bmx_ipv4_public }}"
state: absent
notify:
- Activate Changes
- Sign and bake pending agent jobs
- name: "Remove CheckMK Agent from Host"
ansible.builtin.apt:
name: "check-mk-agent"
state: absent
purge: true
when: ansible_facts['distribution'] == 'Ubuntu' or ansible_facts['distribution'] == 'Debian'
register: cmk_agent_removal
- name: "Purge CheckMK Agent Configuration from Host"
ansible.builtin.file:
name: "/var/lib/cmk-agent"
state: absent
when: cmk_agent_removal.changed

View File

@@ -0,0 +1,10 @@
- name: "Run CheckMK Discovery for Host"
checkmk.general.discovery:
server_url: "{{ checkmk_server_url }}"
site: "{{ checkmk_monitoring_site }}"
automation_user: "{{ checkmk_automation_user }}"
automation_secret: "{{ checkmk_automation_pass }}"
host_name: "{{ ansible_hostname }}"
state: "fix_all"
notify:
- Activate Changes

View File

@@ -0,0 +1,9 @@
- name: "Sign and bake pending agent jobs"
checkmk.general.bakery:
server_url: "{{ checkmk_server_url }}"
site: "{{ checkmk_monitoring_site }}"
automation_user: "{{ checkmk_automation_user }}"
automation_secret: "{{ checkmk_automation_pass }}"
signature_key_id: 1
signature_key_passphrase: "{{ checkmk_agent_bakery_passphrase }}"
state: "baked_signed"

View File

@@ -0,0 +1 @@
clamd_version: 1.4.2

View File

@@ -0,0 +1,16 @@
- name: "Reload Systemd Daemon"
systemd_service:
daemon_reload: true
- name: "Start Clamd Service"
systemd_service:
name: clamd
state: started
enabled: true
- name: "Start Freshclam Service"
systemd_service:
name: freshclam
state: started
enabled: true

View File

@@ -0,0 +1,75 @@
- name: "Download latest ClamAV Version to Control Node"
get_url:
url: https://www.clamav.net/downloads/production/clamav-{{ clamd_version }}.tar.gz
dest: "/tmp/clamav-{{ clamd_version }}.tar.gz"
delegate_to: localhost
- name: Copy ClamAV Tar from Control Node to Ansible Host
copy:
src: "/tmp/clamav-{{ clamd_version }}.tar.gz"
dest: "/usr/local/src/clamav-{{ clamd_version }}.tar.gz"
- name: "Extract ClamAV Tar on Ansible Host"
unarchive:
src: "/usr/local/src/clamav-{{ clamd_version }}.tar.gz"
dest: "/usr/local/src/"
remote_src: true
- name: "Create Build Folder in ClamAV Dir"
file:
path: "/usr/local/src/clamav-{{ clamd_version }}/build"
state: directory
- name: "Pin Cargo Regex Syntax Version"
args:
chdir: "/usr/local/src/clamav-{{ clamd_version }}/build"
shell: |
cargo update -p regex-syntax --precise 0.8.3
- name: "Cmake ClamAV"
args:
chdir: "/usr/local/src/clamav-{{ clamd_version }}/build"
shell: |
cmake .. -D CMAKE_INSTALL_PREFIX=/usr -D CMAKE_INSTALL_LIBDIR=lib -D APP_CONFIG_DIRECTORY=/etc/clamav -D DATABASE_DIRECTORY=/var/lib/clamav -D ENABLE_JSON_SHARED=OFF
- name: "Compile ClamAV"
args:
chdir: "/usr/local/src/clamav-{{ clamd_version }}/build"
shell: |
cmake --build .
- name: "Test Compiled ClamAV"
args:
chdir: "/usr/local/src/clamav-{{ clamd_version }}/build"
shell: |
ctest .
- name: "Install compiled ClamAV"
args:
chdir: "/usr/local/src/clamav-{{ clamd_version }}/build"
shell: |
cmake --build . --target install
- name: "Create Freshclam Log File"
file:
path: "/var/log/freshclam.log"
state: touch
owner: clamav
group: clamav
mode: '600'
- name: "Create ClamAV Log File"
file:
path: "/var/log/clamav.log"
state: touch
owner: clamav
group: clamav
mode: '600'
- name: "Set ClamAV Signature Database Permission"
file:
path: "/var/lib/clamav"
state: directory
owner: clamav
group: clamav
recurse: yes

View File

@@ -0,0 +1,27 @@
- name: Deploy ClamAV Systemd Service
template:
src: templates/systemd-clamav-service.j2
dest: /etc/systemd/system/clamd.service
notify:
- Reload Systemd Daemon
- name: Deploy ClamAV Freshclam Service
template:
src: templates/systemd-freshclam-service.j2
dest: /etc/systemd/system/freshclam.service
notify:
- Reload Systemd Daemon
- name: Deploy Freshclam Config File
template:
src: templates/freshclam-config.j2
dest: /etc/clamav/freshclam.conf
notify:
- Start Freshclam Service
- name: Deploy ClamAV Config File
template:
src: templates/clamav-config.j2
dest: /etc/clamav/clamd.conf
notify:
- Start Clamd Service

View File

@@ -0,0 +1,41 @@
- name: "Install ClamAV Compilation Dependencies"
ansible.builtin.apt:
pkg:
- curl
- gcc
- make
- pkg-config
- python3
- python3-pip
- python3-pytest
- valgrind
- cmake
- check
- libbz2-dev
- libcurl4-openssl-dev
- libjson-c-dev
- libmilter-dev
- libncurses5-dev
- libpcre2-dev
- libssl-dev
- libxml2-dev
- zlib1g-dev
- sudo
state: present
- name: Check if cargo is installed already
shell: command -v cargo
register: cargo_exists
ignore_errors: true
- name: "Install rusttoolchain for Compilation"
become: true
shell: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y
when: cargo_exists.rc != 0
- name: Ensure Cargo is set in Path
shell: |
source $HOME/.cargo/env
args:
executable: /bin/bash

View File

@@ -0,0 +1,12 @@
- name: Install ClamAV Dependencies
import_tasks: install-dependencies.yml
when: ansible_facts['os_family']|lower == 'debian'
- name: Setup ClamAV Service User/Group
import_tasks: setup-clamav-user-group.yml
- name: Compile ClamAV
import_tasks: compile-clamav.yml
- name: Configure ClamAV
import_tasks: configure-clamav.yml

View File

@@ -0,0 +1,13 @@
- name: "Setup ClamAV Service Group"
group:
name: clamav
state: present
- name: "Setup ClamAV Service User"
user:
name: clamav
comment: ClamAV Service Account
shell: /bin/false
group: clamav

View File

@@ -0,0 +1,81 @@
TCPSocket 3310
TCPAddr {{ ansible_default_ipv6.address }}
User clamav
ScanMail true
ScanArchive true
ArchiveBlockEncrypted false
MaxDirectoryRecursion 15
FollowDirectorySymlinks false
FollowFileSymlinks false
ReadTimeout 180
MaxThreads 24
MaxConnectionQueueLength 30
LogSyslog true
LogRotate true
LogFacility LOG_LOCAL6
LogClean false
LogVerbose false
PreludeEnable no
PreludeAnalyzerName ClamAV
DatabaseDirectory /var/lib/clamav
OfficialDatabaseOnly false
SelfCheck 3600
Foreground false
Debug false
ScanPE true
MaxEmbeddedPE 10M
ScanOLE2 true
ScanPDF true
ScanHTML true
MaxHTMLNormalize 10M
MaxHTMLNoTags 2M
MaxScriptNormalize 5M
MaxZipTypeRcg 1M
ScanSWF true
ExitOnOOM false
LeaveTemporaryFiles false
AlgorithmicDetection true
ScanELF true
IdleTimeout 30
CrossFilesystems true
PhishingSignatures true
PhishingScanURLs true
PhishingAlwaysBlockSSLMismatch false
PhishingAlwaysBlockCloak false
PartitionIntersection false
DetectPUA true
ScanPartialMessages false
HeuristicScanPrecedence false
StructuredDataDetection false
CommandReadTimeout 30
SendBufTimeout 200
MaxQueue 100
ExtendedDetectionInfo true
OLE2BlockMacros false
AllowAllMatchScan true
ForceToDisk false
DisableCertCheck false
DisableCache false
MaxScanTime 120000
MaxScanSize 100M
MaxFileSize 25M
MaxRecursion 16
MaxFiles 10000
MaxPartitions 50
MaxIconsPE 100
PCREMatchLimit 10000
PCRERecMatchLimit 5000
PCREMaxFileSize 25M
ScanXMLDOCS true
ScanHWP3 true
MaxRecHWP3 16
StreamMaxLength 25M
LogFile /var/log/clamav.log
LogTime true
LogFileUnlock false
LogFileMaxSize 250M
Bytecode true
BytecodeSecurity TrustSigned
BytecodeTimeout 60000
OnAccessMaxFileSize 5M

View File

@@ -0,0 +1,38 @@
DatabaseOwner clamav
UpdateLogFile /var/log/freshclam.log
LogVerbose false
LogSyslog false
LogFacility LOG_LOCAL6
LogFileMaxSize 0
LogRotate true
LogTime true
Foreground false
Debug false
MaxAttempts 5
DatabaseDirectory /var/lib/clamav
DNSDatabaseInfo current.cvd.clamav.net
ConnectTimeout 30
ReceiveTimeout 0
TestDatabases yes
ScriptedUpdates yes
CompressLocalDatabase no
Bytecode true
NotifyClamd /etc/clamav/clamd.conf
# Check for new database 24 times a day
Checks 24
DatabaseMirror db.local.clamav.net
DatabaseMirror database.clamav.net
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfo.hdb
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfo.ign2
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/javascript.ndb
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/spam_marketing.ndb
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfohtml.hdb
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfoascii.hdb
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfoandroid.hdb
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfoold.hdb
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfopdf.hdb
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfo0hour.hdb
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfo.mdb
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfo.yara
DatabaseCustomURL https://www.securiteinfo.com/get/signatures/a7ef4fbe00e1d0f06492174e93ca2ae8906316d6759eb755c2afd26c5967503d548a5c9502ae78f7903aa618985a55d1284df9b7757128530d523e712bc42ce5/securiteinfo.pdb

View File

@@ -0,0 +1,21 @@
[Unit]
Description=ClamAV Daemon (clamd)
Documentation=man:clamd(8) man:clamd.conf(5) https://www.clamav.net/documents/
After=network.target
ConditionPathExistsGlob=/var/lib/clamav/main.{c[vl]d,inc}
ConditionPathExistsGlob=/var/lib/clamav/daily.{c[vl]d,inc}
[Service]
User=clamav
Group=clamav
ExecStart=/usr/sbin/clamd --foreground=true --config-file=/etc/clamav/clamd.conf
ExecReload=/bin/kill -USR2 $MAINPID
Restart=on-failure
TimeoutStartSec=420
ProtectSystem=full
PrivateTmp=true
RuntimeDirectory=clamav
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,16 @@
[Unit]
Description=ClamAV Signatur-Updater (freshclam)
Documentation=man:freshclam(1) man:freshclam.conf(5) https://www.clamav.net/documents/
Wants=network-online.target
After=network-online.target
ConditionPathExists=!/etc/cron.d/clamav-freshclam
[Service]
User=clamav
Group=clamav
ExecStart=/usr/bin/freshclam -d --foreground=true --config-file /etc/clamav/freshclam.conf
Restart=on-failure
PrivateTmp=true
[Install]
WantedBy=multi-user.target

View File

@@ -5,10 +5,21 @@ authorized_keys_file: >-
# Liste der erwünschten (Good) Keys
good_keys:
- "ssh-rsa AAAAB3... goodkey1"
- "ssh-rsa AAAAB3... goodkey2"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCKcSu464ffJh6fcrWSajlkdGzyeP1+eStHeiFWjfvTZN1YD/05LsADLv8QwnwDbjIHpi/jO2N9mzN55O2MP4FP33Ztmex5CW1sALHynCX7/LtxmklUxbezoJPp1+evhcEQ670KfCpuWWTgGI2ChANnfb/QlON6UWERjauHoNvO33LnO2ySWxHULDlv7BuJCrmk1ZgH2DI7nGIl2KEdkvtJrUaz/fkjalzdfsD+5bsCVxEXBwF5vOAflYdgLAA9AiiHNrwmoU7ELy+WN7YYA0ikoFAUsaW3R4lzA9Cl9wGQmnF30fMChB3JOHF+fFVLFgftChKlB1A1pddaNMPULPyxNJXBXpZCw0ntLcA3UNtnBl0McVKLdVvQfyeWygqqu9OYtkWWO1KApGxss2KDabKG9C+WRhx6z06lFlPMqZK2bmaZDszd8fKI+jbVRKBq2njZmE/uRfEvHHSXqskBDefdMqIUpRN8cN05vZm+sphIaHfOX1vCy1ZDVTiThFcd/z0= root@ansible-servercow"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDsWfznWCcqpgoq4awYDp2W8y62rDT8PEN0xx7818OA1B/mENiBb6jB9qojBpXuSqXKCg7WIVawtl4DSufN4tx2CCNXJPZGcYxkzYrA+bYHMgNUtDF6ps1odFFCu7D1ioVj+hSiM0coFzdgBeT4owg2S8h8kdUmwEbOECp75/3KjV/JUsHrytfJlSTN2mr+SpV3LRL19zFJ67PQXLUyC5oXUR1DZxgzCR2+bWPM7zW0xkVD3c1D+S2JRV4RCZts1Lfgoo/Fl88YMjwk1s3W38Zp/uAgIY6Boan193RWY1yqeCq6u2xAcIiAUqZrVnKesWVnXeRiPuTEESuthK3xSjxd mschild@WS-WIL-MSCHILD"
- "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAiyp00CbVXDS1h+S7SgCNWcgE6PDIxtUmXi/vMbd8Ad6IzVE9gRHeHGkEVZp8YQwMHtlBd4c1+D4T7fHpCVE0kQghXuskp/bvESTO3rD8ZZV2CFU62HD1GwAcXDezd4720bvTqS4BTwZtU/r9/O68+JUIfhF+rC48vP1O04W/W/yKcwmfC1L7JXkLqmmzO0UezIaw2VfB16n4hnkT7NjQrh8q1Egf1+UL8Rzh0Yknmp7tQzF1LGHpVwXiODRVpLtXQ6WUY/v60ucubEER0GxxFs3mu/Re279OErqMmf6vUHtJ1U4SjUUa33DCOO9g7MaZn05cm/2WOlIra2mrQeleaQ== mvogt@NUC6i5MV"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDhWL1f5L8jXm1DSQ8uT0J0LxzYumeYazvGQ3aF+GJabZadzFUbTOU0+6Ce4F/OjpSU2147/HUObdkRQoWoCFir0CdsnaVlYXORMyhd0BssEVleuMaaTkSHtp1VBEjjp3iqduOS3k5uGlCVJeBS4yn9Lp3f4rEAw8YQ0cdWn+m5CmO6WSR7dobYwlqGK7NbQBQ17GEiHbhLMSNfWW62iwivLj0nK35Mz0RmGUJiI+ngPvAr0CPajjwZtyPZeOqHYGk6clIJwsSsb7FSZ/no89cqxP2F5r41+8nsbXgXPB/BiHDd+90ODkuJLOOspqbdxwtufdq5/GezHgt4IEWBhVRd NikolasPapoutsis@NP-E590"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDPiDdYzWGQsitZLNlINovhz6SQPP55XDYWutCC0NglxtIQPtQP/cD7AnT2l8AaA0n99nIukZgAOisjYpz25lLT25TOb5oQ+FMm8vQiZwpiNIbN6JJVE+YnFITASB7fd5Si7dlzl9+2x7Gi80xLQ4zbCGhhJ4qFkafqROoe+yvYEjBHuf3NLqpUbucn9TMNDz9QNfsy4WGvVvYm9bRix9a+JH8gW50cZBrH5AUyiPodlQxmzGPp9zA+zhgqtYPJCAmfxgVphctQPOJhSPrF555XI5YfFM3KRr043I1EaxhZftkVZrVvuHFXscrsYKSCZmnR4dqNlz4giZ59crj/WaWZAfFv5Cb8Ad13eDxwdrktQOfQKOAhppyBNdNAB8Sk2jsGTs311CQwL+nBol8KLVo1vq2CH5S0QULZ/a8ETP12IjvureVILDzfSvPQoH+WaxPvAsZK8DAvZc6AOBOlCdoD0O/WBjC2IIbTSOxVvEAfLSt9Cug7HwlB6efamQPwjFU= Generated by nikla@DESKTOP-IFBGM3B"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCV4VIAiB9znz7eUTYZFxF85bhqh35pWRiFAGnrJwthapmE0yxdCJEq7pfyTIymK3c1GPF9nOCsu9RgZ7Fj7gIA7LspeJa7Il/BrLgSRW1KEHQ11k/XDibE0JTknoEVGguT6MMHh5or/iJYT3sa3uU0UJMDbZdXp66EjcxRWDrQmiyQRPODOwSQQw+ZrC+rDIZHzj99mFx/+SNfCfIG25gsPJsYDHEoTpvd4nrQZvXK7bjh5XNG4/q8hBEoVQC0AQkxTC5NbXC0qeIra4z2TWQL6QGXQRx/cHC7NrOkGjGkvHYP1wQcuOV49bkKzd6oHNKohCbHslDSbaQTuXYaNZ+7i/dCGt631a4e5g2FBQFXogS1pE6LFB0zVtatZlb5YXVhHwkvmEHCTiOSV1bIDZrdLJ7jQmZWjdt+3ShdnHa8d642MieSXklnE1h+RCxTSbIdDQrDHYKXPiyNrap8zkh4KuMP8g07DttA5wdf76YjLUofUrHH0rpOAIf53Z4SGHs= lynn@DESKTOP-U9SRBCB"
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPIPztA01mPBlbvf+AfqRA4/emj5UbYK0Gi15VI5g/CH mail@danilo-schwabe.de"
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINlJlysj2Ff/8lLgNTkNX/uJVz4uIiEtvO/s3qzUMH1j eddsa-key-mv-tinc-20230130"
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICyZYxVyFQlhn/O6XpvnQL9l9bv652pH4jrkiUuNHMsT nm-tinc-eddsa-key-20240805"
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPb3H/K8w22FIpsb+tad+T1PQjrTdry+cM/fmYiLbSDo root@ansible-servercow"
# Liste der unerwünschten (Bad) Keys
bad_keys:
- "ssh-rsa AAAAB3... badkey1"
- "ssh-rsa AAAAB3... badkey2"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCx5Gwq39Jaf9YQr0qWzCZMU0l1sPfrJE7vWyrZiQRv2IgVvkIuDl1gv+Gaf1wL69WookC0TGc4Ce2tH5xfcz2tiH72jIDf60izrf2attmPcbLnZfFgN6cPFzCIoMVMIMhROgOF9wF1MzO9WUggJBEpcxotoiPfKkmIrfYXLnnMmZ6XXs3LCcdP1wNOkh/mZ3KfwhH6/GhV/0/mjymzrO5DL/piu+89ZrLmsVU9F/VUZciG7zCv8g6Hhiy25vyOmtGL/DPHfszzlQuvRo0hjTjEdNsnv9b44zc7OtGYdrZ4SPK7v2dSLdzU9eL3+7m6zocaVrbM6YWTph9acwkKOehV root@ccp-wil-backup01"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCcqqrN2lC4lajOmiFuUqHBQ2C07YTl3w5e/FT3+ddZ5YOiONr+e8FvKkiw4he5fvGnt6/RUZgnJW+rI7jlF5qPJjdkdJ3wZNiwp4gTiebNV2hvLx3AL0aoH/5tN9m4KDTYZKfnF1JZAgsZrLNrfYJp8F8+AQk24rAQINQ3Cku0i4cgenOQBrT48/Ibv7erav7ZkUFvIPkh4B4Owzu6MUGzKNFoLypgMRXMmLN2vyaor/q4aA9xeha2CKdbJYhTwgrYMieiAyDw9dbe8rJe0BB7VXxDmX54seLsmSWhs6/6L2JNDAdpV/f4Jb2n2L0GaFlyjGpi64nwfoWng2Meou0J mo@LenovoP340-Tiny"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDEiO4yxkqnbpReZreQnQcUsJKv+QpiC/Edh7GjVJIy7O/dcudtAo82c6Zq8k3QvDZor5nkbOso7ushmOLC15OBkWQXZTcWc1z0z+/6G3UTxaFZ4vr4NF9BJnC4z+bGvLLDzU2rCucD6iPXCow443lWXNmoujMsbNJY+qqxvTNMN1872qX/s7wl1j9NX/mRnzbZI3wrzUgKnmqd4TWCQsQT51in7MLr4Tg6hCz/4NpQSfRCaWfrrIKdIyvjdLyLGyrWwtaYFAwqtLSdmtYngzQsM0tbOHrp5z4AFsggjYaXKyrDMkV1U3jTJwbfh0PbEMfki6clWjhxMuw0IsiuaJGZbJfLiyHG/+dDj7rV8jIYJw/9olDGKr9bXpQ2MlIEzgGEni+1U1ZRZwVueUO0HWtc3pOkZQkJKj3Td5NfrducEFSyY8nSJM5an4sx9dYwu4W4QIyn4vrCTIm/clOfDV0I/FB9NW5oT+r/jBmDkCjLsuAWXQ59ULukqIO9hTKntDk= denni@ws-wil-dennisewert"
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBkW4GNq7TeV3ImF5TOdh7FJVCLBzT5GTTxZPSGZFAkO sandfly-generated-key-20230102225148"
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCISq39qZUj6jCQ3/mb6AJp9FXEBYtXK01yK7xVuCR8JsSAiMFczdgSnbF5ELl0oSkxkCs5AY5yEuZcpbV7/uCWHIQIDo1PTLOoBzLYOcEr/1xcEZFRT79TVG8ILT9fVjrLkPJIQZweriGgjTBMSDk+9BBNlRfW4YOhgo7V9GW2VvchxJtCMNUi5+EWrrQQLO1sf6zCxHPZQ9vmcpWPf5LnbKH72TnteJKK8S84WT0iiVkzsjsaPlPWPlX+CHiog9jJ4hyhLq3MivCyQ9jkRDXnVYafGNFhcBYOLV5+mFcxRbKQJbNOwDHhqwWUqjmwfDkCMRdKNJ0h6o0LMI3apYHlQU+n2ncoks+z7mbN/4RRaSxTYC/OjZa3s4dvtJzDFGor8iOgcD11BbhGVBtwbqwU4Z4GJP453oV+LTIkVZgz8iAblTPgZrDs4Jk9WINjtofpmLnYnatWajdBWB3HdCr24h1lsjSZZkRtJYmHuvfRESRbStb92AnzO1QOjiEAshQHS8jsCumsiGEyqLqnpzjOvAxOFjnxUKRnK8GzoN2/AguRldU0WgYNcvDuCon0os22cLzCG0MYFF+r6TOeNkG9EqhwlkYtqD/YseVtqXR14FD77VxSEezJiMI1YXIXtTduLRyKR2kYw6QEmCJWOW28ZXwmNB9+t7xBA9n0klk8UQ== noah@Noah"

View File

@@ -0,0 +1,5 @@
- name: "Install mailcow components"
ansible.builtin.apt:
name: "jq"
state: present
update_cache: yes

View File

@@ -17,29 +17,6 @@
name: roles/system
tasks_from: check-disk-utilization.yaml
- name: Check if redirect.conf exists
ansible.builtin.stat:
path: "{{ mailcow_dir_result.files[0].path }}/data/conf/nginx/redirect.conf"
register: redirect_conf
when: mailcow_conf.stat.exists
- name: Delete redirect.conf if it exists
ansible.builtin.file:
path: "{{ mailcow_dir_result.files[0].path }}/data/conf/nginx/redirect.conf"
state: absent
when: redirect_conf.stat.exists
- name: Update mailcow
shell: "cd {{ mailcow_dir_result.files[0].path }} && git fetch && git checkout origin/master update.sh && ./update.sh --force"
shell: "cd {{ mailcow_dir_result.files[0].path }} && git fetch && git checkout origin/master update.sh && git checkout origin/master _modules && ./update.sh --force"
when: local_mailcow_version.stdout != github_mailcow_ver and mailcow_conf.stat.exists and disk_space_output.stdout | bool
- name: Update HTTP_REDIRECT in mailcow.conf if redirect.conf existed
ansible.builtin.lineinfile:
path: "{{ mailcow_dir_result.files[0].path }}/mailcow.conf"
regexp: '^HTTP_REDIRECT='
line: 'HTTP_REDIRECT=y'
when: redirect_conf.stat.exists
- name: Restart mailcow services
ansible.builtin.shell: "cd {{ mailcow_dir_result.files[0].path }} && docker compose up -d"
when: redirect_conf.stat.exists

View File

@@ -1,9 +1,10 @@
# Standardwerte, die überschrieben werden können
os_update_auto_upgrade: true
os_also_update_mirror: false # Can either be true or false | Use this to enable mirror changes. Useful for first runs.
os_also_update_mirror: true # Can either be true or false | Use this to enable mirror changes. Useful for first runs.
os_update_mirrors:
# Role needs two mirros to use for the sources.list.j2 Template
- "http://mirror.tinc.gmbh/debian" # Enter a main mirror here (not security)
- "http://mirror.tinc.gmbh/debian-security" # Enter a security mirror here
- mirror: "http://mirror.tinc.gmbh/debian" # Enter a main mirror here (not security)
type: "main"
- mirror: "http://mirror.tinc.gmbh/debian-security" # Enter a security mirror here
type: "security"
os_update_major_version: false # Can either be true or false | To toggle if systems need to be upgraded to newer codename
os_update_version_codename: "{{ ansible_distribution_release }}" # KEEP UNTOUCHED!! | Used for jinja2 Template fill in as it determines the current codename of system where ansible is run on
os_update_version_codename: "bookworm" # Change to switch major release (e.g. bookworm or trixie) | Used for jinja2 Template fill in as it determines the current codename of system where ansible is run on

View File

@@ -2,10 +2,10 @@
apt:
clean: yes
autoclean: yes
autoremove: yes
- name: Reboot system
command: /sbin/reboot
async: 1
poll: 0
ignore_errors: true
when: reboot_required.stdout == "yes"
ignore_errors: true

View File

@@ -2,9 +2,5 @@
when: os_also_update_mirror|bool
include_tasks: update_mirrors.yaml
- name: Upgrade to new major version if enabled
when: os_update_major_version
include_tasks: update_major_version.yaml
- name: Upgrade all packages
include_tasks: upgrade_packages.yaml

View File

@@ -1,34 +1,125 @@
- name: Update mirrors if necessary
when: os_also_update_mirror|bool
include_tasks: update_mirrors.yaml
# tasks/main.yml
- name: Assert target codename provided
ansible.builtin.assert:
that:
- os_update_version_codename is defined
- os_update_version_codename | length > 0
fail_msg: "Setze die Variable 'os_update_version_codename' (z.B. 'trixie')."
- name: Set current/target codenames
ansible.builtin.set_fact:
current_codename: "{{ ansible_distribution_release | lower }}"
target_codename: "{{ os_update_version_codename | lower }}"
- name: Stat /etc/apt/sources.list.d
ansible.builtin.stat:
path: /etc/apt/sources.list.d
register: sources_list_d_dir
- name: Find *.list files in /etc/apt/sources.list.d
ansible.builtin.find:
paths: /etc/apt/sources.list.d
patterns: "*.list"
file_type: file
register: apt_lists
when: sources_list_d_dir.stat.exists | default(false)
- name: Stat /etc/apt/sources.list
ansible.builtin.stat:
path: /etc/apt/sources.list
register: sources_list_stat
- name: Build list of APT *.list paths
ansible.builtin.set_fact:
apt_list_paths: >-
{{
(vars.get('apt_lists', {}).get('files', [])
| map(attribute='path') | list)
}}
- name: Build list of APT source files
ansible.builtin.set_fact:
apt_source_files: >-
{{
apt_list_paths
+ ([sources_list_stat.stat.path] if (sources_list_stat.stat.exists | default(false)) else [])
}}
# ---------- Backups ----------
- name: Backup existing sources in /etc/apt
copy:
ansible.builtin.copy:
src: "{{ item }}"
dest: "{{ item }}.bak"
remote_src: yes
loop: "{{ lookup('ansible.builtin.fileglob', '/etc/apt/sources.list.d/*.list') + ['/etc/apt/sources.list'] }}"
when: item | file
remote_src: true
force: true
loop: "{{ apt_source_files }}"
loop_control:
label: "{{ item }}"
- name: Update sources.list for new major version
template:
# ---------- Update /etc/apt/sources.list ----------
- name: Update /etc/apt/sources.list from template
ansible.builtin.template:
src: sources.list.j2
dest: /etc/apt/sources.list
owner: root
group: root
mode: "0644"
vars:
os_update_version_codename: "{{ new_version_codename }}" # Variable gets passed by main.yml task
target_codename: "{{ target_codename }}"
- name: Update additional repositories in /etc/apt/sources.list.d
lineinfile:
# ---------- Update additional *.list files ----------
# Ersetzt den Codename (inkl. optionaler Suite-Suffixe wie -security/-updates) in den .d-Dateien
- name: Update codename in /etc/apt/sources.list.d/*.list (keep suffix)
ansible.builtin.replace:
path: "{{ item }}"
regexp: '^(deb .* )({{ os_update_version_codename }})'
line: '\1{{ new_version_codename }}'
loop: "{{ lookup('ansible.builtin.fileglob', '/etc/apt/sources.list.d/*.list') }}"
when: item | file
regexp: '(^\s*deb(?:-src)?(?:\s+\[.*?\])?\s+\S+\s+){{ current_codename | regex_escape }}(?P<suffix>-[a-z]+)?(\s+)'
replace: '\1{{ target_codename }}\g<suffix>\3'
loop: "{{ apt_list_paths }}"
when: apt_list_paths | length > 0
loop_control:
label: "{{ item }}"
# ---- Prevent EXIM (Debian 13 only) ---------
- name: Block installation of Exim with APT Pinning
become: true
ansible.builtin.copy:
dest: /etc/apt/preferences.d/block-exim.pref
owner: root
group: root
mode: '0644'
content: |
Package: exim4*
Pin: release *
Pin-Priority: -1
- name: Remove existing Exim packages (purge + autoremove)
become: true
ansible.builtin.apt:
name:
- exim4
- exim4-base
- exim4-config
- exim4-daemon-light
state: absent
purge: true
autoremove: true
register: exim_purge
# ---------- Upgrade ----------
- name: Update apt cache
apt:
update_cache: yes
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Perform distribution upgrade
apt:
upgrade: yes
allow_unauthenticated: yes
ansible.builtin.apt:
upgrade: dist # dist-upgrade
allow_unauthenticated: false
notify:
- Reboot system
- apt cleanup

View File

@@ -11,12 +11,11 @@
register: latest_kernel
changed_when: false
- name: Check if running kernel matches the latest installed kernel
- name: Check if running kernel matches the latest installed kernel and determine if reboot is required
shell: uname -r
register: running_kernel
changed_when: false
- name: Determine if reboot is required
set_fact:
reboot_required: "yes"
failed_when: false
notify:
- Reboot system
when: running_kernel.stdout != latest_kernel.stdout

View File

@@ -1,5 +1,10 @@
# {{ ansible_managed }}
deb {{ os_update_mirrors[0] }} {{ os_update_version_codename }} main contrib non-free non-free-firmware
deb {{ os_update_mirrors[0] }} {{ os_update_version_codename }}-updates main contrib non-free non-free-firmware
deb {{ os_update_mirrors[0] }} {{ os_update_version_codename }}-backports main contrib non-free non-free-firmware
deb {{ os_update_mirrors[1] }} {{ os_update_version_codename }}-security main contrib non-free non-free-firmware
{% for mirror in os_update_mirrors %}
{% if mirror.type == "main" %}
deb {{ mirror.mirror }} {{ os_update_version_codename }} main contrib non-free non-free-firmware
deb {{ mirror.mirror }} {{ os_update_version_codename }}-updates main contrib non-free non-free-firmware
deb {{ mirror.mirror }} {{ os_update_version_codename }}-backports main contrib non-free non-free-firmware
{% elif mirror.type == "security" %}
deb {{ mirror.mirror }} {{ os_update_version_codename }}-security main contrib non-free non-free-firmware
{% endif %}
{% endfor %}

View File

@@ -0,0 +1,3 @@
use_docker_image_mirror: true
docker_mirror_location: "SC" # or "tinc" based on your preference
docker_install_source: "official"

15
roles/system/files/motd Normal file
View File

@@ -0,0 +1,15 @@
_ _ _ _
| |_(_)_ __ ___ (_) ___ _ __ _ __ _ __ ___ __| |
| __| | '_ \ / __| _____ | |/ __| '_ \ _____ | '_ \| '__/ _ \ / _` |
| |_| | | | | (__ |_____| | | (__| |_) | |_____| | |_) | | | (_) | (_| |
\__|_|_| |_|\___| |_|\___| .__/ | .__/|_| \___/ \__,_|
|_| |_|
-----------------------------------------------------------------
* This server is managed by tinc. Please contact the *
* support team at 'support@tinc.gmbh' for any issues. *
-----------------------------------------------------------------
* WARNING - WARNING - WARNING - WARNING - WARNING - WARNING *
* You are accessing a secured system and your actions will *
* be logged along with identifying information. Disconnect *
* immediately if you are not an authorized user of this system. *
-----------------------------------------------------------------

View File

@@ -0,0 +1,28 @@
- name: Reload systemd
ansible.builtin.systemd:
daemon_reload: true
- name: Restart SSH
systemd_service:
name: sshd
state: restarted
- name: Restart Docker
systemd_service:
name: docker
state: restarted
- name: Restart chronyd
ansible.builtin.systemd:
name: chronyd
state: restarted
- name: Enable Docker
systemd_service:
name: docker
enabled: true
- name: Start Docker
systemd_service:
name: docker
state: started

View File

@@ -0,0 +1,16 @@
- name: Install basic system tools
ansible.builtin.package:
name:
- git
- curl
- wget
- vim
- htop
- net-tools
- unzip
- htop
- tcpdump
- bind9-dnsutils
- gnupg
- sudo
state: present

View File

@@ -0,0 +1,64 @@
- name: Create directory for Docker systemd override
ansible.builtin.file:
path: /etc/systemd/system/docker.service.d
state: directory
mode: '0755'
- name: Setup Docker image mirror (SC)
when: use_docker_image_mirror | bool and docker_mirror_location == "SC"
block:
- name: Install CA certificate for Docker image mirror
ansible.builtin.get_url:
url: http://dim.servercow.com:3128/ca.crt
dest: /usr/local/share/ca-certificates/SCOW-DIM-CA.crt
mode: '0644'
register: sc_ca_cert
- name: Register CA certificate
ansible.builtin.command: update-ca-certificates
when: sc_ca_cert.changed
- name: Write Docker proxy configuration (SC)
ansible.builtin.copy:
dest: /etc/systemd/system/docker.service.d/http-proxy.conf
content: |
[Service]
Environment="HTTP_PROXY=http://dim.servercow.com:3128/"
Environment="HTTPS_PROXY=http://dim.servercow.com:3128/"
owner: root
group: root
mode: '0644'
notify:
- Reload systemd
- Restart Docker
when: sc_ca_cert.changed
- name: Setup Docker Image Mirror (tinc)
when: use_docker_image_mirror | bool and docker_mirror_location == "tinc"
block:
- name: Install CA certificate for Docker image mirror
ansible.builtin.get_url:
url: http://mirror.tinc.gmbh:3128/ca.crt
dest: /usr/local/share/ca-certificates/TINC-DIM-CA.crt
mode: '0644'
register: tinc_ca_cert
- name: Register CA certificate
ansible.builtin.command: update-ca-certificates
when: tinc_ca_cert.changed
- name: Write Docker proxy configuration (tinc)
ansible.builtin.copy:
dest: /etc/systemd/system/docker.service.d/http-proxy.conf
content: |
[Service]
Environment="HTTP_PROXY=http://mirror.tinc.gmbh:3128/"
Environment="HTTPS_PROXY=http://mirror.tinc.gmbh:3128/"
owner: root
group: root
mode: '0644'
notify:
- Reload systemd
- Restart Docker
when: tinc_ca_cert.changed

View File

@@ -0,0 +1,76 @@
- name: Install Docker from official repo
when: docker_install_source == "official"
block:
- name: Ensure Docker GPG key is dearmored and installed
ansible.builtin.get_url:
url: https://download.docker.com/linux/debian/gpg
dest: /tmp/docker.gpg
mode: '0644'
- name: Convert Docker GPG key to binary format (dearmor)
ansible.builtin.command:
cmd: gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg /tmp/docker.gpg
args:
creates: /etc/apt/trusted.gpg.d/docker.gpg
- name: Remove temporary Docker GPG key
ansible.builtin.file:
path: /tmp/docker.gpg
state: absent
- name: Add Docker APT repository (official)
ansible.builtin.copy:
dest: /etc/apt/sources.list.d/docker.list
content: |
deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/docker.gpg] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable
mode: '0644'
register: docker_repo
- name: Install Docker from tinc mirror
when: docker_install_source == "tinc"
block:
- name: Ensure Docker GPG key is dearmored and installed
ansible.builtin.get_url:
url: https://mirror.tinc.gmbh/docker/debian/gpg
dest: /tmp/docker.gpg
mode: '0644'
- name: Convert Docker GPG key to binary format (dearmor)
ansible.builtin.command:
cmd: gpg --dearmor -o /etc/apt/trusted.gpg.d/docker.gpg /tmp/docker.gpg
args:
creates: /etc/apt/trusted.gpg.d/docker.gpg
- name: Remove temporary Docker GPG key
ansible.builtin.file:
path: /tmp/docker.gpg
state: absent
- name: Add Docker APT repository (tinc)
ansible.builtin.copy:
dest: /etc/apt/sources.list.d/docker.list
content: |
deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/docker.gpg] https://mirror.tinc.gmbh/docker/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable
mode: '0644'
register: docker_repo
- name: Update APT cache
ansible.builtin.apt:
update_cache: yes
when: docker_repo.changed
- name: Install Docker packages from mirror
ansible.builtin.apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
- docker-buildx-plugin
- docker-ce-rootless-extras
state: present
notify:
- Enable Docker
- Start Docker
when: docker_repo.changed

View File

@@ -0,0 +1,7 @@
- name: Install custom MOTD
copy:
src: motd
dest: /etc/motd
owner: root
group: root
mode: '0644'

View File

@@ -0,0 +1,26 @@
- name: Purge systemd-timesyncd
ansible.builtin.apt:
name: systemd-timesyncd
state: absent
purge: true
- name: Setup Chrony
ansible.builtin.apt:
name: chrony
state: present
update_cache: yes
- name: Configure Chrony
ansible.builtin.copy:
dest: /etc/chrony/chrony.conf
content: |
server ntp.as208016.net iburst
pool de.pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
owner: root
group: root
mode: '0644'
notify:
- Restart chronyd

View File

@@ -0,0 +1,52 @@
---
- name: User "{{ admin_user }}" anlegen
ansible.builtin.user:
name: "{{ admin_user }}"
shell: /bin/bash
state: present
register: admin_user_result
- name: .sshVerzeichnis anlegen
ansible.builtin.file:
path: "/home/{{ admin_user }}/.ssh"
state: directory
owner: "{{ admin_user }}"
group: "{{ admin_user }}"
mode: "0700"
when: admin_user_result.changed
- name: PublicKeys von URL holen
ansible.builtin.uri:
url: "{{ admin_ssh_pub_key_url }}"
return_content: yes
delegate_to: localhost
register: fetched_keys
- name: Liste der einzelnen Keys erstellen
ansible.builtin.set_fact:
key_list: "{{ fetched_keys.content.splitlines() }}"
- name: authorized_keys anlegen (falls nicht vorhanden)
ansible.builtin.file:
path: "/home/{{ admin_user }}/.ssh/authorized_keys"
state: touch
owner: "{{ admin_user }}"
group: "{{ admin_user }}"
mode: "0600"
- name: Jeden Key einzeln mit authorized_key hinzufügen
ansible.builtin.authorized_key:
user: "{{ admin_user }}"
key: "{{ item | trim }}"
state: present
loop: "{{ key_list }}"
when: item | trim != ""
- name: Passwordlesssudo für alle Befehle konfigurieren
ansible.builtin.copy:
dest: "/etc/sudoers.d/{{ admin_user }}"
content: |
{{ admin_user }} ALL=(ALL) NOPASSWD: ALL
owner: root
group: root
mode: "0440"

View File

@@ -0,0 +1,36 @@
- name: PublicKeys von URL holen
ansible.builtin.uri:
url: "{{ ssh_pub_key_url }}"
return_content: yes
delegate_to: localhost
register: fetched_keys
- name: Liste der einzelnen Keys erstellen
ansible.builtin.set_fact:
key_list: "{{ fetched_keys.content.splitlines() }}"
- name: authorized_keys anlegen (falls nicht vorhanden)
ansible.builtin.file:
path: "/root/.ssh/authorized_keys"
state: touch
owner: "root"
group: "root"
mode: "0600"
- name: Jeden Key einzeln mit authorized_key hinzufügen
ansible.builtin.authorized_key:
user: "root"
key: "{{ item | trim }}"
state: present
loop: "{{ key_list }}"
when: item | trim != ""
- name: Harden SSH configuration
ansible.builtin.template:
src: sshd_config.j2
dest: /etc/ssh/sshd_config
owner: root
group: root
mode: '0644'
notify:
- Restart SSH

View File

@@ -0,0 +1,44 @@
Include /etc/ssh/sshd_config.d/*.conf
Port 22
AddressFamily any
ListenAddress 0.0.0.0
ListenAddress ::
SyslogFacility AUTH
LogLevel INFO
# Authentication:
LoginGraceTime 2m
PermitRootLogin without-password
MaxAuthTries 6
PubkeyAuthentication yes
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
KbdInteractiveAuthentication no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin prohibit-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
UsePAM yes
X11Forwarding yes
PrintMotd no
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
# override default of no subsystems
Subsystem sftp /usr/lib/openssh/sftp-server

12
vault.yml Normal file
View File

@@ -0,0 +1,12 @@
$ANSIBLE_VAULT;1.1;AES256
32313665396633336165656332313162356665623066313165393464666138623230333666313135
3833623133643564323530336531363531623139376636350a653037623861383664623432333961
39633864343631376562343839386637386634333264623231636333663230366134323061356639
6336663761396632660a623433356566373534373266366335393463666562343035393138346663
63396664303837323336396334643663653734666438666364643139386166633938663739303330
39373230616662383263626136663839396662356636663938666135643063363065636133316235
64393962396534393264613534633136353635313564303435313334646533306161346562353566
66383239343932393130626563613437336666623765616439613963306438663665366464326632
37326438386539633930616331303933666537643337303437313234626563363562326361373039
31616661343633303663326165306232306639653035323963363733653538363232333832303833
363165663966363066623762343766393130