1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.haveged;
9
10in
11
12{
13
14 ###### interface
15
16 options = {
17
18 services.haveged = {
19
20 enable = lib.mkEnableOption ''
21 haveged entropy daemon, which refills /dev/random when low.
22 NOTE: does nothing on kernels newer than 5.6
23 '';
24 # source for the note https://github.com/jirka-h/haveged/issues/57
25
26 refill_threshold = lib.mkOption {
27 type = lib.types.int;
28 default = 1024;
29 description = ''
30 The number of bits of available entropy beneath which
31 haveged should refill the entropy pool.
32 '';
33 };
34
35 };
36
37 };
38
39 config = lib.mkIf cfg.enable {
40
41 # https://github.com/jirka-h/haveged/blob/a4b69d65a8dfc5a9f52ff8505c7f58dcf8b9234f/contrib/Fedora/haveged.service
42 systemd.services.haveged = {
43 description = "Entropy Daemon based on the HAVEGE algorithm";
44 unitConfig = {
45 Documentation = "man:haveged(8)";
46 DefaultDependencies = false;
47 ConditionKernelVersion = "<5.6";
48 };
49 wantedBy = [ "sysinit.target" ];
50 after = [ "systemd-tmpfiles-setup-dev.service" ];
51 before = [
52 "sysinit.target"
53 "shutdown.target"
54 "systemd-journald.service"
55 ];
56
57 serviceConfig = {
58 ExecStart = "${pkgs.haveged}/bin/haveged -w ${toString cfg.refill_threshold} --Foreground -v 1";
59 Restart = "always";
60 SuccessExitStatus = "137 143";
61 SecureBits = "noroot-locked";
62 CapabilityBoundingSet = [
63 "CAP_SYS_ADMIN"
64 "CAP_SYS_CHROOT"
65 ];
66 # We can *not* set PrivateTmp=true as it can cause an ordering cycle.
67 PrivateTmp = false;
68 PrivateDevices = true;
69 ProtectSystem = "full";
70 ProtectHome = true;
71 ProtectHostname = true;
72 ProtectKernelLogs = true;
73 ProtectKernelModules = true;
74 RestrictNamespaces = true;
75 RestrictRealtime = true;
76 LockPersonality = true;
77 MemoryDenyWriteExecute = true;
78 SystemCallArchitectures = "native";
79 SystemCallFilter = [
80 "@system-service"
81 "newuname"
82 "~@mount"
83 ];
84 SystemCallErrorNumber = "EPERM";
85 };
86
87 };
88 };
89
90}