{ config, lib, pkgs, ... }: with lib; let cfg = config.numbus.services.clamav; onAccessPaths = lib.mapAttrsToList (n: v: v.dataDir) (lib.filterAttrs (n: v: v ? enable && v.enable && v ? dataDir && v.dataDir != null && v.dataDir != false ) config.numbus.services); in { options.numbus.services.clamav = { enable = mkEnableOption "ClamAV open-source anti-virus software"; }; config = mkIf cfg.enable { environment.systemPackages = [ pkgs.clamav pkgs.curl ]; security.sudo.extraRules = [{ users = [ "clamav" ]; commands = [{ command = "/run/current-system/sw/bin/systemctl start clamav-virus-notify.service"; options = [ "NOPASSWD" ]; }]; }]; services.clamav = { updater.enable = true; clamonacc.enable = true; scanner = { enable = true; interval = "*-*-* 04:00:00"; # Everyday at 4am scanDirectories = [ "/etc" "/home" "/var/lib" "/var/tmp" "/tmp" ]; }; daemon = { enable = true; settings = { OnAccessPrevention = true; OnAccessIncludePath = onAccessPaths; VirusEvent = "printf 'CLAM_VIRUSEVENT_VIRUSNAME=\"%v\"\\nCLAM_VIRUSEVENT_FILENAME=\"%f\"\\n' > /var/lib/clamav/virus_event.env && /run/wrappers/bin/sudo /run/current-system/sw/bin/systemctl start clamav-virus-notify.service"; }; }; }; systemd.services.clamav-periodic-scan = mkIf (onAccessPaths != []) { description = "ClamAV periodic scan of service data directories"; after = [ "clamav-daemon.service" ]; requires = [ "clamav-daemon.service" ]; onFailure = [ "clamav-virus-notify.service" ]; serviceConfig = { Type = "oneshot"; ExecStart = "${pkgs.clamav}/bin/clamdscan --fdpass --multiscan ${lib.escapeShellArgs onAccessPaths}"; User = "clamav"; Group = "clamav"; SupplementaryGroups = [ "users" ]; TimeoutStartSec = "infinity"; }; }; systemd.timers.clamav-periodic-scan = mkIf (onAccessPaths != []) { description = "Timer for ClamAV periodic scan"; wantedBy = [ "timers.target" ]; timerConfig = { OnCalendar = "*-1/2-01 04:00:00"; Persistent = true; Unit = "clamav-periodic-scan.service"; }; }; }; }