Commit 25a78835 authored by Gary Guo's avatar Gary Guo
Browse files

nixos/clamav: add ClamAV on-access scanner support

parent c44e74ba
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -65,6 +65,34 @@ in
          '';
        };
      };

      clamonacc = {
        enable = lib.mkOption {
          default = false;
          example = true;
          description = ''
            Whether to enable ClamAV on-access scanner.

            The settings for ClamAV's on-access scanner is configured in `clamd.conf` via `services.clamav.daemon.settings`.
            Refer to <https://docs.clamav.net/manual/OnAccess.html> on how to configure it.

            Example to scan `/home/foo/Downloads` (and block access until scanning is completed) would be:
            ```
            services.clamav = {
              daemon.enable = true;
              clamonacc.enable = true;

              daemon.settings = {
                OnAccessPrevention = true;
                OnAccessIncludePath = "/home/foo/Downloads";
              };
            };
            ```
          '';
          type = lib.types.bool;
        };
      };

      updater = {
        enable = lib.mkEnableOption "ClamAV freshclam updater";

@@ -177,6 +205,10 @@ in
        assertion = cfg.scanner.enable -> cfg.daemon.enable;
        message = "ClamAV scanner requires ClamAV daemon to operate";
      }
      {
        assertion = cfg.clamonacc.enable -> cfg.daemon.enable;
        message = "ClamAV on-access scanner requires ClamAV daemon to operate";
      }
    ];

    environment.systemPackages = [ cfg.package ];
@@ -198,6 +230,8 @@ in
      PidFile = "/run/clamav/clamd.pid";
      User = clamavUser;
      Foreground = true;
      # Prevent infinite recursion in scanning
      OnAccessExcludeUname = clamavUser;
    };

    services.clamav.updater.settings = {
@@ -258,6 +292,20 @@ in
      };
    };

    systemd.services.clamav-clamonacc = lib.mkIf cfg.clamonacc.enable {
      description = "ClamAV on-access scanner (clamonacc)";
      after = [ "clamav-daemon.socket" ];
      requires = [ "clamav-daemon.socket" ];
      wantedBy = [ "multi-user.target" ];
      restartTriggers = [ clamdConfigFile ];

      # This unit must start as root to be able to use fanotify.
      serviceConfig = {
        ExecStart = "${cfg.package}/bin/clamonacc -F --fdpass";
        Slice = "system-clamav.slice";
      };
    };

    systemd.timers.clamav-freshclam = lib.mkIf cfg.updater.enable {
      description = "Timer for ClamAV virus database updater (freshclam)";
      wantedBy = [ "timers.target" ];