148 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ config, lib, pkgs, ... }:
 | 
						|
with lib;
 | 
						|
let
 | 
						|
  clamavUser = "clamav";
 | 
						|
  stateDir = "/var/lib/clamav";
 | 
						|
  runDir = "/run/clamav";
 | 
						|
  clamavGroup = clamavUser;
 | 
						|
  cfg = config.services.clamav;
 | 
						|
  pkg = pkgs.clamav;
 | 
						|
 | 
						|
  clamdConfigFile = pkgs.writeText "clamd.conf" ''
 | 
						|
    DatabaseDirectory ${stateDir}
 | 
						|
    LocalSocket ${runDir}/clamd.ctl
 | 
						|
    PidFile ${runDir}/clamd.pid
 | 
						|
    TemporaryDirectory /tmp
 | 
						|
    User clamav
 | 
						|
    Foreground yes
 | 
						|
 | 
						|
    ${cfg.daemon.extraConfig}
 | 
						|
  '';
 | 
						|
 | 
						|
  freshclamConfigFile = pkgs.writeText "freshclam.conf" ''
 | 
						|
    DatabaseDirectory ${stateDir}
 | 
						|
    Foreground yes
 | 
						|
    Checks ${toString cfg.updater.frequency}
 | 
						|
 | 
						|
    ${cfg.updater.extraConfig}
 | 
						|
 | 
						|
    DatabaseMirror database.clamav.net
 | 
						|
  '';
 | 
						|
in
 | 
						|
{
 | 
						|
  imports = [
 | 
						|
    (mkRenamedOptionModule [ "services" "clamav" "updater" "config" ] [ "services" "clamav" "updater" "extraConfig" ])
 | 
						|
  ];
 | 
						|
 | 
						|
  options = {
 | 
						|
    services.clamav = {
 | 
						|
      daemon = {
 | 
						|
        enable = mkEnableOption "ClamAV clamd daemon";
 | 
						|
 | 
						|
        extraConfig = mkOption {
 | 
						|
          type = types.lines;
 | 
						|
          default = "";
 | 
						|
          description = ''
 | 
						|
            Extra configuration for clamd. Contents will be added verbatim to the
 | 
						|
            configuration file.
 | 
						|
          '';
 | 
						|
        };
 | 
						|
      };
 | 
						|
      updater = {
 | 
						|
        enable = mkEnableOption "ClamAV freshclam updater";
 | 
						|
 | 
						|
        frequency = mkOption {
 | 
						|
          type = types.int;
 | 
						|
          default = 12;
 | 
						|
          description = ''
 | 
						|
            Number of database checks per day.
 | 
						|
          '';
 | 
						|
        };
 | 
						|
 | 
						|
        interval = mkOption {
 | 
						|
          type = types.str;
 | 
						|
          default = "hourly";
 | 
						|
          description = ''
 | 
						|
            How often freshclam is invoked. See systemd.time(7) for more
 | 
						|
            information about the format.
 | 
						|
          '';
 | 
						|
        };
 | 
						|
 | 
						|
        extraConfig = mkOption {
 | 
						|
          type = types.lines;
 | 
						|
          default = "";
 | 
						|
          description = ''
 | 
						|
            Extra configuration for freshclam. Contents will be added verbatim to the
 | 
						|
            configuration file.
 | 
						|
          '';
 | 
						|
        };
 | 
						|
      };
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
  config = mkIf (cfg.updater.enable || cfg.daemon.enable) {
 | 
						|
    environment.systemPackages = [ pkg ];
 | 
						|
 | 
						|
    users.users.${clamavUser} = {
 | 
						|
      uid = config.ids.uids.clamav;
 | 
						|
      group = clamavGroup;
 | 
						|
      description = "ClamAV daemon user";
 | 
						|
      home = stateDir;
 | 
						|
    };
 | 
						|
 | 
						|
    users.groups.${clamavGroup} =
 | 
						|
      { gid = config.ids.gids.clamav; };
 | 
						|
 | 
						|
    environment.etc."clamav/freshclam.conf".source = freshclamConfigFile;
 | 
						|
    environment.etc."clamav/clamd.conf".source = clamdConfigFile;
 | 
						|
 | 
						|
    systemd.services.clamav-daemon = mkIf cfg.daemon.enable {
 | 
						|
      description = "ClamAV daemon (clamd)";
 | 
						|
      after = optional cfg.updater.enable "clamav-freshclam.service";
 | 
						|
      requires = optional cfg.updater.enable "clamav-freshclam.service";
 | 
						|
      wantedBy = [ "multi-user.target" ];
 | 
						|
      restartTriggers = [ clamdConfigFile ];
 | 
						|
 | 
						|
      preStart = ''
 | 
						|
        mkdir -m 0755 -p ${runDir}
 | 
						|
        chown ${clamavUser}:${clamavGroup} ${runDir}
 | 
						|
      '';
 | 
						|
 | 
						|
      serviceConfig = {
 | 
						|
        ExecStart = "${pkg}/bin/clamd";
 | 
						|
        ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID";
 | 
						|
        PrivateTmp = "yes";
 | 
						|
        PrivateDevices = "yes";
 | 
						|
        PrivateNetwork = "yes";
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    systemd.timers.clamav-freshclam = mkIf cfg.updater.enable {
 | 
						|
      description = "Timer for ClamAV virus database updater (freshclam)";
 | 
						|
      wantedBy = [ "timers.target" ];
 | 
						|
      timerConfig = {
 | 
						|
        OnCalendar = cfg.updater.interval;
 | 
						|
        Unit = "clamav-freshclam.service";
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    systemd.services.clamav-freshclam = mkIf cfg.updater.enable {
 | 
						|
      description = "ClamAV virus database updater (freshclam)";
 | 
						|
      restartTriggers = [ freshclamConfigFile ];
 | 
						|
 | 
						|
      preStart = ''
 | 
						|
        mkdir -m 0755 -p ${stateDir}
 | 
						|
        chown ${clamavUser}:${clamavGroup} ${stateDir}
 | 
						|
      '';
 | 
						|
 | 
						|
      serviceConfig = {
 | 
						|
        Type = "oneshot";
 | 
						|
        ExecStart = "${pkg}/bin/freshclam";
 | 
						|
        SuccessExitStatus = "1"; # if databases are up to date
 | 
						|
        PrivateTmp = "yes";
 | 
						|
        PrivateDevices = "yes";
 | 
						|
      };
 | 
						|
    };
 | 
						|
  };
 | 
						|
}
 |