From 91bda857dcab8a32a87b0e7f7198094e420014d5 Mon Sep 17 00:00:00 2001 From: Christoph Date: Tue, 26 May 2026 02:18:17 +0200 Subject: [PATCH] Add ClamAV integration and AppArmor configuration for Samba virusfilter support --- roles/common/handlers/main.yml | 8 ++ roles/common/tasks/samba-install.yml | 119 +++++++++++++------ roles/common/templates/etc/samba/smb.conf.j2 | 54 +++++---- 3 files changed, 120 insertions(+), 61 deletions(-) diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml index 14eb95a..dc67e37 100644 --- a/roles/common/handlers/main.yml +++ b/roles/common/handlers/main.yml @@ -109,3 +109,11 @@ service: name: nfs-kernel-server 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 diff --git a/roles/common/tasks/samba-install.yml b/roles/common/tasks/samba-install.yml index cc08f4a..5f92a56 100644 --- a/roles/common/tasks/samba-install.yml +++ b/roles/common/tasks/samba-install.yml @@ -6,25 +6,25 @@ - name: (samba-install.yml) Ensure samba packages server (buster) are installed. package: - pkg: '{{ apt_install_server_samba }}' + pkg: "{{ apt_install_server_samba }}" state: present when: - "groups['samba_server']|string is search(inventory_hostname)" tags: - samba-server - # --- # Virusfilter (ClamAV) — only when at least one share has vfs_object_virusfilter: true # --- - name: (samba-install.yml) Ensure virusfilter (ClamAV) packages are installed package: - pkg: '{{ apt_install_server_samba_virusfilter }}' + pkg: "{{ apt_install_server_samba_virusfilter }}" state: present when: - "groups['samba_server']|string is search(inventory_hostname)" - - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0 + - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | + selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0 tags: - samba-server - samba-virusfilter @@ -34,32 +34,83 @@ path: /data/samba/QUARANTINE owner: root group: root - mode: '0750' + mode: "0750" state: directory when: - "groups['samba_server']|string is search(inventory_hostname)" - - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0 + - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | + selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0 tags: - samba-server - samba-virusfilter +- name: (samba-install.yml) Ensure clamav user is member of all NIS groups + user: + name: clamav + groups: "{{ item.name }}" + append: yes + loop: "{{ nis_groups }}" + loop_control: + label: "{{ item.name }}" + when: + - "groups['samba_server']|string is search(inventory_hostname)" + - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | + selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0 + - nis_groups | length > 0 + tags: + - 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 + 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: + - "groups['samba_server']|string is search(inventory_hostname)" + - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | + selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0 + tags: + - samba-server + - samba-virusfilter + +- name: (samba-install.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: + - "groups['samba_server']|string is search(inventory_hostname)" + - samba_shares | selectattr('vfs_object_virusfilter', 'defined') | + selectattr('vfs_object_virusfilter', 'equalto', true) | list | length > 0 + tags: + - samba-server + - samba-virusfilter - name: (samba-install.yml) Ensure samba share directories exists file: path: "{{ item.path }}" owner: "root" group: "{{ item.group_write_list }}" - mode: '2770' + mode: "2770" state: directory with_items: "{{ samba_shares }}" loop_control: - label: '{{ item.name }}' + label: "{{ item.name }}" when: - "groups['samba_server']|string is search(inventory_hostname)" tags: - samba-shares - # --- # /etc/samba/smb.conf # --- @@ -81,14 +132,13 @@ tags: - samba-server - - name: (samba-install.yml) /etc/samba/smb.conf template: dest: /etc/samba/smb.conf src: etc/samba/smb.conf.j2 owner: root group: root - mode: 0644 + mode: 644 when: - "groups['samba_server']|string is search(inventory_hostname)" notify: @@ -97,14 +147,13 @@ tags: - samba-server - - name: (samba-install.yml) Ensure file /etc/samba/users.map exists copy: src: "{{ role_path + '/files/etc/samba/users.map' }}" dest: /etc/samba/users.map owner: root group: root - mode: 0644 + mode: 644 when: - "groups['samba_server']|string is search(inventory_hostname)" notify: @@ -113,12 +162,12 @@ tags: - samba-server - # --- # Cronjob for cleaning up samba trash dirs # --- -- name: (samba-install.yml) Check if file '/root/bin/samba/clean_samba_trash.sh' exists +- name: (samba-install.yml) Check if file '/root/bin/samba/clean_samba_trash.sh' + exists stat: path: /root/bin/samba/clean_samba_trash.sh register: clean_samba_trash_exists @@ -128,7 +177,7 @@ - samba-server - name: (samba-install.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: @@ -137,20 +186,18 @@ tags: - samba-server - - 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 register: clean_samba_trash_dirs - when: + when: - inventory_hostname in groups['samba_server'] - tags: [samba-server, samba-cron] - - + 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 }}" @@ -165,33 +212,33 @@ - inventory_hostname in groups['samba_server'] - clean_samba_trash_exists.stat.exists | bool - (clean_samba_trash_dirs.found | int) > 0 - tags: [samba-server, samba-cron] - + tags: [ samba-server, samba-cron ] # --- # Cronjob for setting permissions on samba shares # --- -- name: (samba-config-server.yml) Check if file '/root/bin/samba/set_permissions_samba_shares.sh' exists +- name: (samba-config-server.yml) Check if file + '/root/bin/samba/set_permissions_samba_shares.sh' exists ansible.builtin.stat: path: /root/bin/samba/set_permissions_samba_shares.sh register: set_permissions_on_samba_shares_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 'set_permissions_samba_shares.sh' +- 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 src: root/bin/samba/conf/set_permissions_samba_shares.conf.j2 when: - inventory_hostname in groups['samba_server'] - 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 + 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 }}" minute: "{{ samba_cronjob_permissions.minute }}" @@ -203,9 +250,8 @@ job: "{{ samba_cronjob_permissions.job }}" when: - inventory_hostname in groups['samba_server'] - - (clean_samba_trash_dirs.found | int) > 0 # << int -> bool - tags: [samba-server, samba-cron] - + - (clean_samba_trash_dirs.found | int) > 0 # << int -> bool + tags: [ samba-server, samba-cron ] # --- # Samba clients @@ -215,9 +261,8 @@ package: pkg: "{{ apt_install_client_samba }}" state: present - when: + when: - "groups['nis_client']|string is search(inventory_hostname)" - ansible_distribution == "Ubuntu" tags: - samba-client - diff --git a/roles/common/templates/etc/samba/smb.conf.j2 b/roles/common/templates/etc/samba/smb.conf.j2 index ae805f4..f0dbe44 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 @@ -92,7 +92,7 @@ # This tells Samba to use a separate log file for each machine # that connects -; log file = /var/log/samba/log.%m + log file = /var/log/samba/log.%m log file = /var/log/samba/%I.log # Cap the size of the individual log files (in KiB). @@ -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 ############ @@ -489,7 +489,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