at 24.11-pre 4.8 kB view raw
1{ config, lib, pkgs, ... }: 2 3let 4 cfg = config.programs.rust-motd; 5 format = pkgs.formats.toml { }; 6 7 # Order the sections in the TOML according to the order of sections 8 # in `cfg.order`. 9 motdConf = pkgs.runCommand "motd.conf" 10 { 11 __structuredAttrs = true; 12 inherit (cfg) order settings; 13 nativeBuildInputs = [ pkgs.remarshal pkgs.jq ]; 14 } 15 '' 16 cat "$NIX_ATTRS_JSON_FILE" \ 17 | jq '.settings as $settings 18 | .order 19 | map({ key: ., value: $settings."\(.)" }) 20 | from_entries' -r \ 21 | json2toml /dev/stdin "$out" 22 ''; 23in { 24 options.programs.rust-motd = { 25 enable = lib.mkEnableOption "rust-motd, a Message Of The Day (MOTD) generator"; 26 enableMotdInSSHD = lib.mkOption { 27 default = true; 28 type = lib.types.bool; 29 description = '' 30 Whether to let `openssh` print the 31 result when entering a new `ssh`-session. 32 By default either nothing or a static file defined via 33 [](#opt-users.motd) is printed. Because of that, 34 the latter option is incompatible with this module. 35 ''; 36 }; 37 refreshInterval = lib.mkOption { 38 default = "*:0/5"; 39 type = lib.types.str; 40 description = '' 41 Interval in which the {manpage}`motd(5)` file is refreshed. 42 For possible formats, please refer to {manpage}`systemd.time(7)`. 43 ''; 44 }; 45 order = lib.mkOption { 46 type = lib.types.listOf lib.types.str; 47 default = builtins.attrNames cfg.settings; 48 defaultText = lib.literalExpression "attrNames cfg.settings"; 49 description = '' 50 The order of the sections in [](#opt-programs.rust-motd.settings). 51 By default they are ordered alphabetically. 52 53 Context: since attribute sets in Nix are always 54 ordered alphabetically internally this means that 55 56 ```nix 57 { 58 uptime = { /* ... */ }; 59 banner = { /* ... */ }; 60 } 61 ``` 62 63 will still have `banner` displayed before `uptime`. 64 65 To work around that, this option can be used to define the order of all keys, 66 i.e. 67 68 ```nix 69 { 70 order = [ 71 "uptime" 72 "banner" 73 ]; 74 } 75 ``` 76 77 makes sure that `uptime` is placed before `banner` in the motd. 78 ''; 79 }; 80 settings = lib.mkOption { 81 type = lib.types.attrsOf format.type; 82 description = '' 83 Settings on what to generate. Please read the 84 [upstream documentation](https://github.com/rust-motd/rust-motd/blob/main/README.md#configuration) 85 for further information. 86 ''; 87 }; 88 }; 89 config = lib.mkIf cfg.enable { 90 assertions = [ 91 { assertion = config.users.motd == null; 92 message = '' 93 `programs.rust-motd` is incompatible with `users.motd`! 94 ''; 95 } 96 { assertion = builtins.sort (a: b: a < b) cfg.order == builtins.attrNames cfg.settings; 97 message = '' 98 Please ensure that every section from `programs.rust-motd.settings` is present in 99 `programs.rust-motd.order`. 100 ''; 101 } 102 ]; 103 systemd.services.rust-motd = { 104 path = with pkgs; [ bash ]; 105 documentation = [ "https://github.com/rust-motd/rust-motd/blob/v${pkgs.rust-motd.version}/README.md" ]; 106 description = "motd generator"; 107 wantedBy = [ "multi-user.target" ]; 108 serviceConfig = { 109 ExecStart = "${pkgs.writeShellScript "update-motd" '' 110 ${pkgs.rust-motd}/bin/rust-motd ${motdConf} > motd 111 ''}"; 112 CapabilityBoundingSet = [ "" ]; 113 LockPersonality = true; 114 MemoryDenyWriteExecute = true; 115 NoNewPrivileges = true; 116 PrivateDevices = true; 117 PrivateTmp = true; 118 ProtectClock = true; 119 ProtectControlGroups = true; 120 ProtectHome = true; 121 ProtectHostname = true; 122 ProtectKernelModules = true; 123 ProtectKernelLogs = true; 124 ProtectKernelTunables = true; 125 ProtectSystem = "full"; 126 StateDirectory = "rust-motd"; 127 RestrictAddressFamilies = [ "AF_UNIX" ]; 128 RestrictNamespaces = true; 129 RestrictRealtime = true; 130 RestrictSUIDSGID = true; 131 RemoveIPC = true; 132 WorkingDirectory = "/var/lib/rust-motd"; 133 }; 134 }; 135 systemd.timers.rust-motd = { 136 wantedBy = [ "timers.target" ]; 137 timerConfig.OnCalendar = cfg.refreshInterval; 138 }; 139 security.pam.services.sshd.text = lib.mkIf cfg.enableMotdInSSHD (lib.mkDefault (lib.mkAfter '' 140 session optional ${pkgs.pam}/lib/security/pam_motd.so motd=/var/lib/rust-motd/motd 141 '')); 142 services.openssh.extraConfig = lib.mkIf (cfg.settings ? last_login && cfg.settings.last_login != {}) '' 143 PrintLastLog no 144 ''; 145 }; 146 meta.maintainers = with lib.maintainers; [ ma27 ]; 147}