diff --git a/nixos/modules/services/security/clamav.nix b/nixos/modules/services/security/clamav.nix index a4d54301fc17..548aee29b266 100644 --- a/nixos/modules/services/security/clamav.nix +++ b/nixos/modules/services/security/clamav.nix @@ -3,78 +3,115 @@ with lib; let clamavUser = "clamav"; stateDir = "/var/lib/clamav"; + runDir = "/var/run/clamav"; + logDir = "/var/log/clamav"; clamavGroup = clamavUser; cfg = config.services.clamav; + clamdConfigFile = pkgs.writeText "clamd.conf" '' + DatabaseDirectory ${stateDir} + LocalSocket ${runDir}/clamd.ctl + LogFile ${logDir}/clamav.log + PidFile ${runDir}/clamd.pid + User clamav + + ${cfg.daemon.extraConfig} + ''; in { - ###### interface - options = { - services.clamav = { + daemon = { + enable = mkEnableOption "clamd daemon"; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration for clamd. Contents will be added verbatim to the + configuration file. + ''; + }; + }; updater = { - enable = mkOption { - default = false; - description = '' - Whether to enable automatic ClamAV virus definitions database updates. - ''; - }; + enable = mkEnableOption "freshclam updater"; - frequency = mkOption { - default = 12; - description = '' - Number of database checks per day. - ''; - }; + frequency = mkOption { + default = 12; + description = '' + Number of database checks per day. + ''; + }; - config = mkOption { - default = ""; - description = '' - Extra configuration for freshclam. Contents will be added verbatim to the - configuration file. - ''; - }; + config = mkOption { + default = ""; + description = '' + Extra configuration for freshclam. Contents will be added verbatim to the + configuration file. + ''; + }; }; }; }; - ###### implementation - - config = mkIf cfg.updater.enable { + config = mkIf cfg.updater.enable or cfg.daemon.enable { environment.systemPackages = [ pkgs.clamav ]; - users.extraUsers = singleton - { name = clamavUser; - uid = config.ids.uids.clamav; - description = "ClamAV daemon user"; - home = stateDir; - }; + users.extraUsers = singleton { + name = clamavUser; + uid = config.ids.uids.clamav; + description = "ClamAV daemon user"; + home = stateDir; + }; - users.extraGroups = singleton - { name = clamavGroup; - gid = config.ids.gids.clamav; - }; + users.extraGroups = singleton { + name = clamavGroup; + gid = config.ids.gids.clamav; + }; - services.clamav.updater.config = '' + services.clamav.updater.config = mkIf cfg.updater.enable '' DatabaseDirectory ${stateDir} Foreground yes Checks ${toString cfg.updater.frequency} DatabaseMirror database.clamav.net ''; - jobs = { - clamav_updater = { - name = "clamav-updater"; - startOn = "started network-interfaces"; - stopOn = "stopping network-interfaces"; - - preStart = '' - mkdir -m 0755 -p ${stateDir} - chown ${clamavUser}:${clamavGroup} ${stateDir} - ''; - exec = "${pkgs.clamav}/bin/freshclam --daemon --config-file=${pkgs.writeText "freshclam.conf" cfg.updater.config}"; - }; + systemd.services.clamd = mkIf cfg.daemon.enable { + description = "ClamAV daemon (clamd)"; + path = [ pkgs.clamav ]; + after = [ "network.target" "freshclam.service" ]; + requires = [ "freshclam.service" ]; + wantedBy = [ "multi-user.target" ]; + preStart = '' + mkdir -m 0755 -p ${logDir} + mkdir -m 0755 -p ${runDir} + chown ${clamavUser}:${clamavGroup} ${logDir} + chown ${clamavUser}:${clamavGroup} ${runDir} + ''; + serviceConfig = { + ExecStart = "${pkgs.clamav}/bin/clamd --config-file=${clamdConfigFile}"; + Type = "forking"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + Restart = "on-failure"; + RestartSec = "10s"; + StartLimitInterval = "1min"; + }; }; + systemd.services.freshclam = mkIf cfg.updater.enable { + description = "ClamAV updater (freshclam)"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.clamav ]; + preStart = '' + mkdir -m 0755 -p ${stateDir} + chown ${clamavUser}:${clamavGroup} ${stateDir} + ''; + serviceConfig = { + ExecStart = "${pkgs.clamav}/bin/freshclam --daemon --config-file=${pkgs.writeText "freshclam.conf" cfg.updater.config}"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + Restart = "on-failure"; + RestartSec = "10s"; + StartLimitInterval = "1min"; + }; + }; }; - }