at 18.09-beta 3.9 kB view raw
1{ config, lib, pkgs, ... }: 2with lib; 3let 4 clamavUser = "clamav"; 5 stateDir = "/var/lib/clamav"; 6 runDir = "/run/clamav"; 7 clamavGroup = clamavUser; 8 cfg = config.services.clamav; 9 pkg = pkgs.clamav; 10 11 clamdConfigFile = pkgs.writeText "clamd.conf" '' 12 DatabaseDirectory ${stateDir} 13 LocalSocket ${runDir}/clamd.ctl 14 PidFile ${runDir}/clamd.pid 15 TemporaryDirectory /tmp 16 User clamav 17 Foreground yes 18 19 ${cfg.daemon.extraConfig} 20 ''; 21 22 freshclamConfigFile = pkgs.writeText "freshclam.conf" '' 23 DatabaseDirectory ${stateDir} 24 Foreground yes 25 Checks ${toString cfg.updater.frequency} 26 27 ${cfg.updater.extraConfig} 28 29 DatabaseMirror database.clamav.net 30 ''; 31in 32{ 33 options = { 34 services.clamav = { 35 daemon = { 36 enable = mkEnableOption "ClamAV clamd daemon"; 37 38 extraConfig = mkOption { 39 type = types.lines; 40 default = ""; 41 description = '' 42 Extra configuration for clamd. Contents will be added verbatim to the 43 configuration file. 44 ''; 45 }; 46 }; 47 updater = { 48 enable = mkEnableOption "ClamAV freshclam updater"; 49 50 frequency = mkOption { 51 type = types.int; 52 default = 12; 53 description = '' 54 Number of database checks per day. 55 ''; 56 }; 57 58 interval = mkOption { 59 type = types.str; 60 default = "hourly"; 61 description = '' 62 How often freshclam is invoked. See systemd.time(7) for more 63 information about the format. 64 ''; 65 }; 66 67 extraConfig = mkOption { 68 type = types.lines; 69 default = ""; 70 description = '' 71 Extra configuration for freshclam. Contents will be added verbatim to the 72 configuration file. 73 ''; 74 }; 75 }; 76 }; 77 }; 78 79 config = mkIf (cfg.updater.enable || cfg.daemon.enable) { 80 environment.systemPackages = [ pkg ]; 81 82 users.users = singleton { 83 name = clamavUser; 84 uid = config.ids.uids.clamav; 85 group = clamavGroup; 86 description = "ClamAV daemon user"; 87 home = stateDir; 88 }; 89 90 users.groups = singleton { 91 name = clamavGroup; 92 gid = config.ids.gids.clamav; 93 }; 94 95 environment.etc."clamav/freshclam.conf".source = freshclamConfigFile; 96 environment.etc."clamav/clamd.conf".source = clamdConfigFile; 97 98 systemd.services.clamav-daemon = optionalAttrs cfg.daemon.enable { 99 description = "ClamAV daemon (clamd)"; 100 after = optional cfg.updater.enable "clamav-freshclam.service"; 101 requires = optional cfg.updater.enable "clamav-freshclam.service"; 102 wantedBy = [ "multi-user.target" ]; 103 restartTriggers = [ clamdConfigFile ]; 104 105 preStart = '' 106 mkdir -m 0755 -p ${runDir} 107 chown ${clamavUser}:${clamavGroup} ${runDir} 108 ''; 109 110 serviceConfig = { 111 ExecStart = "${pkg}/bin/clamd"; 112 ExecReload = "${pkgs.coreutils}/bin/kill -USR2 $MAINPID"; 113 PrivateTmp = "yes"; 114 PrivateDevices = "yes"; 115 PrivateNetwork = "yes"; 116 }; 117 }; 118 119 systemd.timers.clamav-freshclam = optionalAttrs cfg.updater.enable { 120 description = "Timer for ClamAV virus database updater (freshclam)"; 121 wantedBy = [ "timers.target" ]; 122 timerConfig = { 123 OnCalendar = cfg.updater.interval; 124 Unit = "clamav-freshclam.service"; 125 }; 126 }; 127 128 systemd.services.clamav-freshclam = optionalAttrs cfg.updater.enable { 129 description = "ClamAV virus database updater (freshclam)"; 130 restartTriggers = [ freshclamConfigFile ]; 131 132 preStart = '' 133 mkdir -m 0755 -p ${stateDir} 134 chown ${clamavUser}:${clamavGroup} ${stateDir} 135 ''; 136 137 serviceConfig = { 138 Type = "oneshot"; 139 ExecStart = "${pkg}/bin/freshclam"; 140 PrivateTmp = "yes"; 141 PrivateDevices = "yes"; 142 }; 143 }; 144 }; 145}