Compare commits

..

7 Commits

Author SHA1 Message Date
chris 6e086dbac0 Add virusfilter support for Samba homes and update AppArmor configuration 2026-05-29 18:43:06 +02:00
chris 56a2c8464f Add virusfilter support to Samba shares and configure ClamAV database checks 2026-05-26 14:18:36 +02:00
chris 1f78326503 Adds handlers to reload AppArmor and restart ClamAV
Ensures AppArmor profile for ClamAV is reloaded and the ClamAV daemon is restarted when necessary, improving service reliability and reflecting updated security profiles.
2026-05-26 14:16:45 +02:00
chris f1f169d3aa Comment out cron job entries for DNS cache service restart 2026-05-26 13:43:27 +02:00
chris 3c0a252ecc Add virusfilter support to Samba shares configuration 2026-05-26 13:42:56 +02:00
chris 5b3b68b134 Add ClamAV virusfilter support to Samba configuration and tasks 2026-05-26 13:39:43 +02:00
chris d1444e1507 Add cron job to monitor web services and restart if necessary 2026-05-06 15:57:11 +02:00
14 changed files with 403 additions and 60 deletions
+9
View File
@@ -3160,6 +3160,12 @@ apt_install_server_samba:
- samba
- nscd
apt_install_server_samba_virusfilter:
- clamav
- clamav-daemon
- clamav-freshclam
- samba-vfs-modules
# samba_workgroup
#
# example:
@@ -3195,6 +3201,9 @@ samba_user: []
base_home: /home
# include vfs object 'virusfilter' to (private) homes shares
samba_homes_virusfilter: false
# remove_samba_users:
# - name: name1
# - name: name2
+5
View File
@@ -495,6 +495,11 @@ samba_user:
- gubitz-partner
password: '20.mal-te/26%'
- name: jovis
groups:
- intern
password: '20.jo-vis_26!'
- name: hh-lucke
groups: []
password: 'Ole20Steffen_17'
+2
View File
@@ -415,6 +415,7 @@ samba_shares:
group_write_list: buero
file_create_mask: !!str 664
dir_create_mask: !!str 2775
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
@@ -425,6 +426,7 @@ samba_shares:
group_write_list: verwaltung
file_create_mask: !!str 664
dir_create_mask: !!str 2775
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
+14
View File
@@ -643,6 +643,8 @@ samba_user:
base_home: /data/home
samba_homes_virusfilter: true
remove_samba_users:
- name: howe-staff-1
- name: gerhard
@@ -661,6 +663,7 @@ samba_shares:
group_write_list: a-jur
file_create_mask: !!str 664
dir_create_mask: !!str 2775
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
vfs_object_recycle_is_visible: true
@@ -672,6 +675,7 @@ samba_shares:
group_write_list: kanzlei
file_create_mask: !!str 664
dir_create_mask: !!str 2775
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
vfs_object_recycle_is_visible: true
@@ -692,6 +696,7 @@ samba_shares:
group_write_list: wildvang
file_create_mask: !!str 660
dir_create_mask: !!str 2770
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
vfs_object_recycle_is_visible: true
@@ -703,6 +708,7 @@ samba_shares:
# group_write_list: aulmann
# file_create_mask: !!str 660
# dir_create_mask: !!str 2770
# vfs_object_virusfilter: true
# vfs_object_recycle: true
# recycle_path: '@Recycle'
# vfs_object_recycle_is_visible: true
@@ -714,6 +720,7 @@ samba_shares:
# group_write_list: howe
# file_create_mask: !!str 660
# dir_create_mask: !!str 2770
# vfs_object_virusfilter: true
# vfs_object_recycle: true
# recycle_path: '@Recycle'
# vfs_object_recycle_is_visible: true
@@ -725,6 +732,7 @@ samba_shares:
group_write_list: stahmann
file_create_mask: !!str 660
dir_create_mask: !!str 2770
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
vfs_object_recycle_is_visible: true
@@ -736,6 +744,7 @@ samba_shares:
group_write_list: traine
file_create_mask: !!str 660
dir_create_mask: !!str 2770
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
vfs_object_recycle_is_visible: true
@@ -747,6 +756,7 @@ samba_shares:
group_write_list: public
file_create_mask: !!str 660
dir_create_mask: !!str 2770
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
vfs_object_recycle_is_visible: true
@@ -758,6 +768,7 @@ samba_shares:
group_write_list: advoware
file_create_mask: !!str 660
dir_create_mask: !!str 2770
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
vfs_object_recycle_is_visible: true
@@ -769,6 +780,7 @@ samba_shares:
group_write_list: intern
file_create_mask: !!str 660
dir_create_mask: !!str 2770
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
vfs_object_recycle_is_visible: false
@@ -780,6 +792,7 @@ samba_shares:
group_write_list: alle
file_create_mask: !!str 660
dir_create_mask: !!str 2770
vfs_object_virusfilter: true
vfs_object_recycle: true
recycle_path: '@Recycle'
vfs_object_recycle_is_visible: true
@@ -791,6 +804,7 @@ samba_shares:
# group_write_list: web
# file_create_mask: !!str 660
# dir_create_mask: !!str 2770
# vfs_object_virusfilter: true
# vfs_object_recycle: true
# recycle_path: '@Recycle'
+5
View File
@@ -243,6 +243,11 @@ cron_user_special_time_entries:
cron_user_entries:
- name: "Check if webservices sre running. Restart if necessary"
minute: '*/5'
hour: '*'
job: /root/bin/monitoring/check_webservice_load.sh
- name: "Check if SSH service is running. Restart service if needed."
minute: '*/5'
hour: '*'
+5
View File
@@ -145,6 +145,11 @@ cron_user_special_time_entries:
cron_user_entries:
- name: "Check if webservices sre running. Restart if necessary"
minute: '*/5'
hour: '*'
job: /root/bin/monitoring/check_webservice_load.sh
- name: "Check if SSH service is running. Restart service if needed."
minute: '*/5'
hour: '*'
+5
View File
@@ -257,6 +257,11 @@ cron_user_special_time_entries:
cron_user_entries:
- name: "Check if webservices sre running. Restart if necessary"
minute: '*/5'
hour: '*'
job: /root/bin/monitoring/check_webservice_load.sh
- name: "Check if SSH service is running. Restart service if needed."
minute: '*/5'
hour: '*'
+5
View File
@@ -248,6 +248,11 @@ cron_user_special_time_entries:
cron_user_entries:
- name: "Check if webservices sre running. Restart if necessary"
minute: '*/5'
hour: '*'
job: /root/bin/monitoring/check_webservice_load.sh
- name: "Check if SSH service is running. Restart service if needed."
minute: '*/5'
hour: '*'
+5
View File
@@ -250,6 +250,11 @@ cron_user_special_time_entries:
cron_user_entries:
- name: "Check if webservices sre running. Restart if necessary"
minute: '*/5'
hour: '*'
job: /root/bin/monitoring/check_webservice_load.sh
- name: "Check if SSH service is running. Restart service if needed."
minute: '*/5'
hour: '*'
+2 -2
View File
@@ -116,8 +116,8 @@ cron_env_entries:
insertafter: PATH
cron_user_special_time_entries:
#cron_user_special_time_entries:
#
# - name: "Restart DNS Cache service 'systemd-resolved'"
# special_time: reboot
# job: "sleep 5 ; /bin/systemctl restart systemd-resolved"
+7
View File
@@ -112,3 +112,10 @@
daemon_reload: yes
state: restarted
- name: Reload AppArmor profile clamd
command: apparmor_parser -r /etc/apparmor.d/usr.sbin.clamd
- name: Restart clamav-daemon
service:
name: clamav-daemon
state: restarted
+213 -27
View File
@@ -1,19 +1,31 @@
---
# ---
# Samba Server
# ---
- name: (samba-install.yml) Ensure samba packages server are installed.
- name: (samba-config-server.yml) Ensure samba packages server are installed.
package:
pkg: '{{ apt_install_server_samba }}'
pkg: "{{ apt_install_server_samba }}"
state: present
when:
- "groups['samba_server']|string is search(inventory_hostname)"
- inventory_hostname in groups['samba_server']
tags:
- samba-server
- name: (samba-config-server.yml) Ensure quarantine directory exists
file:
path: /data/samba/QUARANTINE
owner: root
group: root
mode: "0750"
state: directory
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Ensure samba share directories exists
file:
path: "{{ item.path }}"
@@ -24,12 +36,197 @@
recurse: no
with_items: "{{ samba_shares }}"
loop_control:
label: '{{ item.name }}'
label: "{{ item.name }}"
when:
- "groups['samba_server']|string is search(inventory_hostname)"
- inventory_hostname in groups['samba_server']
tags:
- samba-shares
# ---
# Virusfilter (ClamAV) - only when at least one share has vfs_object_virusfilter: true
# ---
- name: (samba-config-server.yml) Ensure virusfilter (ClamAV) packages are installed
package:
pkg: "{{ apt_install_server_samba_virusfilter }}"
state: present
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Check if ClamAV virus databases are present
find:
paths: /var/lib/clamav
patterns:
- "*.cvd"
- "*.cld"
register: clamav_db_files
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Stop clamav-freshclam service before initial database download
service:
name: clamav-freshclam
state: stopped
failed_when: false
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
- clamav_db_files.files | length == 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Ensure clamav-daemon service is started before database update
service:
name: clamav-daemon
state: started
enabled: yes
failed_when: false
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Download initial ClamAV virus databases via freshclam
command: freshclam
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
- clamav_db_files.files | length == 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Ensure clamav-daemon service is enabled and started
service:
name: clamav-daemon
state: started
enabled: yes
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Ensure clamav-freshclam service is enabled and started
service:
name: clamav-freshclam
state: started
enabled: yes
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Ensure clamav user is member of all Samba groups
user:
name: clamav
groups: "{{ item.name }}"
append: yes
loop: "{{ samba_groups }}"
loop_control:
label: "{{ item.name }}"
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') |
selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
- samba_groups | length > 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Ensure clamav user is member of all Samba user groups (homes virusfilter)
user:
name: clamav
groups: "{{ item.name }}"
append: yes
loop: "{{ samba_user }}"
loop_control:
label: "{{ item.name }}"
when:
- inventory_hostname in groups['samba_server']
- samba_homes_virusfilter | default(false) | bool
- samba_user | length > 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Get home directories of samba users via getent (homes virusfilter)
ansible.builtin.getent:
database: passwd
key: "{{ item.name }}"
loop: "{{ samba_user }}"
loop_control:
label: "{{ item.name }}"
register: samba_user_getent
when:
- inventory_hostname in groups['samba_server']
- samba_homes_virusfilter | default(false) | bool
- samba_user | length > 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Ensure home directories are group-traversable for clamd (homes virusfilter)
file:
path: "{{ item.ansible_facts.getent_passwd[item.item.name][4] }}"
mode: "0750"
state: directory
loop: "{{ samba_user_getent.results | default([]) }}"
loop_control:
label: "{{ item.item.name }}"
when:
- inventory_hostname in groups['samba_server']
- samba_homes_virusfilter | default(false) | bool
- item.ansible_facts is defined
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Configure AppArmor local profile for clamd (data paths)
template:
src: etc/apparmor.d/local/usr.sbin.clamd.j2
dest: /etc/apparmor.d/local/usr.sbin.clamd
owner: root
group: root
mode: "0644"
notify: Reload AppArmor profile clamd
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') |
selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
tags:
- samba-server
- samba-virusfilter
- name: (samba-config-server.yml) Ensure AllowAllMatchScan is enabled in clamd.conf
lineinfile:
path: /etc/clamav/clamd.conf
regexp: "^#?\\s*AllowAllMatchScan\\s"
line: "AllowAllMatchScan true"
state: present
notify: Restart clamav-daemon
when:
- inventory_hostname in groups['samba_server']
- samba_shares | selectattr('vfs_object_virusfilter', 'defined') |
selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0
tags:
- samba-server
- samba-virusfilter
# ---
# /etc/samba/smb.conf
@@ -40,19 +237,18 @@
path: /etc/samba/smb.conf.ORIG
register: smb_conf_exists
when:
- "groups['samba_server']|string is search(inventory_hostname)"
- inventory_hostname in groups['samba_server']
tags:
- samba-server
- name: (samba-config-server.yml) Backup existing file /etc/samba/smb.conf
command: cp -a /etc/samba/smb.conf /etc/samba/smb.conf.ORIG
when:
- "groups['samba_server']|string is search(inventory_hostname)"
- inventory_hostname in groups['samba_server']
- smb_conf_exists.stat.exists == False
tags:
- samba-server
- name: (samba-config-server.yml) /etc/samba/smb.conf
template:
dest: /etc/samba/smb.conf
@@ -61,16 +257,13 @@
group: root
mode: 0644
when:
- "groups['samba_server']|string is search(inventory_hostname)"
- samba_user is defined and samba_user|length > 0
- samba_shares is defined and samba_shares|length > 0
- inventory_hostname in groups['samba_server']
notify:
- Restart smbd
- Restart nmbd
tags:
- samba-server
- name: (samba-config-server.yml) Ensure file /etc/samba/users.map exists
copy:
src: "{{ role_path + '/files/etc/samba/users.map' }}"
@@ -79,14 +272,13 @@
group: root
mode: 0644
when:
- "groups['samba_server']|string is search(inventory_hostname)"
- inventory_hostname in groups['samba_server']
notify:
- Restart smbd
- Restart nmbd
tags:
- samba-server
# ---
# Cronjob for cleaning up samba trash dirs
# ---
@@ -97,25 +289,25 @@
register: clean_samba_trash_exists
when:
- inventory_hostname in groups['samba_server']
tags: [samba-server, samba-cron]
tags:
- samba-server
- samba-cron
- name: (samba-config-server.yml) Adjust configuration for script 'clean_samba_trash.sh'
template:
dest: /root/bin/samba/conf/clean_samba_trash.conf
src: root/bin/samba/conf/clean_samba_trash.conf.j2
when:
- "groups['samba_server']|string is search(inventory_hostname)"
- inventory_hostname in groups['samba_server']
- clean_samba_trash_exists.stat.exists|bool
tags:
- samba-server
- samba-cron
- name: (samba-config-server.yml) Check if cleaning up trash dirs is configured
ansible.builtin.lineinfile:
path: /root/bin/samba/conf/clean_samba_trash.conf
regexp: '^trash_dirs=*'
regexp: "^trash_dirs=*"
state: absent
check_mode: true
changed_when: false
@@ -124,7 +316,6 @@
- inventory_hostname in groups['samba_server']
tags: [samba-server, samba-cron]
- name: (samba-config-server.yml) Creates a cron job for cleaning up samba trash dirs
ansible.builtin.cron:
name: "{{ samba_cronjob_trash_dirs.name }}"
@@ -141,7 +332,6 @@
- (clean_samba_trash_dirs.found | int) > 0
tags: [samba-server, samba-cron]
# ---
# Cronjob for setting permissions on samba shares
# ---
@@ -154,7 +344,6 @@
- inventory_hostname in groups['samba_server']
tags: [samba-server, samba-cron]
- name: (samba-config-server.yml) Adjust configuration for script 'set_permissions_samba_shares.sh'
ansible.builtin.template:
dest: /root/bin/samba/conf/set_permissions_samba_shares.conf
@@ -164,7 +353,6 @@
- set_permissions_on_samba_shares_exists.stat.exists | bool
tags: [samba-server, samba-cron]
- name: (samba-config-server.yml) Creates a cron job for setting permissions to samba dirs
ansible.builtin.cron:
name: "{{ samba_cronjob_permissions.name }}"
@@ -179,5 +367,3 @@
- inventory_hostname in groups['samba_server']
- (clean_samba_trash_dirs.found | int) > 0 # << int -> bool
tags: [samba-server, samba-cron]
@@ -0,0 +1,11 @@
# {{ ansible_managed }}
# see: roles/common/tasks/samba-config-server.yml
/data/** r,
/data/samba/QUARANTINE/** rw,
{% if samba_homes_virusfilter | default(false) | bool %}
{{ base_home }}/** r,
{% if base_home != '/home' %}
/home/** r,
{% endif %}
{% endif %}
+89 -5
View File
@@ -305,6 +305,14 @@
# next parameter to 'no' if you want to be able to write to them.
read only = no
{% if samba_homes_virusfilter | default(false) | bool %}
# Virusfilter aktiv: Gruppe benötigt Leserecht, damit clamd (als Gruppenmitglied)
# Dateien und Verzeichnisse direkt öffnen kann (SCAN-Kommando an clamd).
create mask = 0640
force create mode = 0040
directory mask = 0750
force directory mode = 0050
{% else %}
# File creation mask is set to 0700 for security reasons. If you want to
# create files with group=rw permissions, set next parameter to 0775.
create mask = 0700
@@ -312,6 +320,7 @@
# Directory creation mask is set to 0700 for security reasons. If you want to
# create dirs. with group=rw permissions, set next parameter to 0775.
directory mask = 0700
{% endif %}
# By default, \\server\username shares can be connected to by anyone
# with access to the samba server.
@@ -319,6 +328,35 @@
# to \\server\username
# This might need tweaking when using external authentication schemes
valid users = %S
{% if samba_homes_virusfilter | default(false) | bool %}
# --- Virusfilter-Einstellungen [homes] ---
vfs objects = virusfilter
virusfilter:scanner = clamav
virusfilter:socket path = /var/run/clamav/clamd.ctl
virusfilter:infected file action = delete
virusfilter:cache entry limit = 1000
virusfilter:cache time limit = 60
virusfilter:max file size = 26214400
virusfilter:min file size = 10
virusfilter:scan on open = yes
virusfilter:scan on close = yes
# Fehlercode bei infizierter Datei (beim Öffnen)
virusfilter:infected file errno on open = EACCES
# Fehlercode beim Schließen
virusfilter:infected file errno on close = EACCES
virusfilter:connect timeout = 30000
virusfilter:io timeout = 60000
{% endif %}
# Un-comment the following and create the netlogon directory for Domain Logons
# (you need to configure Samba to act as a domain controller too.)
@@ -412,10 +450,19 @@
#
wide links = yes
{% endif %}
{%- set vfs_objects_parts = [] %}
{% if item.vfs_object_recycle is defined and item.vfs_object_recycle|bool and item.recycle_path is defined and item.recycle_path|length > 0 %}
{%- set _ = vfs_objects_parts.append('recycle') %}
{% endif %}
{% if item.vfs_object_virusfilter is defined and item.vfs_object_virusfilter|bool %}
{%- set _ = vfs_objects_parts.append('virusfilter') %}
{% endif %}
{% if vfs_objects_parts | length > 0 %}
vfs objects = {{ vfs_objects_parts | join(' ') }}
{% endif %}
{% if item.vfs_object_recycle is defined and item.vfs_object_recycle|bool %}
{% if item.recycle_path is defined and item.recycle_path|length > 0 %}
vfs objects = recycle
recycle:keeptree = yes
# touch access time from this file
# note: this is not the modified time, which is
@@ -449,11 +496,48 @@
veto files = /{{ item.recycle_path | default('@Recycle.Bin') }}/.DS_Store/
{% endif %}
delete veto files = yes
{% else %}
{% endif %}
{% else %}
{% endif %}
{% if item.vfs_object_virusfilter is defined and item.vfs_object_virusfilter|bool %}
# --- Virusfilter-Einstellungen ---
# Scanner auswählen
virusfilter:scanner = clamav
# Socket-Pfad (Debian-Standard)
virusfilter:socket path = /var/run/clamav/clamd.ctl
# Verhalten bei Fund
virusfilter:infected file action = quarantine
virusfilter:quarantine directory = /data/samba/QUARANTINE
# Performance-Tuning: Ergebnis-Cache
#virusfilter:cache entry limit = 500
#virusfilter:cache time limit = 30
# Cache großzügig einstellen
virusfilter:cache entry limit = 1000
virusfilter:cache time limit = 60
# Dateigröße: Was wird gescannt?
#virusfilter:max file size = 52428800 # 50 MB max
virusfilter:max file size = 26214400 # 25 MB max
virusfilter:min file size = 10 # unter 10 Byte ignorieren
# Scan-Zeitpunkt: nur beim Öffnen, nicht beim Schließen
virusfilter:scan on open = yes
virusfilter:scan on close = yes
# Fehlercode bei infizierter Datei (beim Öffnen)
virusfilter:infected file errno on open = EACCES
# Fehlercode beim Schließen
virusfilter:infected file errno on close = EACCES
# Timeouts (Millisekunden)
virusfilter:connect timeout = 30000
virusfilter:io timeout = 60000
{% endif %}
{% endfor %}