Compare commits

...

3 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
7 changed files with 241 additions and 56 deletions
+3
View File
@@ -3201,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'
+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'
+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
+132 -31
View File
@@ -1,24 +1,23 @@
---
# ---
# 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:
- inventory_hostname in groups['samba_server']
tags:
- samba-server
- name: (samba-install.yml) Ensure quarantine directory exists
- name: (samba-config-server.yml) Ensure quarantine directory exists
file:
path: /data/samba/QUARANTINE
owner: root
group: root
mode: '0750'
mode: "0750"
state: directory
when:
- inventory_hostname in groups['samba_server']
@@ -37,7 +36,7 @@
recurse: no
with_items: "{{ samba_shares }}"
loop_control:
label: '{{ item.name }}'
label: "{{ item.name }}"
when:
- inventory_hostname in groups['samba_server']
tags:
@@ -47,9 +46,9 @@
# Virusfilter (ClamAV) - only when at least one share has vfs_object_virusfilter: true
# ---
- name: (samba-install.yml) Ensure virusfilter (ClamAV) packages are installed
- name: (samba-config-server.yml) Ensure virusfilter (ClamAV) packages are installed
package:
pkg: '{{ apt_install_server_samba_virusfilter }}'
pkg: "{{ apt_install_server_samba_virusfilter }}"
state: present
when:
- inventory_hostname in groups['samba_server']
@@ -58,13 +57,13 @@
- samba-server
- samba-virusfilter
- name: (samba-install.yml) Ensure clamav-daemon and clamav-freshclam services are enabled
service:
name: "{{ item }}"
enabled: yes
loop:
- clamav-daemon
- clamav-freshclam
- 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
@@ -72,7 +71,67 @@
- samba-server
- samba-virusfilter
- name: (samba-install.yml) Ensure clamav user is member of all Samba groups
- 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 }}"
@@ -89,17 +148,62 @@
- samba-server
- samba-virusfilter
- name: (samba-install.yml) Configure AppArmor local profile for clamd (data paths)
blockinfile:
path: /etc/apparmor.d/local/usr.sbin.clamd
create: yes
- 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"
marker: "# {mark} ANSIBLE MANAGED - smba virusfilter paths"
block: |
/data/** r,
/data/samba/QUARANTINE/** rw,
notify: Reload AppArmor profile clamd
when:
- inventory_hostname in groups['samba_server']
@@ -109,7 +213,7 @@
- samba-server
- samba-virusfilter
- name: (samba-install.yml) Ensure AllowAllMatchScan is enabled in clamd.conf
- name: (samba-config-server.yml) Ensure AllowAllMatchScan is enabled in clamd.conf
lineinfile:
path: /etc/clamav/clamd.conf
regexp: "^#?\\s*AllowAllMatchScan\\s"
@@ -124,7 +228,6 @@
- samba-server
- samba-virusfilter
# ---
# /etc/samba/smb.conf
# ---
@@ -191,7 +294,7 @@
- samba-cron
- name: (samba-config-server.yml) Adjust configuration for script 'clean_samba_trash.sh'
template:
template:
dest: /root/bin/samba/conf/clean_samba_trash.conf
src: root/bin/samba/conf/clean_samba_trash.conf.j2
when:
@@ -204,7 +307,7 @@
- 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
@@ -262,7 +365,5 @@
job: "{{ samba_cronjob_permissions.job }}"
when:
- inventory_hostname in groups['samba_server']
- (clean_samba_trash_dirs.found | int) > 0 # << int -> bool
- (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 %}
+69 -25
View File
@@ -6,7 +6,7 @@
#
# This is the main Samba configuration file. You should read the
# smb.conf(5) manual page in order to understand the options listed
# here. Samba has a huge number of configurable options most of which
# here. Samba has a huge number of configurable options most of which
# are not shown in this example
#
# Some options that are often worth tuning have been included as
@@ -18,8 +18,8 @@
# enough to be mentioned here
#
# NOTE: Whenever you modify this file you should run the command
# "testparm" to check that you have not made any basic syntactic
# errors.
# "testparm" to check that you have not made any basic syntactic
# errors.
#======================= Global Settings =======================
@@ -31,11 +31,11 @@
; workgroup = WORKGROUP
workgroup = {{ samba_workgroup|default('WORKGROUP') }}
# Option 'netbios name' added to debian's default smb.conf
# Option 'netbios name' added to debian's default smb.conf
#
# This sets the NetBIOS name by which a Samba server is known. By default it
# is the same as the first component of the host's DNS name. If a machine is
# a browse server or logon server this name (or the first component of the
# a browse server or logon server this name (or the first component of the
# hosts DNS name) will be the name that these services are advertised under.
#
# Note that the maximum length for a NetBIOS name is 15 characters.
@@ -46,9 +46,9 @@
{% if samba_server_min_protocol is defined and samba_server_min_protocol|length > 0 %}
# This setting controls the minimum protocol version that the server will allow
# the client to use. Normally this option should not be set as the automatic
# negotiation phase in the SMB protocol takes care of choosing the appropriate
# This setting controls the minimum protocol version that the server will allow
# the client to use. Normally this option should not be set as the automatic
# negotiation phase in the SMB protocol takes care of choosing the appropriate
# protocol unless you have legacy clients which are SMB1 capable only.
#
# See Related command: server max protocol for a full list of available protocols.
@@ -69,7 +69,7 @@
; interfaces = 127.0.0.0/8 eth0
interfaces = {{ samba_server_ip }}/{{ samba_server_cidr_prefix }} 127.0.0.1/8
# Option 'hosts deny' and 'hosts allow' added to debian's default smb.conf
# Option 'hosts deny' and 'hosts allow' added to debian's default smb.conf
hosts deny = 0.0.0.0/0
hosts allow = 192.168.0.0/16 10.0.0.0/8 127.0.0.0/8
@@ -80,8 +80,8 @@
# option cannot handle dynamic or non-broadcast interfaces correctly.
#
# Notice:
# If bind interfaces only is set and the network address 127.0.0.1 is not added to the
# interfaces parameter list smbpasswd(8) may not work as expected due to the reasons
# If bind interfaces only is set and the network address 127.0.0.1 is not added to the
# interfaces parameter list smbpasswd(8) may not work as expected due to the reasons
# covered below.
#
# Default: bind interfaces only = no
@@ -103,13 +103,13 @@
# Append syslog@1 if you want important messages to be sent to syslog too.
logging = file
# Option 'log level' added to debian's default smb.conf
# Option 'log level' added to debian's default smb.conf
#
# The value of the parameter (a astring) allows the debug level (logging level) to be
# The value of the parameter (a astring) allows the debug level (logging level) to be
# specified in the smb.conf file.
#
# This parameter has been extended since the 2.2.x series, now it allows one to specify
# the debug level for multiple debug classes. This is to give greater flexibility in
# This parameter has been extended since the 2.2.x series, now it allows one to specify
# the debug level for multiple debug classes. This is to give greater flexibility in
# the configuration of the system.
#
# See manpage for implemented debug classes
@@ -125,7 +125,7 @@
####### Authentication #######
# Option 'ntlm auth' added to debian's default smb.conf
# Option 'ntlm auth' added to debian's default smb.conf
#
# This parameter determines whether or not smbd(8) will attempt to authenticate
# users using the NTLM encrypted password response for this local passdb (SAM
@@ -167,7 +167,7 @@
# Server role. Defines in which mode Samba will operate. Possible
# values are "standalone server", "member server", "classic primary
# domain controller", "classic backup domain controller", "active
# directory domain controller".
# directory domain controller".
#
# Most people will want "standalone server" or "member server".
# Running as "active directory domain controller" will require first
@@ -197,7 +197,7 @@
# to anonymous connections
map to guest = bad user
# Option 'username map' added to debian's default smb.conf
# Option 'username map' added to debian's default smb.conf
#
username map = /etc/samba/users.map
@@ -206,7 +206,7 @@
#
# The following settings only takes effect if 'server role = primary
# classic domain controller', 'server role = backup domain controller'
# or 'domain logons' is set
# or 'domain logons' is set
#
# It specifies the location of the user's
@@ -235,13 +235,13 @@
# password; please adapt to your needs
; add user script = /usr/sbin/adduser --quiet --disabled-password --gecos "" %u
# This allows machine accounts to be created on the domain controller via the
# SAMR RPC pipe.
# This allows machine accounts to be created on the domain controller via the
# SAMR RPC pipe.
# The following assumes a "machines" group exists on the system
; add machine script = /usr/sbin/useradd -g machines -c "%u machine account" -d /var/lib/samba -s /bin/false %u
# This allows Unix groups to be created on the domain controller via the SAMR
# RPC pipe.
# RPC pipe.
; add group script = /usr/sbin/addgroup --force-badname %g
############ Misc ############
@@ -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.)
@@ -447,8 +485,8 @@
recycle:excludedir = /tmp,/temp,/cache,.Trash
recycle:repository = {{ item.recycle_path | default('@Recycle.Bin') }}
# - This is a list of files and directories that are neither visible nor accessible.
# - Each entry in the list must be separated by a '/', which allows spaces to be
# - This is a list of files and directories that are neither visible nor accessible.
# - Each entry in the list must be separated by a '/', which allows spaces to be
# - included in the entry. '*' and '?' can be used to specify multiple files or
# - directories as in DOS wildcards.
# -
@@ -489,7 +527,13 @@
# Scan-Zeitpunkt: nur beim Öffnen, nicht beim Schließen
virusfilter:scan on open = yes
virusfilter:scan on close = no
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