From 6e086dbac0733ad085cb3a62baae995463dde0fd Mon Sep 17 00:00:00 2001 From: Christoph Date: Fri, 29 May 2026 18:43:06 +0200 Subject: [PATCH] Add virusfilter support for Samba homes and update AppArmor configuration --- group_vars/all/main.yml | 3 + host_vars/file-ah.kanzlei-kiel.netz.yml | 5 + host_vars/file-km-neu.anw-km.netz.yml | 2 + roles/common/tasks/samba-config-server.yml | 128 +++++++++++++----- .../etc/apparmor.d/local/usr.sbin.clamd.j2 | 11 ++ roles/common/templates/etc/samba/smb.conf.j2 | 94 +++++++++---- 6 files changed, 186 insertions(+), 57 deletions(-) create mode 100644 roles/common/templates/etc/apparmor.d/local/usr.sbin.clamd.j2 diff --git a/group_vars/all/main.yml b/group_vars/all/main.yml index b4279fe..f53117f 100644 --- a/group_vars/all/main.yml +++ b/group_vars/all/main.yml @@ -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 diff --git a/host_vars/file-ah.kanzlei-kiel.netz.yml b/host_vars/file-ah.kanzlei-kiel.netz.yml index 2f47400..9bd9f61 100644 --- a/host_vars/file-ah.kanzlei-kiel.netz.yml +++ b/host_vars/file-ah.kanzlei-kiel.netz.yml @@ -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' diff --git a/host_vars/file-km-neu.anw-km.netz.yml b/host_vars/file-km-neu.anw-km.netz.yml index e09099d..56f0849 100644 --- a/host_vars/file-km-neu.anw-km.netz.yml +++ b/host_vars/file-km-neu.anw-km.netz.yml @@ -643,6 +643,8 @@ samba_user: base_home: /data/home +samba_homes_virusfilter: true + remove_samba_users: - name: howe-staff-1 - name: gerhard diff --git a/roles/common/tasks/samba-config-server.yml b/roles/common/tasks/samba-config-server.yml index b4bec05..a554101 100644 --- a/roles/common/tasks/samba-config-server.yml +++ b/roles/common/tasks/samba-config-server.yml @@ -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,7 +57,7 @@ - samba-server - samba-virusfilter -- name: (samba-install.yml) Check if ClamAV virus databases are present +- name: (samba-config-server.yml) Check if ClamAV virus databases are present find: paths: /var/lib/clamav patterns: @@ -72,7 +71,7 @@ - samba-server - samba-virusfilter -- name: (samba-install.yml) Stop clamav-freshclam service before initial database download +- name: (samba-config-server.yml) Stop clamav-freshclam service before initial database download service: name: clamav-freshclam state: stopped @@ -85,7 +84,20 @@ - samba-server - samba-virusfilter -- name: (samba-install.yml) Download initial ClamAV virus databases via freshclam +- 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'] @@ -95,13 +107,11 @@ - samba-server - samba-virusfilter -- name: (samba-install.yml) Ensure clamav-daemon and clamav-freshclam services are enabled +- name: (samba-config-server.yml) Ensure clamav-daemon service is enabled and started service: - name: "{{ item }}" + name: clamav-daemon + state: started enabled: yes - loop: - - clamav-daemon - - clamav-freshclam when: - inventory_hostname in groups['samba_server'] - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0 @@ -109,7 +119,19 @@ - samba-server - samba-virusfilter -- name: (samba-install.yml) Ensure clamav user is member of all Samba groups +- 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 }}" @@ -126,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'] @@ -146,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" @@ -161,7 +228,6 @@ - samba-server - samba-virusfilter - # --- # /etc/samba/smb.conf # --- @@ -228,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: @@ -241,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 @@ -299,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] - - diff --git a/roles/common/templates/etc/apparmor.d/local/usr.sbin.clamd.j2 b/roles/common/templates/etc/apparmor.d/local/usr.sbin.clamd.j2 new file mode 100644 index 0000000..240ed85 --- /dev/null +++ b/roles/common/templates/etc/apparmor.d/local/usr.sbin.clamd.j2 @@ -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 %} diff --git a/roles/common/templates/etc/samba/smb.conf.j2 b/roles/common/templates/etc/samba/smb.conf.j2 index 28bd117..1865a5c 100644 --- a/roles/common/templates/etc/samba/smb.conf.j2 +++ b/roles/common/templates/etc/samba/smb.conf.j2 @@ -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